Skip to content

Commit

Permalink
feat: added double_dash option to args (#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx authored Dec 18, 2024
1 parent bc0774e commit a6a86a0
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 12 deletions.
8 changes: 4 additions & 4 deletions cli/usage.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version "1.6.0"
about "CLI for working with usage-based CLIs"
usage "Usage: usage-cli [OPTIONS] [COMPLETIONS] <COMMAND>"
flag "--usage-spec" help="Outputs a `usage.kdl` spec for this CLI itself"
arg "[COMPLETIONS]" help="Outputs completions for the specified shell for completing the `usage` CLI itself"
arg "[COMPLETIONS]" help="Outputs completions for the specified shell for completing the `usage` CLI itself" required=false
cmd "bash" help="Executes a bash script" {
long_help r"Executes a bash script

Expand All @@ -15,7 +15,7 @@ to properly escape and quote values with spaces in them."
flag "-h" help="show help"
flag "--help" help="show help"
arg "<SCRIPT>"
arg "[ARGS]..." help="arguments to pass to script" var=true
arg "[ARGS]..." help="arguments to pass to script" required=false var=true
}
cmd "complete-word" {
alias "cw"
Expand All @@ -33,13 +33,13 @@ cmd "complete-word" {
flag "--cword" help="current word index" {
arg "<CWORD>"
}
arg "[WORDS]..." help="user's input from the command line" var=true
arg "[WORDS]..." help="user's input from the command line" required=false var=true
}
cmd "exec" hide=true {
alias "x"
arg "<COMMAND>" help="command to execute after parsing usage spec"
arg "<BIN>" help="path to script to execute"
arg "[ARGS]..." help="arguments to pass to script" var=true
arg "[ARGS]..." help="arguments to pass to script" required=false var=true
}
cmd "generate" subcommand_required=true {
alias "g"
Expand Down
26 changes: 26 additions & 0 deletions docs/cli/reference/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"name": "SCRIPT",
"usage": "<SCRIPT>",
"required": true,
"double_dash": "Optional",
"hide": false
},
{
Expand All @@ -22,6 +23,7 @@
"help": "arguments to pass to script",
"help_first_line": "arguments to pass to script",
"required": false,
"double_dash": "Optional",
"var": true,
"hide": false
}
Expand Down Expand Up @@ -68,6 +70,7 @@
"help": "user's input from the command line",
"help_first_line": "user's input from the command line",
"required": false,
"double_dash": "Optional",
"var": true,
"hide": false
}
Expand All @@ -84,6 +87,7 @@
"name": "SHELL",
"usage": "<SHELL>",
"required": true,
"double_dash": "Optional",
"hide": false,
"choices": {
"choices": ["bash", "fish", "zsh"]
Expand All @@ -103,6 +107,7 @@
"name": "FILE",
"usage": "<FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -119,6 +124,7 @@
"name": "SPEC",
"usage": "<SPEC>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -135,6 +141,7 @@
"name": "CWORD",
"usage": "<CWORD>",
"required": true,
"double_dash": "Optional",
"hide": false
}
}
Expand All @@ -157,6 +164,7 @@
"help": "command to execute after parsing usage spec",
"help_first_line": "command to execute after parsing usage spec",
"required": true,
"double_dash": "Optional",
"hide": false
},
{
Expand All @@ -165,6 +173,7 @@
"help": "path to script to execute",
"help_first_line": "path to script to execute",
"required": true,
"double_dash": "Optional",
"hide": false
},
{
Expand All @@ -173,6 +182,7 @@
"help": "arguments to pass to script",
"help_first_line": "arguments to pass to script",
"required": false,
"double_dash": "Optional",
"var": true,
"hide": false
}
Expand All @@ -198,6 +208,7 @@
"name": "SHELL",
"usage": "<SHELL>",
"required": true,
"double_dash": "Optional",
"hide": false,
"choices": {
"choices": ["bash", "fish", "zsh"]
Expand All @@ -209,6 +220,7 @@
"help": "The CLI which we're generates completions for",
"help_first_line": "The CLI which we're generates completions for",
"required": true,
"double_dash": "Optional",
"hide": false
}
],
Expand All @@ -226,6 +238,7 @@
"name": "CACHE_KEY",
"usage": "<CACHE_KEY>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -242,6 +255,7 @@
"name": "FILE",
"usage": "<FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -259,6 +273,7 @@
"name": "USAGE_BIN",
"usage": "<USAGE_BIN>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -275,6 +290,7 @@
"name": "USAGE_CMD",
"usage": "<USAGE_CMD>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand Down Expand Up @@ -316,6 +332,7 @@
"name": "FILE",
"usage": "<FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -332,6 +349,7 @@
"name": "SPEC",
"usage": "<SPEC>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -348,6 +366,7 @@
"name": "OUT_FILE",
"usage": "<OUT_FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
}
Expand Down Expand Up @@ -378,6 +397,7 @@
"name": "FILE",
"usage": "<FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -394,6 +414,7 @@
"name": "SPEC",
"usage": "<SPEC>",
"required": true,
"double_dash": "Optional",
"hide": false
}
}
Expand Down Expand Up @@ -426,6 +447,7 @@
"name": "FILE",
"usage": "<FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -452,6 +474,7 @@
"name": "URL_PREFIX",
"usage": "<URL_PREFIX>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand Down Expand Up @@ -486,6 +509,7 @@
"name": "OUT_DIR",
"usage": "<OUT_DIR>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
Expand All @@ -500,6 +524,7 @@
"name": "OUT_FILE",
"usage": "<OUT_FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
}
Expand Down Expand Up @@ -530,6 +555,7 @@
"help": "Outputs completions for the specified shell for completing the `usage` CLI itself",
"help_first_line": "Outputs completions for the specified shell for completing the `usage` CLI itself",
"required": false,
"double_dash": "Optional",
"hide": false
}
],
Expand Down
5 changes: 5 additions & 0 deletions docs/spec/reference/arg.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ arg "<shell>" {
}

