These are chat archives for kbknapp/clap-rs

6th
Mar 2018
William Murphy
@willmurphyscode
Mar 06 2018 11:43
@kbknapp bumping version on term_size: kbknapp/clap-rs#1202 - it looks like the only 1.0 version of term size is a beta - wanted to be sure you're OK depending on a beta, or should upgrading term size wait?
Aleksey Kladov
@matklad
Mar 06 2018 11:47

Hi! I am experimenting with using clap for Cargo, and I have a question about trailing varags.

Certain cargo commands, have one non-repeat positional argument, as well as vararg. For example, cargo bench foo bar baz should parse foo as an argument named BENCH, and bar baz as a vararg argument named ARGS.

So far so good. Now, I want to add -- to the mix, to allow to separate the trailing vararg (but not the penultimate positional arg). So, I'd want to cargo bench foo -- bar bazhave BENCH=Some("foo") and ARGS=vec!["bar", "baz"] and cargo bench -- foo bar baz have BENCH=None and ARG=vec!["foo", "bar", "baz"]. The second variant does not seem to work for me: BENCH is assigned to Some("foo"), despite the fact that foo is after --. Does this make any sense? Is there a combination of clap options that I can use to get the behavior I want?

William Murphy
@willmurphyscode
Mar 06 2018 11:52
@matklad Good morning! I'm not sure I understand your question completely. It seems like you want -- to prevent the preceding arg from taking a value it can optionally take. Is that correct?
Aleksey Kladov
@matklad
Mar 06 2018 11:55
@willmurphyscode yep, I think this is correct! The situation is kinda hard to describe :)
I'll try to gist an example
@willmurphyscode hopefully this will explain the situation better: https://gist.github.com/matklad/0d148b1c76c576a0dc0e299962926c30
Kevin K.
@kbknapp
Mar 06 2018 12:00
@willmurphyscode Yeah I am. Term_size is one of my libs and 1.0 beta is the exact same as the one we've been using for a long time. Once we go to 3.0 release I'll bump term_size out of beta too
@matklad I'd actually make bench a subcommand
I have a meeting in a minute for an hour but when I get back I'll give a more comprehensive look and answer ;)
Aleksey Kladov
@matklad
Mar 06 2018 12:04
Kevin K.
@kbknapp
Mar 06 2018 12:05
Ah ok gotcha
Check that out too for "args"
It may help
I'll look again after my meeting :)
Aleksey Kladov
@matklad
Mar 06 2018 12:10
Hm, last looks interesting, but it doesn't quit do what I need :-) I want to be able to omit --, so that bench foo bar baz also works (and bar baz are treated as trailing arguments).
So, last gives me cargo bench [OPTIONS] [BENCHNAME] [-- <args>...], and I kinda want cargo bench [OPTIONS] [BENCHNAME] [--] [<args>...]
Kevin K.
@kbknapp
Mar 06 2018 12:22
I understand now, that was my mistake! So actually I don't see why there isn't any reason we can't remove the restriction that -- must be used with Arg::last
I think it was just an implementation detail at the time it was implemented
Denis Lisov
@tanriol
Mar 06 2018 12:24
Would this mean that in cargo bench my_bench --help the --help will not trigger help?
Kevin K.
@kbknapp
Mar 06 2018 12:24
But a safer thing to do would be to just add a method similar to last which didn't require the --
@tanriol I'd have to test it, but yes. Which is true of any of the allow_hyphen_values or TrailingVarArg style args anyways
that's part of the reason I prefer requiring -- when you're pass "external args" to some other program
because it's more clear that --help in this case ins't meant for your program
Aleksey Kladov
@matklad
Mar 06 2018 12:41

@kbknapp ok, I'll try to create an issue for this! I don't think I can fix it myself though: I've looked at get_matches_with and oh my god it is massive :- )

What would be the easierst workaround for the current clap? Have two .multiple(true) arguments, the last one of which is .last(true), manually prepend .skip(1) of the first arg to the second one, and override usage string manually?

Kevin K.
@kbknapp
Mar 06 2018 12:42
massive is an understatement :) This is a big reason for me wanting to get v3 out so badly so I can trim it down...which the current implementation doesn't allow/make easy
I'm actually adding something right now to fill this gap
([BENCH] [--] [ARGS]...)
My meeting was postponed a little bit :P
(not because of this issue!)
Aleksey Kladov
@matklad
Mar 06 2018 12:44
Ah, great, so I don't need to write up a github issue then? :)
Kevin K.
@kbknapp
Mar 06 2018 12:45
nope
Aleksey Kladov
@matklad
Mar 06 2018 12:46

Cool! Thanks! :heart:

FWIW, it's the third time I am trying to do something with the mess which Cargo command line parsing is, and it is the first time I feel I am actually getting somewhere :)

