diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5ec40ec..78dbd7e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v6 with: - go-version: '1.25.5' + go-version: '1.26.0' - name: Install quill CLI run: curl -sSfL https://raw.githubusercontent.com/anchore/quill/main/install.sh | sh -s -- -b /usr/local/bin - name: Check if snapshot build diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 140d577..f5f152b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v6 with: - go-version: '1.25.5' + go-version: '1.26.0' - name: Install dependencies run: go mod download diff --git a/cmd/agent/root.go b/cmd/agent/root.go index d0c9c2b..9355b6a 100644 --- a/cmd/agent/root.go +++ b/cmd/agent/root.go @@ -54,6 +54,10 @@ func New() *cobra.Command { rootCmd.PersistentFlags().BoolVarP(&config.Verbose, "verbose", "v", false, "verbose mode") rootCmd.PersistentFlags().BoolVarP(&config.JSONOutput, "json", "j", false, "output as JSON") rootCmd.PersistentFlags().BoolVarP(&config.CSVOutput, "csv", "x", false, "output as CSV") + rootCmd.MarkFlagsMutuallyExclusive("json", "csv") + + // Disable file completions globally (no flag in this CLI takes a file path) + rootCmd.CompletionOptions.DisableDefaultCmd = true // Special client commands cmd.SelfupdateCommand(&rootCmd) diff --git a/cmd/completion.go b/cmd/completion.go index a08e21f..dce82a8 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -15,13 +15,13 @@ func CompletionCommand(rootCmd *cobra.Command) { RunE: func(cmd *cobra.Command, args []string) error { switch args[0] { case "bash": - _ = rootCmd.GenBashCompletion(cmd.OutOrStdout()) + _ = rootCmd.GenBashCompletionV2(cmd.OutOrStdout(), true) case "zsh": _ = rootCmd.GenZshCompletion(cmd.OutOrStdout()) case "fish": _ = rootCmd.GenFishCompletion(cmd.OutOrStdout(), true) case "powershell": - _ = rootCmd.GenPowerShellCompletion(cmd.OutOrStdout()) + _ = rootCmd.GenPowerShellCompletionWithDesc(cmd.OutOrStdout()) } return nil diff --git a/cmd/node/root.go b/cmd/node/root.go index 1648023..fb2786d 100644 --- a/cmd/node/root.go +++ b/cmd/node/root.go @@ -10,6 +10,7 @@ var RootNodeCommand = &cobra.Command{ Use: "node", Short: "Utility to combine multiple nodes api actions", Long: `Utility to combine multiple nodes api actions`, + GroupID: "resources", DisableFlagsInUseLine: true, Args: cobra.MatchAll(cobra.ExactArgs(0), cobra.OnlyValidArgs), PersistentPreRunE: func(cobraCmd *cobra.Command, args []string) error { diff --git a/cmd/project/root.go b/cmd/project/root.go index 4bea6c9..eb4c308 100644 --- a/cmd/project/root.go +++ b/cmd/project/root.go @@ -10,6 +10,7 @@ var RootProjectCommand = &cobra.Command{ Use: "project", Short: "Utility to combine multiple project api actions", Long: `Utility to combine multiple project api actions`, + GroupID: "admin", DisableFlagsInUseLine: true, Args: cobra.MatchAll(cobra.ExactArgs(0), cobra.OnlyValidArgs), RunE: func(cobraCmd *cobra.Command, args []string) error { diff --git a/go.mod b/go.mod index 6931764..9cd42de 100644 --- a/go.mod +++ b/go.mod @@ -1,28 +1,28 @@ module github.com/G-PORTAL/gpcore-cli -go 1.25.5 +go 1.26.0 // For development //replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( - buf.build/gen/go/gportal/gpcore/grpc/go v1.6.0-20251103085422-b156624a826d.1 - buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20251103085422-b156624a826d.1 + buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260115091005-9b1a7a0cbe2d.1 + buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260115091005-9b1a7a0cbe2d.1 github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f github.com/Nerzal/gocloak/v13 v13.9.0 github.com/charmbracelet/log v0.4.2 github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 github.com/charmbracelet/wish v1.4.7 - github.com/creativeprojects/go-selfupdate v1.5.1 + github.com/creativeprojects/go-selfupdate v1.5.2 github.com/dave/jennifer v1.7.1 github.com/gertd/go-pluralize v0.2.1 - github.com/jedib0t/go-pretty/v6 v6.7.7 - github.com/melbahja/goph v1.4.0 + github.com/jedib0t/go-pretty/v6 v6.7.8 + github.com/melbahja/goph v1.5.0 github.com/spf13/cobra v1.10.2 github.com/stoewer/go-strcase v1.3.1 github.com/zalando/go-keyring v0.2.6 - golang.org/x/crypto v0.47.0 - google.golang.org/grpc v1.77.0 + golang.org/x/crypto v0.48.0 + google.golang.org/grpc v1.79.1 google.golang.org/protobuf v1.36.11 gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 gopkg.in/yaml.v3 v3.0.1 @@ -57,7 +57,7 @@ require ( github.com/go-resty/resty/v2 v2.17.1 // indirect github.com/godbus/dbus/v5 v5.2.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect - github.com/google/go-github/v30 v30.1.0 // indirect + github.com/google/go-github/v74 v74.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect @@ -78,13 +78,13 @@ require ( github.com/segmentio/ksuid v1.0.4 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/ulikunitz/xz v0.5.15 // indirect - github.com/xanzy/go-gitlab v0.115.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + gitlab.com/gitlab-org/api/client-go v1.9.1 // indirect golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect - golang.org/x/net v0.48.0 // indirect + golang.org/x/net v0.49.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.33.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect golang.org/x/time v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect ) diff --git a/go.sum b/go.sum index 5b39608..bcf6e61 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,10 @@ al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeX al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 h1:j9yeqTWEFrtimt8Nng2MIeRrpoCvQzM9/g25XTvqUGg= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM= -buf.build/gen/go/gportal/gpcore/grpc/go v1.6.0-20251103085422-b156624a826d.1 h1:rQT0OIQLVV3cts4cj9OjDhJ3Ho4/TL3Lq1wJIZ951+w= -buf.build/gen/go/gportal/gpcore/grpc/go v1.6.0-20251103085422-b156624a826d.1/go.mod h1:L/Fn0LfYaOU+jnZHI6VDZ66tPtYtoyIBg0tK5/QuGBE= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20251103085422-b156624a826d.1 h1:O66HGIt3igJB7DbDnBrjUd4IWz7bKB4MKDVOJFGqpZA= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20251103085422-b156624a826d.1/go.mod h1:P8EapWY+m/+4oATK4HFxRi9zB1QyW1oAz+yvxT4ckt4= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260115091005-9b1a7a0cbe2d.1 h1:xGdfEcStnSYRi+2wcl4lytjU1Xc0KPqQ1sIbfdTkvGU= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260115091005-9b1a7a0cbe2d.1/go.mod h1:hIDrKxL4ptmR/Xoh7nUdtFVyGi+UVDV4w4hwUPZ5cwc= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260115091005-9b1a7a0cbe2d.1 h1:akVA9bdDvSGgV9/eFWDxSOaZS6aRGTy0LS8VMUxnLa8= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260115091005-9b1a7a0cbe2d.1/go.mod h1:P8EapWY+m/+4oATK4HFxRi9zB1QyW1oAz+yvxT4ckt4= code.gitea.io/sdk/gitea v0.22.1 h1:7K05KjRORyTcTYULQ/AwvlVS6pawLcWyXZcTr7gHFyA= code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= @@ -20,6 +20,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= @@ -53,8 +55,8 @@ github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsV github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/creativeprojects/go-selfupdate v1.5.1 h1:fuyEGFFfqcC8SxDGolcEPYPLXGQ9Mcrc5uRyRG2Mqnk= -github.com/creativeprojects/go-selfupdate v1.5.1/go.mod h1:2uY75rP8z/D/PBuDn6mlBnzu+ysEmwOJfcgF8np0JIM= +github.com/creativeprojects/go-selfupdate v1.5.2 h1:3KR3JLrq70oplb9yZzbmJ89qRP78D1AN/9u+l3k0LJ4= +github.com/creativeprojects/go-selfupdate v1.5.2/go.mod h1:BCOuwIl1dRRCmPNRPH0amULeZqayhKyY2mH/h4va7Dk= github.com/danieljoos/wincred v1.2.3 h1:v7dZC2x32Ut3nEfRH+vhoZGvN72+dQ/snVXo/vMFLdQ= github.com/danieljoos/wincred v1.2.3/go.mod h1:6qqX0WNrS4RzPZ1tnroDzq9kY3fu1KwE7MRLQK4X0bs= github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo= @@ -84,15 +86,13 @@ github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8= github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo= -github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-github/v74 v74.0.0 h1:yZcddTUn8DPbj11GxnMrNiAnXH14gNs559AsUpNpPgM= +github.com/google/go-github/v74 v74.0.0/go.mod h1:ubn/YdyftV80VPSI26nSJvaEsTOnsjrxG3o9kJhcyak= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -109,8 +109,8 @@ github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bP github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.7.7 h1:Y1Id3lJ3k4UB8uwWWy3l8EVFnUlx5chR5+VbsofPNX0= -github.com/jedib0t/go-pretty/v6 v6.7.7/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o= +github.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= @@ -123,8 +123,8 @@ github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2J github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= -github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs= -github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68= +github.com/melbahja/goph v1.5.0 h1:RQUBpLvfg3i7fjfG8rTcSWyMjVRfdhwrrfQhjYee4dQ= +github.com/melbahja/goph v1.5.0/go.mod h1:dDwo+44cmvfDLdiVpc6fJxexf5BA5yEDUeE5YgtuDO4= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= @@ -135,7 +135,6 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU= github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -158,7 +157,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -166,90 +164,62 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/xanzy/go-gitlab v0.115.0 h1:6DmtItNcVe+At/liXSgfE/DZNZrGfalQmBRmOcJjOn8= -github.com/xanzy/go-gitlab v0.115.0/go.mod h1:5XCDtM7AM6WMKmfDdOiEpyRWUqui2iS9ILfvCZ2gJ5M= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= +gitlab.com/gitlab-org/api/client-go v1.9.1 h1:tZm+URa36sVy8UCEHQyGGJ8COngV4YqMHpM6k9O5tK8= +gitlab.com/gitlab-org/api/client-go v1.9.1/go.mod h1:71yTJk1lnHCWcZLvM5kPAXzeJ2fn5GjaoV8gTOPd4ME= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/pkg/generator/add_commands.go b/pkg/generator/add_commands.go index 4d08060..a9580f6 100644 --- a/pkg/generator/add_commands.go +++ b/pkg/generator/add_commands.go @@ -3,10 +3,26 @@ package generator import ( . "github.com/dave/jennifer/jen" "github.com/stoewer/go-strcase" + "sort" ) +// CommandGroup defines a group of commands for help output organization. +type CommandGroup struct { + ID string + Title string +} + +// CommandGroups defines the available command groups in display order. +var CommandGroups = []CommandGroup{ + {ID: "resources", Title: "Cloud Resources:"}, + {ID: "networking", Title: "Networking:"}, + {ID: "billing", Title: "Billing & Reporting:"}, + {ID: "admin", Title: "Administration:"}, +} + // GenerateAddCommands generates the AddGeneratedCommands function, which will -// add all generated commands to the root command. +// add all generated commands to the root command, including command group +// registration for organized help output. func GenerateAddCommands(commands []string, targetFilename string) error { f := NewFile("cmd") warningComment(f) @@ -20,7 +36,23 @@ func GenerateAddCommands(commands []string, targetFilename string) error { f.Func().Id("AddGeneratedCommands"). Params(Id("cmd").Op("*").Qual("github.com/spf13/cobra", "Command")). BlockFunc(func(g *Group) { - for _, command := range commands { + // Register command groups + for _, group := range CommandGroups { + g.Id("cmd").Dot("AddGroup").Call( + Op("&").Qual("github.com/spf13/cobra", "Group").Values(Dict{ + Id("ID"): Lit(group.ID), + Id("Title"): Lit(group.Title), + })) + } + g.Line() + + // Sort commands for consistent output + sorted := make([]string, len(commands)) + copy(sorted, commands) + sort.Strings(sorted) + + // Add commands + for _, command := range sorted { pkg := escapePackage(command) g.Id("cmd").Dot("AddCommand").Call( Qual("github.com/G-PORTAL/gpcore-cli/cmd/"+pkg, "Root"+strcase.UpperCamelCase(pkg)+"Command")) diff --git a/pkg/generator/definition.go b/pkg/generator/definition.go index 13506bb..2868d6f 100644 --- a/pkg/generator/definition.go +++ b/pkg/generator/definition.go @@ -68,6 +68,7 @@ type SubcommandDefinition struct { Identifier string `yaml:"identifier"` IdentifierKey string `yaml:"identifier-key"` Description string `yaml:"description"` + Group string `yaml:"group"` } type SubcommandMetadata struct { diff --git a/pkg/generator/definition/billing-profile.yaml b/pkg/generator/definition/billing-profile.yaml index 683ef20..1e6cad7 100644 --- a/pkg/generator/definition/billing-profile.yaml +++ b/pkg/generator/definition/billing-profile.yaml @@ -1,4 +1,5 @@ description: Manage billing profiles for your account +group: billing actions: list: diff --git a/pkg/generator/definition/country.yaml b/pkg/generator/definition/country.yaml index aee7966..6eed95c 100644 --- a/pkg/generator/definition/country.yaml +++ b/pkg/generator/definition/country.yaml @@ -1,4 +1,5 @@ description: Country related actions +group: admin actions: list: diff --git a/pkg/generator/definition/datacenter.yaml b/pkg/generator/definition/datacenter.yaml index 8ece75a..5a7bbf1 100644 --- a/pkg/generator/definition/datacenter.yaml +++ b/pkg/generator/definition/datacenter.yaml @@ -1,4 +1,5 @@ description: List or update datacenter colocations +group: admin actions: list: diff --git a/pkg/generator/definition/flavour.yaml b/pkg/generator/definition/flavour.yaml index 44a9593..de3eb0a 100644 --- a/pkg/generator/definition/flavour.yaml +++ b/pkg/generator/definition/flavour.yaml @@ -1,4 +1,5 @@ description: Flavours (images/sizes) the customer can choose from +group: resources actions: list: diff --git a/pkg/generator/definition/image.yaml b/pkg/generator/definition/image.yaml index 0acb8df..a567944 100644 --- a/pkg/generator/definition/image.yaml +++ b/pkg/generator/definition/image.yaml @@ -1,4 +1,5 @@ description: Disk images to boot and install on the nodes +group: resources actions: list: diff --git a/pkg/generator/definition/ip.yaml b/pkg/generator/definition/ip.yaml index 9f8baef..dc2869e 100644 --- a/pkg/generator/definition/ip.yaml +++ b/pkg/generator/definition/ip.yaml @@ -1,4 +1,5 @@ description: IP related actions +group: networking actions: history: diff --git a/pkg/generator/definition/log.yaml b/pkg/generator/definition/log.yaml index 6efc236..cb02ee0 100644 --- a/pkg/generator/definition/log.yaml +++ b/pkg/generator/definition/log.yaml @@ -1,4 +1,5 @@ description: Server and admin logs +group: admin actions: server: diff --git a/pkg/generator/definition/network-arp.yaml b/pkg/generator/definition/network-arp.yaml index e17f9f0..7403624 100644 --- a/pkg/generator/definition/network-arp.yaml +++ b/pkg/generator/definition/network-arp.yaml @@ -1,4 +1,5 @@ description: Network ARP table +group: networking actions: lookup: diff --git a/pkg/generator/definition/network-subnet.yaml b/pkg/generator/definition/network-subnet.yaml index acac725..bf1e1af 100644 --- a/pkg/generator/definition/network-subnet.yaml +++ b/pkg/generator/definition/network-subnet.yaml @@ -1,4 +1,5 @@ description: Manage subnets +group: networking actions: delete: diff --git a/pkg/generator/definition/network-switch.yaml b/pkg/generator/definition/network-switch.yaml index a0b1cac..450a48b 100644 --- a/pkg/generator/definition/network-switch.yaml +++ b/pkg/generator/definition/network-switch.yaml @@ -1,4 +1,5 @@ description: Network Switches +group: networking actions: list: diff --git a/pkg/generator/definition/network.yaml b/pkg/generator/definition/network.yaml index d57eca4..cb7811c 100644 --- a/pkg/generator/definition/network.yaml +++ b/pkg/generator/definition/network.yaml @@ -1,4 +1,5 @@ description: Network management +group: networking actions: list: diff --git a/pkg/generator/definition/node-agent.yaml b/pkg/generator/definition/node-agent.yaml index 5106630..940f5cc 100644 --- a/pkg/generator/definition/node-agent.yaml +++ b/pkg/generator/definition/node-agent.yaml @@ -1,4 +1,5 @@ description: Agents, which are deployed on the nodes +group: resources actions: list: diff --git a/pkg/generator/definition/node.yaml b/pkg/generator/definition/node.yaml index 3bcd20b..e4390b4 100644 --- a/pkg/generator/definition/node.yaml +++ b/pkg/generator/definition/node.yaml @@ -1,4 +1,5 @@ description: Node related actions +group: resources actions: list: diff --git a/pkg/generator/definition/operating-systems.yaml b/pkg/generator/definition/operating-systems.yaml index 9cec182..6e9c867 100644 --- a/pkg/generator/definition/operating-systems.yaml +++ b/pkg/generator/definition/operating-systems.yaml @@ -1,4 +1,5 @@ description: Operating system related operations +group: resources actions: list: diff --git a/pkg/generator/definition/project-cloudprovider.yaml b/pkg/generator/definition/project-cloudprovider.yaml index 1f2b7a3..ef97d2b 100644 --- a/pkg/generator/definition/project-cloudprovider.yaml +++ b/pkg/generator/definition/project-cloudprovider.yaml @@ -1,4 +1,5 @@ description: Project cloud providers +group: admin actions: list: diff --git a/pkg/generator/definition/project-image.yaml b/pkg/generator/definition/project-image.yaml index b652482..fc15e6c 100644 --- a/pkg/generator/definition/project-image.yaml +++ b/pkg/generator/definition/project-image.yaml @@ -1,4 +1,5 @@ description: Project images +group: resources actions: list: diff --git a/pkg/generator/definition/project.yaml b/pkg/generator/definition/project.yaml index 0f348fc..0ed9f5e 100644 --- a/pkg/generator/definition/project.yaml +++ b/pkg/generator/definition/project.yaml @@ -1,4 +1,5 @@ description: Project related actions +group: admin actions: list: diff --git a/pkg/generator/definition/region.yaml b/pkg/generator/definition/region.yaml index fd4a194..30440d1 100644 --- a/pkg/generator/definition/region.yaml +++ b/pkg/generator/definition/region.yaml @@ -1,4 +1,5 @@ description: Manage regions in which datacenters are located +group: admin actions: list: diff --git a/pkg/generator/definition/reporting.yaml b/pkg/generator/definition/reporting.yaml index faef6e0..fb6df78 100644 --- a/pkg/generator/definition/reporting.yaml +++ b/pkg/generator/definition/reporting.yaml @@ -1,4 +1,5 @@ description: Reporting +group: billing actions: list: diff --git a/pkg/generator/definition/server-pool.yaml b/pkg/generator/definition/server-pool.yaml index 3a66610..2af4d6a 100644 --- a/pkg/generator/definition/server-pool.yaml +++ b/pkg/generator/definition/server-pool.yaml @@ -1,4 +1,5 @@ description: Server Pools +group: resources actions: list: diff --git a/pkg/generator/definition/server.yaml b/pkg/generator/definition/server.yaml index a086c81..d20ac80 100644 --- a/pkg/generator/definition/server.yaml +++ b/pkg/generator/definition/server.yaml @@ -1,4 +1,5 @@ description: Physical servers +group: resources actions: list: diff --git a/pkg/generator/definition/spla.yaml b/pkg/generator/definition/spla.yaml index 7d07912..b7c8e7c 100644 --- a/pkg/generator/definition/spla.yaml +++ b/pkg/generator/definition/spla.yaml @@ -1,4 +1,5 @@ description: SPLA Reporting +group: billing actions: get: diff --git a/pkg/generator/definition/sshkey.yaml b/pkg/generator/definition/sshkey.yaml index 2ab757a..dcc5698 100644 --- a/pkg/generator/definition/sshkey.yaml +++ b/pkg/generator/definition/sshkey.yaml @@ -1,4 +1,5 @@ description: SSH Key management +group: admin actions: list: diff --git a/pkg/generator/definition/timezone.yaml b/pkg/generator/definition/timezone.yaml index d06a938..c0c7ad0 100644 --- a/pkg/generator/definition/timezone.yaml +++ b/pkg/generator/definition/timezone.yaml @@ -1,4 +1,5 @@ description: Timezones +group: admin actions: list: diff --git a/pkg/generator/definition/user.yaml b/pkg/generator/definition/user.yaml index 575becc..aea5311 100644 --- a/pkg/generator/definition/user.yaml +++ b/pkg/generator/definition/user.yaml @@ -1,4 +1,5 @@ description: User management +group: admin actions: ssh-keys: diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index 3aea70d..d83ee63 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -62,9 +62,9 @@ func main() { log.Fatal(err) } } - // Create root command if not exist + // Generate root command if no custom root.go exists (always regenerate root_gen.go) if _, err := os.Stat("./cmd/" + subcommandName + "/root.go"); os.IsNotExist(err) { - log.Printf(" Create root command ./cmd/%s/root"+generatedFileSuffix+".go ...\n", subcommandName) + log.Printf(" Generate root command ./cmd/%s/root"+generatedFileSuffix+".go ...\n", subcommandName) targetFilename := "./cmd/" + subcommandName + "/root" + generatedFileSuffix + ".go" err = generator.GenerateRootCommand(metadata, targetFilename) if err != nil { diff --git a/pkg/generator/root_command.go b/pkg/generator/root_command.go index 1ba7e81..2498b94 100644 --- a/pkg/generator/root_command.go +++ b/pkg/generator/root_command.go @@ -18,7 +18,7 @@ func GenerateRootCommand(metadata SubcommandDefinition, targetFilename string) e commandName := "Root" + strcase.UpperCamelCase(metadata.Name) + "Command" command := strings.ReplaceAll(metadata.Name, "_", "-") - f.Var().Add(Id(commandName).Op("=").Op("&").Qual("github.com/spf13/cobra", "Command").Values(Dict{ + values := Dict{ Id("Use"): Lit(command), Id("Short"): Lit(metadata.Description), Id("Long"): Lit(metadata.Description), @@ -27,7 +27,11 @@ func GenerateRootCommand(metadata SubcommandDefinition, targetFilename string) e Id("TraverseChildren"): True(), Id("Args"): Qual("github.com/spf13/cobra", "OnlyValidArgs"), Id("RunE"): Qual("github.com/G-PORTAL/gpcore-cli/cmd/help", "UnknownSubcommandAction"), - })) + } + if metadata.Group != "" { + values[Id("GroupID")] = Lit(metadata.Group) + } + f.Var().Add(Id(commandName).Op("=").Op("&").Qual("github.com/spf13/cobra", "Command").Values(values)) return f.Save(targetFilename) } diff --git a/pkg/generator/sub_command.go b/pkg/generator/sub_command.go index 90683bc..063185b 100644 --- a/pkg/generator/sub_command.go +++ b/pkg/generator/sub_command.go @@ -85,22 +85,13 @@ func GenerateSubCommand(metadata SubcommandMetadata, targetFilename string) erro Id("Long"): Lit(metadata.Action.Description), Id("SilenceUsage"): True(), Id("SilenceErrors"): True(), - Id("Args"): Qual("github.com/spf13/cobra", "OnlyValidArgs"), + Id("Args"): Qual("github.com/spf13/cobra", "NoArgs"), Id("RunE"): Func().Params( Id("cobraCmd").Op("*").Qual("github.com/spf13/cobra", "Command"), Id("args").Index().String()).Error(). Block(runCommand(name, metadata)...), } - // Add flags and params - if len(metadata.Action.Params) > 0 { - var args []Code - for _, v := range metadata.Action.Params { - args = append(args, Lit(strcase.KebabCase(v.Name))) - } - values[Id("ValidArgs")] = Index().String().Values(args...) - } - // Final command f.Var().Add(Id(name+"Cmd").Op("="). Op("&").Qual("github.com/spf13/cobra", "Command"). @@ -614,6 +605,40 @@ func initFunc(name string, metadata SubcommandMetadata) []Code { c = append(c, Line()) } + // Register shell completion functions for enum-typed flags + for _, param := range metadata.Action.Params { + paramType := param.Type + if isArrayType(paramType) { + paramType = strings.TrimPrefix(paramType, "[]") + } + if isEnumType(paramType) { + enumPrefix := strings.ToUpper(strcase.SnakeCase(stripEnum(stripPackage(paramType)))) + "_" + c = append(c, + Id(strcase.LowerCamelCase(name)+"Cmd"). + Dot("RegisterFlagCompletionFunc").Call( + Lit(strcase.KebabCase(param.Name)), + Func().Params( + Id("cmd").Op("*").Qual("github.com/spf13/cobra", "Command"), + Id("args").Index().String(), + Id("toComplete").String(), + ).Params(Index().String(), Qual("github.com/spf13/cobra", "ShellCompDirective")).Block( + Var().Id("completions").Index().String(), + For(List(Id("_"), Id("v")).Op(":=").Range().Qual(clientPackageName(paramType), stripPackage(paramType)+"_name")).Block( + If(Qual("strings", "HasSuffix").Call(Id("v"), Lit("UNSPECIFIED"))).Block(Continue()), + Id("completions").Op("=").Append( + Id("completions"), + Qual("strings", "ToLower").Call( + Qual("strings", "TrimPrefix").Call(Id("v"), Lit(enumPrefix)), + ), + ), + ), + Return(Id("completions"), Qual("github.com/spf13/cobra", "ShellCompDirectiveNoFileComp")), + ), + )) + } + } + c = append(c, Line()) + // Add the command to the root command when the user has set up the admin // configuration. addCommand := Id("Root" + strcase.UpperCamelCase(metadata.Definition.Name) + "Command"). diff --git a/tools.go b/tools.go deleted file mode 100644 index f8cdefd..0000000 --- a/tools.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build tools -// +build tools - -package tools - -import _ "github.com/gertd/go-pluralize" -import _ "github.com/stoewer/go-strcase"