Hi, while experimenting, I've seen that this fails:
conan install -o boost:shared=True --build missing ..
whereas this succeeds:
conan install -o boost:shared=True .. --build missing
This is unexpected, as the documentation states the very opposite, saying that the path should be last, after all options if any:
usage: conan install [-h] [-g GENERATOR] [-if INSTALL_FOLDER] [-m [MANIFESTS]]
[-mi [MANIFESTS_INTERACTIVE]] [-v [VERIFY]]
[--no-imports] [-u] [-pr PROFILE] [-r REMOTE]
[-o OPTIONS] [-s SETTINGS] [-e ENV]
[-b [BUILD [BUILD ...]]]
path
I'm using conan 1.0.4 on Ubuntu 14.04.
That output is automatically generated by python-argparse. Try to use --build=missing with equal, so the parser knows better. Otherwise, just use the path always in first position, that is the conan suggested approach in all docs.
For completeness, the reason for this behavior is that the build command line argument is specified with nargs='*'. It therefore automatically absorbs all subsequent arguments including the path.
According to the example in the documentation, the intended use seems to be to specify -b or --build before every pattern similar to options and settings. If this interpretation is correct, the current behavior can also be considered a bug. On the first glance, using something like nargs='?' could be a solution.
On the first glance, using something like nargs='?' could be a solution.
@niosHD: I don't think so, because conan install -o boost:shared=True --build .. is allowed (--build without a value, so .. would be seen as the value). You have --build=never but yet someone thought that saving 7 keystrokes with --build instead of --build=always would be nice, at the price of consistency.
As a result, the command help is also ambiguous:
Default behavior: If you don't specify anything, it will be similar to --build=never, but package recipes can override it and decide to build with "build_policy"
What does "if you don't specify anything" means in that context? If you pass --build without a value? If you don't use a --build=xxxx option? Depending on how the user understands the sentence, the expected result is the _complete opposite_.
Another problem I see in the current implementation is that in the --build=pattern notation, pattern is in the same space as never, outdated and missing, which may lead to collisions. You can't have packages called never,missing or outdated, nor any other keyword possibly added in the future (like always). This would have been better served by a --build-only=pattern separate option (option name could certainly be improved, but you get the idea). Sure this won't happen frequently, but the point is that although you control the values of the --build option, _you don't control the way people want to name their applications_. Otherwise you'll see ugly hacks like `--build='missin?'
I'm pretty sure you won't consider it as it can seen as breaking the API just after 1.0, but IMHO, if possible:
--build alone should be deprecated--build=always would replace it--build=pattern should be deprecated--build-only=pattern would replace itFor what it's worth, git allows -- to signal end of options and beginning of mandatory arguments.
@liberforce I fully agree with your analysis of my suggestion and your broader view on the peculiarities of the --build argument. I also do not really like the fact that patterns and keywords are mixed. However, since we can not break the API anymore, I think we have to live with it for now.
Still, if accepting --build [<pattern> [<pattern> ...]] is considered a bug and even though it does not fix the standalone --build case, I think that switching to nargs='?' would be an improvement for users that always provide an argument to build. Anyway, I do not feel strongly about this and just wanted to suggest an (subjective) improvement.
Thanks all for the feedback.
Yes, that is right, I wish we had had the time before 1.0 to review this, so we could have fixed it, but right now we cannot break, I agree on @niosHD fixing about the nargs, this can be done
I'd suggest as best practice for pattern to use --build=pkgname*, what will avoid collisions with the identifiers, and will put explicitly that it is a pattern, and in fact, can match different packages names like pkgname1, pkgname_other, etc.
I'd suggest as best practice for pattern to use --build=pkgname*, what will avoid collisions with the identifiers
Not sure this is a best practice either, as trying to match packages with (for example) a short name may match other packages. Again, you have no control on what packages the user builds, so this will work for you but not necessarily if someone has (for example) the gtk library and an application that uses gtk and is called gtk-something, and that's a really common naming scheme.
Again, explicit is better than implicit, so when using patterns, one should use the pattern that matches exactly what it's meant to match, and not more.
For what it's worth, git allows -- to signal end of options and beginning of mandatory arguments.
While looking for a fix to this issue I found that using the separator -- for positional arguments as @liberforce said is allowed in argparse and works well with:
$ conan install -o boost:shared=True --build missing -- ..
The proposed solution by @niosHD and similiar do not work as --build can have an argument or not and in the case of writing --build ., the dot will be parsed as the optional argument of --build and not the path positional argument.
The best way to solve this would be to force --build to have always one argument, but we cannot brake the command line API.
I would see if I can make the help message show positional arguments should be on first place.
True, but as I already mentioned, switching to nargs='?' would still improve the current situation for people which do apply the argument. Given that we can make that change without breaking backward compatibility, I think it is a worthwhile improvement.
Anyway, thank you for working on this!