From 9fad10d8feafe8baad9cb13a422fcd2202fd048b Mon Sep 17 00:00:00 2001 From: Nick Tobey Date: Fri, 14 Apr 2023 10:18:33 -0700 Subject: [PATCH] Replace argparser.NewArgParser with NewArgParserWithMaxArgs and NewArgParserWithVariableArgs This requires commands to specify the max number of positional arguments they expect. This makes it harder to accidentally accept extra arguments and ignore them. --- go/cmd/dolt/cli/arg_parser_helpers.go | 40 ++++++++++----------- go/cmd/dolt/commands/admin/setref.go | 2 +- go/cmd/dolt/commands/admin/showroot.go | 2 +- go/cmd/dolt/commands/assist.go | 2 +- go/cmd/dolt/commands/blame.go | 2 +- go/cmd/dolt/commands/cnfcmds/cat.go | 2 +- go/cmd/dolt/commands/cnfcmds/resolve.go | 2 +- go/cmd/dolt/commands/config.go | 2 +- go/cmd/dolt/commands/credcmds/check.go | 2 +- go/cmd/dolt/commands/credcmds/import.go | 2 +- go/cmd/dolt/commands/credcmds/ls.go | 2 +- go/cmd/dolt/commands/credcmds/new.go | 2 +- go/cmd/dolt/commands/credcmds/rm.go | 2 +- go/cmd/dolt/commands/credcmds/use.go | 2 +- go/cmd/dolt/commands/diff.go | 2 +- go/cmd/dolt/commands/docscmds/diff.go | 2 +- go/cmd/dolt/commands/docscmds/read.go | 2 +- go/cmd/dolt/commands/docscmds/write.go | 2 +- go/cmd/dolt/commands/dump.go | 2 +- go/cmd/dolt/commands/dump_docs.go | 2 +- go/cmd/dolt/commands/filter-branch.go | 2 +- go/cmd/dolt/commands/gen_zsh_comp.go | 2 +- go/cmd/dolt/commands/indexcmds/cat.go | 2 +- go/cmd/dolt/commands/indexcmds/ls.go | 2 +- go/cmd/dolt/commands/indexcmds/rebuild.go | 2 +- go/cmd/dolt/commands/init.go | 2 +- go/cmd/dolt/commands/inspect.go | 2 +- go/cmd/dolt/commands/login.go | 2 +- go/cmd/dolt/commands/ls.go | 2 +- go/cmd/dolt/commands/merge_base.go | 2 +- go/cmd/dolt/commands/migrate.go | 2 +- go/cmd/dolt/commands/push.go | 5 +-- go/cmd/dolt/commands/read_tables.go | 2 +- go/cmd/dolt/commands/roots.go | 2 +- go/cmd/dolt/commands/schcmds/export.go | 2 +- go/cmd/dolt/commands/schcmds/import.go | 2 +- go/cmd/dolt/commands/schcmds/show.go | 2 +- go/cmd/dolt/commands/schcmds/tags.go | 2 +- go/cmd/dolt/commands/schcmds/update-tag.go | 2 +- go/cmd/dolt/commands/send_metrics.go | 2 +- go/cmd/dolt/commands/show.go | 2 +- go/cmd/dolt/commands/sql.go | 2 +- go/cmd/dolt/commands/sqlserver/sqlserver.go | 2 +- go/cmd/dolt/commands/stashcmds/clear.go | 2 +- go/cmd/dolt/commands/stashcmds/drop.go | 2 +- go/cmd/dolt/commands/stashcmds/list.go | 2 +- go/cmd/dolt/commands/stashcmds/pop.go | 2 +- go/cmd/dolt/commands/stashcmds/stash.go | 2 +- go/cmd/dolt/commands/status.go | 2 +- go/cmd/dolt/commands/tblcmds/cp.go | 2 +- go/cmd/dolt/commands/tblcmds/export.go | 2 +- go/cmd/dolt/commands/tblcmds/import.go | 2 +- go/cmd/dolt/commands/tblcmds/mv.go | 2 +- go/cmd/dolt/commands/tblcmds/rm.go | 2 +- go/cmd/dolt/commands/version.go | 2 +- go/libraries/utils/argparser/args_test.go | 4 +-- go/libraries/utils/argparser/parser.go | 17 +++++++-- go/libraries/utils/argparser/parser_test.go | 18 +++++----- 58 files changed, 100 insertions(+), 90 deletions(-) diff --git a/go/cmd/dolt/cli/arg_parser_helpers.go b/go/cmd/dolt/cli/arg_parser_helpers.go index 182993bd14..dc7a316400 100644 --- a/go/cmd/dolt/cli/arg_parser_helpers.go +++ b/go/cmd/dolt/cli/arg_parser_helpers.go @@ -136,7 +136,7 @@ var branchForceFlagDesc = "Reset {{.LessThan}}branchname{{.GreaterThan}} to {{.L // CreateCommitArgParser creates the argparser shared dolt commit cli and DOLT_COMMIT. func CreateCommitArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString(MessageArg, "m", "msg", "Use the given {{.LessThan}}msg{{.GreaterThan}} as the commit message.") ap.SupportsFlag(AllowEmptyFlag, "", "Allow recording a commit that has the exact same data as its sole parent. This is usually a mistake, so it is disabled by default. This option bypasses that safety.") ap.SupportsString(DateParam, "", "date", "Specify the date used in the commit. If not specified the current system time is used.") @@ -149,14 +149,14 @@ func CreateCommitArgParser() *argparser.ArgParser { } func CreateConflictsResolveArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(OursFlag, "", "For all conflicts, take the version from our branch and resolve the conflict") ap.SupportsFlag(TheirsFlag, "", "For all conflicts, take the version from their branch and resolve the conflict") return ap } func CreateMergeArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) ap.SupportsFlag(NoFFParam, "", "Create a merge commit even when the merge resolves as a fast-forward.") ap.SupportsFlag(SquashParam, "", "Merge changes to the working set without updating the commit history") ap.SupportsString(MessageArg, "m", "msg", "Use the given {{.LessThan}}msg{{.GreaterThan}} as the commit message.") @@ -170,21 +170,21 @@ func CreateMergeArgParser() *argparser.ArgParser { } func CreatePushArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.SupportsFlag(SetUpstreamFlag, "u", "For every branch that is up to date or successfully pushed, add upstream (tracking) reference, used by argument-less {{.EmphasisLeft}}dolt pull{{.EmphasisRight}} and other commands.") ap.SupportsFlag(ForceFlag, "f", "Update the remote with local history, overwriting any conflicting history in the remote.") return ap } func CreateAddArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "Working table(s) to add to the list tables staged to be committed. The abbreviation '.' can be used to add all tables."}) ap.SupportsFlag(AllFlag, "A", "Stages any and all changes (adds, deletes, and modifications).") return ap } func CreateCloneArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.SupportsString(RemoteParam, "", "name", "Name of the remote to be added to the cloned database. The default is 'origin'.") ap.SupportsString(BranchParam, "b", "branch", "The branch to be cloned. If not specified all branches will be cloned.") ap.SupportsString(dbfactory.AWSRegionParam, "", "region", "") @@ -198,14 +198,14 @@ func CreateCloneArgParser() *argparser.ArgParser { } func CreateResetArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(HardResetParam, "", "Resets the working tables and staged tables. Any changes to tracked tables in the working tree since {{.LessThan}}commit{{.GreaterThan}} are discarded.") ap.SupportsFlag(SoftResetParam, "", "Does not touch the working tables, but removes all tables staged to be committed.") return ap } func CreateRemoteArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsString(dbfactory.AWSRegionParam, "", "region", "") ap.SupportsValidatedString(dbfactory.AWSCredsTypeParam, "", "creds-type", "", argparser.ValidatorFromStrList(dbfactory.AWSCredsTypeParam, dbfactory.AWSCredTypes)) ap.SupportsString(dbfactory.AWSCredsFileParam, "", "file", "AWS credentials file") @@ -214,13 +214,13 @@ func CreateRemoteArgParser() *argparser.ArgParser { } func CreateCleanArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(DryRunFlag, "", "Tests removing untracked tables without modifying the working set.") return ap } func CreateCheckoutArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsString(CheckoutCoBranch, "", "branch", "Create a new branch named {{.LessThan}}new_branch{{.GreaterThan}} and start it at {{.LessThan}}start_point{{.GreaterThan}}.") ap.SupportsFlag(ForceFlag, "f", "If there is any changes in working set, the force flag will wipe out the current changes and checkout the new branch.") ap.SupportsString(TrackFlag, "t", "", "When creating a new branch, set up 'upstream' configuration.") @@ -228,18 +228,18 @@ func CreateCheckoutArgParser() *argparser.ArgParser { } func CreateCherryPickArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() return ap } func CreateFetchArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsString(UserParam, "u", "user", "User name to use when authenticating with the remote. Gets password from the environment variable {{.EmphasisLeft}}DOLT_REMOTE_PASSWORD{{.EmphasisRight}}.") return ap } func CreateRevertArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsString(AuthorParam, "", "author", "Specify an explicit author using the standard A U Thor {{.LessThan}}author@example.com{{.GreaterThan}} format.") ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"revision", "The commit revisions. If multiple revisions are given, they're applied in the order given."}) @@ -248,7 +248,7 @@ func CreateRevertArgParser() *argparser.ArgParser { } func CreatePullArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"remote", "The name of the remote to pull from."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"remoteBranch", "The name of a branch on the specified remote to be merged into the current working set."}) ap.SupportsFlag(SquashParam, "", "Merge changes to the working set without updating the commit history") @@ -262,7 +262,7 @@ func CreatePullArgParser() *argparser.ArgParser { } func CreateBranchArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(ForceFlag, "f", branchForceFlagDesc) ap.SupportsFlag(CopyFlag, "c", "Create a copy of a branch.") ap.SupportsFlag(MoveFlag, "m", "Move/rename a branch") @@ -274,7 +274,7 @@ func CreateBranchArgParser() *argparser.ArgParser { } func CreateTagArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"ref", "A commit ref that the tag should point at."}) ap.SupportsString(MessageArg, "m", "msg", "Use the given {{.LessThan}}msg{{.GreaterThan}} as the tag message.") ap.SupportsFlag(VerboseFlag, "v", "list tags along with their metadata.") @@ -284,7 +284,7 @@ func CreateTagArgParser() *argparser.ArgParser { } func CreateBackupArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"region", "cloud provider region associated with this backup."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"creds-type", "credential type. Valid options are role, env, and file. See the help section for additional details."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"profile", "AWS profile to use."}) @@ -297,7 +297,7 @@ func CreateBackupArgParser() *argparser.ArgParser { } func CreateVerifyConstraintsArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(AllFlag, "a", "Verifies that all rows in the database do not violate constraints instead of just rows modified or inserted in the working set.") ap.SupportsFlag(OutputOnlyFlag, "o", "Disables writing violated constraints to the constraint violations table.") ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "The table(s) to check constraints on. If omitted, checks all tables."}) @@ -305,7 +305,7 @@ func CreateVerifyConstraintsArgParser() *argparser.ArgParser { } func CreateLogArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsInt(NumberFlag, "n", "num_commits", "Limit the number of commits to output.") ap.SupportsInt(MinParentsFlag, "", "parent_count", "The minimum number of parents a commit must have to be included in the log.") ap.SupportsFlag(MergesFlag, "", "Equivalent to min-parents == 2, this will limit the log to commits with 2 or more parents.") @@ -317,7 +317,7 @@ func CreateLogArgParser() *argparser.ArgParser { } func CreateGCArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsFlag(ShallowFlag, "s", "perform a fast, but incomplete garbage collection pass") return ap } diff --git a/go/cmd/dolt/commands/admin/setref.go b/go/cmd/dolt/commands/admin/setref.go index 26c724f74b..e0b2dc1149 100644 --- a/go/cmd/dolt/commands/admin/setref.go +++ b/go/cmd/dolt/commands/admin/setref.go @@ -50,7 +50,7 @@ func (cmd SetRefCmd) Docs() *cli.CommandDocumentation { } func (cmd SetRefCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsOptionalString("branch", "", "branch name", "the branch ref to set") ap.SupportsOptionalString("remote-name", "", "remote name", "the remote name, e.g. origin, of the remote ref to set") ap.SupportsOptionalString("remote-branch", "", "remote branch name", "the remote branch name of the remote ref set") diff --git a/go/cmd/dolt/commands/admin/showroot.go b/go/cmd/dolt/commands/admin/showroot.go index 2bec05b468..2fc34d47c5 100644 --- a/go/cmd/dolt/commands/admin/showroot.go +++ b/go/cmd/dolt/commands/admin/showroot.go @@ -50,7 +50,7 @@ func (cmd ShowRootCmd) Docs() *cli.CommandDocumentation { } func (cmd ShowRootCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) return ap } diff --git a/go/cmd/dolt/commands/assist.go b/go/cmd/dolt/commands/assist.go index ce60312849..81cd5166f7 100755 --- a/go/cmd/dolt/commands/assist.go +++ b/go/cmd/dolt/commands/assist.go @@ -608,7 +608,7 @@ func (a Assist) Docs() *cli.CommandDocumentation { } func (a Assist) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString("model", "m", "open AI model id", "The ID of the Open AI model to use for the assistant. Defaults to gpt-3.5-turbo. "+ "See https://platform.openai.com/docs/models/overview for a full list of models.") diff --git a/go/cmd/dolt/commands/blame.go b/go/cmd/dolt/commands/blame.go index b06d0f9d79..8d8d65b183 100644 --- a/go/cmd/dolt/commands/blame.go +++ b/go/cmd/dolt/commands/blame.go @@ -54,7 +54,7 @@ func (cmd BlameCmd) Docs() *cli.CommandDocumentation { } func (cmd BlameCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) return ap } diff --git a/go/cmd/dolt/commands/cnfcmds/cat.go b/go/cmd/dolt/commands/cnfcmds/cat.go index 33f30da534..cb28edee0e 100644 --- a/go/cmd/dolt/commands/cnfcmds/cat.go +++ b/go/cmd/dolt/commands/cnfcmds/cat.go @@ -68,7 +68,7 @@ func (cmd CatCmd) EventType() eventsapi.ClientEventType { } func (cmd CatCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "List of tables to be printed. '.' can be used to print conflicts for all tables."}) return ap diff --git a/go/cmd/dolt/commands/cnfcmds/resolve.go b/go/cmd/dolt/commands/cnfcmds/resolve.go index 49ff5fd658..a00b159382 100644 --- a/go/cmd/dolt/commands/cnfcmds/resolve.go +++ b/go/cmd/dolt/commands/cnfcmds/resolve.go @@ -80,7 +80,7 @@ func (cmd ResolveCmd) EventType() eventsapi.ClientEventType { } func (cmd ResolveCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "List of tables to be resolved. '.' can be used to resolve all tables."}) ap.SupportsFlag("ours", "", "For all conflicts, take the version from our branch and resolve the conflict") ap.SupportsFlag("theirs", "", "For all conflicts, take the version from their branch and resolve the conflict") diff --git a/go/cmd/dolt/commands/config.go b/go/cmd/dolt/commands/config.go index c8bdafbcc6..aa250be9c2 100644 --- a/go/cmd/dolt/commands/config.go +++ b/go/cmd/dolt/commands/config.go @@ -103,7 +103,7 @@ func (cmd ConfigCmd) Docs() *cli.CommandDocumentation { } func (cmd ConfigCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(globalParamName, "", "Use global config.") ap.SupportsFlag(localParamName, "", "Use repository local config.") ap.SupportsFlag(addOperationStr, "", "Set the value of one or more config parameters") diff --git a/go/cmd/dolt/commands/credcmds/check.go b/go/cmd/dolt/commands/credcmds/check.go index 7ff8c6cb5b..794511e44c 100644 --- a/go/cmd/dolt/commands/credcmds/check.go +++ b/go/cmd/dolt/commands/credcmds/check.go @@ -71,7 +71,7 @@ func (cmd CheckCmd) EventType() eventsapi.ClientEventType { } func (cmd CheckCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString("endpoint", "", "", "API endpoint, otherwise taken from config.") ap.SupportsString("creds", "", "", "Public Key ID or Public Key for credentials, otherwise taken from config.") return ap diff --git a/go/cmd/dolt/commands/credcmds/import.go b/go/cmd/dolt/commands/credcmds/import.go index c615af28d8..6d713a1b1b 100644 --- a/go/cmd/dolt/commands/credcmds/import.go +++ b/go/cmd/dolt/commands/credcmds/import.go @@ -82,7 +82,7 @@ func (cmd ImportCmd) EventType() eventsapi.ClientEventType { const noProfileFlag = "no-profile" func (cmd ImportCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"jwk_filename", "The JWK file. If omitted, import operates on stdin."}) ap.SupportsFlag(noProfileFlag, "", "If provided, no attempt will be made to contact doltremoteapi and update user.name and user.email.") return ap diff --git a/go/cmd/dolt/commands/credcmds/ls.go b/go/cmd/dolt/commands/credcmds/ls.go index 8930bc7678..ec6f09c8d5 100644 --- a/go/cmd/dolt/commands/credcmds/ls.go +++ b/go/cmd/dolt/commands/credcmds/ls.go @@ -68,7 +68,7 @@ func (cmd LsCmd) EventType() eventsapi.ClientEventType { } func (cmd LsCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsFlag("verbose", "v", "Verbose output, including key id.") return ap } diff --git a/go/cmd/dolt/commands/credcmds/new.go b/go/cmd/dolt/commands/credcmds/new.go index 9659a848d0..7c403d8f3b 100644 --- a/go/cmd/dolt/commands/credcmds/new.go +++ b/go/cmd/dolt/commands/credcmds/new.go @@ -65,7 +65,7 @@ func (cmd NewCmd) EventType() eventsapi.ClientEventType { } func (cmd NewCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) return ap } diff --git a/go/cmd/dolt/commands/credcmds/rm.go b/go/cmd/dolt/commands/credcmds/rm.go index ab519e1f0c..34302e7721 100644 --- a/go/cmd/dolt/commands/credcmds/rm.go +++ b/go/cmd/dolt/commands/credcmds/rm.go @@ -51,7 +51,7 @@ func (cmd RmCmd) Docs() *cli.CommandDocumentation { } func (cmd RmCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() return ap } diff --git a/go/cmd/dolt/commands/credcmds/use.go b/go/cmd/dolt/commands/credcmds/use.go index 9335c802fd..d4e7fbf47c 100644 --- a/go/cmd/dolt/commands/credcmds/use.go +++ b/go/cmd/dolt/commands/credcmds/use.go @@ -68,7 +68,7 @@ func (cmd UseCmd) EventType() eventsapi.ClientEventType { } func (cmd UseCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) return ap } diff --git a/go/cmd/dolt/commands/diff.go b/go/cmd/dolt/commands/diff.go index f9fa3efedf..18b6c700a6 100644 --- a/go/cmd/dolt/commands/diff.go +++ b/go/cmd/dolt/commands/diff.go @@ -143,7 +143,7 @@ func (cmd DiffCmd) Docs() *cli.CommandDocumentation { } func (cmd DiffCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(DataFlag, "d", "Show only the data changes, do not show the schema changes (Both shown by default).") ap.SupportsFlag(SchemaFlag, "s", "Show only the schema changes, do not show the data changes (Both shown by default).") ap.SupportsFlag(StatFlag, "", "Show stats of data changes") diff --git a/go/cmd/dolt/commands/docscmds/diff.go b/go/cmd/dolt/commands/docscmds/diff.go index a3cfe7460e..5e4653a384 100644 --- a/go/cmd/dolt/commands/docscmds/diff.go +++ b/go/cmd/dolt/commands/docscmds/diff.go @@ -60,7 +60,7 @@ func (cmd DiffCmd) Docs() *cli.CommandDocumentation { // ArgParser implements cli.Command. func (cmd DiffCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"doc", "Dolt doc to be diffed."}) return ap } diff --git a/go/cmd/dolt/commands/docscmds/read.go b/go/cmd/dolt/commands/docscmds/read.go index 2fdf39e0d3..de47921070 100644 --- a/go/cmd/dolt/commands/docscmds/read.go +++ b/go/cmd/dolt/commands/docscmds/read.go @@ -64,7 +64,7 @@ func (cmd UploadCmd) Docs() *cli.CommandDocumentation { // ArgParser implements cli.Command. func (cmd UploadCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"doc", "Dolt doc name to be updated in the database."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"file", "file to read Dolt doc from."}) return ap diff --git a/go/cmd/dolt/commands/docscmds/write.go b/go/cmd/dolt/commands/docscmds/write.go index 47d15381bd..0effb743dd 100644 --- a/go/cmd/dolt/commands/docscmds/write.go +++ b/go/cmd/dolt/commands/docscmds/write.go @@ -63,7 +63,7 @@ func (cmd PrintCmd) Docs() *cli.CommandDocumentation { // ArgParser implements cli.Command. func (cmd PrintCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"doc", "Dolt doc to be read."}) return ap } diff --git a/go/cmd/dolt/commands/dump.go b/go/cmd/dolt/commands/dump.go index b7b78964eb..bb50eccbec 100644 --- a/go/cmd/dolt/commands/dump.go +++ b/go/cmd/dolt/commands/dump.go @@ -94,7 +94,7 @@ func (cmd DumpCmd) Docs() *cli.CommandDocumentation { } func (cmd DumpCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString(FormatFlag, "r", "result_file_type", "Define the type of the output file. Defaults to sql. Valid values are sql, csv, json and parquet.") ap.SupportsString(filenameFlag, "fn", "file_name", "Define file name for dump file. Defaults to `doltdump.sql`.") ap.SupportsString(directoryFlag, "d", "directory_name", "Define directory name to dump the files in. Defaults to `doltdump/`.") diff --git a/go/cmd/dolt/commands/dump_docs.go b/go/cmd/dolt/commands/dump_docs.go index 577629df81..248cd91b9e 100644 --- a/go/cmd/dolt/commands/dump_docs.go +++ b/go/cmd/dolt/commands/dump_docs.go @@ -66,7 +66,7 @@ func (cmd *DumpDocsCmd) Docs() *cli.CommandDocumentation { } func (cmd *DumpDocsCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString(fileParamName, "", "file", "The file to write CLI docs to") return ap } diff --git a/go/cmd/dolt/commands/filter-branch.go b/go/cmd/dolt/commands/filter-branch.go index 531fd64701..611973936d 100644 --- a/go/cmd/dolt/commands/filter-branch.go +++ b/go/cmd/dolt/commands/filter-branch.go @@ -83,7 +83,7 @@ func (cmd FilterBranchCmd) Docs() *cli.CommandDocumentation { } func (cmd FilterBranchCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.SupportsFlag(cli.VerboseFlag, "v", "logs more information") ap.SupportsFlag(branchesFlag, "b", "filter all branches") ap.SupportsFlag(cli.AllFlag, "a", "filter all branches and tags") diff --git a/go/cmd/dolt/commands/gen_zsh_comp.go b/go/cmd/dolt/commands/gen_zsh_comp.go index 69071a0acc..0ff47f434d 100755 --- a/go/cmd/dolt/commands/gen_zsh_comp.go +++ b/go/cmd/dolt/commands/gen_zsh_comp.go @@ -33,7 +33,7 @@ type GenZshCompCmd struct { } func (z GenZshCompCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString(fileParamName, "", "file", "The file to write zsh comp file to") ap.SupportsFlag("includeHidden", "", "Include hidden commands") return ap diff --git a/go/cmd/dolt/commands/indexcmds/cat.go b/go/cmd/dolt/commands/indexcmds/cat.go index 2e5f31bd1b..623cbeb917 100644 --- a/go/cmd/dolt/commands/indexcmds/cat.go +++ b/go/cmd/dolt/commands/indexcmds/cat.go @@ -72,7 +72,7 @@ func (cmd CatCmd) Docs() *cli.CommandDocumentation { } func (cmd CatCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "The table that the given index belongs to."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"index", "The name of the index that belongs to the given table."}) ap.SupportsString(formatFlag, "r", "result format", "How to format the resulting output. Valid values are tabular, csv, json. Defaults to tabular.") diff --git a/go/cmd/dolt/commands/indexcmds/ls.go b/go/cmd/dolt/commands/indexcmds/ls.go index b3fc306bec..1f8c20cecc 100644 --- a/go/cmd/dolt/commands/indexcmds/ls.go +++ b/go/cmd/dolt/commands/indexcmds/ls.go @@ -50,7 +50,7 @@ func (cmd LsCmd) Docs() *cli.CommandDocumentation { } func (cmd LsCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "The table to display indexes from. If one is not specified, then all tables' indexes are displayed."}) return ap } diff --git a/go/cmd/dolt/commands/indexcmds/rebuild.go b/go/cmd/dolt/commands/indexcmds/rebuild.go index 1fc080cb06..8ff02764dd 100644 --- a/go/cmd/dolt/commands/indexcmds/rebuild.go +++ b/go/cmd/dolt/commands/indexcmds/rebuild.go @@ -52,7 +52,7 @@ func (cmd RebuildCmd) Docs() *cli.CommandDocumentation { } func (cmd RebuildCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "The table that the given index belongs to."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"index", "The name of the index to rebuild."}) return ap diff --git a/go/cmd/dolt/commands/init.go b/go/cmd/dolt/commands/init.go index 3a459309eb..cf1c37f60e 100644 --- a/go/cmd/dolt/commands/init.go +++ b/go/cmd/dolt/commands/init.go @@ -74,7 +74,7 @@ func (cmd InitCmd) Docs() *cli.CommandDocumentation { } func (cmd InitCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString(usernameParamName, "", "name", fmt.Sprintf("The name used in commits to this repo. If not provided will be taken from {{.EmphasisLeft}}%s{{.EmphasisRight}} in the global config.", env.UserNameKey)) ap.SupportsString(emailParamName, "", "email", fmt.Sprintf("The email address used. If not provided will be taken from {{.EmphasisLeft}}%s{{.EmphasisRight}} in the global config.", env.UserEmailKey)) ap.SupportsString(cli.DateParam, "", "date", "Specify the date used in the initial commit. If not specified the current system time is used.") diff --git a/go/cmd/dolt/commands/inspect.go b/go/cmd/dolt/commands/inspect.go index 07c50c57d9..8363a8b181 100644 --- a/go/cmd/dolt/commands/inspect.go +++ b/go/cmd/dolt/commands/inspect.go @@ -67,7 +67,7 @@ func (cmd InspectCmd) Docs() *cli.CommandDocumentation { } func (cmd InspectCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsFlag(tableFileIndexFlag, "i", "Measure distribution error in table file chunk indexes.") return ap } diff --git a/go/cmd/dolt/commands/login.go b/go/cmd/dolt/commands/login.go index 604415b0b2..ab0c73190a 100644 --- a/go/cmd/dolt/commands/login.go +++ b/go/cmd/dolt/commands/login.go @@ -80,7 +80,7 @@ func (cmd LoginCmd) Docs() *cli.CommandDocumentation { } func (cmd LoginCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) ap.SupportsString(authEndpointParam, "e", "hostname:port", fmt.Sprintf("Specify the endpoint used to authenticate this client. Must be used with --%s OR set in the configuration file as `%s`", loginURLParam, env.AddCredsUrlKey)) ap.SupportsString(loginURLParam, "url", "url", "Specify the login url where the browser will add credentials.") ap.SupportsFlag(insecureParam, "i", "If set, makes insecure connection to remote authentication server") diff --git a/go/cmd/dolt/commands/ls.go b/go/cmd/dolt/commands/ls.go index b1ea833756..755302fd56 100644 --- a/go/cmd/dolt/commands/ls.go +++ b/go/cmd/dolt/commands/ls.go @@ -65,7 +65,7 @@ func (cmd LsCmd) Docs() *cli.CommandDocumentation { } func (cmd LsCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) ap.SupportsFlag(cli.VerboseFlag, "v", "show the hash of the table") ap.SupportsFlag(systemFlag, "s", "show system tables") ap.SupportsFlag(cli.AllFlag, "a", "show system tables") diff --git a/go/cmd/dolt/commands/merge_base.go b/go/cmd/dolt/commands/merge_base.go index 622baf4576..8cbe29448e 100644 --- a/go/cmd/dolt/commands/merge_base.go +++ b/go/cmd/dolt/commands/merge_base.go @@ -54,7 +54,7 @@ func (cmd MergeBaseCmd) Docs() *cli.CommandDocumentation { } func (cmd MergeBaseCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) //ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"start-point", "A commit that a new branch should point at."}) return ap } diff --git a/go/cmd/dolt/commands/migrate.go b/go/cmd/dolt/commands/migrate.go index f867fa3e2d..8cfec53021 100644 --- a/go/cmd/dolt/commands/migrate.go +++ b/go/cmd/dolt/commands/migrate.go @@ -64,7 +64,7 @@ func (cmd MigrateCmd) Docs() *cli.CommandDocumentation { } func (cmd MigrateCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsFlag(migrateDropConflictsFlag, "", "Drop any conflicts visited during the migration") return ap } diff --git a/go/cmd/dolt/commands/push.go b/go/cmd/dolt/commands/push.go index 31f303b7f9..d5a6fa9036 100644 --- a/go/cmd/dolt/commands/push.go +++ b/go/cmd/dolt/commands/push.go @@ -71,10 +71,7 @@ func (cmd PushCmd) Docs() *cli.CommandDocumentation { } func (cmd PushCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() - ap.SupportsFlag(cli.SetUpstreamFlag, "u", "For every branch that is up to date or successfully pushed, add upstream (tracking) reference, used by argument-less {{.EmphasisLeft}}dolt pull{{.EmphasisRight}} and other commands.") - ap.SupportsFlag(cli.ForceFlag, "f", "Update the remote with local history, overwriting any conflicting history in the remote.") - return ap + return cli.CreatePushArgParser() } // EventType returns the type of the event to log diff --git a/go/cmd/dolt/commands/read_tables.go b/go/cmd/dolt/commands/read_tables.go index 5ce90b9d64..6344281646 100644 --- a/go/cmd/dolt/commands/read_tables.go +++ b/go/cmd/dolt/commands/read_tables.go @@ -73,7 +73,7 @@ func (cmd ReadTablesCmd) RequiresRepo() bool { } func (cmd ReadTablesCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = [][2]string{ {"remote-repo", "Remote repository to retrieve data from"}, {"commit", "Branch or commit hash representing a point in time to retrieve tables from"}, diff --git a/go/cmd/dolt/commands/roots.go b/go/cmd/dolt/commands/roots.go index 2a3057d3f3..5bcf93f4b6 100644 --- a/go/cmd/dolt/commands/roots.go +++ b/go/cmd/dolt/commands/roots.go @@ -74,7 +74,7 @@ func (cmd RootsCmd) Docs() *cli.CommandDocumentation { } func (cmd RootsCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsInt(numFilesParam, "n", "number", "Number of table files to scan.") return ap } diff --git a/go/cmd/dolt/commands/schcmds/export.go b/go/cmd/dolt/commands/schcmds/export.go index d95a5baa2b..e53c977711 100644 --- a/go/cmd/dolt/commands/schcmds/export.go +++ b/go/cmd/dolt/commands/schcmds/export.go @@ -62,7 +62,7 @@ func (cmd ExportCmd) Docs() *cli.CommandDocumentation { } func (cmd ExportCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "table whose schema is being exported."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"file", "the file to which the schema will be exported."}) return ap diff --git a/go/cmd/dolt/commands/schcmds/import.go b/go/cmd/dolt/commands/schcmds/import.go index 69e68da346..f2093b07a4 100644 --- a/go/cmd/dolt/commands/schcmds/import.go +++ b/go/cmd/dolt/commands/schcmds/import.go @@ -142,7 +142,7 @@ func (cmd ImportCmd) Docs() *cli.CommandDocumentation { } func (cmd ImportCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "Name of the table to be created."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"file", "The file being used to infer the schema."}) ap.SupportsFlag(createFlag, "c", "Create a table with the schema inferred from the {{.LessThan}}file{{.GreaterThan}} provided.") diff --git a/go/cmd/dolt/commands/schcmds/show.go b/go/cmd/dolt/commands/schcmds/show.go index 39551dff12..e5ed7f3083 100644 --- a/go/cmd/dolt/commands/schcmds/show.go +++ b/go/cmd/dolt/commands/schcmds/show.go @@ -61,7 +61,7 @@ func (cmd ShowCmd) Docs() *cli.CommandDocumentation { } func (cmd ShowCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "table(s) whose schema is being displayed."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"commit", "commit at which point the schema will be displayed."}) return ap diff --git a/go/cmd/dolt/commands/schcmds/tags.go b/go/cmd/dolt/commands/schcmds/tags.go index 9be57680a7..abaf98851d 100644 --- a/go/cmd/dolt/commands/schcmds/tags.go +++ b/go/cmd/dolt/commands/schcmds/tags.go @@ -58,7 +58,7 @@ func (cmd TagsCmd) Docs() *cli.CommandDocumentation { } func (cmd TagsCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "table(s) whose tags will be displayed."}) ap.SupportsString(commands.FormatFlag, "r", "result output format", "How to format result output. Valid values are tabular, csv, json. Defaults to tabular.") return ap diff --git a/go/cmd/dolt/commands/schcmds/update-tag.go b/go/cmd/dolt/commands/schcmds/update-tag.go index fa536c71c6..17db47ae4d 100644 --- a/go/cmd/dolt/commands/schcmds/update-tag.go +++ b/go/cmd/dolt/commands/schcmds/update-tag.go @@ -58,7 +58,7 @@ func (cmd UpdateTagCmd) Docs() *cli.CommandDocumentation { } func (cmd UpdateTagCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(3) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "The name of the table"}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"column", "The name of the column"}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"tag", "The new tag value"}) diff --git a/go/cmd/dolt/commands/send_metrics.go b/go/cmd/dolt/commands/send_metrics.go index a376ee6bdf..bf4f64f0d3 100644 --- a/go/cmd/dolt/commands/send_metrics.go +++ b/go/cmd/dolt/commands/send_metrics.go @@ -67,7 +67,7 @@ func (cmd SendMetricsCmd) Docs() *cli.CommandDocumentation { } func (cmd SendMetricsCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsFlag(outputFlag, "o", "Flush events to stdout.") return ap } diff --git a/go/cmd/dolt/commands/show.go b/go/cmd/dolt/commands/show.go index faa3ec958f..11b3e60fc8 100644 --- a/go/cmd/dolt/commands/show.go +++ b/go/cmd/dolt/commands/show.go @@ -69,7 +69,7 @@ func (cmd ShowCmd) Docs() *cli.CommandDocumentation { } func (cmd ShowCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() // Flags inherited from Log ap.SupportsFlag(cli.ParentsFlag, "", "Shows all parents of each commit in the log.") ap.SupportsString(cli.DecorateFlag, "", "decorate_fmt", "Shows refs next to commits. Valid options are short, full, no, and auto") diff --git a/go/cmd/dolt/commands/sql.go b/go/cmd/dolt/commands/sql.go index 613a7f49ca..77f6690ab1 100644 --- a/go/cmd/dolt/commands/sql.go +++ b/go/cmd/dolt/commands/sql.go @@ -144,7 +144,7 @@ func (cmd SqlCmd) Docs() *cli.CommandDocumentation { } func (cmd SqlCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString(QueryFlag, "q", "SQL query to run", "Runs a single query and exits.") ap.SupportsString(FormatFlag, "r", "result output format", "How to format result output. Valid values are tabular, csv, json, vertical. Defaults to tabular.") ap.SupportsString(saveFlag, "s", "saved query name", "Used with --query, save the query to the query catalog with the name provided. Saved queries can be examined in the dolt_query_catalog system table.") diff --git a/go/cmd/dolt/commands/sqlserver/sqlserver.go b/go/cmd/dolt/commands/sqlserver/sqlserver.go index 8aae26e14e..458ede945c 100644 --- a/go/cmd/dolt/commands/sqlserver/sqlserver.go +++ b/go/cmd/dolt/commands/sqlserver/sqlserver.go @@ -130,7 +130,7 @@ func (cmd SqlServerCmd) Docs() *cli.CommandDocumentation { func (cmd SqlServerCmd) ArgParser() *argparser.ArgParser { serverConfig := DefaultServerConfig() - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsString(configFileFlag, "", "file", "When provided configuration is taken from the yaml config file and all command line parameters are ignored.") ap.SupportsString(hostFlag, "H", "host address", fmt.Sprintf("Defines the host address that the server will run on. Defaults to `%v`.", serverConfig.Host())) ap.SupportsUint(portFlag, "P", "port", fmt.Sprintf("Defines the port that the server will run on. Defaults to `%v`.", serverConfig.Port())) diff --git a/go/cmd/dolt/commands/stashcmds/clear.go b/go/cmd/dolt/commands/stashcmds/clear.go index c7777e0473..53d444545b 100644 --- a/go/cmd/dolt/commands/stashcmds/clear.go +++ b/go/cmd/dolt/commands/stashcmds/clear.go @@ -53,7 +53,7 @@ func (cmd StashClearCmd) Docs() *cli.CommandDocumentation { } func (cmd StashClearCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) return ap } diff --git a/go/cmd/dolt/commands/stashcmds/drop.go b/go/cmd/dolt/commands/stashcmds/drop.go index 3667f18c30..1e53cab85d 100644 --- a/go/cmd/dolt/commands/stashcmds/drop.go +++ b/go/cmd/dolt/commands/stashcmds/drop.go @@ -56,7 +56,7 @@ func (cmd StashDropCmd) Docs() *cli.CommandDocumentation { } func (cmd StashDropCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) return ap } diff --git a/go/cmd/dolt/commands/stashcmds/list.go b/go/cmd/dolt/commands/stashcmds/list.go index 83d743d1bc..11bcdd930c 100644 --- a/go/cmd/dolt/commands/stashcmds/list.go +++ b/go/cmd/dolt/commands/stashcmds/list.go @@ -53,7 +53,7 @@ func (cmd StashListCmd) Docs() *cli.CommandDocumentation { } func (cmd StashListCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) return ap } diff --git a/go/cmd/dolt/commands/stashcmds/pop.go b/go/cmd/dolt/commands/stashcmds/pop.go index 0ddc90979b..06c5ee6ce9 100644 --- a/go/cmd/dolt/commands/stashcmds/pop.go +++ b/go/cmd/dolt/commands/stashcmds/pop.go @@ -60,7 +60,7 @@ func (cmd StashPopCmd) Docs() *cli.CommandDocumentation { } func (cmd StashPopCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(1) return ap } diff --git a/go/cmd/dolt/commands/stashcmds/stash.go b/go/cmd/dolt/commands/stashcmds/stash.go index b3c93ba742..a2182a0c27 100644 --- a/go/cmd/dolt/commands/stashcmds/stash.go +++ b/go/cmd/dolt/commands/stashcmds/stash.go @@ -77,7 +77,7 @@ func (cmd StashCmd) Docs() *cli.CommandDocumentation { } func (cmd StashCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsFlag(IncludeUntrackedFlag, "u", "All untracked files (added tables) are also stashed.") return ap } diff --git a/go/cmd/dolt/commands/status.go b/go/cmd/dolt/commands/status.go index b747bbc5ba..9e1187b924 100644 --- a/go/cmd/dolt/commands/status.go +++ b/go/cmd/dolt/commands/status.go @@ -56,7 +56,7 @@ func (cmd StatusCmd) Docs() *cli.CommandDocumentation { } func (cmd StatusCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) return ap } diff --git a/go/cmd/dolt/commands/tblcmds/cp.go b/go/cmd/dolt/commands/tblcmds/cp.go index fe60707103..13f60e72a2 100644 --- a/go/cmd/dolt/commands/tblcmds/cp.go +++ b/go/cmd/dolt/commands/tblcmds/cp.go @@ -57,7 +57,7 @@ func (cmd CpCmd) Docs() *cli.CommandDocumentation { } func (cmd CpCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"oldtable", "The table being copied."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"newtable", "The destination where the table is being copied to."}) ap.SupportsFlag(forceParam, "f", "If data already exists in the destination, the force flag will allow the target to be overwritten.") diff --git a/go/cmd/dolt/commands/tblcmds/export.go b/go/cmd/dolt/commands/tblcmds/export.go index 387be58383..24b3da6970 100644 --- a/go/cmd/dolt/commands/tblcmds/export.go +++ b/go/cmd/dolt/commands/tblcmds/export.go @@ -171,7 +171,7 @@ func (cmd ExportCmd) Docs() *cli.CommandDocumentation { } func (cmd ExportCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "The table being exported."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"file", "The file being output to."}) ap.SupportsFlag(forceParam, "f", "If data already exists in the destination, the force flag will allow the target to be overwritten.") diff --git a/go/cmd/dolt/commands/tblcmds/import.go b/go/cmd/dolt/commands/tblcmds/import.go index db456b9f8d..13d5cf8ae0 100644 --- a/go/cmd/dolt/commands/tblcmds/import.go +++ b/go/cmd/dolt/commands/tblcmds/import.go @@ -347,7 +347,7 @@ func (cmd ImportCmd) Docs() *cli.CommandDocumentation { } func (cmd ImportCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{tableParam, "The new or existing table being imported to."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{fileParam, "The file being imported. Supported file types are csv, psv, and nbf."}) ap.SupportsFlag(createParam, "c", "Create a new table, or overwrite an existing table (with the -f flag) from the imported data.") diff --git a/go/cmd/dolt/commands/tblcmds/mv.go b/go/cmd/dolt/commands/tblcmds/mv.go index 0ad1ec5e4f..7e5ea0663a 100644 --- a/go/cmd/dolt/commands/tblcmds/mv.go +++ b/go/cmd/dolt/commands/tblcmds/mv.go @@ -59,7 +59,7 @@ func (cmd MvCmd) Docs() *cli.CommandDocumentation { } func (cmd MvCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(2) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"oldtable", "The table being moved."}) ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"newtable", "The new name of the table"}) ap.SupportsFlag(forceParam, "f", "If data already exists in the destination, the force flag will allow the target to be overwritten.") diff --git a/go/cmd/dolt/commands/tblcmds/rm.go b/go/cmd/dolt/commands/tblcmds/rm.go index 7db01ea24a..7d5310d728 100644 --- a/go/cmd/dolt/commands/tblcmds/rm.go +++ b/go/cmd/dolt/commands/tblcmds/rm.go @@ -60,7 +60,7 @@ func (cmd RmCmd) Docs() *cli.CommandDocumentation { } func (cmd RmCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithVariableArgs() ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"table", "The table to remove"}) return ap } diff --git a/go/cmd/dolt/commands/version.go b/go/cmd/dolt/commands/version.go index 5905400692..d9a4e466ab 100644 --- a/go/cmd/dolt/commands/version.go +++ b/go/cmd/dolt/commands/version.go @@ -53,7 +53,7 @@ func (cmd VersionCmd) Docs() *cli.CommandDocumentation { } func (cmd VersionCmd) ArgParser() *argparser.ArgParser { - ap := argparser.NewArgParser() + ap := argparser.NewArgParserWithMaxArgs(0) ap.SupportsFlag(featureVersionFlag, "f", "query the feature version of this repository.") return ap } diff --git a/go/libraries/utils/argparser/args_test.go b/go/libraries/utils/argparser/args_test.go index 56aae79c13..85a8bc35f3 100644 --- a/go/libraries/utils/argparser/args_test.go +++ b/go/libraries/utils/argparser/args_test.go @@ -195,7 +195,7 @@ func TestParsing(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - parser := NewArgParser() + parser := NewArgParserWithVariableArgs() for _, opt := range test.options { parser.SupportOption(opt) @@ -215,7 +215,7 @@ func TestParsing(t *testing.T) { } func TestValidation(t *testing.T) { - ap := NewArgParser() + ap := NewArgParserWithVariableArgs() ap.SupportsString("string", "s", "string_value", "A string") ap.SupportsString("string2", "", "string_value", "Another string") ap.SupportsFlag("flag", "f", "A flag") diff --git a/go/libraries/utils/argparser/parser.go b/go/libraries/utils/argparser/parser.go index 04388ff661..3064d466b8 100644 --- a/go/libraries/utils/argparser/parser.go +++ b/go/libraries/utils/argparser/parser.go @@ -49,15 +49,21 @@ func ValidatorFromStrList(paramName string, validStrList []string) ValidationFun } type ArgParser struct { + MaxArgs int Supported []*Option nameOrAbbrevToOpt map[string]*Option ArgListHelp [][2]string } -func NewArgParser() *ArgParser { +func NewArgParserWithVariableArgs() *ArgParser { + return NewArgParserWithMaxArgs(-1) +} + +func NewArgParserWithMaxArgs(maxArgs int) *ArgParser { var supported []*Option nameOrAbbrevToOpt := make(map[string]*Option) return &ArgParser{ + MaxArgs: maxArgs, Supported: supported, nameOrAbbrevToOpt: nameOrAbbrevToOpt, } @@ -253,7 +259,7 @@ func (ap *ArgParser) matchValueOption(arg string, isLongFormFlag bool) (match *O // methods. Any unrecognized arguments or incorrect types will result in an appropriate error being returned. If the // universal --help or -h flag is found, an ErrHelp error is returned. func (ap *ArgParser) Parse(args []string) (*ArgParseResults, error) { - list := make([]string, 0, 16) + list := make([]string, 0, ap.MaxArgs) results := make(map[string]string) i := 0 @@ -338,6 +344,13 @@ func (ap *ArgParser) Parse(args []string) (*ArgParseResults, error) { copy(list, args[i:]) } + if ap.MaxArgs == 0 && len(list) > 0 { + return nil, fmt.Errorf("error: this command does not take positional arguments, but got %s.", len(list)) + } + if ap.MaxArgs != -1 && len(list) > ap.MaxArgs { + return nil, fmt.Errorf("error: too many positional arguments. Expected at most %s, got %s.", ap.MaxArgs, len(list)) + } + return &ArgParseResults{results, list, ap}, nil } diff --git a/go/libraries/utils/argparser/parser_test.go b/go/libraries/utils/argparser/parser_test.go index 29a4dff487..15764826c7 100644 --- a/go/libraries/utils/argparser/parser_test.go +++ b/go/libraries/utils/argparser/parser_test.go @@ -30,63 +30,63 @@ func TestArgParser(t *testing.T) { expectedArgs []string }{ { - NewArgParser(), + NewArgParserWithVariableArgs(), []string{}, nil, map[string]string{}, []string{}, }, { - NewArgParser(), + NewArgParserWithVariableArgs(), []string{"arg1", "arg2"}, nil, map[string]string{}, []string{"arg1", "arg2"}, }, { - NewArgParser(), + NewArgParserWithVariableArgs(), []string{"--unknown_flag"}, UnknownArgumentParam{"unknown_flag"}, map[string]string{}, []string{}, }, { - NewArgParser(), + NewArgParserWithVariableArgs(), []string{"--help"}, ErrHelp, map[string]string{}, []string{}, }, { - NewArgParser(), + NewArgParserWithVariableArgs(), []string{"-h"}, ErrHelp, map[string]string{}, []string{}, }, { - NewArgParser(), + NewArgParserWithVariableArgs(), []string{"help"}, nil, map[string]string{}, []string{"help"}, }, { - NewArgParser().SupportsString("param", "p", "", ""), + NewArgParserWithVariableArgs().SupportsString("param", "p", "", ""), []string{"--param", "value", "arg1"}, nil, map[string]string{"param": "value"}, []string{"arg1"}, }, { - NewArgParser().SupportsString("param", "p", "", ""), + NewArgParserWithVariableArgs().SupportsString("param", "p", "", ""), []string{"-pvalue"}, nil, map[string]string{"param": "value"}, []string{}, }, { - NewArgParser().SupportsString("param", "p", "", ""), + NewArgParserWithVariableArgs().SupportsString("param", "p", "", ""), []string{"--paramvalue"}, UnknownArgumentParam{"paramvalue"}, map[string]string{},