Move control-plane --json off the shared persistent flag · Entire

Move control-plane --json off the shared persistent flag

6b93696→main· gtrrz-victor·1w ago·9 files·+154 added/-13 removed

--json was registered persistently on the repo/org/project/grant group roots, so every subcommand inherited it — including side-effect verbs (delete, clone, mirror create/remove, grant remove) that never render a payload and silently accepted it as a no-op. Cobra can't hide a persistent flag from a subset of children, so the flag now lives locally on exactly the 20 commands that honor it via the runCore* helpers. Non-honoring commands reject --json with "unknown flag" and no longer advertise it in help.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

01KX0QXN74C8QB357FH8FW1MA2View transcript

?\ Validate and Relocate JSON Global FlagClaude Code·Opus 4.8[1m]·1 step

Changes

9

20 unmodified lines

// addControlPlaneFlags registers the persistent flags shared by every  
// control-plane command group. Persistent so they're inherited by nested  
// subcommands (e.g. `entire repo mirror list`):  
//   - --json: emit the raw wire JSON instead of the default human table.  
//   - --insecure-http-auth: permit the token exchange over plain http://  
//     (local/dev deployments where the core isn't behind TLS). Hidden, as  
//     elsewhere in the CLI.  
//     elsewhere in the CLI. Applies to every subcommand because they all build  
//     a control-plane client.  
//  
// --json is deliberately NOT persistent here: it only makes sense on the read  
// and mutation verbs that render a wire payload, so it's registered per-command  
// with addJSONFlag. A persistent --json was inherited by side-effect verbs  
// (delete, clone, mirror create/remove, grant remove) that silently ignored it;  
// cobra can't hide a persistent flag from a subset of children, so the flag  
// lives on exactly the commands that honor it.  
func addControlPlaneFlags(cmd *cobra.Command) {  
    cmd.PersistentFlags().Bool("json", false, "Output raw JSON instead of a table")  
    cmd.PersistentFlags().Bool("insecure-http-auth", false, "Allow authentication over plain HTTP (insecure, for local development only)")  
    if err := cmd.PersistentFlags().MarkHidden("insecure-http-auth"); err != nil {  
        panic(fmt.Sprintf("hide insecure-http-auth flag: %v", err))  
    }  
}

// addJSONFlag registers the local --json flag on a command that renders a wire  
// payload (list/get/create/mutation verbs routed through the runCore* helpers).  
// Local, not persistent, so only these commands advertise and accept it — see  
// addControlPlaneFlags for why. Read it with jsonRequested.  
func addJSONFlag(cmd *cobra.Command) {  
    cmd.Flags().Bool("json", false, "Output raw JSON instead of a table")  
}

// jsonRequested reports whether --json was set on cmd or an ancestor. A  
// lookup error means the flag isn't defined on this command tree, which is  
// treated as "not requested".  

Mcmd/entire/cli/corecmd.go+17/-3

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52

package cli

import (  
    "sort"  
    "testing"  
    "github.com/spf13/cobra"  
    "github.com/stretchr/testify/require"  
)

// TestControlPlaneJSONFlag_OnlyOnHonoringCommands pins the structural fix that  
// moved --json off the shared control-plane persistent flag and onto a local  
// flag registered only where the command actually renders JSON.  
// The old design registered --json persistently on each group root, so it was  
// inherited by every subcommand — including side-effect verbs (delete, clone,  
// mirror create/remove, grant remove) that ignored it, silently accepting a  
// no-op flag. Now the flag exists exactly on the commands that honor it, so the  
// non-honoring commands reject --json with "unknown flag" and their help never  
// advertises it.  
func TestControlPlaneJSONFlag_OnlyOnHonoringCommands(t *testing.T) {  
    t.Parallel()  
    
    // path (relative to the group root) -> honors --json.  
    want := map[string]bool{  
        // org  
        "org create": true,  
        "org list":   true,  
        "org get":    true,  
        "org delete": false,  
        // project  
        "project create": true,  
        "project list":   true,  
        "project get":    true,  
        "project delete": false,  
        // repo  
        "repo create":                    true,  
        "repo list":                      true,  
        "repo get":                       true,  
        "repo delete":                    false,  
        "repo clone":                     false,  
        "repo mirror create":             false,  
        "repo mirror list":               true,  
        "repo mirror get":                true,  
        "repo mirror remove":             false,  
        "repo mirror collaborators list": true,  
        "repo visibility get":            true,  
        "repo visibility set":            true,  
        // grant  
        "grant org add":        true,  
        "grant org list":       true,  
        "grant org remove":     false,  
        "grant project add":    true,  
        "grant project list":   true,  
        "grant project remove": false,  
        "grant repo add":       true,  
        "grant repo list":      true,  
        "grant repo remove":    false,  
    }  
    
    got := map[string]bool{}  
    for _, root := range []*cobra.Command{newOrgCmd(), newProjectCmd(), newRepoCmd(), newGrantCmd()} {  
        collectJSONFlag(t, root, root.Name(), got)  
    }

// Every command we expect an answer for must exist in the tree, and vice  
    // versa — a drift in either direction (renamed/removed command, or a new  
    // leaf we forgot to classify) should fail loudly.  
    require.Equal(t, sortedKeys(want), sortedKeys(got), "command tree drifted from the expected --json map")  
    for path, expected := range want {  
        require.Equal(t, expected, got[path], "command %q: --json presence mismatch", path)  
    }  
}

// collectJSONFlag walks the command tree rooted at cmd, recording for each leaf  
// command whether --json is visible on it (local flags merged with inherited).  
func collectJSONFlag(t *testing.T, cmd *cobra.Command, path string, out map[string]bool) {  
    t.Helper()  
    children := cmd.Commands()  
    if len(children) == 0 {  
        // Merge parent persistent flags so an accidentally-inherited --json is  
        // still caught here, not just a locally-registered one.  
        out[path] = cmd.Flags().Lookup("json") != nil || cmd.InheritedFlags().Lookup("json") != nil  
        return  
    }  
    for _, child := range children {  
        collectJSONFlag(t, child, path+" "+child.Name(), out)  
    }  
}

func sortedKeys(m map[string]bool) []string {  
    keys := make([]string, 0, len(m))  
    for k := range m {  
        keys = append(keys, k)  
    }  
    sort.Strings(keys)  
    return keys  
}  
``
Mcmd/entire/cli/corecmd_json_flag_test.go+98  

144 unmodified lines


... [Content continues to include the rest of the relevant commands and structures] ...