Open ChrisDenton opened 3 years ago
Does one as an user implicitly expect to CARGO_MANIFEST_DIR being set when running any cargo command whether it is sub-command or not?
I did :)
While the documentation doesn't explicitly rule out other environment variables,
It does define only one variable gets passed down quite clearly:
Environment variables Cargo sets for 3rd party subcommands
Cargo exposes this environment variable to 3rd party subcommands (ie. programs named cargo-foobar placed in $PATH):
CARGO β Path to the cargo binary performing the build.
And this seems to be the truth I found the hard way :)
I would like as an user to see the environment variables like CARGO_MANIFEST_DIR passed/available as current working directory may not be optimal so I can run sub-commands same way I run my test.
I wonder what was the reasoning for these environment variables not being passed explicitly down in more numbers or was it due to accidental security through obscurity pattern to hide path(s) for good and bad whilst fearing some other information e.g. secrets could leak out to sub-command?
httmock relies on CARGO_MANIFEST_DIR when I gave relative path with some of my mocks
It works fine with cargo test but when I ran it thru sub-command tarpaulin it didn't find the env
Perhaps the document should be more explicit about warning this seemingly unexpected implicit behavior and document the reason why?
I would like as an user to see the environment variables like CARGO_MANIFEST_DIR passed/available as current working directory may not be optimal so I can run sub-commands same way I run my test.
I wonder what was the reasoning for these environment variables not being passed explicitly down in more numbers or was it due to accidental security through obscurity pattern to hide path(s) for good and bad whilst fearing some other information e.g. secrets could leak out to sub-command?
For CARGO_MANIFEST_DIR
, I'm assuming cargo doesn't know it. Subcommands, not cargo, accept --manifest-path
for an explicit manifest to then determine the manifest dir. They then infer the manifest-path if it isn't set.
I know a lot of us use cargo_metadata for querying cargo for manifest information in our custom subcommands. I've written clap_cargo::Manifest
to help with handling the optional parameter and bridging things with cargo_metadata
.
I'm assuming cargo looking up CARGO_MANIFEST_DIR
would add a performance hit to a lot of commands because that and other env variables will likely be insufficient and will need to call cargo_metadata
anyways.
Tbh I wrote the OP early(ish) on in my Rust career when I was trying to extend Cargo with a custom command. Nowadays I'd probably write something that better details the use case I was aiming for π.
Now I'm more experienced I can understand why this may not be the default. Still, I do think it's worth while to have some way to figure out how Cargo collects and collates all the configuration options (e.g. from the environment, from the current directory, from CARGO_HOME
, from the command line, etc),
I remember I did write a patch to output this info (via a metadata
like command mentioned in the OP) but unfortunately I didn't really have the bandwidth to pursue it further at the time so I've no idea how robust it was.
Describe the problem you are trying to solve
Cargo gives a veritable wealth of information to build scripts. In contrast, subcommands get a single variable:
CARGO
. This gives the path of the cargo binary. Useful but not much to go on.This means if subcommands (or other third party tools) want any information they have to either reimplement parts of cargo or try to scrounge what little information they can from build-plan (unstable, unreliable) or metadata (limited).
For example, something as simple getting the default target (usually the host) or the output directory.
Describe the solution you'd like
I can think of two solutions. Implementing one does not exclude implementing the other.
When starting a subcommand, set the same (or similar) environment variables to build scripts so it's almost as if the command is a build script in the root package. Obviously the variables passed to build scripts can depend on arguments passed in on the command line or perhaps even the command itself, so these values should instead be set to reasonable defaults. This would at least give subcommands a baseline to work from.
Have a built in
query-build
command (actual name to be decided). The user of this command can pass in arguments in the same manner as how they are passed tocargo build
. This would effectively do a dry run of setting up the environment for a build script but instead of invoking one, it only collects the environment variables into json. This information is then printed.The second option would be good for any tools trying to integrate with Cargo, not just subcommands. A simplified version of it would be to just have a command that spits out some limited set of defaults. E.g., default target, output directory, rustc path, etc.
Notes
I'm not sure how easy or hard either of these is to implement. Looking at the code I'm not entirely certain where to begin.