| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "flag" |
| 5 | |
| 6 | "github.com/carlosframework/platform/internal/cliflag" |
| 7 | ) |
| 8 | |
| 9 | // flags.go is the carlos CLI's face of internal/cliflag (the spec's |
| 10 | // claimed short-flag namespace: -a app, -c channel, -d destination, |
| 11 | // -e environment, -v version). The four helpers below are the only way the aliased |
| 12 | // flags are registered in this package; sites with something bespoke to |
| 13 | // say pass it through, and an empty usage takes the flag's common |
| 14 | // wording. The table itself, the registrar, and the usage printer live |
| 15 | // in internal/cliflag so out-of-package verbs (internal/vet) register |
| 16 | // through the same table instead of open-coding an alias pair. |
| 17 | |
| 18 | // cliAliases is the claimed table, shared with every registrar caller. |
| 19 | var cliAliases = cliflag.Aliases |
| 20 | |
| 21 | // aliasedString registers name and its short form against one variable |
| 22 | // with one default — see cliflag.String for the default-value trap this |
| 23 | // signature exists to prevent. |
| 24 | func aliasedString(fs *flag.FlagSet, name, def, usage string) *string { |
| 25 | return cliflag.String(fs, name, def, usage) |
| 26 | } |
| 27 | |
| 28 | // flagUsage renders a flag set with aliases folded into their primary |
| 29 | // and -- canonical; see cliflag.Usage. |
| 30 | func flagUsage(fs *flag.FlagSet, header string) func() { |
| 31 | return cliflag.Usage(fs, header) |
| 32 | } |
| 33 | |
| 34 | // consoleOption registers --console, and with it --destination / -d: |
| 35 | // every verb that can be pointed at a console can equally be pointed at a |
| 36 | // named destination in .carlos/config, which is where its console comes |
| 37 | // from. The destination lands in the package-level destinationFlag that |
| 38 | // loadConfig reads (config.go). |
| 39 | func consoleOption(fs *flag.FlagSet, usage string) *string { |
| 40 | c := fs.String("console", "", usage) |
| 41 | destinationOption(fs) |
| 42 | return c |
| 43 | } |
| 44 | |
| 45 | // destinationOption registers --destination / -d alone, for the verbs that |
| 46 | // read or write .carlos/config without taking --console (auth default). |
| 47 | func destinationOption(fs *flag.FlagSet) { |
| 48 | fs.Var(destinationValue{}, "destination", |
| 49 | "use the `name`d block from .carlos/config's destinations (default: CARLOS_DESTINATION, else the file's default or only one)") |
| 50 | fs.Var(destinationValue{}, cliAliases["destination"], "alias for --destination") |
| 51 | } |
| 52 | |
| 53 | // destinationValue writes straight to destinationFlag. A flag.Value rather |
| 54 | // than fs.StringVar because StringVar assigns the default at registration: |
| 55 | // a verb that builds a second flag set mid-run (deploy re-running auth |
| 56 | // login on a moved console) would otherwise wipe the destination the |
| 57 | // operator chose. |
| 58 | type destinationValue struct{} |
| 59 | |
| 60 | func (destinationValue) String() string { return destinationFlag } |
| 61 | func (destinationValue) Set(v string) error { destinationFlag = v; return nil } |
| 62 | |
| 63 | func appFlag(fs *flag.FlagSet, usage string) *string { |
| 64 | if usage == "" { |
| 65 | usage = "app name" |
| 66 | } |
| 67 | return aliasedString(fs, "app", "", usage) |
| 68 | } |
| 69 | |
| 70 | func channelFlag(fs *flag.FlagSet, usage string) *string { |
| 71 | if usage == "" { |
| 72 | usage = "release channel" |
| 73 | } |
| 74 | return aliasedString(fs, "channel", "", usage) |
| 75 | } |
| 76 | |
| 77 | func environmentFlag(fs *flag.FlagSet, usage string) *string { |
| 78 | if usage == "" { |
| 79 | usage = "named environment bundle (omit for the default bundle)" |
| 80 | } |
| 81 | return aliasedString(fs, "environment", "", usage) |
| 82 | } |
| 83 | |
| 84 | func versionFlag(fs *flag.FlagSet, usage string) *string { |
| 85 | if usage == "" { |
| 86 | usage = "version (git short sha)" |
| 87 | } |
| 88 | return aliasedString(fs, "version", "", usage) |
| 89 | } |
| 90 | |
| 91 | // flagWasSet reports whether the user typed a flag, by its primary name |
| 92 | // OR its short alias — the wizard and the saved deploy block must never |
| 93 | // override an explicit choice. fs.Visit reports the spelling actually |
| 94 | // typed (measured in the spec), so matching the primary alone would go |
| 95 | // false when -a was given: a wizard that then re-prompts for a value |
| 96 | // the user just named. alias is "" for unaliased names, and f.Name is |
| 97 | // never "", so the extra compare is inert there. |
| 98 | func flagWasSet(fs *flag.FlagSet, name string) bool { |
| 99 | alias := cliAliases[name] |
| 100 | set := false |
| 101 | fs.Visit(func(f *flag.Flag) { |
| 102 | if f.Name == name || f.Name == alias { |
| 103 | set = true |
| 104 | } |
| 105 | }) |
| 106 | return set |
| 107 | } |
| 108 | |