From 601fcf40c4b0150f0545e453d8c149c2a854f7b1 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Sun, 3 Mar 2024 17:17:21 -0500 Subject: [PATCH] cli, gapi: empty, lang, yaml: Refactor the args structs Put these datastructures into an external package so they can be re-used for parsing elsewhere. Since we remove these dependencies, we need to manually import the GAPI's so that they register. Despite efforts to embed them deeper into the import tree without cycles, this failed. Logically what this told me is that it actually makes sense to allow a different binary with only one of the multiple GAPI's contained within. --- cli/deploy.go | 9 +++------ cli/run.go | 9 +++------ cli/util/args.go | 32 ++++++++++++++++++++++++++++++++ gapi/empty/empty.go | 3 --- lang/gapi/gapi.go | 26 ++------------------------ main.go | 3 +++ yamlgraph/gapi.go | 9 ++------- 7 files changed, 45 insertions(+), 46 deletions(-) diff --git a/cli/deploy.go b/cli/deploy.go index e96292fc..eeaee709 100644 --- a/cli/deploy.go +++ b/cli/deploy.go @@ -29,12 +29,9 @@ import ( "github.com/purpleidea/mgmt/etcd/deployer" etcdfs "github.com/purpleidea/mgmt/etcd/fs" "github.com/purpleidea/mgmt/gapi" - emptyGAPI "github.com/purpleidea/mgmt/gapi/empty" - langGAPI "github.com/purpleidea/mgmt/lang/gapi" "github.com/purpleidea/mgmt/lib" "github.com/purpleidea/mgmt/util" "github.com/purpleidea/mgmt/util/errwrap" - yamlGAPI "github.com/purpleidea/mgmt/yamlgraph" "github.com/pborman/uuid" git "gopkg.in/src-d/go-git.v4" @@ -50,9 +47,9 @@ type DeployArgs struct { NoGit bool `arg:"--no-git" help:"don't look at git commit id for safe deploys"` Force bool `arg:"--force" help:"force a new deploy, even if the safety chain would break"` - DeployEmpty *emptyGAPI.Args `arg:"subcommand:empty" help:"deploy empty payload"` - DeployLang *langGAPI.Args `arg:"subcommand:lang" help:"deploy lang (mcl) payload"` - DeployYaml *yamlGAPI.Args `arg:"subcommand:yaml" help:"deploy yaml graph payload"` + DeployEmpty *cliUtil.EmptyArgs `arg:"subcommand:empty" help:"deploy empty payload"` + DeployLang *cliUtil.LangArgs `arg:"subcommand:lang" help:"deploy lang (mcl) payload"` + DeployYaml *cliUtil.YamlArgs `arg:"subcommand:yaml" help:"deploy yaml graph payload"` } // Run executes the correct subcommand. It errors if there's ever an error. It diff --git a/cli/run.go b/cli/run.go index 4ae55cd4..495e7aed 100644 --- a/cli/run.go +++ b/cli/run.go @@ -28,12 +28,9 @@ import ( cliUtil "github.com/purpleidea/mgmt/cli/util" "github.com/purpleidea/mgmt/gapi" - emptyGAPI "github.com/purpleidea/mgmt/gapi/empty" - langGAPI "github.com/purpleidea/mgmt/lang/gapi" "github.com/purpleidea/mgmt/lib" "github.com/purpleidea/mgmt/util" "github.com/purpleidea/mgmt/util/errwrap" - yamlGAPI "github.com/purpleidea/mgmt/yamlgraph" "github.com/spf13/afero" ) @@ -91,9 +88,9 @@ type RunArgs struct { Prometheus bool `arg:"--prometheus" help:"start a prometheus instance"` PrometheusListen string `arg:"--prometheus-listen" help:"specify prometheus instance binding"` - RunEmpty *emptyGAPI.Args `arg:"subcommand:empty" help:"run empty payload"` - RunLang *langGAPI.Args `arg:"subcommand:lang" help:"run lang (mcl) payload"` - RunYaml *yamlGAPI.Args `arg:"subcommand:yaml" help:"run yaml graph payload"` + RunEmpty *cliUtil.EmptyArgs `arg:"subcommand:empty" help:"run empty payload"` + RunLang *cliUtil.LangArgs `arg:"subcommand:lang" help:"run lang (mcl) payload"` + RunYaml *cliUtil.YamlArgs `arg:"subcommand:yaml" help:"run yaml graph payload"` } // Run executes the correct subcommand. It errors if there's ever an error. It diff --git a/cli/util/args.go b/cli/util/args.go index ff2cce0c..49931ee0 100644 --- a/cli/util/args.go +++ b/cli/util/args.go @@ -56,3 +56,35 @@ func LookupSubcommand(obj interface{}, st interface{}) string { } return "" // not found } + +// EmptyArgs is the empty CLI parsing structure and type of the parsed result. +type EmptyArgs struct{} + +// LangArgs is the lang CLI parsing structure and type of the parsed result. +type LangArgs struct { + // Input is the input mcl code or file path or any input specification. + Input string `arg:"positional,required"` + + // TODO: removed (temporarily?) + //Stdin bool `arg:"--stdin" help:"use passthrough stdin"` + + Download bool `arg:"--download" help:"download any missing imports"` + OnlyDownload bool `arg:"--only-download" help:"stop after downloading any missing imports"` + Update bool `arg:"--update" help:"update all dependencies to the latest versions"` + + OnlyUnify bool `arg:"--only-unify" help:"stop after type unification"` + SkipUnify bool `arg:"--skip-unify" help:"skip type unification"` + + Depth int `arg:"--depth" default:"-1" help:"max recursion depth limit (-1 is unlimited)"` + + // The default of 0 means any error is a failure by default. + Retry int `arg:"--depth" help:"max number of retries (-1 is unlimited)"` + + ModulePath string `arg:"--module-path,env:MGMT_MODULE_PATH" help:"choose the modules path (absolute)"` +} + +// YamlArgs is the yaml CLI parsing structure and type of the parsed result. +type YamlArgs struct { + // Input is the input yaml code or file path or any input specification. + Input string `arg:"positional,required"` +} diff --git a/gapi/empty/empty.go b/gapi/empty/empty.go index 1ba2af4a..024e9253 100644 --- a/gapi/empty/empty.go +++ b/gapi/empty/empty.go @@ -34,9 +34,6 @@ func init() { gapi.Register(Name, func() gapi.GAPI { return &GAPI{} }) // register } -// Args is the CLI parsing structure and type of the parsed result. -type Args struct{} - // GAPI implements the main lang GAPI interface. type GAPI struct { data *gapi.Data diff --git a/lang/gapi/gapi.go b/lang/gapi/gapi.go index f03d4bf4..77150bb9 100644 --- a/lang/gapi/gapi.go +++ b/lang/gapi/gapi.go @@ -26,6 +26,7 @@ import ( "sync" "time" + cliUtil "github.com/purpleidea/mgmt/cli/util" "github.com/purpleidea/mgmt/engine" "github.com/purpleidea/mgmt/gapi" "github.com/purpleidea/mgmt/lang" @@ -53,29 +54,6 @@ func init() { gapi.Register(Name, func() gapi.GAPI { return &GAPI{} }) // register } -// Args is the CLI parsing structure and type of the parsed result. -type Args struct { - // Input is the input mcl code or file path or any input specification. - Input string `arg:"positional,required"` - - // TODO: removed (temporarily?) - //Stdin bool `arg:"--stdin" help:"use passthrough stdin"` - - Download bool `arg:"--download" help:"download any missing imports"` - OnlyDownload bool `arg:"--only-download" help:"stop after downloading any missing imports"` - Update bool `arg:"--update" help:"update all dependencies to the latest versions"` - - OnlyUnify bool `arg:"--only-unify" help:"stop after type unification"` - SkipUnify bool `arg:"--skip-unify" help:"skip type unification"` - - Depth int `arg:"--depth" default:"-1" help:"max recursion depth limit (-1 is unlimited)"` - - // The default of 0 means any error is a failure by default. - Retry int `arg:"--depth" help:"max number of retries (-1 is unlimited)"` - - ModulePath string `arg:"--module-path,env:MGMT_MODULE_PATH" help:"choose the modules path (absolute)"` -} - // GAPI implements the main lang GAPI interface. type GAPI struct { InputURI string // input URI of code file system to run @@ -108,7 +86,7 @@ type GAPI struct { // to an etcdFs, and `run` copies to a memFs. All GAPI's run off of the fs that // is passed in. func (obj *GAPI) Cli(info *gapi.Info) (*gapi.Deploy, error) { - args, ok := info.Args.(*Args) + args, ok := info.Args.(*cliUtil.LangArgs) if !ok { // programming error return nil, fmt.Errorf("could not convert to our struct") diff --git a/main.go b/main.go index 98fdb25e..a7739ba6 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,9 @@ import ( "github.com/purpleidea/mgmt/cli" cliUtil "github.com/purpleidea/mgmt/cli/util" + _ "github.com/purpleidea/mgmt/gapi/empty" // import so the gapi registers + _ "github.com/purpleidea/mgmt/lang/gapi" // import so the gapi registers + _ "github.com/purpleidea/mgmt/yamlgraph" // import so the gapi registers "go.etcd.io/etcd/server/v3/etcdmain" ) diff --git a/yamlgraph/gapi.go b/yamlgraph/gapi.go index 620c0508..92704483 100644 --- a/yamlgraph/gapi.go +++ b/yamlgraph/gapi.go @@ -22,6 +22,7 @@ import ( "fmt" "sync" + cliUtil "github.com/purpleidea/mgmt/cli/util" "github.com/purpleidea/mgmt/engine" "github.com/purpleidea/mgmt/gapi" "github.com/purpleidea/mgmt/pgraph" @@ -40,12 +41,6 @@ func init() { gapi.Register(Name, func() gapi.GAPI { return &GAPI{} }) // register } -// Args is the CLI parsing structure and type of the parsed result. -type Args struct { - // Input is the input yaml code or file path or any input specification. - Input string `arg:"positional,required"` -} - // GAPI implements the main yamlgraph GAPI interface. type GAPI struct { InputURI string // input URI of file system containing yaml graph to use @@ -60,7 +55,7 @@ type GAPI struct { // are any validation problems, you should return an error. If there is no // deploy, then you should return a nil deploy and a nil error. func (obj *GAPI) Cli(info *gapi.Info) (*gapi.Deploy, error) { - args, ok := info.Args.(*Args) + args, ok := info.Args.(*cliUtil.YamlArgs) if !ok { // programming error return nil, fmt.Errorf("could not convert to our struct")