From 9dc105fa51b3d7d011f8c8ff0f8121f453b58026 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sat, 5 Jun 2021 14:40:09 -0700 Subject: [PATCH 1/5] Enable/fix `xflags-macros/tests/it/{,src/}help.rs` --- xflags-macros/tests/it/help.rs | 4 ++-- xflags-macros/tests/it/main.rs | 1 + xflags-macros/tests/it/src/help.rs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/xflags-macros/tests/it/help.rs b/xflags-macros/tests/it/help.rs index 70edb26..f3d9f7f 100644 --- a/xflags-macros/tests/it/help.rs +++ b/xflags-macros/tests/it/help.rs @@ -3,7 +3,7 @@ use std::{ffi::OsString, path::PathBuf}; #[derive(Debug)] pub struct Helpful { - pub src: Option, + pub src: Option, pub switch: (), pub subcommand: HelpfulCmd, @@ -64,7 +64,7 @@ impl Helpful { _ => (), } if let (done_ @ false, buf_) = &mut src { - buf_.push(p_.value_from_str::("src", arg_)?); + buf_.push(arg_.into()); *done_ = true; continue; } diff --git a/xflags-macros/tests/it/main.rs b/xflags-macros/tests/it/main.rs index 9d24e04..1ce0588 100644 --- a/xflags-macros/tests/it/main.rs +++ b/xflags-macros/tests/it/main.rs @@ -1,6 +1,7 @@ mod repeated_pos; mod smoke; mod subcommands; +mod help; use std::{ffi::OsString, fmt}; diff --git a/xflags-macros/tests/it/src/help.rs b/xflags-macros/tests/it/src/help.rs index 2d006f5..893bc96 100644 --- a/xflags-macros/tests/it/src/help.rs +++ b/xflags-macros/tests/it/src/help.rs @@ -2,7 +2,7 @@ xflags! { /// Does stuff cmd helpful /// With an arg. - optional src: PathBut + optional src: PathBuf { /// And a switch. required -s, --switch From d428f966ad1b15c443680e126f4972e2ce7ad5fa Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sat, 5 Jun 2021 20:56:46 -0700 Subject: [PATCH 2/5] Support multiline doc comments --- xflags-macros/src/emit.rs | 16 ++++++++++++--- xflags-macros/src/parse.rs | 14 +++++++++++++- xflags-macros/tests/it/help.rs | 31 ++++++++++++++++++++++++++++-- xflags-macros/tests/it/src/help.rs | 11 +++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/xflags-macros/src/emit.rs b/xflags-macros/src/emit.rs index 0d2186c..05d5f01 100644 --- a/xflags-macros/src/emit.rs +++ b/xflags-macros/src/emit.rs @@ -331,10 +331,20 @@ fn emit_help(buf: &mut String, xflags: &ast::XFlags) { w!(buf, "}}\n"); } +fn write_lines_indented(buf: &mut String, multiline_str: &str, indent: usize) { + for line in multiline_str.split('\n').map(str::trim_end) { + if line.is_empty() { + w!(buf, "\n") + } else { + w!(buf, "{blank:indent$}{}\n", line, indent = indent, blank = ""); + } + } +} + fn help_rec(buf: &mut String, prefix: &str, cmd: &ast::Cmd) { w!(buf, "{}{}\n", prefix, cmd.name); if let Some(doc) = &cmd.doc { - w!(buf, " {}\n", doc) + write_lines_indented(buf, doc, 2); } let indent = if prefix.is_empty() { "" } else { " " }; @@ -355,7 +365,7 @@ fn help_rec(buf: &mut String, prefix: &str, cmd: &ast::Cmd) { }; w!(buf, " {}{}{}\n", l, arg.val.name, r); if let Some(doc) = &arg.doc { - w!(buf, " {}\n", doc) + write_lines_indented(buf, doc, 6) } } } @@ -374,7 +384,7 @@ fn help_rec(buf: &mut String, prefix: &str, cmd: &ast::Cmd) { let value = flag.val.as_ref().map(|it| format!(" <{}>", it.name)).unwrap_or_default(); w!(buf, " {}--{}{}\n", short, flag.name, value); if let Some(doc) = &flag.doc { - w!(buf, " {}\n", doc) + write_lines_indented(buf, doc, 6); } } } diff --git a/xflags-macros/src/parse.rs b/xflags-macros/src/parse.rs index a0c5d93..2d614c6 100644 --- a/xflags-macros/src/parse.rs +++ b/xflags-macros/src/parse.rs @@ -155,7 +155,7 @@ fn ty(p: &mut Parser) -> Result { Ok(res) } -fn opt_doc(p: &mut Parser) -> Result> { +fn opt_single_doc(p: &mut Parser) -> Result> { if !p.eat_punct('#') { return Ok(None); } @@ -170,6 +170,18 @@ fn opt_doc(p: &mut Parser) -> Result> { Ok(Some(res)) } +fn opt_doc(p: &mut Parser) -> Result> { + let lines = + core::iter::from_fn(|| opt_single_doc(p).transpose()).collect::>>()?; + let lines = lines.join("\n"); + + if lines.is_empty() { + Ok(None) + } else { + Ok(Some(lines)) + } +} + fn cmd_name(p: &mut Parser) -> Result { let name = p.expect_name()?; if name.starts_with('-') { diff --git a/xflags-macros/tests/it/help.rs b/xflags-macros/tests/it/help.rs index f3d9f7f..7f13785 100644 --- a/xflags-macros/tests/it/help.rs +++ b/xflags-macros/tests/it/help.rs @@ -4,6 +4,7 @@ use std::{ffi::OsString, path::PathBuf}; #[derive(Debug)] pub struct Helpful { pub src: Option, + pub extra: Option, pub switch: (), pub subcommand: HelpfulCmd, @@ -15,7 +16,9 @@ pub enum HelpfulCmd { } #[derive(Debug)] -pub struct Sub; +pub struct Sub { + pub flag: bool, +} impl Helpful { pub const HELP: &'static str = Self::HELP_; @@ -47,6 +50,7 @@ impl Helpful { let mut switch = Vec::new(); let mut src = (false, Vec::new()); + let mut extra = (false, Vec::new()); let mut sub_ = None; while let Some(arg_) = p_.pop_flag() { @@ -68,12 +72,18 @@ impl Helpful { *done_ = true; continue; } + if let (done_ @ false, buf_) = &mut extra { + buf_.push(p_.value_from_str::("extra", arg_)?); + *done_ = true; + continue; + } return Err(p_.unexpected_arg(arg_)); } } } Ok(Self { src: p_.optional("src", src.1)?, + extra: p_.optional("extra", extra.1)?, switch: p_.required("--switch", switch)?, subcommand: p_.subcommand(sub_)?, @@ -83,9 +93,12 @@ impl Helpful { impl Sub { fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { + let mut flag = Vec::new(); + while let Some(arg_) = p_.pop_flag() { match arg_ { Ok(flag_) => match flag_.as_str() { + "--flag" | "-f" => flag.push(()), _ => return Err(p_.unexpected_flag(&flag_)), }, Err(arg_) => { @@ -93,7 +106,7 @@ impl Sub { } } } - Ok(Self {}) + Ok(Self { flag: p_.optional("--flag", flag)?.is_some() }) } } impl Helpful { @@ -101,10 +114,19 @@ impl Helpful { helpful Does stuff + Helpful stuff. + ARGS: [src] With an arg. + [extra] + Another arg. + + This time, there's some extra info about the + arg. Maybe some caveats, or what kinds of + values are accepted. + OPTIONS: -s, --switch And a switch. @@ -113,5 +135,10 @@ SUBCOMMANDS: helpful sub And even a subcommand! + + OPTIONS: + -f, --flag + With an optional flag. This has a really long + description which spans multiple lines. "; } diff --git a/xflags-macros/tests/it/src/help.rs b/xflags-macros/tests/it/src/help.rs index 893bc96..399cb67 100644 --- a/xflags-macros/tests/it/src/help.rs +++ b/xflags-macros/tests/it/src/help.rs @@ -1,14 +1,25 @@ xflags! { /// Does stuff + /// + /// Helpful stuff. cmd helpful /// With an arg. optional src: PathBuf + /// Another arg. + /// + /// This time, there's some extra info about the + /// arg. Maybe some caveats, or what kinds of + /// values are accepted. + optional extra: String { /// And a switch. required -s, --switch /// And even a subcommand! cmd sub { + /// With an optional flag. This has a really long + /// description which spans multiple lines. + optional -f, --flag } } } From 29d9bb4fb14381f1ae7172619d7b1778faa63193 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sat, 5 Jun 2021 20:57:09 -0700 Subject: [PATCH 3/5] Fix xtask help text --- xtask/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtask/src/main.rs b/xtask/src/main.rs index d79a477..133b201 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -51,7 +51,7 @@ fn try_main() -> Result<()> { fn print_usage() { eprintln!( "\ -Usage: cargo run -p xtask +Usage: cargo run -p xtask -- SUBCOMMANDS: ci From 191249cbd3506713a5cd82ea8e3a84ce0c84ec43 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 6 Jun 2021 16:39:03 -0700 Subject: [PATCH 4/5] Bump version numbers to 0.2.2 --- Cargo.toml | 4 ++-- xflags-macros/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7d6fa95..7f3fa14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xflags" -version = "0.2.1" # NB: update me in 3 places +version = "0.2.2" # NB: update me in 3 places description = "Moderately simple command line arguments parser." categories = ["command-line-interface"] license = "MIT OR Apache-2.0" @@ -14,4 +14,4 @@ exclude = [".github/", "bors.toml", "rustfmt.toml"] members = ["xtask", "xflags-macros"] [dependencies] -xflags-macros = { path = "./xflags-macros", version = "=0.2.1" } +xflags-macros = { path = "./xflags-macros", version = "=0.2.2" } diff --git a/xflags-macros/Cargo.toml b/xflags-macros/Cargo.toml index cbe9c64..0945903 100644 --- a/xflags-macros/Cargo.toml +++ b/xflags-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xflags-macros" -version = "0.2.1" +version = "0.2.2" description = "Private implementation details of xflags." license = "MIT OR Apache-2.0" repository = "https://github.com/matklad/xflags" From 6f36cfe54a4014702506dab97c1357bfa0778945 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 6 Jun 2021 16:58:31 -0700 Subject: [PATCH 5/5] Take a stab in the dark about the CI failure --- xflags-macros/tests/it/help.rs | 2 +- xflags-macros/tests/it/src/help.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xflags-macros/tests/it/help.rs b/xflags-macros/tests/it/help.rs index 7f13785..36a9664 100644 --- a/xflags-macros/tests/it/help.rs +++ b/xflags-macros/tests/it/help.rs @@ -123,7 +123,7 @@ ARGS: [extra] Another arg. - This time, there's some extra info about the + This time, we provide some extra info about the arg. Maybe some caveats, or what kinds of values are accepted. diff --git a/xflags-macros/tests/it/src/help.rs b/xflags-macros/tests/it/src/help.rs index 399cb67..d552c1e 100644 --- a/xflags-macros/tests/it/src/help.rs +++ b/xflags-macros/tests/it/src/help.rs @@ -7,7 +7,7 @@ xflags! { optional src: PathBuf /// Another arg. /// - /// This time, there's some extra info about the + /// This time, we provide some extra info about the /// arg. Maybe some caveats, or what kinds of /// values are accepted. optional extra: String