From 57ba4fae613cfa8ed7932f49dc89ed563a4a957b Mon Sep 17 00:00:00 2001 From: MaxHuang22 Date: Tue, 2 Jun 2026 16:55:02 +0800 Subject: [PATCH] feat: unconditionally inject --format flag for all shortcuts (#1156) * feat: unconditionally inject --format flag for all shortcuts Removes three HasFormat guards in runner.go so every shortcut gets --format regardless of the Shortcut.HasFormat field value. Shortcuts that already define a custom 'format' flag in Flags[] are skipped to avoid redefinition panics (e.g. mail +triage, +watch). HasFormat is retained in the struct but marked deprecated. Change-Id: I5e8fe07e839d5aed4cefaf7d753dabbaee68fb6e * test: isolate config dir in format-universal test Change-Id: I3a59942aa8a6753cd949ca42f2a19a72f032ff55 * test: revert unnecessary config-dir isolation (mount-only test) Change-Id: I0146e5a2f57f5419863bdeeaa1a662fd8f70bddf --- shortcuts/common/runner.go | 14 +++---- .../common/runner_format_universal_test.go | 39 +++++++++++++++++++ shortcuts/common/types.go | 2 +- 3 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 shortcuts/common/runner_format_universal_test.go diff --git a/shortcuts/common/runner.go b/shortcuts/common/runner.go index ea69cfd31..2a795d550 100644 --- a/shortcuts/common/runner.go +++ b/shortcuts/common/runner.go @@ -860,9 +860,7 @@ func newRuntimeContext(cmd *cobra.Command, f *cmdutil.Factory, s *Shortcut, conf } rctx.larkSDK = sdk - if s.HasFormat { - rctx.Format = rctx.Str("format") - } + rctx.Format = rctx.Str("format") rctx.JqExpr, _ = cmd.Flags().GetString("jq") return rctx, nil } @@ -1026,17 +1024,15 @@ func registerShortcutFlagsWithContext(ctx context.Context, cmd *cobra.Command, f } cmd.Flags().Bool("dry-run", false, "print request without executing") - if s.HasFormat { + if cmd.Flags().Lookup("format") == nil { cmd.Flags().String("format", "json", "output format: json (default) | pretty | table | ndjson | csv") + cmdutil.RegisterFlagCompletion(cmd, "format", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { + return []string{"json", "pretty", "table", "ndjson", "csv"}, cobra.ShellCompDirectiveNoFileComp + }) } if s.Risk == "high-risk-write" { cmd.Flags().Bool("yes", false, "confirm high-risk operation") } cmd.Flags().StringP("jq", "q", "", "jq expression to filter JSON output") cmdutil.AddShortcutIdentityFlag(ctx, cmd, f, s.AuthTypes) - if s.HasFormat { - cmdutil.RegisterFlagCompletion(cmd, "format", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { - return []string{"json", "pretty", "table", "ndjson", "csv"}, cobra.ShellCompDirectiveNoFileComp - }) - } } diff --git a/shortcuts/common/runner_format_universal_test.go b/shortcuts/common/runner_format_universal_test.go new file mode 100644 index 000000000..777cd2e47 --- /dev/null +++ b/shortcuts/common/runner_format_universal_test.go @@ -0,0 +1,39 @@ +// Copyright (c) 2026 Lark Technologies Pte. Ltd. +// SPDX-License-Identifier: MIT + +package common + +import ( + "context" + "testing" + + "github.com/larksuite/cli/internal/cmdutil" + "github.com/spf13/cobra" +) + +// TestShortcutMount_FormatFlagAlwaysRegistered verifies that --format is +// injected for every shortcut regardless of the HasFormat field value. +func TestShortcutMount_FormatFlagAlwaysRegistered(t *testing.T) { + f, _, _, _ := cmdutil.TestFactory(t, nil) + parent := &cobra.Command{Use: "root"} + shortcut := Shortcut{ + Service: "im", + Command: "+message-send", + Description: "send message", + HasFormat: false, // explicitly false — format must still be registered + Execute: func(context.Context, *RuntimeContext) error { return nil }, + } + shortcut.Mount(parent, f) + + cmd, _, err := parent.Find([]string{"+message-send"}) + if err != nil { + t.Fatalf("Find() error = %v", err) + } + flag := cmd.Flags().Lookup("format") + if flag == nil { + t.Fatal("--format flag not registered; expected it to be injected even when HasFormat is false") + } + if flag.DefValue != "json" { + t.Errorf("--format default = %q, want %q", flag.DefValue, "json") + } +} diff --git a/shortcuts/common/types.go b/shortcuts/common/types.go index 76626c06c..bf3f0307b 100644 --- a/shortcuts/common/types.go +++ b/shortcuts/common/types.go @@ -49,7 +49,7 @@ type Shortcut struct { // Declarative fields (new framework). AuthTypes []string // supported identities: "user", "bot" (default: ["user"]) Flags []Flag // flag definitions; --dry-run is auto-injected - HasFormat bool // auto-inject --format flag (json|pretty|table|ndjson|csv) + HasFormat bool // Deprecated: --format is now always injected; this field has no effect. Tips []string // optional tips shown in --help output Hidden bool // hide from --help / tab completion (still executable); use when deprecating a command in favor of a replacement