arg "<file>" long_help="longer help for --help (as oppoosed to -h)"

# double-dash behavior
arg "<file>" double_dash="required" # arg must be passed after a double dash (e.g. mycli -- file.txt)
arg "<file>" double_dash="optional" # arg may be passed after a double dash (e.g. mycli -- file.txt or mycli file.txt)
arg "<file>..." double_dash="automatic" # once arg is passed, behave as if a double dash was passed (e.g. mycli file.txt --filewithdash)
```
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ flag "--shell" {
}
}
arg "<arg1>" help="arg1 description"
arg "[arg2]" help="arg2 description" default="default value" {
arg "[arg2]" help="arg2 description" required=false default="default value" {
choices "choice1" "choice2" "choice3"
}
arg "<arg3>" help="arg3 description" help_long="arg3 long description"
arg "<argrest>..." var=true
arg "[with-default]" default="default value"
arg "[with-default]" required=false default="default value"
complete "plugin" run="echo \"plugin-1\nplugin-2\nplugin-3\""
cmd "plugin" {
cmd "install" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ flag "--shell" {
}
}
arg "<arg1>" help="arg1 description"
arg "[arg2]" help="arg2 description" default="default value" {
arg "[arg2]" help="arg2 description" required=false default="default value" {
choices "choice1" "choice2" "choice3"
}
arg "<arg3>" help="arg3 description" help_long="arg3 long description"
arg "<argrest>..." var=true
arg "[with-default]" default="default value"
arg "[with-default]" required=false default="default value"
complete "plugin" run="echo \"plugin-1\nplugin-2\nplugin-3\""
cmd "plugin" {
cmd "install" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ flag "--shell" {
}
}
arg "<arg1>" help="arg1 description"
arg "[arg2]" help="arg2 description" default="default value" {
arg "[arg2]" help="arg2 description" required=false default="default value" {
choices "choice1" "choice2" "choice3"
}
arg "<arg3>" help="arg3 description" help_long="arg3 long description"
arg "<argrest>..." var=true
arg "[with-default]" default="default value"
arg "[with-default]" required=false default="default value"
complete "plugin" run="echo \"plugin-1\nplugin-2\nplugin-3\""
cmd "plugin" {
cmd "install" {
Expand Down
39 changes: 37 additions & 2 deletions lib/src/spec/arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ use crate::spec::helpers::NodeHelper;
use crate::spec::is_false;
use crate::{string, SpecChoices};

#[derive(Debug, Default, Clone, Serialize, PartialEq, Eq, strum::EnumString, strum::Display)]
pub enum SpecDoubleDashChoices {
/// Once an arg is entered, behave as if "--" was passed
Automatic,
/// Allow "--" to be passed
#[default]
Optional,
/// Require "--" to be passed
Required,
}

#[derive(Debug, Default, Clone, Serialize)]
pub struct SpecArg {
pub name: String,
Expand All @@ -25,6 +36,7 @@ pub struct SpecArg {
#[serde(skip_serializing_if = "Option::is_none")]
pub help_first_line: Option<String>,
pub required: bool,
pub double_dash: SpecDoubleDashChoices,
#[serde(skip_serializing_if = "is_false")]
pub var: bool,
#[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -48,6 +60,7 @@ impl SpecArg {
"help_long" => arg.help_long = Some(v.ensure_string()?),
"help_md" => arg.help_md = Some(v.ensure_string()?),
"required" => arg.required = v.ensure_bool()?,
"double_dash" => arg.double_dash = v.ensure_string()?.parse()?,
"var" => arg.var = v.ensure_bool()?,
"hide" => arg.hide = v.ensure_bool()?,
"var_min" => arg.var_min = v.ensure_usize().map(Some)?,
Expand Down Expand Up @@ -75,10 +88,15 @@ impl SpecArg {

impl SpecArg {
pub fn usage(&self) -> String {
let name = if self.double_dash == SpecDoubleDashChoices::Required {
format!("-- {}", self.name)
} else {
self.name.clone()
};
let mut name = if self.required {
format!("<{}>", self.name)
format!("<{}>", name)
} else {
format!("[{}]", self.name)
format!("[{}]", name)
};
if self.var {
name = format!("{}...", name);
Expand All @@ -100,6 +118,15 @@ impl From<&SpecArg> for KdlNode {
if let Some(desc) = &arg.help_md {
node.push(KdlEntry::new_prop("help_md", desc.clone()));
}
if !arg.required {
node.push(KdlEntry::new_prop("required", false));
}
if arg.double_dash != SpecDoubleDashChoices::Optional {
node.push(KdlEntry::new_prop(
"double_dash",
arg.double_dash.to_string(),
));
}
if arg.var {
node.push(KdlEntry::new_prop("var", true));
}
Expand Down Expand Up @@ -146,6 +173,7 @@ impl From<&str> for SpecArg {
}
_ => {}
}
// TODO: handle doubledash choice
arg
}
}
Expand Down Expand Up @@ -183,6 +211,13 @@ impl From<&clap::Arg> for SpecArg {
.to_string(),
usage: "".into(),
required,
double_dash: if arg.is_last_set() {
SpecDoubleDashChoices::Required
} else if arg.is_trailing_var_arg_set() {
SpecDoubleDashChoices::Automatic
} else {
SpecDoubleDashChoices::Optional
},
help,
help_long,
help_md: None,
Expand Down

0 comments on commit a6a86a0

Please sign in to comment.