sigoden / argc Goto Github PK
View Code? Open in Web Editor NEWA Bash CLI framework, also a Bash command runner.
License: Apache License 2.0
A Bash CLI framework, also a Bash command runner.
License: Apache License 2.0
As command strings are based on the shell function name, it's not possible to use dashes.
For example, using the following script:
#!/bin/sh
# @describe This is a test
# @cmd Start the service
start_service() {
echo do stuff
}
argc $0 "$@"
The help function is:
This is a test
USAGE: argc-test <COMMAND>
COMMANDS:
start_service Start the service
I would like to be able to use dashes instead of underscores as word-delimiters in command names:
This is a test
USAGE: argc-test <COMMAND>
COMMANDS:
start-service Start the service
I see two potential solutions:
_
) with dashes (-
) in command names (maybe not by default, for example by adding a flag for that)@name
flag to be able to force the command name:# @cmd Start the service
# @name start-service
start_service() {
echo do stuff
}
I know it's possible to use @alias
to make it work, but I would prefer to hide the service_start
function name in this output:
This is a test
USAGE: argc-test <COMMAND>
COMMANDS:
start_service Start service [aliases: start-service]
Let me know what you think.
And thanks for this great tool ! Can't wait to see the upcoming v1.0.0 released.
EDIT: looks like v1.0.0 was released 30 minutes ago ๐
ๅทฒ็ป่ฎพ็ฝฎ ARGC_SHELL_PATH ไธบ scoop ไธ็ git-bash.exe ่ทฏๅพ
# @arg mode[dev|prod|pre] Arg with choices
# @arg mode[=dev|prod|pre] Arg with choices and default value
Hey, AUR maintainer of argc
here ๐๐ผ
I'm getting the following test failure while trying to build the latest version:
running 10 tests
test compgen::tests::test_get_last_word ... ok
test parser::tests::test_parse_no_long_flag_arg ... ok
test parser::tests::test_parse_no_long_option_arg ... ok
test parser::tests::test_parse_line ... ok
test utils::tests::test_cobol ... ok
test parser::tests::test_parse_with_long_flag_arg ... ok
test parser::tests::test_parse_with_long_flag_arg_single_dash ... ok
test parser::tests::test_parse_positional_arg ... ok
test parser::tests::test_parse_with_long_option_arg ... ok
test parser::tests::test_parse_with_long_option_arg_single_dash ... ok
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/bin/argc/main.rs (target/debug/deps/argc-05cd09e0693dbda7)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running tests/tests.rs (target/debug/deps/integration-343b0242d08b2e78)
running 79 tests
test cli::help ... ok
test cli::version ... ok
test argcfile::argcfile_path ... ok
test fail::arg_miss_default_fn ... ok
test fail::cmd_miss_fn ... ok
test fail::arg_miss_choice_fn ... ok
test fail::conflict_alias ... ok
test fail::conflict_short_flag ... ok
test fail::conflict_cmd ... ok
test fail::conflict_long_flag ... ok
test fail::conflict_positional ... ok
test fail::conflict_long_option ... ok
test fail::conflict_short_option ... ok
test fail::option_miss_choice_fn ... ok
test fail::unsupported_tag ... ok
test fail::option_miss_default_fn ... ok
test fail::unexpected_arg ... ok
test cli::compgen ... ok
test create::create ... ok
test create::create_with_tasks ... ok
test argcfile::argcfile ... ok
test compgen::nested_subcmds ... ok
test compgen::subcmds ... ok
test main_fn::nested_subcmd_no_main ... ok
test main_fn::subcmd_no_main ... ok
test export::case1 ... ok
test spec::undefine_positionals ... ok
test misc::escape ... ok
test param_fn::case1 ... ok
test main_fn::nested_subcmd_main ... ok
test validate::arg_choice ... ok
test validate::arg_choice_fn_pass ... ok
test compgen::multiple ... ok
test spec::arg_no_param ... ok
test validate::arg_missing ... ok
test validate::arg_help_subcmd ... ok
test validate::arg_unknown ... ok
test spec::arg_no_option ... ok
test main_fn::no_main ... ok
test spec::option_help ... ok
test validate::arg_choice_fn_skip ... ok
test validate::option_choice_fn_pass ... ok
test validate::flag_not_multiple ... ok
test param_fn::case3 ... ok
test spec::option_shorts ... ok
test spec::same_option_positional ... ok
test compgen::shorts ... ok
test validate::option_not_multiple ... ok
test validate::option_mismatch_values ... ok
test main_fn::with_main ... ok
test validate::param_missing ... ok
test validate::flag_with_value ... ok
test validate::option_choice ... ok
test param_fn::case2 ... ok
test validate::help_version_shadow ... ok
test compgen::positionals ... ok
test spec::arg_two_multi ... ok
test wrap_help::wrap ... ok
test validate::option_missing ... ok
test validate::option_unknown ... ok
test validate::param_missing_parent ... ok
test validate::option_choice_fn_skip ... ok
test validate::empty_choices ... ok
test spec::dashdash_split ... ok
test main_fn::subcmd_main ... ok
test wrap_help::wrap2 ... ok
test wrap_help::nowrap ... ok
test validate::arg_invalid_subcmd ... ok
test validate::help_version ... ok
test spec::arg_subcmd_help ... ok
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__compgen__choice.snap.new
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__validate__arg_choice_fn.snap.new
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__validate__arg_choice_multi.snap.new
test validate::arg_choice_fn ... FAILED
test compgen::choice ... FAILED
test validate::arg_choice_multi ... FAILED
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__validate__option_choice_fn.snap.new
test validate::option_choice_fn ... FAILED
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__spec__option_eval.snap.new
test spec::option_eval ... FAILED
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__validate__choice_access_vars.snap.new
test validate::choice_access_vars ... FAILED
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__validate__option_choice_multi.snap.new
stored new snapshot /build/argc/src/argc-1.1.0/tests/snapshots/integration__spec__arg_eval.snap.new
test validate::option_choice_multi ... FAILED
test spec::arg_eval ... FAILED
test interrupt::interrupt ... ok
failures:
---- validate::arg_choice_fn stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__validate__arg_choice_fn.snap
Snapshot: arg_choice_fn
Source: tests/validate.rs:64
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2 2 โ
3 3 โ OUTPUT
4 4 โ cat >&2 <<-'EOF'
5 5 โ error: invalid value 'val' for '[VAL]'
6 โ- [possible values: abc, def, ghi]
6 โ+ [possible values: ]
7 7 โ
8 8 โ For more information, try '--help'.
9 9 โ
10 10 โ EOF
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'validate::arg_choice_fn' panicked at 'snapshot assertion for 'arg_choice_fn' failed in line 64', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
---- compgen::choice stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__compgen__choice.snap
Snapshot: choice
Source: tests/compgen.rs:164
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
0 0 โ ************ COMPGEN `prog --oa ` ************
1 โ-abc
2 โ-def
3 โ-ghi
4 1 โ
2 โ+
5 3 โ ************ COMPGEN `prog --ob ` ************
6 4 โ x
7 5 โ y
8 6 โ z
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
16 14 โ
17 15 โ ************ COMPGEN `prog v1 ` ************
18 16 โ --oa
19 17 โ --ob
20 โ-abc
21 โ-def
22 โ-ghi
23 18 โ
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'compgen::choice' panicked at 'snapshot assertion for 'choice' failed in line 164', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- validate::arg_choice_multi stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__validate__arg_choice_multi.snap
Snapshot: arg_choice_multi
Source: tests/validate.rs:87
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1 1 โ prog cmdl abc val
2 2 โ
3 3 โ OUTPUT
4 4 โ cat >&2 <<-'EOF'
5 โ-error: invalid value 'val' for '[VAL]...'
6 โ- [possible values: abc, def, ghi]
5 โ+error: invalid value 'abc' for '[VAL]...'
6 โ+ [possible values: ]
7 7 โ
8 8 โ For more information, try '--help'.
9 9 โ
10 10 โ EOF
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'validate::arg_choice_multi' panicked at 'snapshot assertion for 'arg_choice_multi' failed in line 87', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
---- validate::option_choice_fn stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__validate__option_choice_fn.snap
Snapshot: option_choice_fn
Source: tests/validate.rs:131
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2 2 โ
3 3 โ OUTPUT
4 4 โ cat >&2 <<-'EOF'
5 5 โ error: invalid value 'val' for '<CC>'
6 โ- [possible values: abc, def, ghi]
6 โ+ [possible values: ]
7 7 โ
8 8 โ For more information, try '--help'.
9 9 โ
10 10 โ EOF
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'validate::option_choice_fn' panicked at 'snapshot assertion for 'option_choice_fn' failed in line 131', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
---- spec::option_eval stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__spec__option_eval.snap
Snapshot: option_eval
Source: tests/spec.rs:21
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
71 71 โ ************ RUN ************
72 72 โ prog cmda --cc abc
73 73 โ
74 74 โ OUTPUT
75 โ-argc_cc=abc
76 โ-argc__args=( )
77 โ-argc__fn=cmda
78 โ-cmda
75 โ+cat >&2 <<-'EOF'
76 โ+error: invalid value 'abc' for '<CC>'
77 โ+ [possible values: ]
78 โ+
79 โ+For more information, try '--help'.
80 โ+
81 โ+EOF
82 โ+exit 1
79 83 โ
80 84 โ ************ RUN ************
81 85 โ prog cmda -soa soa
82 86 โ
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'spec::option_eval' panicked at 'snapshot assertion for 'option_eval' failed in line 21', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
---- validate::choice_access_vars stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__validate__choice_access_vars.snap
Snapshot: choice_access_vars
Source: tests/validate.rs:209
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2 2 โ
3 3 โ OUTPUT
4 4 โ cat >&2 <<-'EOF'
5 5 โ error: invalid value 'foo' for '[VAL]'
6 โ- [possible values: abc]
6 โ+ [possible values: ]
7 7 โ
8 8 โ For more information, try '--help'.
9 9 โ
10 10 โ EOF
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
15 15 โ
16 16 โ OUTPUT
17 17 โ cat >&2 <<-'EOF'
18 18 โ error: invalid value 'foo' for '[VAL]'
19 โ- [possible values: def]
19 โ+ [possible values: ]
20 20 โ
21 21 โ For more information, try '--help'.
22 22 โ
23 23 โ EOF
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'validate::choice_access_vars' panicked at 'snapshot assertion for 'choice_access_vars' failed in line 209', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
---- validate::option_choice_multi stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__validate__option_choice_multi.snap
Snapshot: option_choice_multi
Source: tests/validate.rs:154
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1 1 โ prog cmda --ce abc val
2 2 โ
3 3 โ OUTPUT
4 4 โ cat >&2 <<-'EOF'
5 โ-error: invalid value 'val' for '<CE>'
6 โ- [possible values: abc, def, ghi]
5 โ+error: invalid value 'abc' for '<CE>'
6 โ+ [possible values: ]
7 7 โ
8 8 โ For more information, try '--help'.
9 9 โ
10 10 โ EOF
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'validate::option_choice_multi' panicked at 'snapshot assertion for 'option_choice_multi' failed in line 154', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
---- spec::arg_eval stdout ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Snapshot Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Snapshot file: tests/snapshots/integration__spec__arg_eval.snap
Snapshot: arg_eval
Source: tests/spec.rs:58
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expression: data
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-old snapshot
+new results
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
54 54 โ ************ RUN ************
55 55 โ prog cmdj abc
56 56 โ
57 57 โ OUTPUT
58 โ-argc_val=abc
59 โ-argc__args=( abc )
60 โ-argc__fn=cmdj
61 โ-cmdj abc
58 โ+cat >&2 <<-'EOF'
59 โ+error: invalid value 'abc' for '[VAL]'
60 โ+ [possible values: ]
61 โ+
62 โ+For more information, try '--help'.
63 โ+
64 โ+EOF
65 โ+exit 1
62 66 โ
63 67 โ ************ RUN ************
64 68 โ prog cmdp v1 v2
65 69 โ
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To update snapshots run `cargo insta review`
Stopped on the first failure. Run `cargo insta test` to run all snapshots.
thread 'spec::arg_eval' panicked at 'snapshot assertion for 'arg_eval' failed in line 58', /build/.cargo/registry/src/github.com-1ecc6299db9ec823/insta-1.29.0/src/runtime.rs:569:9
failures:
compgen::choice
spec::arg_eval
spec::option_eval
validate::arg_choice_fn
validate::arg_choice_multi
validate::choice_access_vars
validate::option_choice_fn
validate::option_choice_multi
test result: FAILED. 71 passed; 8 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.02s
error: test failed, to rerun pass `--test integration`
I'm wondering if there is a setup procedure for test or maybe a recommended way to run them?
Thank you very much for argc
. I have adopted it as my "go-to" command parser.
I have encountered a use case related to issue #251, in which parsing the command line like GNU getopt would be helpful. I, too, want to use argc to write a wrapper around another CLI tool to which I may wish to pass additional arguments and flags.
The issue arises when there are other arguments defined in addition to # @arg remaining_args~
MacOS Darwin Kernel Version 23.5.0: arm64
argc 1.19.0
My sample script double-dash-tester.sh
appears as follows:
#!/usr/bin/env bash
# @describe Testing out the use of double-dash to stop parsing.
# @flag -t --test Test flag
# @arg first! Search query
# @arg second=/tmp
# @arg remaining_args~
main () {
echo -n " "; declare -p argc_test
echo -n " "; declare -p argc_first
echo -n " "; declare -p argc_second
echo -n " "; declare -p argc_remaining_args
}
argc_test=""
argc_remaining_args=()
eval "$(argc --argc-eval "$0" "$@")"
With argc 1.19.0
, I get the following output using a variety of flags:
$ ./double-dash-tester.sh --
error: the following required arguments were not provided:
<FIRST>
$ ./double-dash-tester.sh -- first second
declare -- argc_test=""
declare -- argc_first="first"
declare -- argc_second="second"
declare -a argc_remaining_args='()'
$ ./double-dash-tester.sh first -- second
declare -- argc_test=""
declare -- argc_first="first"
declare -- argc_second="second"
declare -a argc_remaining_args='()'
$ ./double-dash-tester.sh first second -- -t
declare -- argc_test=""
declare -- argc_first="first"
declare -- argc_second="second"
declare -a argc_remaining_args='([0]="--" [1]="-t")'
My reading of GNU Standards for Command Line Interfaces and the getopt
sample code is that argument parsing should terminate upon finding a --
.
I would anticipate the following results if parsing terminated on --
:
$ ./double-dash-tester.sh -- first second
error: the following required arguments were not provided:
<FIRST>
$ ./double-dash-tester.sh first -- second
declare -- argc_test=""
declare -- argc_first="first"
declare -- argc_second="/tmp"
declare -a argc_remaining_args='([0]="--" [1]="second")'
$ ./double-dash-tester.sh first second -- -t
declare -- argc_test=""
declare -- argc_first="first"
declare -- argc_second="second"
declare -a argc_remaining_args='([0]="--" [1]="-t")'
I don't assume that the GNU getopt behavior is the goal, but it would be helpful in my use case since I want to pass these arguments after the double-dash on to another command.
argc
is checking all functions for duplicates, but it should only check top-level ones which are tagged with @cmd
or @alias
.
Reproducer:
#!/bin/sh
# unused function
util_func() {
case $(basename ${SHELL}) in
zsh)
_local_func() {
echo "do this"
}
;;
bash)
_local_func() {
echo "do that instead"
}
;;
esac
}
# @cmd Run tests
test() {
echo "do something"
}
eval "$(argc "$0" "$@")"
If I run the script, argc
exits with the following error:
_local_func(line 13) is conflicted with cmd or alias at line 7
IMHO, _local_func()
should not be checked for duplicates, as well as util_func()
because none of them have @cmd
or @alias
tags,
Also, all forms of heredoc
should be ignored too. For example, using the following script:
#!/bin/sh
# just a random heredoc
cat >/dev/null <<EOF
func_test() {
echo test
}
func_test() {
echo test
}
EOF
# @cmd Run tests
test() {
echo "do something"
}
eval "$(argc "$0" "$@")"
argc
exits with the following error:
func_test(line 8) is conflicted with cmd or alias at line 5
This seems to be a regression as the two above example are working with v0.12.0, but failing with v0.13.0.
With Nushell 0.89.0, the completion script generated by argc --argc-completions nushell
causes error:
Error: ร Automatically spreading lists is deprecated
โญโ[<pathToArgc>\argc-completions\tmp\argc-completions.nu:1:1]
1 โ def _argc_completer [args: list<string>] {
2 โ argc --argc-compgen nushell "" $args
ยท โโโฌโโ
ยท โฐโโ Spreading lists automatically when calling external commands is deprecated and will be removed in 0.91.
3 โ | split row "\n" | range 0..-2
โฐโโโโ
help: Use the spread operator (put a '...' before the argument)
Use spread operator (added in Nushell 0.89.0, won't work in previous versions) in ...$args
.
argc/src/bin/argc/completions/argc.nu
Lines 1 to 5 in afa5302
def _argc_completer [args: list<string>] {
argc --argc-compgen nushell "" ...$args
| split row "\n" | range 0..-2
| each { |line| $line | split column "\t" value description } | flatten
}
How to define separate flags, args, options for each subcommand ?
Not able to figureout that from docs
Thanks
#!/bin/bash
# @cmd A wrapper for multiple subcommands
wrapper() {
subcommandA
# subcommandB
# subcommandC
}
# @cmd A subcommand
# @option --sub_option=defaultValue
subcommandA() {
echo "subcommandA ${argc_sub_option}"
}
eval "$(argc --argc-eval "$0" "$@")"
$ ./test subcommandA
subcommandA defaultValue
$ ./test wrapper
subcommandA
If a subcommand "wrapper" consists of multiple other subcommands, the subcommands option default values are not beeing present.
Is this expected behavior?
A small change which would be a bit more hygienic is to exec the Argcfile.sh when it's used.
Consider an Argcfile.sh like this one:
#!/usr/bin/env bash
main() {
exec bash
}
eval "$(argc --argc-eval "$0" "$@")"
When we run this, it results in a process tree like this one:
$ ps uf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
ubuntu 2034 0.1 0.0 247380 17112 pts/1 Ss 10:40 0:06 -fish
ubuntu 36428 0.0 0.0 3304 4 pts/1 Sl 11:53 0:00 \_ argc
ubuntu 36430 1.0 0.0 8664 5436 pts/1 S+ 11:53 0:00 \_ bash
The feature request is for argc (PID 36428) to use exec
when it runs the Argcfile.sh, instead of starting it as a child process. This is minor but would be slightly cleaner.
Hi, I was just looking for a better task runner than my previous choice, and I came across this project. I think it's very simple and elegant and would make a great choice for my scripts. However, one of the main things that I want is to include lots of documentation in the generated help messages, and there presently isn't a way to do that. What I'd like to see is some sort of "long description" field that gets printed in the usage message, applicable to both the top command and subcommands. The precise syntax doesn't really matter, but here is a proposal to consider:
# @description my sweet command
# Extra lines after the @description, which don't start with an @, are
# treated as the long description. A line which is not a comment ends
# the block.
# @cmd Run subcommand
# Extra comments after the @cmd line, which don't start with an @, are
# treated as the long description. A line which is not a comment ends
# the block.
subcommand() { true; }
This long description would just be put in the command help:
my sweet command
USAGE: test <COMMAND>
COMMANDS:
subcommand Run subcommand
Extra lines after the @description, which don't start with an @, are
treated as the long description. A line which is not a comment ends
the block.
Run subcommand
USAGE: test subcommand
Extra comments after the @cmd line, which don't start with an @, are
treated as the long description. A line which is not a comment ends
the block.
Thanks for your consideration!
# @cmd
# @alias b
build() {
:;
}
# @cmd
# @alias t,tst
test() {
:;
}
It's typical for programs to treat an argument of --
as signifying "end-of-arguments" and do not further parsing. Argc sort of follows this, but it removes all --
arguments from the input.
# @cmd
# @arg command! Command to run
test() {
echo "${argc_command[@]}"
}
$ argc foo -- -- -- --
foo
$ echo foo -- -- -- --
foo -- -- -- --
Use argc --argc-create <cmd...>
to generate boilerplate file
For example, run argc --argc-create build test run
will create argcfile.sh
in current directory with following content
#!/usr/bin/env bash
set -e
# @cmd
build() {
echo "build to be implemented"
}
# @cmd
test() {
echo "test to be implemented"
}
# @cmd
run() {
echo "run to be implemented"
}
eval $(argc --argc-eval "$0" "$@")
Hello! Thank you for adding extended documentation in #97. I've begun migrating my dotfiles to them and noticed a minor problem with the generated shell completions.
If you run argc --argc-compgen fish
on the linked file, you get this output:
create-docker-workspace Copy the docker workspace root template to the named directory.
traefik Start an automatic local vhost for Docker containers.
The traefik container will run permanently. The dashboard will be available
at the root domain. All docker containers will be made available at URLs
according to their compose configuration, by default:
http://SERVICE-PROJECT.lvh.me/
- Docker label reference: https://doc.traefik.io/traefik/providers/docker/
create-argcfile Create a sample Argcfile.
As you can see, the extended documentation is included in the completion output, which causes each line to appear as a separate (invalid) completion. This also happens for zsh.
Hello, love the project! What a clean API and implementation!
Just curious what you'd think about supporting subcommands being implemented in other files. I'm not currently seeing a way to break large CLI projects down into smaller files for organization purposes.
I was thinking something like this could be useful:
# main.sh
# @describe A demo cli
# @cmd Upload a file
# @alias u
# @arg target! File to upload
upload() {
echo "cmd upload"
echo "arg: target $argc_target"
}
# @cmd Download a file
# @cmd-file ./subcommands/download.sh
eval "$(argc --argc-eval "$0" "$@")"
# subcommands/download.sh
# @alias d
# @flag -f --force Override existing file
# @option -t --tries <NUM> Set number of retries to NUM
# @arg source! Url to download from
# @arg target Save file to
download() {
echo "cmd: download"
echo "flag: --force $argc_force"
echo "option: --tries $argc_tries"
echo "arg: source $argc_source"
echo "arg: target $argc_target"
}
This might just be opening a big can of worms, but I'd love to hear your thoughts!
At least variable values are not propperly escaped.
e.g. running the demo.sh
like this:
export foo="this is broken" ; ./demo.sh download -t '$foo' bar
should result in
cmd: download
flag: --force
option: --tries $foo
arg: source bar
arg: target
but results in
cmd: download
flag: --force
option: --tries this is broken
arg: source bar
arg: target
this is since calling argc -e demo.sh download -t '$foo' bar
results in
argc_tries="$foo"
argc_source="bar"
download
``` riight there is an unescaped `$foo`
Hi sigoden, I was recently setting up a repository where I needed to symlink the Argcfile into a different location. I wanted to do this specifically because I wanted argc's directory handling (so that the script would always be run from the directory with the symlink).
The behavior I observe:
argc --argc-script-path
prints the path to the symlinkargc
will cd into the directory containing the target of the symlink.I feel like one of these exhibits the wrong behavior. For me, I'd prefer that argc did not resolve the symlink before changing directory (since I can't imagine a time when that behavior would be useful), but if this is desired behavior, then --argc-script-path
should be consistent with it.
Thanks as always for the great software package.
Can we have colored helped, please? I haven't seen anything about color in README or issues.
clap
's default color choice is auto, i.e. when terminal supports it:
https://docs.rs/clap/3.2.17/clap/enum.ColorChoice.html#variant.Auto
Hello, thanks for this amazing project which is helping me a lot in standardizing my scripts and simplify how to configure them using flags/args etc.
I'm having some issues with the @env
and @meta dotenv
annotations.
Probably I'm misunderstanding the way these annotations are meant to be used, but my expectation was that if a .env
file was present in the current folder, it was read and used to override the default values from the @env
annotation.
For example, in my script I have these annotations
# @env MY_PROFILE=someprofile The profile used
# @meta dotenv
And I've created a .env
file in the same folder filled like this
MY_PROFILE=special
When I print the actual env variable I'm getting this
echo $MY_PROFILE => "someprofile"
# I was expecting instead "special"
Is this the expected behavior? There's a way to override the env using the .env file?
Many thank
I saw on README.md that argc
has completions for bash/zsh/powershell. Maybe consider adding fish as well?
In gdb the default behavior of ctrl-c is to interrupt the process. For example:
(gdb) c
Continuing.
^C
Thread 1 "main" received signal SIGINT, Interrupt.
0x00002aaab428480d in nanosleep () from /lib64/libc.so.6
(gdb)
But if run gdb from argc, ctrl-c would terminate the gdb debug process.
# @cmd debug
debug () {
gdb -p `pgrep main` \
-ex 'c'
#exec gdb -p `pgrep main` \
# -ex 'c'
}
argc debug
# in gdb
# ctrl-c would terminate the debug process.
Its exit code is 130 and the output is like:
^C
Thread 1 "main" received signal SIGINT, Interrupt.
[Switching to Thread 0x2aaaaab30640 (LWP 177491)]
0x00002aaab5bfa80d in nanosleep () from /lib64/libc.so.6
(130)
Is there any solution or workaround to not terminate the gdb?
Hi @sigoden, continuing to love using argc for all of my shell scripts. One pattern that I see coming up sometimes is a desire for a "default subcommand". Basically, I have a script called "backup", and I want it to... perform a backup. But I also want to add subcommands, like "backup verify" or "backup restore". With the current system, I can't do this, because the main command is completely masked by the presence of subcommands.
So the feature request is for the ability to designate a subcommand as a "default" one. Something like this:
#!/usr/bin/env bash
# @cmd
# @default_subcommand
backup() { :; }
# @cmd
restore() { :; }
eval "$(argc --argc-eval "$0" "$@")"
This script could be invoked as argc; argc backup; argc restore
. Now, this behavior would cause ambiguity with positional arguments. For example, if the backup
subcommand accepted arguments, should argc $PARAM
be an error, or invoke argc backup $PARAM
? What if $PARAM
was restore
? So, in order for a subcommand to be eligible as a default subcommand, it cannot accept any positional arguments.
Ideally this feature would also work with nested subcommands in the same way, so e.g. with 3 subcommands backup; backup::incremental; backup::full
I could designate backup::incremental
as the default for the backup
command (which again could be the default subcommand for the overall script).
It would be nice if the shell completion also understood when a command was the default and showed arguments for that subcommand when there wasn't one given.
Thanks again for the consideration. Loving the activity on this project!
Hey, loving the activity on this project. Thanks for resolving #118 so quickly. I've now ported most of my projects to using argc, and I'm seeing how far I can push it.
It's great that argc automatically cds into the directory of the Argcfile.sh it finds in the parent hierarchy; this is generally the thing that a script author wants. However, if the command accepts a filename argument, the filename is invalid when the script gets run. See this Argcfile for an example:
#!/usr/bin/env bash
# @arg file <FILE>
set -e
eval "$(argc --argc-eval "$0" "$@")"
ls $argc_file
Run this script:
mkdir directory
cd directory
touch test.txt
argc test.txt
The script fails, because the file does not exist, because the directory was changed.
I can think of a few options here:
ARGC_ORIGINAL_PATH
or some other variable, which contains the path of the original pwd.The first option seems like the best overall to me. The second requires that the argument values are tagged properly, and there could also be use cases where we don't need a specific argument, but we still want to know the original directory of the command.
Thanks for your consideration!
I do a lot of wrapping commands with argc. Generally, I include an escape hatch to pass arguments directly to the wrapped program, and this works well (post #232 ๐) using argc my-command -- --foo-bar
.
A useful addition to argc might be an "external subcommand" feature. Basically, when there is an external subcommand in play, as soon as an unsupported argument is found, all remaining arguments get treated as positional, even if argc would otherwise recognize them. There's a few ways this would work:
@arg args+
we use @remaining_args args+
or something (@rest
, @remainder
, ...). Must be after all @arg
, and after this starts to match, it consumes the rest of the input, ignoring further flags and options.@arg args+
we use @arg args...
or some other sigil. Same idea.@meta external_subcommand
or something which applies this rule to the last @arg
.Here's a quick example:
#!/usr/bin/env bash
# @describe Example Argcfile
set -eu
# @cmd Wrapper that works today (wraps terraform)
#
# Example: run with auto-approval
# argc terraform apply -- -auto-approve
# @arg subcommand Subcommand for terraform
# @arg args* Additional arguments for terraform
# @option -e --environment=production Name of the environment to operate in
terraform() {
echo terraform -chdir=terraform "${argc_subcommand:?}" -var-file="${argc_environment:?}.tfvars" ${args_args+"${argc_args[@]}"}
}
# @cmd Wrapper that would be nice (1st idea)
#
# Example: run with auto-approval
# argc terraform2 apply -auto-approve
# @arg subcommand Subcommand for terraform
# @remaining_args args Additional arguments for terraform
# @option -e --environment=production Name of the environment to operate in
terraform2() {
echo terraform -chdir=terraform "${argc_subcommand:?}" -var-file="${argc_environment:?}.tfvars" ${args_args+"${argc_args[@]}"}
}
# @cmd Wrapper that would be nice (2nd idea)
#
# Example: run with auto-approval
# argc terraform3 apply -auto-approve
# @arg subcommand Subcommand for terraform
# @arg args... Additional arguments for terraform
# @option -e --environment=production Name of the environment to operate in
terraform3() {
echo terraform -chdir=terraform "${argc_subcommand:?}" -var-file="${argc_environment:?}.tfvars" ${args_args+"${argc_args[@]}"}
}
# @cmd Wrapper that would be nice (3rd idea)
#
# Example: run with auto-approval
# argc terraform4 apply -auto-approve
# @arg subcommand Subcommand for terraform
# @arg args* Additional arguments for terraform
# @option -e --environment=production Name of the environment to operate in
# @meta external_subcommand
terraform4() {
echo terraform -chdir=terraform "${argc_subcommand:?}" -var-file="${argc_environment:?}.tfvars" ${args_args+"${argc_args[@]}"}
}
if ! command -v argc >/dev/null; then
echo "This command requires argc. Install from https://github.com/sigoden/argc" >&2
exit 100
fi
eval "$(argc --argc-eval "$0" "$@")"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.