mirror of https://github.com/rust-lang/cargo
Tell subprocesses the path to self in an env variable #3778
This commit is contained in:
parent
ef8fa8fc1c
commit
015a08a0c4
|
@ -320,7 +320,12 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[String]) -> C
|
|||
.into())
|
||||
}
|
||||
};
|
||||
let err = match util::process(&command).args(&args[1..]).exec() {
|
||||
|
||||
let cargo_exe = config.cargo_exe()?;
|
||||
let err = match util::process(&command)
|
||||
.env(cargo::CARGO_ENV, cargo_exe)
|
||||
.args(&args[1..])
|
||||
.exec() {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(e) => e,
|
||||
};
|
||||
|
|
|
@ -41,6 +41,8 @@ use term::color::{BLACK};
|
|||
|
||||
pub use util::{CargoError, CargoResult, CliError, CliResult, human, Config, ChainError};
|
||||
|
||||
pub const CARGO_ENV: &'static str = "CARGO";
|
||||
|
||||
macro_rules! bail {
|
||||
($($fmt:tt)*) => (
|
||||
return Err(::util::human(&format_args!($($fmt)*)))
|
||||
|
|
|
@ -143,6 +143,9 @@ impl<'cfg> Compilation<'cfg> {
|
|||
|
||||
let metadata = pkg.manifest().metadata();
|
||||
|
||||
let cargo_exe = self.config.cargo_exe()?;
|
||||
cmd.env(::CARGO_ENV, cargo_exe);
|
||||
|
||||
cmd.env("CARGO_MANIFEST_DIR", pkg.root())
|
||||
.env("CARGO_PKG_VERSION_MAJOR", &pkg.version().major.to_string())
|
||||
.env("CARGO_PKG_VERSION_MINOR", &pkg.version().minor.to_string())
|
||||
|
|
|
@ -28,6 +28,7 @@ pub struct Config {
|
|||
rustc: LazyCell<Rustc>,
|
||||
values: LazyCell<HashMap<String, ConfigValue>>,
|
||||
cwd: PathBuf,
|
||||
cargo_exe: LazyCell<PathBuf>,
|
||||
rustdoc: LazyCell<PathBuf>,
|
||||
extra_verbose: Cell<bool>,
|
||||
frozen: Cell<bool>,
|
||||
|
@ -44,6 +45,7 @@ impl Config {
|
|||
rustc: LazyCell::new(),
|
||||
cwd: cwd,
|
||||
values: LazyCell::new(),
|
||||
cargo_exe: LazyCell::new(),
|
||||
rustdoc: LazyCell::new(),
|
||||
extra_verbose: Cell::new(false),
|
||||
frozen: Cell::new(false),
|
||||
|
@ -93,6 +95,15 @@ impl Config {
|
|||
self.rustc.get_or_try_init(|| Rustc::new(self.get_tool("rustc")?))
|
||||
}
|
||||
|
||||
pub fn cargo_exe(&self) -> CargoResult<&Path> {
|
||||
self.cargo_exe.get_or_try_init(||
|
||||
env::current_exe().and_then(|path| path.canonicalize())
|
||||
.chain_error(|| {
|
||||
human("couldn't get the path to cargo executable")
|
||||
})
|
||||
).map(AsRef::as_ref)
|
||||
}
|
||||
|
||||
pub fn values(&self) -> CargoResult<&HashMap<String, ConfigValue>> {
|
||||
self.values.get_or_try_init(|| self.load_values())
|
||||
}
|
||||
|
|
|
@ -30,8 +30,9 @@ configuration values, as described in [that documentation][config-env]
|
|||
|
||||
# Environment variables Cargo sets for crates
|
||||
|
||||
Cargo exposes these environment variables to your crate when it is compiled. To get the
|
||||
value of any of these variables in a Rust program, do this:
|
||||
Cargo exposes these environment variables to your crate when it is compiled.
|
||||
Note that this applies for test binaries as well.
|
||||
To get the value of any of these variables in a Rust program, do this:
|
||||
|
||||
```
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
|
@ -39,6 +40,7 @@ let version = env!("CARGO_PKG_VERSION");
|
|||
|
||||
`version` will now contain the value of `CARGO_PKG_VERSION`.
|
||||
|
||||
* `CARGO` - Path to the `cargo` binary performing the build.
|
||||
* `CARGO_MANIFEST_DIR` - The directory containing the manifest of your package.
|
||||
* `CARGO_PKG_VERSION` - The full version of your package.
|
||||
* `CARGO_PKG_VERSION_MAJOR` - The major version of your package.
|
||||
|
@ -96,3 +98,10 @@ let out_dir = env::var("OUT_DIR").unwrap();
|
|||
[links]: build-script.html#the-links-manifest-key
|
||||
[profile]: manifest.html#the-profile-sections
|
||||
[clang]:http://clang.llvm.org/docs/CrossCompilation.html#target-triple
|
||||
|
||||
# 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.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
extern crate cargo;
|
||||
extern crate cargotest;
|
||||
extern crate hamcrest;
|
||||
|
||||
|
@ -10,8 +11,8 @@ use std::str;
|
|||
|
||||
use cargotest::cargo_process;
|
||||
use cargotest::support::paths::{self, CargoPathExt};
|
||||
use cargotest::support::{execs, project, ProjectBuilder};
|
||||
use hamcrest::{assert_that};
|
||||
use cargotest::support::{execs, project, ProjectBuilder, basic_bin_manifest};
|
||||
use hamcrest::{assert_that, existing_file};
|
||||
|
||||
#[cfg_attr(windows,allow(dead_code))]
|
||||
enum FakeKind<'a> {
|
||||
|
@ -81,11 +82,11 @@ fn list_command_looks_at_path() {
|
|||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn list_command_resolves_symlinks() {
|
||||
use cargotest::support::cargo_dir;
|
||||
use cargotest::support::cargo_exe;
|
||||
|
||||
let proj = project("list-non-overlapping");
|
||||
let proj = fake_file(proj, Path::new("path-test"), "cargo-2",
|
||||
FakeKind::Symlink{target:&cargo_dir().join("cargo")});
|
||||
FakeKind::Symlink{target:&cargo_exe()});
|
||||
let mut pr = cargo_process();
|
||||
|
||||
let mut path = path();
|
||||
|
@ -161,6 +162,37 @@ fn override_cargo_home() {
|
|||
assert!(contents.contains(r#"authors = ["foo <bar>"]"#));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cargo_subcommand_env() {
|
||||
use cargotest::support::cargo_exe;
|
||||
|
||||
let src = format!(r#"
|
||||
use std::env;
|
||||
|
||||
fn main() {{
|
||||
println!("{{}}", env::var("{}").unwrap());
|
||||
}}
|
||||
"#, cargo::CARGO_ENV);
|
||||
|
||||
let p = project("cargo-envtest")
|
||||
.file("Cargo.toml", &basic_bin_manifest("cargo-envtest"))
|
||||
.file("src/main.rs", &src);
|
||||
|
||||
let target_dir = p.target_debug_dir();
|
||||
|
||||
assert_that(p.cargo_process("build"), execs().with_status(0));
|
||||
assert_that(&p.bin("cargo-envtest"), existing_file());
|
||||
|
||||
let mut pr = cargo_process();
|
||||
let cargo = cargo_exe().canonicalize().unwrap();
|
||||
let mut path = path();
|
||||
path.push(target_dir);
|
||||
let path = env::join_paths(path.iter()).unwrap();
|
||||
|
||||
assert_that(pr.arg("envtest").env("PATH", &path),
|
||||
execs().with_status(0).with_stdout(cargo.to_str().unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cargo_help() {
|
||||
assert_that(cargo_process(),
|
||||
|
|
|
@ -90,7 +90,7 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
|
|||
}
|
||||
|
||||
pub fn cargo_process() -> cargo::util::ProcessBuilder {
|
||||
process(&support::cargo_dir().join("cargo"))
|
||||
process(&support::cargo_exe())
|
||||
}
|
||||
|
||||
pub fn sleep_ms(ms: u64) {
|
||||
|
|
|
@ -165,7 +165,7 @@ impl ProjectBuilder {
|
|||
assert!(self.is_build.get(),
|
||||
"call `.build()` before calling `.cargo()`, \
|
||||
or use `.cargo_process()`");
|
||||
let mut p = self.process(&cargo_dir().join("cargo"));
|
||||
let mut p = self.process(&cargo_exe());
|
||||
p.arg(cmd);
|
||||
return p;
|
||||
}
|
||||
|
@ -317,6 +317,10 @@ pub fn cargo_dir() -> PathBuf {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn cargo_exe() -> PathBuf {
|
||||
cargo_dir().join(format!("cargo{}", env::consts::EXE_SUFFIX))
|
||||
}
|
||||
|
||||
/// Returns an absolute path in the filesystem that `path` points to. The
|
||||
/// returned path does not contain any symlinks in its hierarchy.
|
||||
/*
|
||||
|
|
|
@ -8,12 +8,12 @@ use std::io::prelude::*;
|
|||
use std::env;
|
||||
|
||||
use cargo::util::ProcessBuilder;
|
||||
use cargotest::support::{execs, paths, cargo_dir};
|
||||
use cargotest::support::{execs, paths, cargo_exe};
|
||||
use hamcrest::{assert_that, existing_file, existing_dir, is_not};
|
||||
use tempdir::TempDir;
|
||||
|
||||
fn cargo_process(s: &str) -> ProcessBuilder {
|
||||
let mut p = cargotest::process(&cargo_dir().join("cargo"));
|
||||
let mut p = cargotest::process(&cargo_exe());
|
||||
p.arg(s).cwd(&paths::root()).env("HOME", &paths::home());
|
||||
p
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::io::prelude::*;
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use cargotest::{cargo_process, process};
|
||||
use cargotest::support::{project, execs, paths, git, path2url, cargo_dir};
|
||||
use cargotest::support::{project, execs, paths, git, path2url, cargo_exe};
|
||||
use flate2::read::GzDecoder;
|
||||
use hamcrest::{assert_that, existing_file, contains};
|
||||
use tar::Archive;
|
||||
|
@ -481,7 +481,7 @@ fn repackage_on_source_change() {
|
|||
"#).unwrap();
|
||||
std::mem::drop(file);
|
||||
|
||||
let mut pro = process(&cargo_dir().join("cargo"));
|
||||
let mut pro = process(&cargo_exe());
|
||||
pro.arg("package").cwd(p.root());
|
||||
|
||||
// Check that cargo rebuilds the tarball
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::io::prelude::*;
|
|||
use std::str;
|
||||
|
||||
use cargotest::{sleep_ms, is_nightly};
|
||||
use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest};
|
||||
use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest, cargo_exe};
|
||||
use cargotest::support::paths::CargoPathExt;
|
||||
use cargotest::support::registry::Package;
|
||||
use hamcrest::{assert_that, existing_file, is_not};
|
||||
|
@ -2666,3 +2666,32 @@ fn doctest_and_registry() {
|
|||
assert_that(p.cargo_process("test").arg("--all").arg("-v"),
|
||||
execs().with_status(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cargo_test_env() {
|
||||
let src = format!(r#"
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[test]
|
||||
fn env_test() {{
|
||||
use std::env;
|
||||
println!("{{}}", env::var("{}").unwrap());
|
||||
}}
|
||||
"#, cargo::CARGO_ENV);
|
||||
|
||||
let p = project("env_test")
|
||||
.file("Cargo.toml", &basic_lib_manifest("env_test"))
|
||||
.file("src/lib.rs", &src);
|
||||
|
||||
let mut pr = p.cargo_process("test");
|
||||
let cargo = cargo_exe().canonicalize().unwrap();
|
||||
assert_that(pr.args(&["--lib", "--", "--nocapture"]),
|
||||
execs().with_status(0).with_stdout(format!("
|
||||
running 1 test
|
||||
{}
|
||||
test env_test ... ok
|
||||
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
|
||||
|
||||
", cargo.to_str().unwrap())));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue