Move certain sub-command optional fields to options on flag parsing method call

This commit is contained in:
Brian Picciano 2024-12-10 22:07:25 +01:00
parent 81cfdd5030
commit 37d436a428
10 changed files with 79 additions and 56 deletions

View File

@ -13,7 +13,6 @@ import (
var subCmdDaemon = subCmd{ var subCmdDaemon = subCmd{
name: "daemon", name: "daemon",
descr: "Runs the isle daemon (Default if no sub-command given)", descr: "Runs the isle daemon (Default if no sub-command given)",
noNetwork: true,
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
daemonConfigPath := ctx.flags.StringP( daemonConfigPath := ctx.flags.StringP(
"config-path", "c", "", "config-path", "c", "",
@ -25,7 +24,9 @@ var subCmdDaemon = subCmd{
"Write the default configuration file to stdout and exit.", "Write the default configuration file to stdout and exit.",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(&withParsedFlagsOpts{
noNetwork: true,
})
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }

View File

@ -34,7 +34,6 @@ func initMCConfigDir(envVars daecommon.EnvVars) (string, error) {
var subCmdGarageMC = subCmd{ var subCmdGarageMC = subCmd{
name: "mc", name: "mc",
descr: "Runs the mc (minio-client) binary. The isle garage can be accessed under the `garage` alias", descr: "Runs the mc (minio-client) binary. The isle garage can be accessed under the `garage` alias",
passthroughArgs: true,
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
keyID := ctx.flags.StringP( keyID := ctx.flags.StringP(
"key-id", "i", "", "key-id", "i", "",
@ -46,7 +45,9 @@ var subCmdGarageMC = subCmd{
"Optional key secret to use, defaults to that of the shared global key", "Optional key secret to use, defaults to that of the shared global key",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(&withParsedFlagsOpts{
passthroughArgs: true,
})
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -115,9 +116,10 @@ var subCmdGarageMC = subCmd{
var subCmdGarageCLI = subCmd{ var subCmdGarageCLI = subCmd{
name: "cli", name: "cli",
descr: "Runs the garage binary, automatically configured to point to the garage sub-process of a running isle daemon", descr: "Runs the garage binary, automatically configured to point to the garage sub-process of a running isle daemon",
passthroughArgs: true,
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(&withParsedFlagsOpts{
passthroughArgs: true,
})
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }

View File

@ -31,7 +31,7 @@ var subCmdHostCreate = subCmd{
"The new host should have the ability to create hosts too", "The new host should have the ability to create hosts too",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -58,7 +58,7 @@ var subCmdHostList = subCmd{
name: "list", name: "list",
descr: "Lists all hosts in the network, and their IPs", descr: "Lists all hosts in the network, and their IPs",
do: doWithOutput(func(ctx subCmdCtx) (any, error) { do: doWithOutput(func(ctx subCmdCtx) (any, error) {
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing flags: %w", err) return nil, fmt.Errorf("parsing flags: %w", err)
} }
@ -122,7 +122,7 @@ var subCmdHostRemove = subCmd{
"Name of the host to remove", "Name of the host to remove",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }

View File

@ -50,7 +50,6 @@ func binPath(name string) string {
var rootCmd = subCmd{ var rootCmd = subCmd{
name: "isle", name: "isle",
descr: "All Isle sub-commands", descr: "All Isle sub-commands",
noNetwork: true,
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
return ctx.doSubCmd( return ctx.doSubCmd(
subCmdDaemon, subCmdDaemon,

View File

@ -15,7 +15,6 @@ import (
var subCmdNetworkCreate = subCmd{ var subCmdNetworkCreate = subCmd{
name: "create", name: "create",
descr: "Create's a new network, with this host being the first host in that network.", descr: "Create's a new network, with this host being the first host in that network.",
noNetwork: true,
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
var ( var (
ipNet ipNetFlag ipNet ipNetFlag
@ -45,7 +44,9 @@ var subCmdNetworkCreate = subCmd{
"Name of this host, which will be the first host in the network", "Name of this host, which will be the first host in the network",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(&withParsedFlagsOpts{
noNetwork: true,
})
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -71,13 +72,14 @@ var subCmdNetworkCreate = subCmd{
var subCmdNetworkJoin = subCmd{ var subCmdNetworkJoin = subCmd{
name: "join", name: "join",
descr: "Joins this host to an existing network", descr: "Joins this host to an existing network",
noNetwork: true,
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
bootstrapPath := ctx.flags.StringP( bootstrapPath := ctx.flags.StringP(
"bootstrap-path", "b", "", "Path to a bootstrap.json file.", "bootstrap-path", "b", "", "Path to a bootstrap.json file.",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(&withParsedFlagsOpts{
noNetwork: true,
})
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -100,9 +102,10 @@ var subCmdNetworkJoin = subCmd{
var subCmdNetworkList = subCmd{ var subCmdNetworkList = subCmd{
name: "list", name: "list",
descr: "Lists all networks which have been joined", descr: "Lists all networks which have been joined",
noNetwork: true,
do: doWithOutput(func(ctx subCmdCtx) (any, error) { do: doWithOutput(func(ctx subCmdCtx) (any, error) {
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(&withParsedFlagsOpts{
noNetwork: true,
})
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing flags: %w", err) return nil, fmt.Errorf("parsing flags: %w", err)
} }
@ -183,7 +186,7 @@ var subCmdNetworkGetConfig = subCmd{
name: "get-config", name: "get-config",
descr: "Displays the currently active configuration for a joined network", descr: "Displays the currently active configuration for a joined network",
do: doWithOutput(func(ctx subCmdCtx) (any, error) { do: doWithOutput(func(ctx subCmdCtx) (any, error) {
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing flags: %w", err) return nil, fmt.Errorf("parsing flags: %w", err)
} }

View File

@ -87,7 +87,7 @@ var subCmdStorageAllocationAdd = subCmd{
" on. Will be automatically assigned if not given.", " on. Will be automatically assigned if not given.",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -118,7 +118,7 @@ var subCmdStorageAllocationList = subCmd{
plural: "s", plural: "s",
descr: "Lists all storage which is currently allocated on this host", descr: "Lists all storage which is currently allocated on this host",
do: doWithOutput(func(ctx subCmdCtx) (any, error) { do: doWithOutput(func(ctx subCmdCtx) (any, error) {
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing flags: %w", err) return nil, fmt.Errorf("parsing flags: %w", err)
} }
@ -144,7 +144,7 @@ var subCmdStorageAllocationRemove = subCmd{
"specified more than once", "specified more than once",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }

View File

@ -15,7 +15,6 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
// TODO noNetwork and passthroughArgs should be arguments to withParsedFlags.
type subCmd struct { type subCmd struct {
name string name string
descr string descr string
@ -23,15 +22,6 @@ type subCmd struct {
// If set then the name will be allowed to be suffixed with this string. // If set then the name will be allowed to be suffixed with this string.
plural string plural string
// noNetwork, if true, means the call doesn't require a network to be
// specified on the command-line if there are more than one networks
// configured.
noNetwork bool
// Extra arguments on the command-line will be passed through to some
// underlying command.
passthroughArgs bool
} }
func (c subCmd) fullName() string { func (c subCmd) fullName() string {
@ -108,7 +98,31 @@ func usagePrefix(subCmdNames []string) string {
return fmt.Sprintf("USAGE:\n %s %s", os.Args[0], subCmdNamesStr) return fmt.Sprintf("USAGE:\n %s %s", os.Args[0], subCmdNamesStr)
} }
func (ctx subCmdCtx) withParsedFlags() (subCmdCtx, error) { type withParsedFlagsOpts struct {
// noNetwork, if true, means the call doesn't require a network to be
// specified on the command-line if there are more than one networks
// configured.
noNetwork bool
// Extra arguments on the command-line will be passed through to some
// underlying command.
passthroughArgs bool
}
func (o *withParsedFlagsOpts) withDefaults() *withParsedFlagsOpts {
if o == nil {
o = new(withParsedFlagsOpts)
}
return o
}
func (ctx subCmdCtx) withParsedFlags(
opts *withParsedFlagsOpts,
) (
subCmdCtx, error,
) {
opts = opts.withDefaults()
logLevel := logLevelFlag{mlog.LevelInfo} logLevel := logLevelFlag{mlog.LevelInfo}
ctx.flags.VarP( ctx.flags.VarP(
&logLevel, &logLevel,
@ -117,7 +131,7 @@ func (ctx subCmdCtx) withParsedFlags() (subCmdCtx, error) {
) )
var network string var network string
if !ctx.subCmd.noNetwork { if !opts.noNetwork {
ctx.flags.StringVar( ctx.flags.StringVar(
&network, &network,
"network", "", "network", "",
@ -142,7 +156,7 @@ func (ctx subCmdCtx) withParsedFlags() (subCmdCtx, error) {
} }
var passthroughStr string var passthroughStr string
if ctx.subCmd.passthroughArgs { if opts.passthroughArgs {
passthroughStr = " [--] [args...]" passthroughStr = " [--] [args...]"
} }

View File

@ -9,13 +9,17 @@ import (
var subCmdVersion = subCmd{ var subCmdVersion = subCmd{
name: "version", name: "version",
descr: "Dumps version and build info to stdout", descr: "Dumps version and build info to stdout",
noNetwork: true,
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
ctx, err := ctx.withParsedFlags(&withParsedFlagsOpts{
noNetwork: true,
})
if err != nil {
return fmt.Errorf("parsing flags: %w", err)
}
versionPath := filepath.Join(envAppDirPath, "share/version") versionPath := filepath.Join(envAppDirPath, "share/version")
version, err := os.ReadFile(versionPath) version, err := os.ReadFile(versionPath)
if err != nil { if err != nil {
return fmt.Errorf("reading version info from %q: %w", versionPath, err) return fmt.Errorf("reading version info from %q: %w", versionPath, err)
} }

View File

@ -24,7 +24,7 @@ var subCmdVPNCreateCert = subCmd{
`Path to PEM file containing public key which will be embedded in the cert.`, `Path to PEM file containing public key which will be embedded in the cert.`,
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }

View File

@ -90,7 +90,7 @@ var subCmdVPNFirewallAdd = subCmd{
"One or more comma-separated group names to allow", "One or more comma-separated group names to allow",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -136,7 +136,7 @@ var subCmdVPNFirewallCommit = subCmd{
name: "commit", name: "commit",
descr: "Commit all changes which were staged using 'add' or 'remove'", descr: "Commit all changes which were staged using 'add' or 'remove'",
do: func(ctx subCmdCtx) error { do: func(ctx subCmdCtx) error {
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -178,7 +178,7 @@ var subCmdVPNFirewallRemove = subCmd{
"Comma-separated indexes of rules to remove, as returned by 'show --staged'", "Comma-separated indexes of rules to remove, as returned by 'show --staged'",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
@ -290,7 +290,7 @@ var subCmdVPNFirewallShow = subCmd{
"Return the firewall configuration with staged changes included", "Return the firewall configuration with staged changes included",
) )
ctx, err := ctx.withParsedFlags() ctx, err := ctx.withParsedFlags(nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing flags: %w", err) return nil, fmt.Errorf("parsing flags: %w", err)
} }