From d353c6ed82126f95bf07d5a77b963fd01087bde9 Mon Sep 17 00:00:00 2001 From: Nick Van Wiggeren Date: Mon, 23 Feb 2026 16:47:40 -0800 Subject: [PATCH 1/3] Bump Go to 1.26 and fix fmt format verb errors Go 1.26 tightened fmt format verb checking. `printer.Format` is a `type Format int`, and `%q` on an int-based type formats as a rune literal rather than a quoted string. This was flagged by the stricter vet checks. Fix by changing `Format.String()` to a value receiver (so it works on values returned by `Printer.Format()`) and replacing `%q` with `"%s"` across all call sites to properly invoke the Stringer interface. --- go.mod | 2 +- internal/cmd/backup/delete.go | 2 +- internal/cmd/branch/delete.go | 2 +- internal/cmd/database/delete.go | 2 +- internal/cmd/password/delete.go | 2 +- internal/cmd/role/delete.go | 2 +- internal/cmd/role/reassign.go | 2 +- internal/cmd/role/reset.go | 2 +- internal/cmd/role/reset_default.go | 2 +- internal/cmd/workflow/cancel.go | 2 +- internal/cmd/workflow/cutover.go | 2 +- internal/cmd/workflow/switch_traffic.go | 2 +- internal/printer/printer.go | 6 +++--- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index ec1a8aaf..30e42a9d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/planetscale/cli -go 1.25.5 +go 1.26.0 require ( github.com/99designs/keyring v1.2.2 diff --git a/internal/cmd/backup/delete.go b/internal/cmd/backup/delete.go index 6589bddd..65219f85 100644 --- a/internal/cmd/backup/delete.go +++ b/internal/cmd/backup/delete.go @@ -36,7 +36,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete backup with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot delete backup with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, backup) diff --git a/internal/cmd/branch/delete.go b/internal/cmd/branch/delete.go index ba2bcdb5..8570c212 100644 --- a/internal/cmd/branch/delete.go +++ b/internal/cmd/branch/delete.go @@ -50,7 +50,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete branch with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot delete branch with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } if db.Kind == "mysql" { diff --git a/internal/cmd/database/delete.go b/internal/cmd/database/delete.go index 3b435a11..0c0d2236 100644 --- a/internal/cmd/database/delete.go +++ b/internal/cmd/database/delete.go @@ -36,7 +36,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete database with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot delete database with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/cmd/password/delete.go b/internal/cmd/password/delete.go index d239c7d4..1d9eb16a 100644 --- a/internal/cmd/password/delete.go +++ b/internal/cmd/password/delete.go @@ -102,7 +102,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete password with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot delete password with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } var confirmationName string diff --git a/internal/cmd/role/delete.go b/internal/cmd/role/delete.go index 3b65ed3a..2d6103d4 100644 --- a/internal/cmd/role/delete.go +++ b/internal/cmd/role/delete.go @@ -38,7 +38,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete role with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot delete role with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, roleID) diff --git a/internal/cmd/role/reassign.go b/internal/cmd/role/reassign.go index f1a8888c..40426c50 100644 --- a/internal/cmd/role/reassign.go +++ b/internal/cmd/role/reassign.go @@ -41,7 +41,7 @@ func ReassignCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot reassign role objects with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot reassign role objects with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, roleID) diff --git a/internal/cmd/role/reset.go b/internal/cmd/role/reset.go index 1fb3d670..373dda49 100644 --- a/internal/cmd/role/reset.go +++ b/internal/cmd/role/reset.go @@ -36,7 +36,7 @@ func ResetCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot reset role password with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot reset role password with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, roleID) diff --git a/internal/cmd/role/reset_default.go b/internal/cmd/role/reset_default.go index f02afe77..1f2e9e1b 100644 --- a/internal/cmd/role/reset_default.go +++ b/internal/cmd/role/reset_default.go @@ -37,7 +37,7 @@ func ResetDefaultCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete password with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot delete password with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s", database, branch) diff --git a/internal/cmd/workflow/cancel.go b/internal/cmd/workflow/cancel.go index bfd81633..8233add1 100644 --- a/internal/cmd/workflow/cancel.go +++ b/internal/cmd/workflow/cancel.go @@ -40,7 +40,7 @@ marks it as cancelled, allowing you to start a new workflow if needed.`, if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot cancel workflow with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot cancel workflow with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/cmd/workflow/cutover.go b/internal/cmd/workflow/cutover.go index c0e1f11b..39597237 100644 --- a/internal/cmd/workflow/cutover.go +++ b/internal/cmd/workflow/cutover.go @@ -39,7 +39,7 @@ func CutoverCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot cutover with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot cutover with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/cmd/workflow/switch_traffic.go b/internal/cmd/workflow/switch_traffic.go index df53ddd9..9076dc9f 100644 --- a/internal/cmd/workflow/switch_traffic.go +++ b/internal/cmd/workflow/switch_traffic.go @@ -44,7 +44,7 @@ By default, this command will route all queries for primary, replica, and read-o if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot switch query traffic with the output format %q (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf("cannot switch query traffic with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/printer/printer.go b/internal/printer/printer.go index d7e6886d..b484d37b 100644 --- a/internal/printer/printer.go +++ b/internal/printer/printer.go @@ -41,8 +41,8 @@ func NewFormatValue(val Format, p *Format) *Format { return (*Format)(p) } -func (f *Format) String() string { - switch *f { +func (f Format) String() string { + switch f { case Human: return "human" case JSON: @@ -199,7 +199,7 @@ func (p *Printer) PrintResource(v interface{}) error { func (p *Printer) ConfirmCommand(confirmationName, commandShortName, confirmFailedName string) error { if p.Format() != Human { - return fmt.Errorf("cannot %s with the output format %q (run with --force to override)", commandShortName, p.Format()) + return fmt.Errorf("cannot %s with the output format \"%s\" (run with --force to override)", commandShortName, p.Format()) } if !IsTTY { From 0d6f3c48b6cee037bd8d3cdc1cf76331eafbb1f8 Mon Sep 17 00:00:00 2001 From: Nick Van Wiggeren Date: Mon, 23 Feb 2026 16:49:31 -0800 Subject: [PATCH 2/3] Use raw string literals for format strings with quotes --- internal/cmd/backup/delete.go | 2 +- internal/cmd/branch/delete.go | 2 +- internal/cmd/database/delete.go | 2 +- internal/cmd/password/delete.go | 2 +- internal/cmd/role/delete.go | 2 +- internal/cmd/role/reassign.go | 2 +- internal/cmd/role/reset.go | 2 +- internal/cmd/role/reset_default.go | 2 +- internal/cmd/workflow/cancel.go | 2 +- internal/cmd/workflow/cutover.go | 2 +- internal/cmd/workflow/switch_traffic.go | 2 +- internal/printer/printer.go | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/cmd/backup/delete.go b/internal/cmd/backup/delete.go index 65219f85..8c1d4809 100644 --- a/internal/cmd/backup/delete.go +++ b/internal/cmd/backup/delete.go @@ -36,7 +36,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete backup with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot delete backup with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, backup) diff --git a/internal/cmd/branch/delete.go b/internal/cmd/branch/delete.go index 8570c212..4822f967 100644 --- a/internal/cmd/branch/delete.go +++ b/internal/cmd/branch/delete.go @@ -50,7 +50,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete branch with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot delete branch with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } if db.Kind == "mysql" { diff --git a/internal/cmd/database/delete.go b/internal/cmd/database/delete.go index 0c0d2236..20f0d3bd 100644 --- a/internal/cmd/database/delete.go +++ b/internal/cmd/database/delete.go @@ -36,7 +36,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete database with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot delete database with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/cmd/password/delete.go b/internal/cmd/password/delete.go index 1d9eb16a..e7fce5c7 100644 --- a/internal/cmd/password/delete.go +++ b/internal/cmd/password/delete.go @@ -102,7 +102,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete password with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot delete password with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } var confirmationName string diff --git a/internal/cmd/role/delete.go b/internal/cmd/role/delete.go index 2d6103d4..f5eeba57 100644 --- a/internal/cmd/role/delete.go +++ b/internal/cmd/role/delete.go @@ -38,7 +38,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete role with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot delete role with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, roleID) diff --git a/internal/cmd/role/reassign.go b/internal/cmd/role/reassign.go index 40426c50..34e0b85c 100644 --- a/internal/cmd/role/reassign.go +++ b/internal/cmd/role/reassign.go @@ -41,7 +41,7 @@ func ReassignCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot reassign role objects with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot reassign role objects with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, roleID) diff --git a/internal/cmd/role/reset.go b/internal/cmd/role/reset.go index 373dda49..5cf7c639 100644 --- a/internal/cmd/role/reset.go +++ b/internal/cmd/role/reset.go @@ -36,7 +36,7 @@ func ResetCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot reset role password with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot reset role password with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s/%s", database, branch, roleID) diff --git a/internal/cmd/role/reset_default.go b/internal/cmd/role/reset_default.go index 1f2e9e1b..ed727597 100644 --- a/internal/cmd/role/reset_default.go +++ b/internal/cmd/role/reset_default.go @@ -37,7 +37,7 @@ func ResetDefaultCmd(ch *cmdutil.Helper) *cobra.Command { if !flags.force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot delete password with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot delete password with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } confirmationName := fmt.Sprintf("%s/%s", database, branch) diff --git a/internal/cmd/workflow/cancel.go b/internal/cmd/workflow/cancel.go index 8233add1..b91ebf52 100644 --- a/internal/cmd/workflow/cancel.go +++ b/internal/cmd/workflow/cancel.go @@ -40,7 +40,7 @@ marks it as cancelled, allowing you to start a new workflow if needed.`, if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot cancel workflow with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot cancel workflow with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/cmd/workflow/cutover.go b/internal/cmd/workflow/cutover.go index 39597237..5609030f 100644 --- a/internal/cmd/workflow/cutover.go +++ b/internal/cmd/workflow/cutover.go @@ -39,7 +39,7 @@ func CutoverCmd(ch *cmdutil.Helper) *cobra.Command { if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot cutover with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot cutover with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/cmd/workflow/switch_traffic.go b/internal/cmd/workflow/switch_traffic.go index 9076dc9f..69301afb 100644 --- a/internal/cmd/workflow/switch_traffic.go +++ b/internal/cmd/workflow/switch_traffic.go @@ -44,7 +44,7 @@ By default, this command will route all queries for primary, replica, and read-o if !force { if ch.Printer.Format() != printer.Human { - return fmt.Errorf("cannot switch query traffic with the output format \"%s\" (run with --force to override)", ch.Printer.Format()) + return fmt.Errorf(`cannot switch query traffic with the output format "%s" (run with --force to override)`, ch.Printer.Format()) } if !printer.IsTTY { diff --git a/internal/printer/printer.go b/internal/printer/printer.go index b484d37b..fdbc1749 100644 --- a/internal/printer/printer.go +++ b/internal/printer/printer.go @@ -199,7 +199,7 @@ func (p *Printer) PrintResource(v interface{}) error { func (p *Printer) ConfirmCommand(confirmationName, commandShortName, confirmFailedName string) error { if p.Format() != Human { - return fmt.Errorf("cannot %s with the output format \"%s\" (run with --force to override)", commandShortName, p.Format()) + return fmt.Errorf(`cannot %s with the output format "%s" (run with --force to override)`, commandShortName, p.Format()) } if !IsTTY { From 9f75fcc405d3e51ddf90893a5639a0ec31d91216 Mon Sep 17 00:00:00 2001 From: Nick Van Wiggeren Date: Mon, 23 Feb 2026 16:50:49 -0800 Subject: [PATCH 3/3] Bump Go Docker images to 1.26.0 --- Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index d896bd06..686fde14 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.25.5 AS build +FROM golang:1.26.0 AS build WORKDIR /app COPY . . diff --git a/docker-compose.yml b/docker-compose.yml index 881a93db..b117f940 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '2' services: app: - image: golang:1.25.5 + image: golang:1.26.0 volumes: - .:/work working_dir: /work