From aabc4ee47baa913f1b2563ced8cad4eff66e0300 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Tue, 18 Nov 2025 09:40:00 +0100 Subject: [PATCH 01/20] chore(deps): update all dependencies and go itself Signed-off-by: Aaron Fischer --- go.mod | 58 ++++++++++--------- go.sum | 178 +++++++++++++++++++++++---------------------------------- 2 files changed, 102 insertions(+), 134 deletions(-) diff --git a/go.mod b/go.mod index 79fbae2..ec56036 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/G-PORTAL/gpcore-cli -go 1.24.6 +go 1.25.4 // For development //replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( - buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2 - buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1 + buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 + buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.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 @@ -16,44 +16,46 @@ require ( github.com/creativeprojects/go-selfupdate v1.5.1 github.com/dave/jennifer v1.7.1 github.com/gertd/go-pluralize v0.2.1 - github.com/jedib0t/go-pretty/v6 v6.6.8 + github.com/jedib0t/go-pretty/v6 v6.7.2 github.com/melbahja/goph v1.4.0 github.com/spf13/cobra v1.10.1 github.com/stoewer/go-strcase v1.3.1 github.com/zalando/go-keyring v0.2.6 - golang.org/x/crypto v0.42.0 - google.golang.org/grpc v1.75.1 - google.golang.org/protobuf v1.36.9 + golang.org/x/crypto v0.44.0 + google.golang.org/grpc v1.77.0 + google.golang.org/protobuf v1.36.10 gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 gopkg.in/yaml.v3 v3.0.1 ) require ( al.essio.dev/pkg/shellescape v1.6.0 // indirect - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 // indirect - code.gitea.io/sdk/gitea v0.22.0 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 // indirect + code.gitea.io/sdk/gitea v0.22.1 // indirect github.com/42wim/httpsig v1.2.3 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.3.2 // indirect - github.com/charmbracelet/keygen v0.5.3 // indirect + github.com/charmbracelet/colorprofile v0.3.3 // indirect + github.com/charmbracelet/keygen v0.5.4 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.10.1 // indirect - github.com/charmbracelet/x/cellbuf v0.0.13 // indirect - github.com/charmbracelet/x/conpty v0.1.1 // indirect - github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21 // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect + github.com/charmbracelet/x/ansi v0.11.1 // indirect + github.com/charmbracelet/x/cellbuf v0.0.14 // indirect + github.com/charmbracelet/x/conpty v0.2.0 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect + github.com/clipperhouse/displaywidth v0.6.0 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/creack/pty v1.1.24 // indirect - github.com/danieljoos/wincred v1.2.2 // indirect + github.com/danieljoos/wincred v1.2.3 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-fed/httpsig v1.1.0 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logfmt/logfmt v0.6.1 // indirect github.com/go-resty/resty/v2 v2.16.5 // indirect - github.com/godbus/dbus/v5 v5.1.0 // 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-querystring v1.1.0 // indirect @@ -65,24 +67,24 @@ require ( github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pkg/sftp v1.13.9 // indirect + github.com/pkg/sftp v1.13.10 // indirect github.com/rivo/uniseg v0.4.7 // indirect 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 - golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect - golang.org/x/net v0.44.0 // indirect - golang.org/x/oauth2 v0.31.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/text v0.29.0 // indirect - golang.org/x/time v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect + golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/oauth2 v0.33.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/time v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect ) diff --git a/go.sum b/go.sum index 35f00c4..3d89282 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,13 @@ al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA= al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 h1:DQLS/rRxLHuugVzjJU5AvOwD57pdFl9he/0O7e5P294= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1/go.mod h1:aY3zbkNan5F+cGm9lITDP6oxJIwu0dn9KjJuJjWaHkg= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2 h1:6gjQy8rvNdpfbuzEPoimtQ2BD5hebvV9TMxiuNWQGCQ= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20250804091548-289250b42883.2/go.mod h1:/rxp37k3p7xxCe1X1jfSNMtYowCkcEvhiDbL3tBpyWA= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1 h1:oUYlXzAMRIm/umpdF+7CxjDc5BrLJTAc+SDTXW3xSKE= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.9-20250804091548-289250b42883.1/go.mod h1:9cZ5Dad/JncDI9XPW3QDXovAAL/bj/Ro+/fPcBL0uIw= -code.gitea.io/sdk/gitea v0.22.0 h1:HCKq7bX/HQ85Nw7c/HAhWgRye+vBp5nQOE8Md1+9Ef0= -code.gitea.io/sdk/gitea v0.22.0/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 h1:31on4W/yPcV4nZHL4+UCiCvLPsMqe/vJcNg8Rci0scc= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1/go.mod h1:fUl8CEN/6ZAMk6bP8ahBJPUJw7rbp+j4x+wCcYi2IG4= +buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 h1:2mTDOUSt3hHaeAjxY5KljY2DXyMqO2iC15eiL4HK8nk= +buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2/go.mod h1:dTA7kNFwWSjEiP42gb1QA7V+B+aMi0Heq03BKqeULiU= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1 h1:4eZgyGoegoDwt1ZT9cR3f2oE/8Ys/csbiKnMYmxQ9xg= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1/go.mod h1:L7GAI5uJLx5y5vl+4w/x9kNWt0YaOZ6LfUEbhyv9Udg= +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= github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f h1:gvIRcU/B46blquBfuf/oVEzmnlW3etX0R6a9Oa1Mbs0= @@ -22,10 +22,10 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= 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.3.2 h1:9J27WdztfJQVAQKX2WOlSSRB+5gaKqqITmrvb1uTIiI= -github.com/charmbracelet/colorprofile v0.3.2/go.mod h1:mTD5XzNeWHj8oqHb+S1bssQb7vIHbepiebQ2kPKVKbI= -github.com/charmbracelet/keygen v0.5.3 h1:2MSDC62OUbDy6VmjIE2jM24LuXUvKywLCmaJDmr/Z/4= -github.com/charmbracelet/keygen v0.5.3/go.mod h1:TcpNoMAO5GSmhx3SgcEMqCrtn8BahKhB8AlwnLjRUpk= +github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI= +github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4= +github.com/charmbracelet/keygen v0.5.4 h1:XQYgf6UEaTGgQSSmiPpIQ78WfseNQp4Pz8N/c1OsrdA= +github.com/charmbracelet/keygen v0.5.4/go.mod h1:t4oBRr41bvK7FaJsAaAQhhkUuHslzFXVjOBwA55CZNM= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= @@ -34,25 +34,29 @@ github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 h1:dCVbCRRtg9+ts github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= github.com/charmbracelet/wish v1.4.7 h1:O+jdLac3s6GaqkOHHSwezejNK04vl6VjO1A+hl8J8Yc= github.com/charmbracelet/wish v1.4.7/go.mod h1:OBZ8vC62JC5cvbxJLh+bIWtG7Ctmct+ewziuUWK+G14= -github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= -github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= -github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= -github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= -github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs= -github.com/charmbracelet/x/conpty v0.1.1/go.mod h1:OmtR77VODEFbiTzGE9G1XiRJAga6011PIm4u5fTNZpk= -github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21 h1:hEZp21B03sMDSyChx2152zUm43m5b2A3WykdyvOaZkI= -github.com/charmbracelet/x/errors v0.0.0-20250922100529-c9afca5d6f21/go.mod h1:O2BTD/aMVQDmrvqroIO3fB6zXUuU07ZpVt21QTmZjRg= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/ansi v0.11.1 h1:iXAC8SyMQDJgtcz9Jnw+HU8WMEctHzoTAETIeA3JXMk= +github.com/charmbracelet/x/ansi v0.11.1/go.mod h1:M49wjzpIujwPceJ+t5w3qh2i87+HRtHohgb5iTyepL0= +github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= +github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= +github.com/charmbracelet/x/conpty v0.2.0 h1:eKtA2hm34qNfgJCDp/M6Dc0gLy7e07YEK4qAdNGOvVY= +github.com/charmbracelet/x/conpty v0.2.0/go.mod h1:fexgUnVrZgw8scD49f6VSi0Ggj9GWYIrpedRthAwW/8= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= +github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s= +github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= 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/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= -github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +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= github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -68,23 +72,22 @@ github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlL github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE= +github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +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.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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= @@ -106,8 +109,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.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.6.8 h1:JnnzQeRz2bACBobIaa/r+nqjvws4yEhcmaZ4n1QzsEc= -github.com/jedib0t/go-pretty/v6 v6.6.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.2 h1:EYWgQNIH/+JsyHki7ns9OHyBKuHPkzrBo02uYjran7w= +github.com/jedib0t/go-pretty/v6 v6.7.2/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= @@ -118,8 +121,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +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/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= @@ -133,11 +136,10 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr 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.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw= -github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA= +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= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -171,37 +173,29 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu 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= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +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= 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.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= -golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= -golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= @@ -209,22 +203,13 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v 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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= -golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.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/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= @@ -236,55 +221,36 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= 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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= -golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +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/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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-20250922171735-9219d122eba9 h1:V1jCN2HBa8sySkR5vLcCSqJSTMv093Rw9EJefhQGP7M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/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/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 h1:wO6teAQa+/6NqTzys8iAd3kWzcWWzrIhLZOdTGfDYAo= From a5978a309fcca132dbd13e6a50d0acef33ab8fac Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Tue, 18 Nov 2025 09:40:29 +0100 Subject: [PATCH 02/20] fix(build): disable darwin builds for now Signed-off-by: Aaron Fischer --- .goreleaser.yaml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 1b51922..00ae61b 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -15,19 +15,20 @@ builds: ldflags: - "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'" - - id: gpcore-macos - goos: - - darwin - ldflags: - - "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'" - goarch: - - amd64 - - arm64 - hooks: - post: - - cmd: quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv - env: - - QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log +# TODO: Disabled for now due to a missing agreement from apple developer account. +# - id: gpcore-macos +# goos: +# - darwin +# ldflags: +# - "-s -w -X '{{ .ModulePath }}/cmd.version={{.Tag}}' -X '{{ .ModulePath }}/cmd.commit={{.Commit}}' -X '{{ .ModulePath }}/cmd.date={{.Date}}'" +# goarch: +# - amd64 +# - arm64 +# hooks: +# post: +# - cmd: quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv +# env: +# - QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log archives: - formats: From bb4ec29aada15df4da32421110a45b79b805e89f Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Fri, 19 Dec 2025 10:40:35 +0100 Subject: [PATCH 03/20] chore(dependencies): update all dependencies, go version, action versions Ticket: TV-1092 Signed-off-by: Aaron Fischer --- .github/workflows/danger.yml | 2 +- .github/workflows/release.yml | 6 +-- .github/workflows/test.yml | 4 +- go.mod | 38 ++++++++--------- go.sum | 77 ++++++++++++++++++----------------- 5 files changed, 64 insertions(+), 63 deletions(-) diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 83f365d..b159ab6 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'pull_request' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ruby/setup-ruby@v1 with: ruby-version: '3.3' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 74a2e77..5ec40ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: pull-requests: write # to be able to comment on released pull requests steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: fetch-tags: true - name: Setup Node.js @@ -32,7 +32,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v6 with: - go-version: '1.25.4' + go-version: '1.25.5' - 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 @@ -50,7 +50,7 @@ jobs: QUILL_NOTARY_KEY_ID: ${{ secrets.QUILL_NOTARY_KEY_ID }} QUILL_NOTARY_ISSUER: ${{ secrets.QUILL_NOTARY_ISSUER }} - name: Upload dist artifacts to GitHub when not on main - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: "!contains(github.ref, 'main')" with: name: gpcore diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 26ff654..140d577 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,12 +6,12 @@ jobs: tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup Go uses: actions/setup-go@v6 with: - go-version: '1.25.4' + go-version: '1.25.5' - name: Install dependencies run: go mod download diff --git a/go.mod b/go.mod index ec56036..c741058 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/G-PORTAL/gpcore-cli -go 1.25.4 +go 1.25.5 // For development //replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( - buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 - buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1 + 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 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 @@ -16,36 +16,36 @@ require ( github.com/creativeprojects/go-selfupdate v1.5.1 github.com/dave/jennifer v1.7.1 github.com/gertd/go-pluralize v0.2.1 - github.com/jedib0t/go-pretty/v6 v6.7.2 + github.com/jedib0t/go-pretty/v6 v6.7.7 github.com/melbahja/goph v1.4.0 - github.com/spf13/cobra v1.10.1 + 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.44.0 + golang.org/x/crypto v0.46.0 google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + 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 ) require ( al.essio.dev/pkg/shellescape v1.6.0 // indirect - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 // indirect code.gitea.io/sdk/gitea v0.22.1 // indirect github.com/42wim/httpsig v1.2.3 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.3.3 // indirect + github.com/charmbracelet/colorprofile v0.4.1 // indirect github.com/charmbracelet/keygen v0.5.4 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.11.1 // indirect + github.com/charmbracelet/x/ansi v0.11.3 // indirect github.com/charmbracelet/x/cellbuf v0.0.14 // indirect github.com/charmbracelet/x/conpty v0.2.0 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect - github.com/clipperhouse/displaywidth v0.6.0 // indirect + github.com/clipperhouse/displaywidth v0.6.2 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/creack/pty v1.1.24 // indirect @@ -54,14 +54,14 @@ require ( github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-logfmt/logfmt v0.6.1 // indirect - github.com/go-resty/resty/v2 v2.16.5 // indirect + 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-querystring v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kr/fs v0.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect @@ -80,11 +80,11 @@ require ( 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 - golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect ) diff --git a/go.sum b/go.sum index 3d89282..1c10ab0 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA= al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 h1:31on4W/yPcV4nZHL4+UCiCvLPsMqe/vJcNg8Rci0scc= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1/go.mod h1:fUl8CEN/6ZAMk6bP8ahBJPUJw7rbp+j4x+wCcYi2IG4= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2 h1:2mTDOUSt3hHaeAjxY5KljY2DXyMqO2iC15eiL4HK8nk= -buf.build/gen/go/gportal/gpcore/grpc/go v1.5.1-20251103085422-b156624a826d.2/go.mod h1:dTA7kNFwWSjEiP42gb1QA7V+B+aMi0Heq03BKqeULiU= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1 h1:4eZgyGoegoDwt1ZT9cR3f2oE/8Ys/csbiKnMYmxQ9xg= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.10-20251103085422-b156624a826d.1/go.mod h1:L7GAI5uJLx5y5vl+4w/x9kNWt0YaOZ6LfUEbhyv9Udg= +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= 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= @@ -22,8 +22,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= 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.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI= -github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4= +github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= +github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= github.com/charmbracelet/keygen v0.5.4 h1:XQYgf6UEaTGgQSSmiPpIQ78WfseNQp4Pz8N/c1OsrdA= github.com/charmbracelet/keygen v0.5.4/go.mod h1:t4oBRr41bvK7FaJsAaAQhhkUuHslzFXVjOBwA55CZNM= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= @@ -34,8 +34,8 @@ github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 h1:dCVbCRRtg9+ts github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= github.com/charmbracelet/wish v1.4.7 h1:O+jdLac3s6GaqkOHHSwezejNK04vl6VjO1A+hl8J8Yc= github.com/charmbracelet/wish v1.4.7/go.mod h1:OBZ8vC62JC5cvbxJLh+bIWtG7Ctmct+ewziuUWK+G14= -github.com/charmbracelet/x/ansi v0.11.1 h1:iXAC8SyMQDJgtcz9Jnw+HU8WMEctHzoTAETIeA3JXMk= -github.com/charmbracelet/x/ansi v0.11.1/go.mod h1:M49wjzpIujwPceJ+t5w3qh2i87+HRtHohgb5iTyepL0= +github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI= +github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI= github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= github.com/charmbracelet/x/conpty v0.2.0 h1:eKtA2hm34qNfgJCDp/M6Dc0gLy7e07YEK4qAdNGOvVY= @@ -44,8 +44,8 @@ github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSg github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= -github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s= -github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= +github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo= +github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= @@ -78,8 +78,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= -github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= +github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= +github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= 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= @@ -105,12 +105,12 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +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.2 h1:EYWgQNIH/+JsyHki7ns9OHyBKuHPkzrBo02uYjran7w= -github.com/jedib0t/go-pretty/v6 v6.7.2/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +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/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= @@ -145,8 +145,8 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -185,16 +185,17 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6 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.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.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= -golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0= -golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +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= @@ -203,11 +204,11 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v 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.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +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/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +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= @@ -221,20 +222,20 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc 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.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.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.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= 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.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= 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= @@ -245,12 +246,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T 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-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +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/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 h1:wO6teAQa+/6NqTzys8iAd3kWzcWWzrIhLZOdTGfDYAo= From e99a68a04724061ce84851cb43a1af7112778014 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:02:07 +0000 Subject: [PATCH 04/20] chore(deps): bump golang.org/x/crypto from 0.46.0 to 0.47.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.46.0 to 0.47.0. - [Commits](https://github.com/golang/crypto/compare/v0.46.0...v0.47.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.47.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index c741058..6931764 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( 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.46.0 + golang.org/x/crypto v0.47.0 google.golang.org/grpc v1.77.0 google.golang.org/protobuf v1.36.11 gopkg.in/op/go-logging.v1 v1.0.0-20160315200505-970db520ece7 @@ -83,8 +83,8 @@ require ( golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.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 1c10ab0..5b39608 100644 --- a/go.sum +++ b/go.sum @@ -192,8 +192,8 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5 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.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +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/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= @@ -222,20 +222,20 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc 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.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.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.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= -golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +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/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.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +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/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= From 950e79999e3bfdc23011a4f4d7d260ae9b3b5ec9 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 2 Mar 2026 10:20:08 +0100 Subject: [PATCH 05/20] chore(deps): update dependencies and improve cobra command handling Update Go from 1.25.5 to 1.26.0 and all dependencies to latest versions. Improve cobra command configuration with flag mutual exclusivity, completion options, and shell completion functions for enum-typed flags. Remove unused tools.go file and update all YAML definitions with missing fields. Key changes: - Update Go version and all dependencies - Add flag mutual exclusivity for json/csv output - Disable default file completions globally - Implement shell completion for enum-typed flags - Remove tools.go and clean up unused code - Update workflow action versions Ticket: GPCO-8 --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- cmd/agent/root.go | 4 + cmd/completion.go | 4 +- cmd/node/root.go | 1 + cmd/project/root.go | 1 + go.mod | 26 ++--- go.sum | 106 +++++++----------- pkg/generator/add_commands.go | 36 +++++- pkg/generator/definition.go | 1 + pkg/generator/definition/billing-profile.yaml | 1 + pkg/generator/definition/country.yaml | 1 + pkg/generator/definition/datacenter.yaml | 1 + pkg/generator/definition/flavour.yaml | 1 + pkg/generator/definition/image.yaml | 1 + pkg/generator/definition/ip.yaml | 1 + pkg/generator/definition/log.yaml | 1 + pkg/generator/definition/network-arp.yaml | 1 + pkg/generator/definition/network-subnet.yaml | 1 + pkg/generator/definition/network-switch.yaml | 1 + pkg/generator/definition/network.yaml | 1 + pkg/generator/definition/node-agent.yaml | 1 + pkg/generator/definition/node.yaml | 1 + .../definition/operating-systems.yaml | 1 + .../definition/project-cloudprovider.yaml | 1 + pkg/generator/definition/project-image.yaml | 1 + pkg/generator/definition/project.yaml | 1 + pkg/generator/definition/region.yaml | 1 + pkg/generator/definition/reporting.yaml | 1 + pkg/generator/definition/server-pool.yaml | 1 + pkg/generator/definition/server.yaml | 1 + pkg/generator/definition/spla.yaml | 1 + pkg/generator/definition/sshkey.yaml | 1 + pkg/generator/definition/timezone.yaml | 1 + pkg/generator/definition/user.yaml | 1 + pkg/generator/generator.go | 4 +- pkg/generator/root_command.go | 8 +- pkg/generator/sub_command.go | 45 ++++++-- tools.go | 7 -- 39 files changed, 164 insertions(+), 108 deletions(-) delete mode 100644 tools.go 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" From 9bab5cb5200108a2c1219732c7ee524658c90bbe Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 2 Mar 2026 12:49:23 +0100 Subject: [PATCH 06/20] fix(node): add id parameter to node update action The node update action was missing the required 'id' parameter in its definition. This fix adds the id parameter (Node UUID) as a required field to the node.yaml definition, ensuring the update action can properly identify which node to update. Ticket: GPCO-8 --- pkg/generator/definition/node.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/generator/definition/node.yaml b/pkg/generator/definition/node.yaml index e4390b4..afc089d 100644 --- a/pkg/generator/definition/node.yaml +++ b/pkg/generator/definition/node.yaml @@ -38,7 +38,12 @@ actions: update: api-call: admin.UpdateNode description: Update node details + identifier: nil params: + - name: id + type: string + description: Node UUID + required: true - name: managed type: bool required: true From 5958d1bd60d3a67d114e07d5153a88f1af1f1ad5 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 2 Mar 2026 13:01:10 +0100 Subject: [PATCH 07/20] fix(project): deprecate description and environment fields and fix generator enum handling Make description and environment optional in project create/update since they are deprecated in the proto (removal date 2025/03/01 already passed). Fix generator bug where non-required enum params incorrectly used pointer semantics for plain proto3 enum fields. Add explicit 'optional' YAML flag for proto oneof/optional pointer fields. - Mark project description/environment as deprecated and optional - Fix generator enum pointer handling in sub_command.go - Add Optional field to Param struct in definition.go - Mark image cloud_provider_type as optional (oneof pointer field) Ticket: GPCO-8 --- pkg/generator/definition.go | 1 + pkg/generator/definition/image.yaml | 1 + pkg/generator/definition/project.yaml | 30 +++++++++++++-------------- pkg/generator/sub_command.go | 13 ++++++++---- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/pkg/generator/definition.go b/pkg/generator/definition.go index 2868d6f..f58d3b4 100644 --- a/pkg/generator/definition.go +++ b/pkg/generator/definition.go @@ -32,6 +32,7 @@ type Param struct { Description string `yaml:"description"` Required bool `yaml:"required"` Default interface{} `yaml:"default"` + Optional bool `yaml:"optional"` // Proto field is a pointer type (oneof/optional) } type APICall struct { diff --git a/pkg/generator/definition/image.yaml b/pkg/generator/definition/image.yaml index a567944..1fa8ad3 100644 --- a/pkg/generator/definition/image.yaml +++ b/pkg/generator/definition/image.yaml @@ -25,6 +25,7 @@ actions: default: typev1.CLOUD_PROVIDER_TYPE_AWS description: Filter by cloud provider type required: false + optional: true fields: - Id - Name diff --git a/pkg/generator/definition/project.yaml b/pkg/generator/definition/project.yaml index 0ed9f5e..09c7db2 100644 --- a/pkg/generator/definition/project.yaml +++ b/pkg/generator/definition/project.yaml @@ -23,7 +23,6 @@ actions: description: Project ID required: true - # TODO: Fix after dependency upgrade update: api-call: cloud.UpdateProject description: Update project details @@ -32,23 +31,22 @@ actions: type: string description: Project name required: true - - name: description - type: string - description: Project description - required: true - - name: environment - type: cloudv1.ProjectEnvironment - description: Project environment - default: cloudv1.PROJECT_ENVIRONMENT_DEVELOPMENT - required: true - name: credit_card_id type: string description: Credit card ID required: true - name: billing_address_id type: string - description: Billing address ID + description: Billing profile ID required: true + - name: description + type: string + description: Project description (deprecated) + default: "" + - name: environment + type: cloudv1.ProjectEnvironment + description: Project environment (deprecated) + default: cloudv1.PROJECT_ENVIRONMENT_DEVELOPMENT create: api-call: cloud.CreateProject @@ -59,16 +57,18 @@ actions: type: string description: Project name required: true + - name: billing_address_id + type: string + description: Billing profile ID + required: true - name: description type: string + description: Project description (deprecated) default: "" - name: environment type: cloudv1.ProjectEnvironment + description: Project environment (deprecated) default: cloudv1.PROJECT_ENVIRONMENT_DEVELOPMENT - required: true - - name: billing_address_id - type: string - required: true delete: api-call: cloud.DeleteProject diff --git a/pkg/generator/sub_command.go b/pkg/generator/sub_command.go index 063185b..ac0c167 100644 --- a/pkg/generator/sub_command.go +++ b/pkg/generator/sub_command.go @@ -185,8 +185,11 @@ func runCommand(name string, metadata SubcommandMetadata) []Code { variable := strcase.LowerCamelCase(name) + title(strcase.LowerCamelCase(param.Name)) var val *Statement if isEnumType(param.Type) && !isArrayType(param.Type) { - // Enum helper function call - if !param.Required { + // Enum helper function call. Use a pointer when the proto field + // is explicitly marked as optional (oneof/optional pointer type). + if param.Optional { + // Variable is shadowed and converted before the API call, + // take its address for the pointer proto field. val = Op("&").Id(variable) } else { val = Qual("github.com/G-PORTAL/gpcore-cli/pkg/protobuf", stripPackage(param.Type)+"ToProto").Call(Id(variable)) @@ -213,9 +216,11 @@ func runCommand(name string, metadata SubcommandMetadata) []Code { respC := make([]Code, 0) - // Special variables for pointer usage + // For enum params marked as optional, the proto field is a pointer type + // (oneof/optional). We need to convert the string to the enum value and + // take its address. for _, param := range metadata.Action.Params { - if isEnumType(param.Type) && !param.Required { + if isEnumType(param.Type) && param.Optional { variable := strcase.LowerCamelCase(name) + title(strcase.LowerCamelCase(param.Name)) respC = append(respC, Id(variable). Op(":="). From 282a6fc0e0a3abe162d1ef036be960df6fdcac40 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 2 Mar 2026 13:17:43 +0100 Subject: [PATCH 08/20] fix(network): disable network create command until ListSubnets endpoint available The network create command has been disabled because the ListSubnets endpoint is missing from the gRPC API. This endpoint is required to resolve subnet IDs provided by users. The command will be re-enabled once the admin.ListSubnets endpoint becomes available in the gRPC API. Key changes: - Replaced full implementation with documentation comments - Added TODO for re-enabling once ListSubnets is available - Noted the flag name fix needed (subnet-ids vs subnets) Ticket: GPCO-8 --- cmd/project/_network_create.go | 89 ++++------------------------------ 1 file changed, 9 insertions(+), 80 deletions(-) diff --git a/cmd/project/_network_create.go b/cmd/project/_network_create.go index 85247e9..61463b0 100644 --- a/cmd/project/_network_create.go +++ b/cmd/project/_network_create.go @@ -1,82 +1,11 @@ package project -import ( - "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc" - adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1" - cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" - "encoding/json" - "github.com/G-PORTAL/gpcore-cli/pkg/client" - "github.com/G-PORTAL/gpcore-cli/pkg/config" - "github.com/G-PORTAL/gpcore-cli/pkg/protobuf" - "github.com/spf13/cobra" - "google.golang.org/grpc" -) - -// This command is disabled at the moment because the ListSubnets endpoint is -// missing on gRPC (which is needed to get the subnets from the IDs). - -var networkCreateProjectId string -var networkCreateName string -var networkCreateType string -var networkCreateSubnets []string -var networkCreateVlanId int32 -var networkCreateDatacenter string - -var networkCreateCmd = &cobra.Command{ - Args: cobra.OnlyValidArgs, - DisableFlagsInUseLine: true, - Long: "", - RunE: func(cobraCmd *cobra.Command, args []string) error { - ctx := client.ExtractContext(cobraCmd) - grpcConn := ctx.Value("conn").(*grpc.ClientConn) - client := adminv1grpc.NewAdminServiceClient(grpcConn) - - networkCreateSubnetStructs := make([]*cloudv1.Subnet, 0) - // TODO: Get subnets from networkCreateSubnetUUIDList IDs - // TODO: ListSubnets endpoint missing on gRPC - - networkCreateDatacenterStruct := &cloudv1.Datacenter{ - Id: networkCreateDatacenter, - } - - resp, err := client.CreateProjectNetwork(cobraCmd.Context(), &adminv1.CreateProjectNetworkRequest{ - Name: networkCreateName, - ProjectId: networkCreateProjectId, - Subnets: networkCreateSubnetStructs, - Datacenter: networkCreateDatacenterStruct, - Type: protobuf.NetworkTypeToProto(networkCreateType), - VlanId: &networkCreateVlanId, - }) - if err != nil { - return err - } - respData := resp - if config.JSONOutput { - jsonData, err := protobuf.MarshalIndent(respData) - if err != nil { - return err - } - cobraCmd.Println(string(jsonData)) - } - return nil - }, - Short: "", - Use: "network-create", - ValidArgs: []string{"project-id", "name", "type", "subnet-ids", "datacenter-id", "vlan-id"}, -} - -func init() { - networkCreateCmd.Flags().StringVar(&networkCreateProjectId, "project-id", "", "Project ID (required)") - networkCreateCmd.Flags().StringVar(&networkCreateName, "name", "", "Network name (required)") - networkCreateCmd.Flags().StringVar(&networkCreateType, "type", "PRIVATE", "Network type (default:\"cloudv1.NETWORK_TYPE_PRIVATE\")") - networkCreateCmd.Flags().StringSliceVar(&networkCreateSubnets, "subnet-ids", []string{}, "Subnets (required)") - networkCreateCmd.Flags().StringVar(&networkCreateDatacenter, "datacenter-id", "", "Datacenter ID (required)") - networkCreateCmd.Flags().Int32Var(&networkCreateVlanId, "vlan-id", int32(0), "VLAN ID") - - networkCreateCmd.MarkFlagRequired("project-id") - networkCreateCmd.MarkFlagRequired("name") - networkCreateCmd.MarkFlagRequired("type") - networkCreateCmd.MarkFlagRequired("subnets") - - RootProjectCommand.AddCommand(networkCreateCmd) -} +// This command is disabled because the ListSubnets endpoint is missing on +// gRPC (which is needed to resolve subnet IDs). It will be re-enabled once +// the endpoint is available. +// +// TODO: Re-enable once admin.ListSubnets is available in the gRPC API. +// The command should: +// - Accept --subnet-ids and resolve them via ListSubnets +// - Register itself with RootProjectCommand.AddCommand(networkCreateCmd) +// - Fix MarkFlagRequired to use "subnet-ids" (not "subnets") From a9b25068ae5d337c9bae6c706d982ad2bdeb28c0 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 2 Mar 2026 13:20:20 +0100 Subject: [PATCH 09/20] fix(cli): fix parameter descriptions and defaults across commands Correct misleading flag descriptions and defaults in several commands. - Fix network-arp mac_address description from "IP address" to "MAC address" - Make node reinstall user_data optional with empty default - Remove false "(required)" from rescue mode enabled/password descriptions Ticket: GPCO-8 --- cmd/node/change_rescue_mode.go | 4 ++-- pkg/generator/definition/network-arp.yaml | 2 +- pkg/generator/definition/node.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/node/change_rescue_mode.go b/cmd/node/change_rescue_mode.go index 5edf89d..11c44e5 100644 --- a/cmd/node/change_rescue_mode.go +++ b/cmd/node/change_rescue_mode.go @@ -52,8 +52,8 @@ var changeRescueModeCmd = &cobra.Command{ func init() { changeRescueModeCmd.Flags().StringVar(&changeRescueModeId, "id", "", "Node ID (required)") changeRescueModeCmd.Flags().StringVar(&changeRescueModeProjectId, "project-id", "", "Project ID (required)") - changeRescueModeCmd.Flags().BoolVar(&changeRescueModeEnabled, "enabled", false, "Enable or disable rescue mode (required)") - changeRescueModeCmd.Flags().StringVar(&changeRescueModePassword, "password", "", "Password for rescue mode (required)") + changeRescueModeCmd.Flags().BoolVar(&changeRescueModeEnabled, "enabled", false, "Enable or disable rescue mode") + changeRescueModeCmd.Flags().StringVar(&changeRescueModePassword, "password", "", "Password for rescue mode") changeRescueModeCmd.MarkFlagRequired("id") changeRescueModeCmd.MarkFlagRequired("project-id") diff --git a/pkg/generator/definition/network-arp.yaml b/pkg/generator/definition/network-arp.yaml index 7403624..78e84be 100644 --- a/pkg/generator/definition/network-arp.yaml +++ b/pkg/generator/definition/network-arp.yaml @@ -8,7 +8,7 @@ actions: params: - name: mac_address type: string - description: IP address + description: MAC address required: true list: diff --git a/pkg/generator/definition/node.yaml b/pkg/generator/definition/node.yaml index afc089d..16c8420 100644 --- a/pkg/generator/definition/node.yaml +++ b/pkg/generator/definition/node.yaml @@ -146,7 +146,7 @@ actions: - name: user_data type: string description: User data - required: true + default: "" power-action: api-call: cloud.PowerActionNode From 02c4c2127ef01a8a870ee7ef5d9815e5331f9e58 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 27 Apr 2026 11:40:22 +0200 Subject: [PATCH 10/20] chore(deps): update dependencies and go version to 1.26.2 Update all dependencies to their latest versions including: - buf.build/gen/go/gportal/gpcore packages - charmbracelet/log to v1.0.0 - go-pretty/v6 to v6.7.10 - zalando/go-keyring to v0.2.8 - golang.org/x/crypto to v0.50.0 - google.golang.org/grpc to v1.80.0 Also bump Go version from 1.26.0 to 1.26.2 in go.mod and update GitHub Actions workflows to use the new Go version. Ticket: GPCO-8 --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- go.mod | 66 ++++++++-------- go.sum | 144 ++++++++++++++++------------------ 4 files changed, 103 insertions(+), 111 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 78dbd7e..6690e63 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.26.0' + go-version: '1.26.2' - 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 f5f152b..f74e404 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.26.0' + go-version: '1.26.2' - name: Install dependencies run: go mod download diff --git a/go.mod b/go.mod index 9cd42de..b74d4ad 100644 --- a/go.mod +++ b/go.mod @@ -1,73 +1,71 @@ module github.com/G-PORTAL/gpcore-cli -go 1.26.0 +go 1.26.2 // For development //replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( - 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 + buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260316135506-01d4d7c6b8fb.1 + buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260316135506-01d4d7c6b8fb.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/log v1.0.0 github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 github.com/charmbracelet/wish v1.4.7 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.8 + github.com/jedib0t/go-pretty/v6 v6.7.10 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.48.0 - google.golang.org/grpc v1.79.1 + github.com/zalando/go-keyring v0.2.8 + golang.org/x/crypto v0.50.0 + google.golang.org/grpc v1.80.0 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 ) require ( - al.essio.dev/pkg/shellescape v1.6.0 // indirect - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 // indirect - code.gitea.io/sdk/gitea v0.22.1 // indirect - github.com/42wim/httpsig v1.2.3 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1 // indirect + code.gitea.io/sdk/gitea v0.24.1 // indirect + github.com/42wim/httpsig v1.2.4 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.4.1 // indirect + github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/keygen v0.5.4 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.11.3 // indirect - github.com/charmbracelet/x/cellbuf v0.0.14 // indirect + github.com/charmbracelet/x/ansi v0.11.7 // indirect + github.com/charmbracelet/x/cellbuf v0.0.15 // indirect github.com/charmbracelet/x/conpty v0.2.0 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect - github.com/clipperhouse/displaywidth v0.6.2 // indirect - github.com/clipperhouse/stringish v0.1.1 // indirect - github.com/clipperhouse/uax29/v2 v2.3.0 // indirect + github.com/clipperhouse/displaywidth v0.11.0 // indirect + github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/creack/pty v1.1.24 // indirect github.com/danieljoos/wincred v1.2.3 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-logfmt/logfmt v0.6.1 // indirect - 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/go-resty/resty/v2 v2.17.2 // indirect + github.com/godbus/dbus/v5 v5.2.2 // indirect + github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/google/go-github/v74 v74.0.0 // indirect - github.com/google/go-querystring v1.1.0 // indirect + github.com/google/go-querystring v1.2.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect - github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/go-version v1.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kr/fs v0.1.0 // indirect - github.com/lucasb-eyer/go-colorful v1.3.0 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect + github.com/lucasb-eyer/go-colorful v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.22 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.23 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect @@ -79,12 +77,12 @@ require ( github.com/spf13/pflag v1.0.10 // indirect github.com/ulikunitz/xz v0.5.15 // 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.49.0 // indirect - golang.org/x/oauth2 v0.34.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 + gitlab.com/gitlab-org/api/client-go v1.46.0 // indirect + golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/time v0.15.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 // indirect ) diff --git a/go.sum b/go.sum index bcf6e61..6b0bca9 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,13 @@ -al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA= -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.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= -github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1 h1:s6hzCXtND/ICdGPTMGk7C+/BFlr2Jg5GyH0NKf4XGXg= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260316135506-01d4d7c6b8fb.1 h1:+242bjl6n/YYlOnNCLgkjo5AaWYWCklo1IszlHa3C/E= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260316135506-01d4d7c6b8fb.1/go.mod h1:4mlZn6bCRnl095MLXElGusnT0eRWUtxNi5JVtRqNamM= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260316135506-01d4d7c6b8fb.1 h1:OuLb5jA9t2cT9LtVQEij8P2BNaNcl1/jx0IFum+9wXw= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260316135506-01d4d7c6b8fb.1/go.mod h1:P8EapWY+m/+4oATK4HFxRi9zB1QyW1oAz+yvxT4ckt4= +code.gitea.io/sdk/gitea v0.24.1 h1:hpaqcdGcBmfMpV7JSbBJVwE99qo+WqGreJYKrDKEyW8= +code.gitea.io/sdk/gitea v0.24.1/go.mod h1:5/77BL3sHneCMEiZaMT9lfTvnnibsYxyO48mceCF3qA= +github.com/42wim/httpsig v1.2.4 h1:mI5bH0nm4xn7K18fo1K3okNDRq8CCJ0KbBYWyA6r8lU= +github.com/42wim/httpsig v1.2.4/go.mod h1:yKsYfSyTBEohkPik224QPFylmzEBtda/kjyIAJjh3ps= github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f h1:gvIRcU/B46blquBfuf/oVEzmnlW3etX0R6a9Oa1Mbs0= github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f/go.mod h1:CoJMebbI1HNVoUR6iATl1QfoDSyfjC+BbeGH1kDZS7k= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= @@ -24,34 +22,32 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF 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= -github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= +github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= +github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= github.com/charmbracelet/keygen v0.5.4 h1:XQYgf6UEaTGgQSSmiPpIQ78WfseNQp4Pz8N/c1OsrdA= github.com/charmbracelet/keygen v0.5.4/go.mod h1:t4oBRr41bvK7FaJsAaAQhhkUuHslzFXVjOBwA55CZNM= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= -github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= -github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= +github.com/charmbracelet/log v1.0.0 h1:HVVVMmfOorfj3BA9i8X8UL69Hoz9lI0PYwXfJvOdRc4= +github.com/charmbracelet/log v1.0.0/go.mod h1:uYgY3SmLpwJWxmlrPwXvzVYujxis1vAKRV/0VQB7yWA= github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 h1:dCVbCRRtg9+tsfiTXTp0WupDlHruAXyp+YoxGVofHHc= github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= github.com/charmbracelet/wish v1.4.7 h1:O+jdLac3s6GaqkOHHSwezejNK04vl6VjO1A+hl8J8Yc= github.com/charmbracelet/wish v1.4.7/go.mod h1:OBZ8vC62JC5cvbxJLh+bIWtG7Ctmct+ewziuUWK+G14= -github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI= -github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI= -github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= -github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= +github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI= +github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ= +github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= +github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/conpty v0.2.0 h1:eKtA2hm34qNfgJCDp/M6Dc0gLy7e07YEK4qAdNGOvVY= github.com/charmbracelet/x/conpty v0.2.0/go.mod h1:fexgUnVrZgw8scD49f6VSi0Ggj9GWYIrpedRthAwW/8= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= -github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo= -github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= -github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= -github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= -github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= +github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= +github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= +github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= 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= @@ -80,49 +76,49 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= -github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= -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/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= +github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= +github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ= +github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= +github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= +github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= 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.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/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= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0= +github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/graph-gophers/graphql-go v1.9.0 h1:yu0ucKHLc5qGpRwLYKIWtr9bOoxovkWasuBrPQwlHls= +github.com/graph-gophers/graphql-go v1.9.0/go.mod h1:23olKZ7duEvHlF/2ELEoSZaY1aNPfShjP782SOoNTyM= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= -github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= -github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= +github.com/hashicorp/go-version v1.9.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.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o= -github.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.10 h1:B/2qW2Bkv2L6n14PP8o1kx75kWzHOQ3YTluWzg9icac= +github.com/jedib0t/go-pretty/v6 v6.7.10/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= -github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= +github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= +github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= 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/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= +github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= 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= @@ -166,10 +162,10 @@ 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/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/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= +github.com/zalando/go-keyring v0.2.8 h1:6sD/Ucpl7jNq10rM2pgqTs0sZ9V3qMrqfIIy5YPccHs= +github.com/zalando/go-keyring v0.2.8/go.mod h1:tsMo+VpRq5NGyKfxoBVjCuMrG47yj8cmakZDO5QGii0= +gitlab.com/gitlab-org/api/client-go v1.46.0 h1:YxBWFZIFYKcGESCb9fpkwzouo+apyB9pr/XTWzNoL24= +gitlab.com/gitlab-org/api/client-go v1.46.0/go.mod h1:FtgyU6g2HS5+fMhw6nLK96GBEEBx5MzntOiJWfIaiN8= 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.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= @@ -186,40 +182,38 @@ 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.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/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -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/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= 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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= 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.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/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -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/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.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= -google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 h1:XF8+t6QQiS0o9ArVan/HW8Q7cycNPGsJf6GA2nXxYAg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= 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= From c31097bc9264118c27527885c038c83876304f66 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Wed, 6 May 2026 10:36:12 +0200 Subject: [PATCH 11/20] fix(cli): improve enum completion filtering and update cobra setup comment Improve enum value completion by filtering suggestions based on user input and sorting results alphabetically. This provides better UX when completing enum values. Also clarified the comment explaining why Cobra's default completion subcommand is disabled in favor of a custom implementation. Ticket: GPCO-8 --- cmd/agent/root.go | 2 +- pkg/generator/sub_command.go | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/cmd/agent/root.go b/cmd/agent/root.go index 9355b6a..dec2024 100644 --- a/cmd/agent/root.go +++ b/cmd/agent/root.go @@ -56,7 +56,7 @@ func New() *cobra.Command { 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) + // Disable Cobra's built-in "completion" subcommand (a custom one is registered below) rootCmd.CompletionOptions.DisableDefaultCmd = true // Special client commands diff --git a/pkg/generator/sub_command.go b/pkg/generator/sub_command.go index ac0c167..d93bc20 100644 --- a/pkg/generator/sub_command.go +++ b/pkg/generator/sub_command.go @@ -630,13 +630,17 @@ func initFunc(name string, metadata SubcommandMetadata) []Code { 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)), + Id("name").Op(":=").Qual("strings", "ToLower").Call( + Qual("strings", "TrimPrefix").Call(Id("v"), Lit(enumPrefix)), + ), + If(Qual("strings", "HasPrefix").Call(Id("name"), Id("toComplete"))).Block( + Id("completions").Op("=").Append( + Id("completions"), + Id("name"), ), ), ), + Qual("sort", "Strings").Call(Id("completions")), Return(Id("completions"), Qual("github.com/spf13/cobra", "ShellCompDirectiveNoFileComp")), ), )) From aaf3b38e5eeb28cd78fc043f9c48ffbd129edaa8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:57:12 +0000 Subject: [PATCH 12/20] chore(deps): bump google.golang.org/grpc from 1.80.0 to 1.81.0 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.80.0 to 1.81.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.80.0...v1.81.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-version: 1.81.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index b74d4ad..8f7990b 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/stoewer/go-strcase v1.3.1 github.com/zalando/go-keyring v0.2.8 golang.org/x/crypto v0.50.0 - google.golang.org/grpc v1.80.0 + google.golang.org/grpc v1.81.0 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 diff --git a/go.sum b/go.sum index 6b0bca9..f2346a5 100644 --- a/go.sum +++ b/go.sum @@ -168,16 +168,16 @@ gitlab.com/gitlab-org/api/client-go v1.46.0 h1:YxBWFZIFYKcGESCb9fpkwzouo+apyB9pr gitlab.com/gitlab-org/api/client-go v1.46.0/go.mod h1:FtgyU6g2HS5+fMhw6nLK96GBEEBx5MzntOiJWfIaiN8= 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.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.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= 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= @@ -212,8 +212,8 @@ gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 h1:XF8+t6QQiS0o9ArVan/HW8Q7cycNPGsJf6GA2nXxYAg= google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= -google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= +google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= 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= From a7bffe0843efc2baafa07056c9c228b5ced14a75 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Tue, 9 Jun 2026 11:28:43 +0200 Subject: [PATCH 13/20] ci(release): make next the prerelease branch The preview branch is now 'next' (the GitHub default), not the unused 'dev' branch which no longer exists. Configure semantic-release so 'main' cuts production releases and 'next' cuts prereleases for testing before going to production. --- .releaserc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.releaserc b/.releaserc index e665d6f..013ec31 100644 --- a/.releaserc +++ b/.releaserc @@ -1,12 +1,12 @@ { "branches": [ - { - "name": "dev", - "prerelease": true - }, { "name": "main", "prerelease": false + }, + { + "name": "next", + "prerelease": true } ], "plugins": [ From 3120a01c2b5c9b07fa52512f214b445b3702eea3 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 8 Jun 2026 12:55:21 +0200 Subject: [PATCH 14/20] chore(deps): bump gpcore gRPC/protobuf to 20260601 schema Bump buf.build gpcore grpc/go to v1.6.2-20260601154410 and protocolbuffers/go to v1.36.11-20260601154410 (pulls grpc v1.81.0). The new schema adds the AdminService ServerIssues/ValidateServer RPCs used by later commits. GPCO-49 --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 8f7990b..a766836 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ go 1.26.2 //replace github.com/G-PORTAL/gpcore-go => ../gpcore-go require ( - buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260316135506-01d4d7c6b8fb.1 - buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260316135506-01d4d7c6b8fb.1 + buf.build/gen/go/gportal/gpcore/grpc/go v1.6.2-20260601154410-8490479c7661.1 + buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260601154410-8490479c7661.1 github.com/G-PORTAL/gpcore-go v0.0.0-20250923094355-04f2fe445e8f github.com/Nerzal/gocloak/v13 v13.9.0 github.com/charmbracelet/log v1.0.0 diff --git a/go.sum b/go.sum index f2346a5..3c66034 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1 h1:s6hzCXtND/ICdGPTMGk7C+/BFlr2Jg5GyH0NKf4XGXg= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM= -buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260316135506-01d4d7c6b8fb.1 h1:+242bjl6n/YYlOnNCLgkjo5AaWYWCklo1IszlHa3C/E= -buf.build/gen/go/gportal/gpcore/grpc/go v1.6.1-20260316135506-01d4d7c6b8fb.1/go.mod h1:4mlZn6bCRnl095MLXElGusnT0eRWUtxNi5JVtRqNamM= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260316135506-01d4d7c6b8fb.1 h1:OuLb5jA9t2cT9LtVQEij8P2BNaNcl1/jx0IFum+9wXw= -buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260316135506-01d4d7c6b8fb.1/go.mod h1:P8EapWY+m/+4oATK4HFxRi9zB1QyW1oAz+yvxT4ckt4= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.2-20260601154410-8490479c7661.1 h1:6VSqM8RcjqhIqrk7mJAiHbOfAJANuVkpk7BOzUSCCbU= +buf.build/gen/go/gportal/gpcore/grpc/go v1.6.2-20260601154410-8490479c7661.1/go.mod h1:CtydbfeRdqoQ9NgmVTdXkArcelU4AC3NpBtzToK6A5g= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260601154410-8490479c7661.1 h1:Fu0IVtmzobbb6SK5H0s5zrAzmILVXqhmIEja3Sjijwg= +buf.build/gen/go/gportal/gpcore/protocolbuffers/go v1.36.11-20260601154410-8490479c7661.1/go.mod h1:P8EapWY+m/+4oATK4HFxRi9zB1QyW1oAz+yvxT4ckt4= code.gitea.io/sdk/gitea v0.24.1 h1:hpaqcdGcBmfMpV7JSbBJVwE99qo+WqGreJYKrDKEyW8= code.gitea.io/sdk/gitea v0.24.1/go.mod h1:5/77BL3sHneCMEiZaMT9lfTvnnibsYxyO48mceCF3qA= github.com/42wim/httpsig v1.2.4 h1:mI5bH0nm4xn7K18fo1K3okNDRq8CCJ0KbBYWyA6r8lU= From 4c0f041b6708d8372a12caa81285ce05eb7a2e44 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 8 Jun 2026 12:55:51 +0200 Subject: [PATCH 15/20] feat(generator): add session-sourced params and --project-id override Generator changes that let project-scoped commands accept either an explicit --project-id flag or the project selected via "project use": - Add Param.Source ("session.CurrentProject"): makes a flag optional and falls back to the session project, erroring if neither is set. - Auto-expose an optional --project-id override on actions whose identifier is session.CurrentProject (with the same fallback/erroring), via the new resolveIdentifier helper. - Fix defaultValue panic for optional enum flags without a default (emit ""). - parameterDescription hints session-sourced flags instead of "(required)". - Document intentional API coverage gaps on the APICall type. GPCO-49 --- pkg/generator/definition.go | 28 ++++++++ pkg/generator/helpers.go | 10 +++ pkg/generator/sub_command.go | 130 +++++++++++++++++++++++++++++------ 3 files changed, 148 insertions(+), 20 deletions(-) diff --git a/pkg/generator/definition.go b/pkg/generator/definition.go index f58d3b4..17ff2bf 100644 --- a/pkg/generator/definition.go +++ b/pkg/generator/definition.go @@ -33,8 +33,36 @@ type Param struct { Required bool `yaml:"required"` Default interface{} `yaml:"default"` Optional bool `yaml:"optional"` // Proto field is a pointer type (oneof/optional) + // Source, when set, makes the flag optional and falls back to a value from + // the session when the flag is left empty. The only supported value is + // "session.CurrentProject", which uses the project selected via + // "project use". If neither the flag nor the session value is set, the + // command errors out. This lets project-scoped commands omit --project-id + // once a project has been selected. + Source string `yaml:"source"` } +// APICall maps a CLI action to a gRPC endpoint via the "api-call" field in the +// YAML definitions (e.g. "admin.ListServers", "cloudv2.ListNodes"). +// +// Intentional API coverage gaps (do NOT add commands for these): +// - payment.* credit-card RPCs (AddCreditCard, RemoveCreditCard, +// ListCreditCards, ChangeDefaultCreditCard): credit cards are no longer +// used, so these calls are not supported. +// - payment.* plan-code RPCs (ListPlanCodes, GetDefaultPlanCode, +// ChangeDefaultPlanCode): Lago is no longer used, so plan codes are not +// supported. +// - auth.* RPCs (CreateClient, ListClients, GetClient, UpdateClient, +// DeleteClient, ResetClientSecret, Register, ResendConfirmEMail, GetUser): +// OAuth client management is not needed in the CLI. +// - admin.GetDashboard: not needed in the CLI. +// - admin.CreateProjectNetwork: dropped. It requires resolving subnet IDs via +// a ListSubnets endpoint that is not available on the gRPC API, and the +// request carries nested struct fields the generator cannot express. The +// previously disabled cmd/project/_network_create.go stub was removed. +// +// Internal / agent-plane services are also intentionally not surfaced in the +// CLI: network.v1.*, metadata.v1.*, gateway.v1.*, and cloud.v2.ReadinessCheck. type APICall struct { Client string Endpoint string diff --git a/pkg/generator/helpers.go b/pkg/generator/helpers.go index eae2bb3..30eacd8 100644 --- a/pkg/generator/helpers.go +++ b/pkg/generator/helpers.go @@ -216,6 +216,11 @@ func defaultValue(param Param) *Statement { if isArrayType(param.Type) { return Index().Id(strings.TrimPrefix(param.Type, "[]")).Values(Dict{}) } + // Enum-typed flags are bound to string variables, so an empty + // string is the correct zero value when no default is given. + if isEnumType(param.Type) { + return Lit("") + } } } else { // TODO: Fileupload @@ -252,6 +257,11 @@ func defaultValue(param Param) *Statement { // parameterDescription returns the description of a parameter. If the parameter // has a default value, the default value is added to the description. func parameterDescription(param Param) string { + // Session-sourced params are optional flags with a session fallback. + if param.Source == "session.CurrentProject" { + return fmt.Sprintf("%s (defaults to the project selected via \"project use\")", param.Description) + } + var flags []string if param.Required { flags = append(flags, "required") diff --git a/pkg/generator/sub_command.go b/pkg/generator/sub_command.go index d93bc20..7a1fb46 100644 --- a/pkg/generator/sub_command.go +++ b/pkg/generator/sub_command.go @@ -44,6 +44,11 @@ func GenerateSubCommand(metadata SubcommandMetadata, targetFilename string) erro for _, param := range metadata.Action.Params { f.Var().Add(variableDefinition(name, param)) } + // When the identifier is the current-project session value, declare the + // optional --project-id override variable. + if resolveIdentifier(metadata) == "session.CurrentProject" { + f.Var().Id(strcase.LowerCamelCase(name) + "ProjectIdOverride").String() + } f.Line() // Enum helper functions @@ -121,21 +126,7 @@ func runCommand(name string, metadata SubcommandMetadata) []Code { // Identifiers can be set on the action or the definition. If the action // is set, the action identifier is used. If not, the definition identifier // is used. - identifier := "" - // "Global identifier for all actions present? - if metadata.Definition.Identifier != "" { - identifier = metadata.Definition.Identifier - } - // Override with action identifier - if metadata.Action.Identifier != "" { - // Reset identifier on purpose (override) global identifier - if metadata.Action.Identifier == "nil" { - identifier = "" - } else { - // Action specific identifier - identifier = metadata.Action.Identifier - } - } + identifier := resolveIdentifier(metadata) // The identifier key is the key used in the request to identify the // resource. By default, this is "Id". This can be overridden globally @@ -148,6 +139,13 @@ func runCommand(name string, metadata SubcommandMetadata) []Code { identifierKey = metadata.Action.IdentifierKey } + // When the identifier comes from the current project session value, we also + // expose an optional --project-id flag that overrides it. This lets the + // command be used either after "project use" or by passing --project-id + // explicitly (mirroring the source: session.CurrentProject params). + identifierProjectOverride := identifier == "session.CurrentProject" + identifierOverrideVar := strcase.LowerCamelCase(name) + "ProjectIdOverride" + if identifier != "" { c = append(c, Id("session").Op(":="). Id("ctx"). @@ -155,8 +153,56 @@ func runCommand(name string, metadata SubcommandMetadata) []Code { Assert(Op("*").Qual("github.com/G-PORTAL/gpcore-cli/pkg/config", "SessionConfig"))) c = append(c, If(Id("session").Op("==").Nil()).Block( Return(Qual("fmt", "Errorf").Call(Lit("no session found, please login first"))))) - c = append(c, If(Id(identifier).Op("==").Nil()).Block( - Return(Qual("fmt", "Errorf").Call(Lit("no identifier found, please set the identifier first"))))) + + if identifierProjectOverride { + // resolvedProjectId := + // if resolvedProjectId == "" { if session.CurrentProject == nil { err } else { resolvedProjectId = *session.CurrentProject } } + c = append(c, Id("resolvedProjectId").Op(":=").Id(identifierOverrideVar)) + c = append(c, If(Id("resolvedProjectId").Op("==").Lit("")).Block( + If(Id(identifier).Op("==").Nil()).Block( + Return(Qual("fmt", "Errorf").Call( + Lit("no project selected: pass --project-id or select one with \"project use\"")))), + Id("resolvedProjectId").Op("=").Op("*").Id(identifier), + )) + } else { + c = append(c, If(Id(identifier).Op("==").Nil()).Block( + Return(Qual("fmt", "Errorf").Call(Lit("no identifier found, please set the identifier first"))))) + } + c = append(c, Line()) + } + + // Session-sourced params (e.g. --project-id falling back to the project + // selected via "project use"). The flag is optional; when empty we fall + // back to the session value and error if that is unset as well. + sourceParams := make([]Param, 0) + for _, param := range metadata.Action.Params { + if param.Source != "" { + sourceParams = append(sourceParams, param) + } + } + if len(sourceParams) > 0 { + // Declare the session once (it may already be declared above when an + // identifier is used). + if identifier == "" { + c = append(c, Id("session").Op(":="). + Id("ctx"). + Dot("Value").Call(Lit("config")). + Assert(Op("*").Qual("github.com/G-PORTAL/gpcore-cli/pkg/config", "SessionConfig"))) + c = append(c, If(Id("session").Op("==").Nil()).Block( + Return(Qual("fmt", "Errorf").Call(Lit("no session found, please login first"))))) + } + for _, param := range sourceParams { + variable := strcase.LowerCamelCase(name) + title(strcase.LowerCamelCase(param.Name)) + sessionField := strings.TrimPrefix(param.Source, "session.") + flagName := strcase.KebabCase(param.Name) + // if == "" { if session. == nil { error } else { var = *session. } } + c = append(c, If(Id(variable).Op("==").Lit("")).Block( + If(Id("session").Dot(sessionField).Op("==").Nil()).Block( + Return(Qual("fmt", "Errorf").Call( + Lit("no project selected: pass --"+flagName+" or select one with \"project use\"")))), + Id(variable).Op("=").Op("*").Id("session").Dot(sessionField), + )) + } c = append(c, Line()) } @@ -177,7 +223,11 @@ func runCommand(name string, metadata SubcommandMetadata) []Code { apiCallParams := Dict{} // Do we have an identifier? if identifier != "" { - apiCallParams[Id(identifierKey)] = Op("*").Id(identifier) + if identifierProjectOverride { + apiCallParams[Id(identifierKey)] = Id("resolvedProjectId") + } else { + apiCallParams[Id(identifierKey)] = Op("*").Id(identifier) + } } // Specific parameters set? @@ -194,6 +244,10 @@ func runCommand(name string, metadata SubcommandMetadata) []Code { } else { val = Qual("github.com/G-PORTAL/gpcore-cli/pkg/protobuf", stripPackage(param.Type)+"ToProto").Call(Id(variable)) } + } else if param.Source != "" { + // Session-sourced param: the variable is resolved (flag or session + // fallback) before the API call and always passed by value. + val = Id(variable) } else { // Optional pointer type if !param.Required && param.Default == nil { @@ -556,6 +610,24 @@ func tableColValue(col string, structPrefix string) []Code { return c } +// resolveIdentifier returns the effective identifier for an action, taking the +// definition-level identifier and any action-level override (including the +// "nil" reset) into account. An empty string means no identifier is used. +func resolveIdentifier(metadata SubcommandMetadata) string { + identifier := "" + if metadata.Definition.Identifier != "" { + identifier = metadata.Definition.Identifier + } + if metadata.Action.Identifier != "" { + if metadata.Action.Identifier == "nil" { + identifier = "" + } else { + identifier = metadata.Action.Identifier + } + } + return identifier +} + // initFunc generates the init function, which will add all flags and params to // the command and add it to the root command. Required flags are marked as // such. @@ -595,10 +667,28 @@ func initFunc(name string, metadata SubcommandMetadata) []Code { c = append(c, Line()) } - // Required fields + // Optional --project-id override for commands whose identifier is the + // current-project session value. Lets the command run either after + // "project use" or with an explicit --project-id. + if resolveIdentifier(metadata) == "session.CurrentProject" { + c = append(c, + Id(name+"Cmd"). + Dot("Flags").Call(). + Dot("StringVar").Params( + Op("&").Id(strcase.LowerCamelCase(name)+"ProjectIdOverride"), + Lit("project-id"), + Lit(""), + Lit("Project UUID (defaults to the project selected via \"project use\")"), + )) + c = append(c, Line()) + } + + // Required fields. Session-sourced params (param.Source set) are never + // marked required: they fall back to the session value (e.g. the project + // selected via "project use") when the flag is omitted. containsRequiredFields := false for _, param := range metadata.Action.Params { - if param.Required { + if param.Required && param.Source == "" { c = append(c, Id(strcase.LowerCamelCase(name)+"Cmd"). Dot("MarkFlagRequired"). From ab0fd7b818b8f4b421485a9bae8b000180a55b10 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 8 Jun 2026 12:56:37 +0200 Subject: [PATCH 16/20] fix(cli): accept --project-id or "project use" interchangeably Resolve the duplicated/mandatory --project-id flag so project-scoped commands work with either an explicit --project-id or the project selected via "project use": - node (get/create/destroy/reinstall/power-action/change-billing-period) and project-image (get/delete/delete-version): project_id is now a session-sourced optional param instead of a required flag. - change-rescue-mode (manual): same optional --project-id fallback. - Drop node root PersistentPreRunE that forced a selected project, so a command can run by passing --project-id without "project use" first. Identifier-based commands (project, project-cloudprovider, node list, ...) gain the optional --project-id override automatically via the generator. GPCO-49 --- cmd/node/change_rescue_mode.go | 18 ++++++++++++++++-- cmd/node/root.go | 17 ++++------------- pkg/generator/definition/node.yaml | 13 +++++++------ pkg/generator/definition/project-image.yaml | 6 +++--- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/cmd/node/change_rescue_mode.go b/cmd/node/change_rescue_mode.go index 11c44e5..87666da 100644 --- a/cmd/node/change_rescue_mode.go +++ b/cmd/node/change_rescue_mode.go @@ -3,6 +3,7 @@ package node import ( "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/cloud/v1/cloudv1grpc" cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" + "fmt" "github.com/G-PORTAL/gpcore-cli/pkg/client" "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/G-PORTAL/gpcore-cli/pkg/protobuf" @@ -21,6 +22,20 @@ var changeRescueModeCmd = &cobra.Command{ Long: "Change rescue mode", RunE: func(cobraCmd *cobra.Command, args []string) error { ctx := client.ExtractContext(cobraCmd) + + // --project-id is optional and falls back to the project selected via + // "project use" (mirrors the generated commands' behavior). + session := ctx.Value("config").(*config.SessionConfig) + if session == nil { + return fmt.Errorf("no session found, please login first") + } + if changeRescueModeProjectId == "" { + if session.CurrentProject == nil { + return fmt.Errorf("no project selected: pass --project-id or select one with \"project use\"") + } + changeRescueModeProjectId = *session.CurrentProject + } + grpcConn := ctx.Value("conn").(*grpc.ClientConn) client := cloudv1grpc.NewCloudServiceClient(grpcConn) resp, err := client.ChangeNodeRescueMode(cobraCmd.Context(), &cloudv1.ChangeNodeRescueModeRequest{ @@ -51,12 +66,11 @@ var changeRescueModeCmd = &cobra.Command{ func init() { changeRescueModeCmd.Flags().StringVar(&changeRescueModeId, "id", "", "Node ID (required)") - changeRescueModeCmd.Flags().StringVar(&changeRescueModeProjectId, "project-id", "", "Project ID (required)") + changeRescueModeCmd.Flags().StringVar(&changeRescueModeProjectId, "project-id", "", "Project ID (defaults to the project selected via \"project use\")") changeRescueModeCmd.Flags().BoolVar(&changeRescueModeEnabled, "enabled", false, "Enable or disable rescue mode") changeRescueModeCmd.Flags().StringVar(&changeRescueModePassword, "password", "", "Password for rescue mode") changeRescueModeCmd.MarkFlagRequired("id") - changeRescueModeCmd.MarkFlagRequired("project-id") RootNodeCommand.AddCommand(changeRescueModeCmd) } diff --git a/cmd/node/root.go b/cmd/node/root.go index fb2786d..ed11ca6 100644 --- a/cmd/node/root.go +++ b/cmd/node/root.go @@ -1,11 +1,13 @@ package node import ( - "fmt" - "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/spf13/cobra" ) +// Note: node subcommands no longer require a globally selected project here. +// Each subcommand accepts an optional --project-id that falls back to the +// project selected via "project use" (and errors if neither is set). This +// avoids forcing "project use" when the project is passed explicitly. var RootNodeCommand = &cobra.Command{ Use: "node", Short: "Utility to combine multiple nodes api actions", @@ -13,17 +15,6 @@ var RootNodeCommand = &cobra.Command{ GroupID: "resources", DisableFlagsInUseLine: true, Args: cobra.MatchAll(cobra.ExactArgs(0), cobra.OnlyValidArgs), - PersistentPreRunE: func(cobraCmd *cobra.Command, args []string) error { - // Context is not set in PersistentPreRunE, so we need to get the session config manually - config, err := config.GetSessionConfig() - if err != nil { - return err - } - if config.CurrentProject == nil { - return fmt.Errorf("no project selected") - } - return nil - }, RunE: func(cobraCmd *cobra.Command, args []string) error { return cobraCmd.Usage() }, diff --git a/pkg/generator/definition/node.yaml b/pkg/generator/definition/node.yaml index 16c8420..d191d9c 100644 --- a/pkg/generator/definition/node.yaml +++ b/pkg/generator/definition/node.yaml @@ -31,7 +31,7 @@ actions: - name: project_id description: Project ID type: string - required: true + source: session.CurrentProject # There is an update actions in the cloud API as well. Not sure which # update node actions we should use here. @@ -56,7 +56,7 @@ actions: - name: project_id type: string description: Project ID - required: true + source: session.CurrentProject - name: flavour_id type: string description: Flavour ID @@ -102,7 +102,7 @@ actions: - name: project_id type: string description: Project UUID - required: true + source: session.CurrentProject destroy-immediately: api-call: admin.DestroyNode @@ -126,7 +126,7 @@ actions: - name: project_id type: string description: Project ID - required: true + source: session.CurrentProject - name: fqdn type: string description: Fully qualified domain name @@ -160,7 +160,7 @@ actions: - name: project_id description: Project ID type: string - required: true + source: session.CurrentProject - name: power_state type: cloudv1.ServerPowerState default: cloudv1.SERVER_POWER_STATE_REBOOT @@ -189,7 +189,8 @@ actions: required: true - name: project_id type: string - required: true + description: Project ID + source: session.CurrentProject - name: billing_period type: cloudv1.BillingPeriod default: cloudv1.BILLING_PERIOD_MONTHLY diff --git a/pkg/generator/definition/project-image.yaml b/pkg/generator/definition/project-image.yaml index fc15e6c..3357490 100644 --- a/pkg/generator/definition/project-image.yaml +++ b/pkg/generator/definition/project-image.yaml @@ -24,7 +24,7 @@ actions: - name: project_id type: string description: Project ID - required: true + source: session.CurrentProject create: api-call: cloud.CreateProjectImage @@ -55,7 +55,7 @@ actions: - name: project_id type: string description: Project ID - required: true + source: session.CurrentProject delete-version: api-call: cloud.DeleteProjectImageVersion @@ -69,6 +69,6 @@ actions: - name: project_id type: string description: Project ID - required: true + source: session.CurrentProject identifier: session.CurrentProject \ No newline at end of file From 1508384542f90ea3a05571ea934a087fe4c0f6ea Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 8 Jun 2026 12:57:33 +0200 Subject: [PATCH 17/20] fix(cli): reconcile command params with the gRPC request fields Full review of every command's params against the latest gRPC request messages. Add missing, non-deprecated fields and fix a real bug: - flavour list-project / project flavours: include_sold_out - image update: contains_spla_license - ip history, log admin, network-switch list, node list: search (+ admin log admin_user_id / user_id filters) - project images: only_available; project logs: search, user_id - server update: autofix, maintenance, maintenance_reason (is_broken left out, deprecated); server delete: skip_clean - spla get: year, month; user unlock: reason - project-cloudprovider delete-image: add missing cloud_provider_image_id (previously impossible to target the image) - operating-systems update / flavour update: document fields that cannot be expressed as flags (File / repeated nested messages) No stale params were found; all pre-existing params map to real fields. GPCO-49 --- pkg/generator/definition/flavour.yaml | 8 ++++++++ pkg/generator/definition/image.yaml | 4 ++++ pkg/generator/definition/ip.yaml | 5 +++++ pkg/generator/definition/log.yaml | 13 ++++++++++++ pkg/generator/definition/network-switch.yaml | 5 +++++ pkg/generator/definition/node.yaml | 5 +++++ .../definition/operating-systems.yaml | 3 +++ .../definition/project-cloudprovider.yaml | 4 ++++ pkg/generator/definition/project.yaml | 20 +++++++++++++++++++ pkg/generator/definition/server.yaml | 17 ++++++++++++++++ pkg/generator/definition/spla.yaml | 11 +++++++++- 11 files changed, 94 insertions(+), 1 deletion(-) diff --git a/pkg/generator/definition/flavour.yaml b/pkg/generator/definition/flavour.yaml index de3eb0a..5960432 100644 --- a/pkg/generator/definition/flavour.yaml +++ b/pkg/generator/definition/flavour.yaml @@ -31,6 +31,11 @@ actions: type: string description: Datacenter UUID required: true + - name: include_sold_out + type: bool + description: Include sold-out flavours in the result + required: false + optional: true fields: - Id - Name @@ -106,6 +111,9 @@ actions: update: api-call: admin.UpdateFlavour description: Update flavour details + # NOTE: UpdateFlavourRequest also has a repeated "mappings" + # ([]FlavourMapping) field. It is intentionally not exposed because the + # generator cannot express a repeated nested message as command flags. params: - name: id type: string diff --git a/pkg/generator/definition/image.yaml b/pkg/generator/definition/image.yaml index 1fa8ad3..c999cc3 100644 --- a/pkg/generator/definition/image.yaml +++ b/pkg/generator/definition/image.yaml @@ -77,6 +77,10 @@ actions: type: "[]cloudv1.AuthenticationType" description: Authentication types required: true + - name: contains_spla_license + type: bool + description: Contains SPLA license + required: true create: api-call: admin.CreateImage diff --git a/pkg/generator/definition/ip.yaml b/pkg/generator/definition/ip.yaml index dc2869e..423936a 100644 --- a/pkg/generator/definition/ip.yaml +++ b/pkg/generator/definition/ip.yaml @@ -6,6 +6,11 @@ actions: api-call: admin.ListIPHistories description: List all IP history entries root-key: IpHistories + params: + - name: search + type: string + description: Optional search term + required: false fields: - CreatedAt.DateTime - User diff --git a/pkg/generator/definition/log.yaml b/pkg/generator/definition/log.yaml index cb02ee0..4879dbd 100644 --- a/pkg/generator/definition/log.yaml +++ b/pkg/generator/definition/log.yaml @@ -24,6 +24,19 @@ actions: api-call: admin.ListAdminLogs description: List all admin logs root-key: Logs + params: + - name: search + type: string + description: Optional search term + required: false + - name: admin_user_id + type: string + description: Filter by admin user UUID + required: false + - name: user_id + type: string + description: Filter by target user UUID + required: false fields: - CreatedAt.DateTime - AdminUser.BasicUser diff --git a/pkg/generator/definition/network-switch.yaml b/pkg/generator/definition/network-switch.yaml index 450a48b..ce1c636 100644 --- a/pkg/generator/definition/network-switch.yaml +++ b/pkg/generator/definition/network-switch.yaml @@ -6,6 +6,11 @@ actions: api-call: admin.ListSwitches description: List all network switches root-key: Switches + params: + - name: search + type: string + description: Optional search term + required: false fields: - Id - Name diff --git a/pkg/generator/definition/node.yaml b/pkg/generator/definition/node.yaml index d191d9c..69a5b46 100644 --- a/pkg/generator/definition/node.yaml +++ b/pkg/generator/definition/node.yaml @@ -6,6 +6,11 @@ actions: api-call: cloudv2.ListNodes description: List all nodes in the project root-key: Nodes + params: + - name: search + type: string + description: Optional search term + required: false fields: - Id - Fqdn diff --git a/pkg/generator/definition/operating-systems.yaml b/pkg/generator/definition/operating-systems.yaml index 6e9c867..3e11456 100644 --- a/pkg/generator/definition/operating-systems.yaml +++ b/pkg/generator/definition/operating-systems.yaml @@ -37,6 +37,9 @@ actions: update: api-call: admin.UpdateOperatingSystem description: Update operating system details + # NOTE: UpdateOperatingSystemRequest also has an optional "icon" (File) + # field. It is intentionally not exposed because the generator cannot + # express a nested File message (file upload) as command flags. params: - name: id type: string diff --git a/pkg/generator/definition/project-cloudprovider.yaml b/pkg/generator/definition/project-cloudprovider.yaml index ef97d2b..51bd5b0 100644 --- a/pkg/generator/definition/project-cloudprovider.yaml +++ b/pkg/generator/definition/project-cloudprovider.yaml @@ -137,6 +137,10 @@ actions: identifier: nil params: - name: image_id + type: string + description: Image UUID + required: true + - name: cloud_provider_image_id type: string description: Cloud Provider image ID required: true diff --git a/pkg/generator/definition/project.yaml b/pkg/generator/definition/project.yaml index 09c7db2..d02c392 100644 --- a/pkg/generator/definition/project.yaml +++ b/pkg/generator/definition/project.yaml @@ -88,6 +88,11 @@ actions: description: Datacenter to fetch the flavours from type: string required: true + - name: include_sold_out + type: bool + description: Include sold-out flavours in the result + required: false + optional: true fields: - Id - Name @@ -107,6 +112,15 @@ actions: logs: api-call: cloudv2.ListProjectLogs description: List all logs in the project + params: + - name: search + type: string + description: Optional search term + default: "" + - name: user_id + type: string + description: Filter by user UUID + default: "" fields: - CreatedAt.DateTime - User.BasicUser @@ -173,6 +187,12 @@ actions: images: api-call: cloud.ListProjectImages description: List all images in the project + params: + - name: only_available + type: bool + description: Only include available images + required: false + optional: true # TODO: Custom formatter to output keys in authorized_keys format ssh-keys: diff --git a/pkg/generator/definition/server.yaml b/pkg/generator/definition/server.yaml index d20ac80..a7c54c4 100644 --- a/pkg/generator/definition/server.yaml +++ b/pkg/generator/definition/server.yaml @@ -77,6 +77,19 @@ actions: type: string description: Server Pool UUID required: false + # is_broken is deprecated in the gRPC API and intentionally not exposed. + - name: autofix + type: bool + description: Enable the automated monitoring fix job for this server + default: false + - name: maintenance + type: bool + description: Set or clear maintenance mode + required: false + - name: maintenance_reason + type: string + description: Reason for maintenance (used when maintenance is true) + required: false delete: api-call: admin.DeleteServer @@ -91,6 +104,10 @@ actions: description: Force destroy the server, even if the server is unresponsive default: false required: true + - name: skip_clean + type: bool + description: Allow deletion without cleaning the device + default: false replace: api-call: admin.ReplaceServer diff --git a/pkg/generator/definition/spla.yaml b/pkg/generator/definition/spla.yaml index b7c8e7c..a11d6fc 100644 --- a/pkg/generator/definition/spla.yaml +++ b/pkg/generator/definition/spla.yaml @@ -4,4 +4,13 @@ group: billing actions: get: api-call: admin.GetSplaReporting - description: Get SPLA reporting details \ No newline at end of file + description: Get SPLA reporting details + params: + - name: year + type: int32 + description: Reporting year + required: true + - name: month + type: int32 + description: Reporting month (1-12) + required: true \ No newline at end of file From 253efc7161365bc7050b856e7858f64ff9475cda Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 8 Jun 2026 12:58:21 +0200 Subject: [PATCH 18/20] feat(cli): add missing gRPC coverage commands Expand CLI coverage toward parity with the gRPC API: - admin-project (new resource): list/get/nodes (generated) and update (manual; nested BillingProfile). Kept separate from the user-facing "project" command to avoid colliding with the cloud.* endpoints. - server: issues (ListServerIssues), server-issues (GetServerIssues), validate (ValidateServer), search-options (GetServerSearchOptions), and a manual "filter" command using ListServers ExtendedSearch. - network-arp: search-options (GetArpEntriesSearchOptions). - user: stats (GetUserStats); billing-profile: update/delete. - notifications (manual): cloud.SubscribeNotifications, sharing the stream loop with livelog via the new api.StreamMessages helper. - Add FormatServerIssueSource formatter. Intentionally excluded: payment credit-card/plan-code, auth client mgmt, admin GetDashboard, and internal network/metadata/gateway/readiness RPCs. GPCO-49 --- cmd/admin_project/update.go | 75 +++++++++ cmd/agent/root.go | 1 + cmd/livelog.go | 31 +--- cmd/notifications.go | 61 +++++++ cmd/server/filter.go | 155 ++++++++++++++++++ pkg/api/formatter.go | 5 + pkg/api/stream.go | 46 ++++++ pkg/generator/definition/admin-project.yaml | 60 +++++++ pkg/generator/definition/billing-profile.yaml | 55 ++++++- pkg/generator/definition/network-arp.yaml | 8 +- pkg/generator/definition/server.yaml | 57 +++++++ pkg/generator/definition/user.yaml | 10 +- 12 files changed, 534 insertions(+), 30 deletions(-) create mode 100644 cmd/admin_project/update.go create mode 100644 cmd/notifications.go create mode 100644 cmd/server/filter.go create mode 100644 pkg/api/stream.go create mode 100644 pkg/generator/definition/admin-project.yaml diff --git a/cmd/admin_project/update.go b/cmd/admin_project/update.go new file mode 100644 index 0000000..68bedc1 --- /dev/null +++ b/cmd/admin_project/update.go @@ -0,0 +1,75 @@ +package admin_project + +import ( + "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc" + adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1" + cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" + "github.com/G-PORTAL/gpcore-cli/pkg/client" + "github.com/G-PORTAL/gpcore-cli/pkg/config" + "github.com/G-PORTAL/gpcore-cli/pkg/protobuf" + "github.com/spf13/cobra" + "google.golang.org/grpc" +) + +// update is implemented manually (not generated) because +// admin.UpdateProjectRequest carries a nested BillingProfile message which the +// YAML generator cannot express as command flags. The billing profile is +// referenced by its UUID; the backend resolves the full profile from the ID. + +var updateId string +var updateName string +var updateAvatarUrl string +var updateBillingProfileId string +var updateServerPoolIds []string + +var updateCmd = &cobra.Command{ + Args: cobra.OnlyValidArgs, + DisableFlagsInUseLine: true, + Long: "Update project details (admin)", + RunE: func(cobraCmd *cobra.Command, args []string) error { + ctx := client.ExtractContext(cobraCmd) + grpcConn := ctx.Value("conn").(*grpc.ClientConn) + grpcClient := adminv1grpc.NewAdminServiceClient(grpcConn) + + req := &adminv1.UpdateProjectRequest{ + Id: updateId, + Name: updateName, + AvatarUrl: updateAvatarUrl, + ServerPoolIds: updateServerPoolIds, + } + if updateBillingProfileId != "" { + req.BillingProfile = cloudv1.BillingProfile_builder{ + Id: updateBillingProfileId, + }.Build() + } + + resp, err := grpcClient.UpdateProject(cobraCmd.Context(), req) + if err != nil { + return err + } + if config.JSONOutput { + jsonData, err := protobuf.MarshalIndent(resp) + if err != nil { + return err + } + cobraCmd.Println(string(jsonData)) + } + return nil + }, + Short: "Update project details (admin)", + Use: "update", + ValidArgs: []string{"id", "name", "avatar-url", "billing-profile-id", "server-pool-ids"}, +} + +func init() { + updateCmd.Flags().StringVar(&updateId, "id", "", "Project UUID (required)") + updateCmd.Flags().StringVar(&updateName, "name", "", "Project name (required)") + updateCmd.Flags().StringVar(&updateAvatarUrl, "avatar-url", "", "Avatar URL") + updateCmd.Flags().StringVar(&updateBillingProfileId, "billing-profile-id", "", "Billing profile UUID") + updateCmd.Flags().StringSliceVar(&updateServerPoolIds, "server-pool-ids", nil, "Server pool UUIDs") + + updateCmd.MarkFlagRequired("id") + updateCmd.MarkFlagRequired("name") + + RootAdminProjectCommand.AddCommand(updateCmd) +} diff --git a/cmd/agent/root.go b/cmd/agent/root.go index dec2024..be4e79c 100644 --- a/cmd/agent/root.go +++ b/cmd/agent/root.go @@ -63,6 +63,7 @@ func New() *cobra.Command { cmd.SelfupdateCommand(&rootCmd) cmd.SetLogLevelCommand(&rootCmd) cmd.LiveLogCommand(&rootCmd) + cmd.NotificationsCommand(&rootCmd) //InteractiveCLICommand(&rootCmd) // Autogenerated commands diff --git a/cmd/livelog.go b/cmd/livelog.go index ade33f6..7a1afbd 100644 --- a/cmd/livelog.go +++ b/cmd/livelog.go @@ -4,7 +4,7 @@ import ( "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc" adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1" cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" - "github.com/charmbracelet/ssh" + "github.com/G-PORTAL/gpcore-cli/pkg/api" "github.com/jedib0t/go-pretty/v6/text" "github.com/spf13/cobra" "google.golang.org/grpc" @@ -18,37 +18,16 @@ func LiveLogCommand(rootCmd *cobra.Command) { DisableFlagsInUseLine: true, Args: cobra.OnlyValidArgs, RunE: func(cobraCmd *cobra.Command, args []string) error { - sshSession := cobraCmd.Context().Value("ssh").(*ssh.Session) - cobraCmd.SetOut(*sshSession) - conn := cobraCmd.Context().Value("conn").(*grpc.ClientConn) admin := adminv1grpc.NewAdminServiceClient(conn) - res, err := admin.SubscribeServerLogs(cobraCmd.Context(), &adminv1.SubscribeServerLogsRequest{}) + stream, err := admin.SubscribeServerLogs(cobraCmd.Context(), &adminv1.SubscribeServerLogsRequest{}) if err != nil { return err } - connectionClosed := false - go func() { - breakChan := make(chan bool) - (*sshSession).Break(breakChan) - <-breakChan - connectionClosed = true - }() - - cobraCmd.Printf("\033[33mWaiting for new notifications ...\033[0m\n") // We wait for (and print out) relevant notifications until the break // request is received. - for { - if connectionClosed { - break - } - - msg, err := res.Recv() // Blocking - if err != nil { - return err - } - + return api.StreamMessages(cobraCmd, stream, func(msg *adminv1.SubscribeServerLogsResponse) { // TODO: Filter for source/server/datacenter // TODO: Only above level ... @@ -78,9 +57,7 @@ func LiveLogCommand(rootCmd *cobra.Command) { cobraCmd.Printf("%s: [%s] [%s] [%s] -> %s\n", color.Sprint(time), datacenter, server, source, color.Sprint(m.GetMessage())) } - } - - return nil + }) }, }) } diff --git a/cmd/notifications.go b/cmd/notifications.go new file mode 100644 index 0000000..f968717 --- /dev/null +++ b/cmd/notifications.go @@ -0,0 +1,61 @@ +package cmd + +import ( + "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/cloud/v1/cloudv1grpc" + cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" + "github.com/G-PORTAL/gpcore-cli/pkg/api" + "github.com/jedib0t/go-pretty/v6/text" + "github.com/spf13/cobra" + "google.golang.org/grpc" +) + +// NotificationsCommand registers the user-facing "notifications" command, which +// streams notifications via cloud.SubscribeNotifications. It shares the +// break/recv stream loop with "livelog" through api.StreamMessages; only the +// per-message rendering differs. +func NotificationsCommand(rootCmd *cobra.Command) { + rootCmd.AddCommand(&cobra.Command{ + Use: "notifications", + Short: "Live notification stream", + Long: "Subscribe to and print live notifications for your account", + DisableFlagsInUseLine: true, + Args: cobra.OnlyValidArgs, + RunE: func(cobraCmd *cobra.Command, args []string) error { + conn := cobraCmd.Context().Value("conn").(*grpc.ClientConn) + cloudClient := cloudv1grpc.NewCloudServiceClient(conn) + stream, err := cloudClient.SubscribeNotifications(cobraCmd.Context(), &cloudv1.SubscribeNotificationsRequest{}) + if err != nil { + return err + } + + return api.StreamMessages(cobraCmd, stream, func(msg *cloudv1.SubscribeNotificationsResponse) { + notification := msg.GetNotification() + if notification == nil { + return + } + + switch { + case notification.GetNode() != nil: + node := notification.GetNode() + label := text.Colors{text.FgCyan, text.BgBlack}.Sprint("Node") + cobraCmd.Printf("[%s] %s (%s)\n", label, node.GetFqdn(), node.GetId()) + case notification.GetProject() != nil: + project := notification.GetProject() + label := text.Colors{text.FgGreen, text.BgBlack}.Sprint("Project") + cobraCmd.Printf("[%s] %s (%s)\n", label, project.GetName(), project.GetId()) + case notification.GetUser() != nil: + user := notification.GetUser() + label := text.Colors{text.FgMagenta, text.BgBlack}.Sprint("User") + cobraCmd.Printf("[%s] %s (%s)\n", label, user.GetFullName(), user.GetId()) + case notification.GetServerLog() != nil: + m := notification.GetServerLog() + label := text.Colors{text.FgYellow, text.BgBlack}.Sprint("ServerLog") + t := m.GetUpdatedAt().AsTime().Format("15:04:05") + cobraCmd.Printf("[%s] %s -> %s\n", label, t, m.GetMessage()) + case notification.GetHeartbeat() != nil: + // Heartbeats keep the stream alive; ignore them in output. + } + }) + }, + }) +} diff --git a/cmd/server/filter.go b/cmd/server/filter.go new file mode 100644 index 0000000..aabb572 --- /dev/null +++ b/cmd/server/filter.go @@ -0,0 +1,155 @@ +package server + +import ( + "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/admin/v1/adminv1grpc" + adminv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/admin/v1" + typesv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/type/v1" + "fmt" + "strconv" + "strings" + + "github.com/G-PORTAL/gpcore-cli/pkg/api" + "github.com/G-PORTAL/gpcore-cli/pkg/client" + "github.com/G-PORTAL/gpcore-cli/pkg/config" + "github.com/G-PORTAL/gpcore-cli/pkg/protobuf" + "github.com/charmbracelet/ssh" + "github.com/jedib0t/go-pretty/v6/table" + "github.com/spf13/cobra" + "google.golang.org/grpc" + "google.golang.org/protobuf/proto" +) + +// filter is implemented manually (not generated) because it calls ListServers +// with an ExtendedSearch payload, which contains a repeated Filter message that +// the YAML generator cannot express as command flags. Use "server +// search-options" to discover the valid filter names and values. + +var filterSearch string +var filterFilters []string + +// parseFilter converts a "name=value" string into a typesv1.Filter. Values are +// treated as strings by default. Prefix the value with "int:" or "bool:" to +// send an integer or boolean filter value respectively. +func parseFilter(raw string) (*typesv1.Filter, error) { + parts := strings.SplitN(raw, "=", 2) + if len(parts) != 2 || parts[0] == "" { + return nil, fmt.Errorf("invalid filter %q, expected format name=value", raw) + } + name, value := parts[0], parts[1] + + builder := typesv1.Filter_builder{Name: name} + switch { + case strings.HasPrefix(value, "int:"): + n, err := strconv.ParseInt(strings.TrimPrefix(value, "int:"), 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid integer filter value for %q: %w", name, err) + } + builder.IntegerValue = &n + case strings.HasPrefix(value, "bool:"): + b, err := strconv.ParseBool(strings.TrimPrefix(value, "bool:")) + if err != nil { + return nil, fmt.Errorf("invalid boolean filter value for %q: %w", name, err) + } + builder.BooleanValue = &b + default: + builder.StringValue = &value + } + return builder.Build(), nil +} + +var filterCmd = &cobra.Command{ + Args: cobra.OnlyValidArgs, + DisableFlagsInUseLine: true, + Long: "List servers using extended search filters. Use 'server search-options' to discover valid filter names and values.", + RunE: func(cobraCmd *cobra.Command, args []string) error { + ctx := client.ExtractContext(cobraCmd) + grpcConn := ctx.Value("conn").(*grpc.ClientConn) + grpcClient := adminv1grpc.NewAdminServiceClient(grpcConn) + + var extendedSearch *typesv1.SearchRequest + if len(filterFilters) > 0 { + filters := make([]*typesv1.Filter, 0, len(filterFilters)) + for _, raw := range filterFilters { + f, err := parseFilter(raw) + if err != nil { + return err + } + filters = append(filters, f) + } + extendedSearch = typesv1.SearchRequest_builder{Filters: filters}.Build() + } + + sshSession := ctx.Value("ssh").(*ssh.Session) + tbl := table.NewWriter() + tbl.SetStyle(table.StyleRounded) + tbl.SetOutputMirror(*sshSession) + cobraCmd.SetOut(*sshSession) + defer cobraCmd.SetOut(nil) + tbl.AppendHeader(table.Row{"Id", "Name", "InPool", "PowerState", "ProvisionState", "CreatedAt"}) + + var combinedData []proto.Message + var totalPages int32 + pagination := &typesv1.PaginationRequest{Page: 1} + for { + req := &adminv1.ListServersRequest{Pagination: pagination} + if filterSearch != "" { + req.Search = &filterSearch + } + if extendedSearch != nil { + req.ExtendedSearch = extendedSearch + } + + resp, err := grpcClient.ListServers(cobraCmd.Context(), req) + if err != nil { + return err + } + + for _, entry := range resp.Servers { + tbl.AppendRow(table.Row{ + fmt.Sprintf("%v", entry.Id), + fmt.Sprintf("%v", entry.Name), + api.FormatBoolean(entry.InPool), + api.FormatServerPowerState(entry.PowerState), + api.FormatServerProvisioningState(entry.ProvisionState), + api.FormatDate(entry.CreatedAt), + }) + combinedData = append(combinedData, entry) + } + + if resp.Pagination == nil { + break + } + totalPages = resp.GetPagination().GetTotal() + pagination.Page++ + if resp.Pagination.Page >= totalPages { + break + } + } + + if config.CSVOutput { + tbl.RenderCSV() + return nil + } + if !config.JSONOutput { + tbl.Render() + } + if config.JSONOutput { + jsonData, err := protobuf.MarshalIndent(combinedData) + if err != nil { + return err + } + cobraCmd.Println(string(jsonData)) + } + return nil + }, + Short: "List servers using extended search filters", + Use: "filter", + ValidArgs: []string{"search", "filter"}, +} + +func init() { + filterCmd.Flags().StringVar(&filterSearch, "search", "", "Optional free-text search term") + filterCmd.Flags().StringArrayVar(&filterFilters, "filter", nil, "Extended search filter in the form name=value (prefix value with int: or bool: to type it). Repeatable.") + + RootServerCommand.AddCommand(filterCmd) +} diff --git a/pkg/api/formatter.go b/pkg/api/formatter.go index a442293..d9d24e7 100644 --- a/pkg/api/formatter.go +++ b/pkg/api/formatter.go @@ -37,6 +37,7 @@ var SpecialFormatters = []string{ "ServerProvisioningState", "ServerPowerState", "BillingPeriod", + "ServerIssueSource", } func FormatPrice(price *typesv1.Price) string { @@ -229,3 +230,7 @@ func FormatServerPowerState(state cloudv1.ServerPowerState) string { return strings.TrimPrefix(state.String(), "SERVER_POWER_STATE_") // TODO: More colors here } + +func FormatServerIssueSource(source cloudv1.ServerIssueSource) string { + return strings.TrimPrefix(source.String(), "SERVER_ISSUE_SOURCE_") +} diff --git a/pkg/api/stream.go b/pkg/api/stream.go new file mode 100644 index 0000000..76aee5b --- /dev/null +++ b/pkg/api/stream.go @@ -0,0 +1,46 @@ +package api + +import ( + "github.com/charmbracelet/ssh" + "github.com/spf13/cobra" +) + +// RecvStream is the minimal interface implemented by a gRPC server-streaming +// client (e.g. grpc.ServerStreamingClient[T]). It is satisfied by the streams +// returned by SubscribeServerLogs and SubscribeNotifications. +type RecvStream[T any] interface { + Recv() (*T, error) +} + +// StreamMessages consumes a gRPC server stream until the SSH client sends a +// break (Ctrl-C) or the stream returns an error. Each received message is +// passed to the handler for rendering. This is shared by the "livelog" and +// "notifications" commands, which both follow the same break/recv loop. +func StreamMessages[T any](cobraCmd *cobra.Command, stream RecvStream[T], handler func(msg *T)) error { + sshSession := cobraCmd.Context().Value("ssh").(*ssh.Session) + cobraCmd.SetOut(*sshSession) + + connectionClosed := false + go func() { + breakChan := make(chan bool) + (*sshSession).Break(breakChan) + <-breakChan + connectionClosed = true + }() + + cobraCmd.Printf("\033[33mWaiting for new notifications ...\033[0m\n") + for { + if connectionClosed { + break + } + + msg, err := stream.Recv() // Blocking + if err != nil { + return err + } + + handler(msg) + } + + return nil +} diff --git a/pkg/generator/definition/admin-project.yaml b/pkg/generator/definition/admin-project.yaml new file mode 100644 index 0000000..0dbf811 --- /dev/null +++ b/pkg/generator/definition/admin-project.yaml @@ -0,0 +1,60 @@ +description: Administrative project actions (cross-tenant, requires admin credentials) +group: admin + +# NOTE: This resource intentionally exposes the admin.* project endpoints under +# a dedicated "admin-project" command, separate from the user-facing "project" +# command (which is bound to cloud.* endpoints). The two cannot be merged +# because: +# - The gRPC connection is session-global (admin OR client-credentials, see +# pkg/api/connection.go), so we cannot switch credentials per-call. +# - Generated init() functions register subcommands unconditionally, so two +# actions with the same name under one root command would collide in cobra. +# The admin.UpdateProject action is implemented manually in update.go, because +# its request contains a nested BillingProfile message which the generator +# cannot express as command flags. + +actions: + list: + api-call: admin.ListProjects + description: List all projects (admin) + root-key: Projects + params: + - name: search + type: string + description: Optional search term + required: false + - name: user_id + type: string + description: Optional filter by user UUID + required: false + fields: + - Id + - Name + - Currency.Currency + - CanForceDeleteNodes.Boolean + - CreatedAt.Date + + get: + api-call: admin.GetProject + description: Get details for a project (admin) + params: + - name: id + type: string + description: Project UUID + required: true + + nodes: + api-call: admin.ListProjectNodes + description: List all nodes in a project (admin) + root-key: Nodes + params: + - name: id + type: string + description: Project UUID + required: true + fields: + - Id + - Fqdn + - Status.ServerProvisioningState + - Flavour.Flavour + - Datacenter.Datacenter diff --git a/pkg/generator/definition/billing-profile.yaml b/pkg/generator/definition/billing-profile.yaml index 1e6cad7..c182735 100644 --- a/pkg/generator/definition/billing-profile.yaml +++ b/pkg/generator/definition/billing-profile.yaml @@ -102,4 +102,57 @@ actions: - name: billing_email description: Defines the billing email address type: string - default: "" \ No newline at end of file + default: "" + + update: + api-call: payment.UpdateBillingProfile + description: Update an existing billing profile + identifier: nil + params: + - name: id + type: string + description: Billing Profile UUID + required: true + - name: name + type: string + description: Full name + required: true + - name: company + description: Company name + type: string + - name: vat_id + description: Vat ID (e.g. DE123456789) + type: string + - name: country_code + description: Country Code (e.g. DE) + type: string + required: true + - name: state + description: State + type: string + - name: street + description: Street (e.g. Some Road 123) + type: string + required: true + - name: city + description: City + type: string + required: true + - name: postcode + description: Post Code + type: string + required: true + - name: billing_email + description: Defines the billing email address + type: string + default: "" + + delete: + api-call: payment.DeleteBillingProfile + description: Delete a billing profile + identifier: nil + params: + - name: id + type: string + description: Billing Profile UUID + required: true \ No newline at end of file diff --git a/pkg/generator/definition/network-arp.yaml b/pkg/generator/definition/network-arp.yaml index 78e84be..9d35055 100644 --- a/pkg/generator/definition/network-arp.yaml +++ b/pkg/generator/definition/network-arp.yaml @@ -21,4 +21,10 @@ actions: - IpAddress - MacAddress - UpdatedAt.Date - # TODO: Implement SearchRequest/SearchOptions to include extended_search here \ No newline at end of file + # TODO: Implement SearchRequest/SearchOptions to include extended_search here + + # search-options returns the valid extended-search filter fields for ARP + # entries (the counterpart to "server search-options"). + search-options: + api-call: admin.GetArpEntriesSearchOptions + description: List available extended-search filter options for ARP entries \ No newline at end of file diff --git a/pkg/generator/definition/server.yaml b/pkg/generator/definition/server.yaml index a7c54c4..5bf7293 100644 --- a/pkg/generator/definition/server.yaml +++ b/pkg/generator/definition/server.yaml @@ -19,6 +19,14 @@ actions: description: Optional search term required: false + # search-options returns the set of valid extended-search filter fields and + # their allowed values. Use it to discover the --filter keys accepted by the + # "server filter" command (which calls the same ListServers RPC with an + # ExtendedSearch payload). + search-options: + api-call: admin.GetServerSearchOptions + description: List available extended-search filter options for servers + list-available: api-call: admin.ListAvailableServer description: List all available servers @@ -132,6 +140,55 @@ actions: description: Get server platform management details params: - name: id + type: string + description: Server UUID + required: true + + issues: + api-call: admin.ListServerIssues + description: List server issues across all servers + root-key: Issues + params: + - name: source + type: cloudv1.ServerIssueSource + description: Filter by issue source + optional: true + required: false + - name: datacenter_id + type: string + description: Filter by datacenter UUID + required: false + - name: include_resolved + type: bool + description: Include resolved issues + required: false + optional: true + - name: check_name + type: string + description: Filter by check name (e.g. device_exists, primary_interface, pm_offline) + required: false + fields: + - Id + - ServerId + - Source.ServerIssueSource + - CheckName + - Message + - Resolved.Boolean + + server-issues: + api-call: admin.GetServerIssues + description: Get all issues for a specific server + params: + - name: server_id + type: string + description: Server UUID + required: true + + validate: + api-call: admin.ValidateServer + description: Validate a server and trigger a sync if needed + params: + - name: server_id type: string description: Server UUID required: true \ No newline at end of file diff --git a/pkg/generator/definition/user.yaml b/pkg/generator/definition/user.yaml index aea5311..2422fd2 100644 --- a/pkg/generator/definition/user.yaml +++ b/pkg/generator/definition/user.yaml @@ -80,4 +80,12 @@ actions: - name: user_id type: string description: User ID - required: true \ No newline at end of file + required: true + - name: reason + type: string + description: Reason for unlocking the user + required: true + + stats: + api-call: admin.GetUserStats + description: Get aggregated user statistics \ No newline at end of file From e737af3245d1b44a4b9227f41dfe7da63cf2f474 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 8 Jun 2026 13:03:48 +0200 Subject: [PATCH 19/20] fix(cli): keep active project consistent across user contexts The active project ("project use") is per user/impersonation context and must not leak across context switches: - impersonate: clear CurrentProject when entering impersonation. - logout: also clear a lingering CurrentProject when not impersonating (e.g. after an expired impersonation / agent restart). - project use: now selects (arg), shows the active project (no arg, with a GetProject lookup that self-heals a stale selection), or clears it (--clear). - Add FormatCommandError with actionable hints (used by the agent) and make the NotFound hint generic instead of referencing flags that not every command has. GPCO-49 --- cmd/agent/start.go | 3 +- cmd/project/use.go | 79 ++++++++++++++++++++++++++++++++++++++--- cmd/user/impersonate.go | 5 +++ cmd/user/logout.go | 13 +++++++ pkg/client/error.go | 60 +++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 pkg/client/error.go diff --git a/cmd/agent/start.go b/cmd/agent/start.go index ab98a2b..d5f2dcb 100644 --- a/cmd/agent/start.go +++ b/cmd/agent/start.go @@ -10,6 +10,7 @@ import ( "syscall" "github.com/G-PORTAL/gpcore-cli/pkg/api" + "github.com/G-PORTAL/gpcore-cli/pkg/client" "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/G-PORTAL/gpcore-cli/pkg/consts" "github.com/charmbracelet/log" @@ -71,7 +72,7 @@ var startCmd = &cobra.Command{ if err := rootCmd.ExecuteContext(ctx); err != nil { log.Errorf("Error executing command on agent: %v", err) - rootCmd.Printf("Error executing command on agent: %v\n", err) + rootCmd.Printf("Error: %s\n", client.FormatCommandError(err)) _ = s.Exit(1) // send cmd exit code to the client return } diff --git a/cmd/project/use.go b/cmd/project/use.go index f05d409..4de3851 100644 --- a/cmd/project/use.go +++ b/cmd/project/use.go @@ -3,6 +3,7 @@ package project import ( "buf.build/gen/go/gportal/gpcore/grpc/go/gpcore/api/cloud/v1/cloudv1grpc" cloudv1 "buf.build/gen/go/gportal/gpcore/protocolbuffers/go/gpcore/api/cloud/v1" + "fmt" "github.com/G-PORTAL/gpcore-cli/pkg/client" "github.com/G-PORTAL/gpcore-cli/pkg/config" "github.com/charmbracelet/log" @@ -10,18 +11,84 @@ import ( "google.golang.org/grpc" ) +var useClear bool + var useCmd = &cobra.Command{ - Use: "use", - Short: "Selects a project to use", - Long: "Selects a project to use", + Use: "use [project-name-or-id]", + Short: "Select, show or clear the active project", + Long: "Manage the active project used as the default --project-id for\n" + + "project-scoped commands (e.g. \"node get\").\n\n" + + " - With an argument: selects the given project (by name or UUID).\n" + + " - Without arguments: shows the currently active project.\n" + + " - With --clear: clears the active project selection.", + Example: " gpcore project use my-project\n" + + " gpcore project use # show the active project\n" + + " gpcore project use --clear # clear the active project", DisableFlagsInUseLine: true, - Args: cobra.MatchAll(cobra.ExactArgs(1)), + Args: cobra.MaximumNArgs(1), RunE: func(cobraCmd *cobra.Command, args []string) error { ctx := client.ExtractContext(cobraCmd) + cfg := ctx.Value("config").(*config.SessionConfig) + + // Clear the active project. + if useClear { + if len(args) > 0 { + return fmt.Errorf("--clear cannot be combined with a project argument") + } + if cfg.CurrentProject == nil { + cobraCmd.Println("No active project was set.") + return nil + } + cfg.CurrentProject = nil + if err := cfg.Write(); err != nil { + return err + } + if err := config.RefreshSessionConfig(); err != nil { + return err + } + log.Info("Cleared active project") + cobraCmd.Println("Active project cleared.") + return nil + } + grpcConn := ctx.Value("conn").(*grpc.ClientConn) grpcClient := cloudv1grpc.NewCloudServiceClient(grpcConn) - cfg := ctx.Value("config").(*config.SessionConfig) + // No argument: show the currently active project. + if len(args) == 0 { + if cfg.CurrentProject == nil { + cobraCmd.Println("No active project selected.") + cobraCmd.Println("Select one with \"project use \".") + return nil + } + + // Resolve the project to show its name and to verify it is still + // accessible in the current (possibly impersonated) user context. + projectID := *cfg.CurrentProject + resp, err := grpcClient.GetProject(cobraCmd.Context(), &cloudv1.GetProjectRequest{ + Id: projectID, + }) + if err != nil || resp.GetProject() == nil { + // The active project is not accessible in the current context + // (e.g. it was selected while impersonating another user). Clear + // the stale selection so it cannot leak across contexts. + cfg.CurrentProject = nil + if werr := cfg.Write(); werr != nil { + return werr + } + if rerr := config.RefreshSessionConfig(); rerr != nil { + return rerr + } + cobraCmd.Printf("The previously active project (%s) is not accessible "+ + "in the current context and has been cleared.\n", projectID) + cobraCmd.Println("Select one with \"project use \".") + return nil + } + cobraCmd.Printf("Active project: %s (%s)\n", resp.GetProject().GetName(), projectID) + return nil + } + + // Argument given: select the project. var newProject *cloudv1.Project resp, err := grpcClient.ListProjects(cobraCmd.Context(), &cloudv1.ListProjectsRequest{}) @@ -62,5 +129,7 @@ var useCmd = &cobra.Command{ } func init() { + useCmd.Flags().BoolVar(&useClear, "clear", false, "Clear the active project selection") + RootProjectCommand.AddCommand(useCmd) } diff --git a/cmd/user/impersonate.go b/cmd/user/impersonate.go index 4889a1c..5912e92 100644 --- a/cmd/user/impersonate.go +++ b/cmd/user/impersonate.go @@ -46,6 +46,11 @@ var impersonateCmd = &cobra.Command{ expiresIn := int(resp.GetToken().GetExpiresAt().GetSeconds()) sessionConfig.ImpersonateExpiresIn = &expiresIn + // The active project belongs to the previous user context and is not + // valid for the impersonated user. Clear it so project-scoped commands + // don't operate on a project that does not belong to the new context. + sessionConfig.CurrentProject = nil + err = sessionConfig.Write() if err != nil { return err diff --git a/cmd/user/logout.go b/cmd/user/logout.go index 9c65188..f004dbf 100644 --- a/cmd/user/logout.go +++ b/cmd/user/logout.go @@ -28,6 +28,19 @@ var logoutCmd = &cobra.Command{ } if !isImpersonated { + // Even when not impersonating, clear any lingering active project so + // a selection left over from a previous (expired) impersonation does + // not leak into the current user context. + if sessionConfig.CurrentProject != nil { + sessionConfig.CurrentProject = nil + if err = sessionConfig.Write(); err != nil { + return err + } + if err = config.RefreshSessionConfig(); err != nil { + return err + } + cobraCmd.Println("Cleared a lingering active project from a previous session.") + } cobraCmd.Println("No need to logout, you do not impersonate anybody.") return nil } diff --git a/pkg/client/error.go b/pkg/client/error.go new file mode 100644 index 0000000..c36df8a --- /dev/null +++ b/pkg/client/error.go @@ -0,0 +1,60 @@ +package client + +import ( + "fmt" + "strings" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// FormatCommandError turns an error returned from a command into a clean, +// user-facing message. For gRPC errors it unwraps the underlying status so +// the user sees the actual server message (e.g. "failed to load node") and a +// short, actionable hint based on the status code instead of the raw +// "rpc error: code = Unknown desc = ..." wrapper. +func FormatCommandError(err error) string { + if err == nil { + return "" + } + + st, ok := status.FromError(err) + if !ok { + // Not a gRPC status error, return as-is. + return err.Error() + } + + msg := st.Message() + if hint := hintFor(st.Code(), msg); hint != "" { + return fmt.Sprintf("%s\n%s", msg, hint) + } + return msg +} + +// hintFor returns a short, actionable hint for an error. It inspects the +// message first (to catch cases the status code alone can not distinguish, +// e.g. a missing-role error returned as Unauthenticated) and falls back to a +// per-code hint. An empty string means no extra hint should be shown. +func hintFor(code codes.Code, msg string) string { + lower := strings.ToLower(msg) + + // Missing roles/permissions can be reported by the backend as either + // PermissionDenied or Unauthenticated. Detect it by message so we do not + // wrongly tell the user their session expired. + if strings.Contains(lower, "required role") || strings.Contains(lower, "permission") { + return "Hint: your account is missing the roles required for this action. Ask an administrator to grant the listed roles." + } + + switch code { + case codes.NotFound: + return "Hint: the resource was not found. Verify the IDs you passed and that the selected project (\"project use\" or --project-id) is the one that owns the resource." + case codes.PermissionDenied: + return "Hint: you do not have permission to access this resource." + case codes.Unauthenticated: + return "Hint: authentication failed. Your session may have expired, try logging in again." + case codes.InvalidArgument: + return "Hint: one or more arguments are invalid. Check the values passed to the command." + default: + return "" + } +} From fc1e6d8f89fd8f5daa97cd6bd3658c5348338e7d Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Mon, 8 Jun 2026 13:04:02 +0200 Subject: [PATCH 20/20] chore(project): remove disabled network-create stub The command was a disabled placeholder blocked on a missing ListSubnets gRPC endpoint. The intentional exclusion is now documented on the APICall type in the generator. GPCO-49 --- cmd/project/_network_create.go | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 cmd/project/_network_create.go diff --git a/cmd/project/_network_create.go b/cmd/project/_network_create.go deleted file mode 100644 index 61463b0..0000000 --- a/cmd/project/_network_create.go +++ /dev/null @@ -1,11 +0,0 @@ -package project - -// This command is disabled because the ListSubnets endpoint is missing on -// gRPC (which is needed to resolve subnet IDs). It will be re-enabled once -// the endpoint is available. -// -// TODO: Re-enable once admin.ListSubnets is available in the gRPC API. -// The command should: -// - Accept --subnet-ids and resolve them via ListSubnets -// - Register itself with RootProjectCommand.AddCommand(networkCreateCmd) -// - Fix MarkFlagRequired to use "subnet-ids" (not "subnets")