@@ -3,6 +3,7 @@ package base
33import (
44 "errors"
55 "fmt"
6+ "log"
67 "slices"
78 "strings"
89
@@ -22,25 +23,57 @@ type DeleteCmd struct {
2223 ShortDescription string
2324 NameSuggestions func (client hcapi2.Client ) func () []string
2425 AdditionalFlags func (* cobra.Command )
25- Fetch func ( s state. State , cmd * cobra. Command , idOrName string ) ( interface {}, * hcloud. Response , error )
26+ Fetch FetchFunc
2627 Delete func (s state.State , cmd * cobra.Command , resource interface {}) (* hcloud.Action , error )
2728
29+ // FetchFunc is a factory function that produces [DeleteCmd.Fetch]. Should be set in case the resource has
30+ // more than a single identifier that is used in the positional arguments.
31+ // See [DeleteCmd.PositionalArgumentOverride].
32+ FetchFunc func (s state.State , cmd * cobra.Command , args []string ) (FetchFunc , error )
33+
34+ // In case the resource does not have a single identifier that matches [DeleteCmd.ResourceNameSingular], this field
35+ // can be set to define the list of positional arguments.
36+ // For example, passing:
37+ // []string{"a", "b", "c"}
38+ // Would result in the usage string:
39+ // <a> <b> <c>...
40+ // Where c is are resources to be deleted.
41+ PositionalArgumentOverride []string
42+
43+ // Can be set if the default [DeleteCmd.NameSuggestions] is not enough. This is usually the case when
44+ // [DeleteCmd.FetchWithArgs] and [DeleteCmd.PositionalArgumentOverride] is being used.
45+ ValidArgsFunction func (client hcapi2.Client ) []cobra.CompletionFunc
46+
2847 // Experimental is a function that will be used to mark the command as experimental.
2948 Experimental func (state.State , * cobra.Command ) * cobra.Command
3049}
3150
51+ type FetchFunc func (s state.State , cmd * cobra.Command , idOrName string ) (any , * hcloud.Response , error )
52+
3253// CobraCommand creates a command that can be registered with cobra.
3354func (dc * DeleteCmd ) CobraCommand (s state.State ) * cobra.Command {
55+ var suggestArgs []cobra.CompletionFunc
56+ switch {
57+ case dc .NameSuggestions != nil :
58+ suggestArgs = append (suggestArgs ,
59+ cmpl .SuggestCandidatesF (dc .NameSuggestions (s .Client ())),
60+ )
61+ case dc .ValidArgsFunction != nil :
62+ suggestArgs = append (suggestArgs , dc .ValidArgsFunction (s .Client ())... )
63+ default :
64+ log .Fatalf ("delete command %s is missing ValidArgsFunction or NameSuggestions" , dc .ResourceNameSingular )
65+ }
66+
3467 opts := ""
3568 if dc .AdditionalFlags != nil {
3669 opts = "[options] "
3770 }
3871
3972 cmd := & cobra.Command {
40- Use : fmt .Sprintf ("delete %s<%s> ..." , opts , util . ToKebabCase (dc .ResourceNameSingular )),
73+ Use : fmt .Sprintf ("delete %s%s ..." , opts , positionalArguments (dc .ResourceNameSingular , dc . PositionalArgumentOverride )),
4174 Short : dc .ShortDescription ,
4275 Args : util .Validate ,
43- ValidArgsFunction : cmpl .SuggestCandidatesF ( dc . NameSuggestions ( s . Client ()) ),
76+ ValidArgsFunction : cmpl .SuggestArgs ( suggestArgs ... ),
4477 TraverseChildren : true ,
4578 DisableFlagsInUseLine : true ,
4679 PreRunE : util .ChainRunE (s .EnsureToken ),
@@ -62,17 +95,32 @@ const deleteBatchSize = 10
6295
6396// Run executes a delete command.
6497func (dc * DeleteCmd ) Run (s state.State , cmd * cobra.Command , args []string ) error {
65- errs := make ([]error , 0 , len (args ))
66- deleted := make ([]string , 0 , len (args ))
98+ toDelete := args [max (0 , len (dc .PositionalArgumentOverride )- 1 ):]
99+
100+ errs := make ([]error , 0 , len (toDelete ))
101+ deleted := make ([]string , 0 , len (toDelete ))
102+
103+ var (
104+ fetch FetchFunc
105+ err error
106+ )
107+ if dc .FetchFunc != nil {
108+ fetch , err = dc .FetchFunc (s , cmd , args )
109+ if err != nil {
110+ return err
111+ }
112+ } else {
113+ fetch = dc .Fetch
114+ }
67115
68- for batch := range slices .Chunk (args , deleteBatchSize ) {
116+ for batch := range slices .Chunk (toDelete , deleteBatchSize ) {
69117 results := make ([]util.ResourceState , len (batch ))
70118 actions := make ([]* hcloud.Action , 0 , len (batch ))
71119
72120 for i , idOrName := range batch {
73121 results [i ] = util.ResourceState {IDOrName : idOrName }
74122
75- resource , _ , err := dc . Fetch (s , cmd , idOrName )
123+ resource , _ , err := fetch (s , cmd , idOrName )
76124 if err != nil {
77125 results [i ].Error = err
78126 continue
0 commit comments