Skip to content

Commit

Permalink
Auto merge of #12303 - epage:config, r=joshtriplett
Browse files Browse the repository at this point in the history
fix(script): Process config relative to script, not CWD

### What does this PR try to resolve?

This is part of the work for #12207.

When you put in your path `foo.rs`:
```rust
#!/usr/bin/env cargo

fn main() {}
```

You expect it to build once and then repeatedly run the same version.  However, `.cargo/config.toml` doesn't work like that (normally).  It is an environment file, like `.env`, and is based on your current working directory.  So if you run `foo.rs` from within a random project, it might rebuild due to RUSTFLAGS in `.cargo/config.toml`.

I had some concern about whether this current behavior is right or not and [noted this in the Pre-RFC](/~https://github.com/epage/cargo-script-mvs/blob/main/0000-cargo-script.md#unresolved-questions).  This came up again while we were [discussing editions on zulip](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/cargo.20script.20and.20edition).  In looking further into this, it turns out we already have precedence for this with `cargo install --path <path>`.

### How should we test and review this PR?

The second commit has the fix, the docs, and a change to a test (from the first commit) to show that the fix actually changed behavior.
  • Loading branch information
bors committed Jun 22, 2023
2 parents 5e842cc + 78334e8 commit 2035d0d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/bin/cargo/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,21 @@ pub fn is_manifest_command(arg: &str) -> bool {
|| path.file_name() == Some(OsStr::new("Cargo.toml"))
}

pub fn exec_manifest_command(config: &Config, cmd: &str, args: &[OsString]) -> CliResult {
pub fn exec_manifest_command(config: &mut Config, cmd: &str, args: &[OsString]) -> CliResult {
if !config.cli_unstable().script {
return Err(anyhow::anyhow!("running `{cmd}` requires `-Zscript`").into());
}

let manifest_path = Path::new(cmd);
let manifest_path = root_manifest(Some(manifest_path), config)?;

// Treat `cargo foo.rs` like `cargo install --path foo` and re-evaluate the config based on the
// location where the script resides, rather than the environment from where it's being run.
let parent_path = manifest_path
.parent()
.expect("a file should always have a parent");
config.reload_rooted_at(parent_path)?;

let mut ws = Workspace::new(&manifest_path, config)?;
if config.cli_unstable().avoid_dev_deps {
ws.set_require_optional_deps(false);
Expand Down
3 changes: 3 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,9 @@ A parameter is identified as a manifest-command if it has one of:
- A `.rs` extension
- The file name is `Cargo.toml`

Differences between `cargo run --manifest-path <path>` and `cargo <path>`
- `cargo <path>` runs with the config for `<path>` and not the current dir, more like `cargo install --path <path>`

### `[lints]`

* Tracking Issue: [#12115](/~https://github.com/rust-lang/cargo/issues/12115)
Expand Down
41 changes: 41 additions & 0 deletions tests/testsuite/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,47 @@ fn main() {
.run();
}

#[cargo_test]
fn use_script_config() {
let script = ECHO_SCRIPT;
let _ = cargo_test_support::project()
.at("script")
.file("script.rs", script)
.build();

let p = cargo_test_support::project()
.file(
".cargo/config",
r#"
[build]
rustc = "non-existent-rustc"
"#,
)
.file("script.rs", script)
.build();

// Verify the config is bad
p.cargo("-Zscript script.rs -NotAnArg")
.masquerade_as_nightly_cargo(&["script"])
.with_status(101)
.with_stderr_contains(
"\
[ERROR] could not execute process `non-existent-rustc -vV` (never executed)
",
)
.run();

// Verify that the config isn't used
p.cargo("-Zscript ../script/script.rs -NotAnArg")
.masquerade_as_nightly_cargo(&["script"])
.with_stdout(
r#"bin: [..]/debug/script[EXE]
args: ["-NotAnArg"]
"#,
)
.run();
}

#[cargo_test]
fn test_line_numbering_preserved() {
let script = r#"#!/usr/bin/env cargo
Expand Down

0 comments on commit 2035d0d

Please sign in to comment.