Kevin K.
@kbknapp
Mar 06 2018 12:46
:heart:
Aleksey Kladov
@matklad
Mar 06 2018 12:53
Oh, and one more question: will v3 be significantly backwards incompatible with v2? I know that something like clap-derive will be added, which is cool, but would it be possible to use the old stringly-typed API?
Kevin K.
@kbknapp
Mar 06 2018 12:54
Yes it will. My goal is to make upgrading from v2 to v3 pretty painless
Aleksey Kladov
@matklad
Mar 06 2018 12:55
Super!
Kevin K.
@kbknapp
Mar 06 2018 12:55
Although we've moving off the stringly typed nature, I'm planning on using a way that still allows the old stringly typed version to work
In fact, I'm specifically not including a few changes because it'd make upgrading much harder
Aleksey Kladov
@matklad
Mar 06 2018 12:58

I'm asking because in Cargo we have this super-weird pattern, when certain group of options is repeated in several sub commands, but not quite exactly repeated:

https://github.com/rust-lang/cargo/blob/master/src/bin/bench.rs#L53-L62
https://github.com/rust-lang/cargo/blob/master/src/bin/test.rs#L55-L65

(help messages are different)

I think I know how to deal with this repetition with stringly-typed API without copy-paste, and I didn't manage to invent a deriving solution for this which is not massively complicated.

Kevin K.
@kbknapp
Mar 06 2018 14:01
@matklad fixed this - putting in the PR now
it'll go out as 2.31.1
Aleksey Kladov
@matklad
Mar 06 2018 14:02
Aweeeeeeeeeeeesome!!! Thanks!
Kevin K.
@kbknapp
Mar 06 2018 14:03
It'll require using the setting AllowMissingPositional which allows using -- to "skip to the last positional argument" but doesn't require -- be used if all arguments are specified anyways (unlike Arg::last)
Lars Hupel
@larsrh
Mar 06 2018 20:35
Can I set a conflict from a subcommand flag to a global flag?
I have a global flag --force
in the subcommand I have a --diff flag that conflicts with --force
so in the YAML config, I specified conflicts_with: force
but I don't get any conflict errors when I pass both
Kevin K.
@kbknapp
Mar 06 2018 20:38
It could be a bug, let me test it real quick
It's giving me a conflict error
Lars Hupel
@larsrh
Mar 06 2018 20:41
Can I paste my YAML spec for you to reproduce?
Kevin K.
@kbknapp
Mar 06 2018 20:41
extern crate clap;
use clap::{Arg, App, SubCommand};

fn main(){
    let _ = App::new("fake")
        .arg(Arg::with_name("glob")
            .short("g")
            .global(true))
        .subcommand(SubCommand::with_name("foo")
            .arg(Arg::with_name("conf")
                .short("c")
                .conflicts_with("glob")))
        .get_matches_from(vec!["fake", "foo", "-g", "-c"]);
}
gives:
error: The argument '-g' cannot be used with '-c'

USAGE:
    fake foo -c -g

For more information try --help
I did notice the usage is a bug though, it shouldn't be suggesting both when conflict with each other :P
Yes, you can paste your YAML, I'll take a look :)
Executing my_binary -f check -d
Kevin K.
@kbknapp
Mar 06 2018 20:45
It looks like force isn't declared as global
Lars Hupel
@larsrh
Mar 06 2018 20:45
aaah, there's the difference
let me try
yes!
Kevin K.
@kbknapp
Mar 06 2018 20:46
but also, it won't detect conflicts across subcommand bounds (arg subcommand arg2)
Lars Hupel
@larsrh
Mar 06 2018 20:46
Thank you :100:
ah, that's unfortunate
by accident I ran check -f -d and that failed as expected
but -f check -d succeeds
Kevin K.
@kbknapp
Mar 06 2018 20:47
It's by design though
Lars Hupel
@larsrh
Mar 06 2018 20:47
Hmm, why is that?
Kevin K.
@kbknapp
Mar 06 2018 20:55
Primarily because subcommands were designed to like separate namespaces to prevent conflicts, and because when specifying things like this it's easy to get into a unintentional conflict
which most of the time is what you want
but when you want a global conflict it means you have to manually check the top level
There's a case to be made that this is a bug though
because if the global took a value, and that value was propagated down, it should create a conflict, but doesn't due to how it's implemented
I can see arguments both wayas
The more I stare at the screen, I'll call this a bug
Would you mind filing a bug report? I should be able to knock it out relatively quick
Lars Hupel
@larsrh
Mar 06 2018 21:18
Will do, thanks
Lars Hupel
@larsrh
Mar 06 2018 21:25
#1204
Kevin K.
@kbknapp
Mar 06 2018 21:30
Thanks! :+1: