New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically split the fist argument to cmd!
macro?
#58
Comments
Agreed that it's convenient in the common case, but I think the downsides are a little too big. The first one is that I'd be worried about confusing people with a command like this: cmd!("git commit --author", my_author, "--message=foo --no-verify") In that case, it appears that The second downside is that I'd worry about encouraging people to build commands with string concatenation. It's not as bad as passing commands to a shell, but it's still potentially problematic if you think you're letting the caller set the value of some flag, but in fact they can supply arbitrary extra flags. That said, if you want to write shell commands without separately quoting things, there is an add-on crate that exposes a couple functions to make that easy. Is there any chance that this helps with some of your use cases? https://github.com/oconnor663/duct.rs/tree/master/duct_sh That one used to be part of duct itself, but I got too freaked out by it :) |
Yeah, agree that the exact proposed API has pretty dangerous foot-guns. However, at the same time I do feel that "construct a complex command line invocation from a static string, and then append custom arguments at the end" is an overwhelmingly common case... I wonder if we can invent some safe API with a nice syntax? The syntax of A strawman proposal: /// A convenience function to parse a string with command name and arguments
/// into an `Expression`
///
/// Example:
/// ```rust
/// let e = parse_cmd("git symbolic-ref --short").arg(commit_hash)
/// ```
fn parse_cmd(cmd: &'static str) -> Expression {
let mut tokens = cmd.split_whitespace(); // TODO: error if quotes are present, or implement proper tokenization
let prog_name = tokens.next().expect("Bad cmd: {:?}", cmd);
cmd(prog_name, tokens)
}
|
The "TODO: error if quotes are present" is another one of the details that makes me shy away from this. I totally agree with the TODO. It would be pretty confusing if people thought quotes were getting interpreted, but actually they were passing through as literals. Failing on that case is probably better. But that opens up a can of worms:
If there's a spectrum from "zero magic" to "100% magic", I kind of lean towards sitting at one of the ends. Being 80% magic tends to make things more complicated over time. |
Seems reasonable! I definitely don't want to argue either way here, because I don't have strong feelings, but, if the aim is to be as easy as bash, some amount of magic wouldn't hurt. I've also seen https://github.com/ipetkov/conch-parser, which sounds like it could help with accurately dealing with parsing issues? |
I've kind of imagined duct being as capable as bash, but with fewer footguns. I think shell programming suffers a lot from not handling corner cases correctly, and the correctness aspect matters a lot to me. That said, I'm actually thinking about removing some of the capabilities, the |
I guess it is fine to close the issue then! Thanks for an interesting discussion! |
Hi!
A common usability issue with constructing a command line is that each argument must be a separate string literal:
I think a nice qol improvement would be to automatically split the first argument of
cmd!
on whitespace, so the same could be written more compactly asNote that this allows one to supply additional arguments just fine:
Does this look like a useful feature to have?
The text was updated successfully, but these errors were encountered: