Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cargo Scripts with -Zscript should override current_exe #12870

Open
novafacing opened this issue Oct 23, 2023 · 6 comments
Open

Cargo Scripts with -Zscript should override current_exe #12870

novafacing opened this issue Oct 23, 2023 · 6 comments
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-triage Status: This issue is waiting on initial triage. Z-script Nightly: cargo script

Comments

@novafacing
Copy link

novafacing commented Oct 23, 2023

Problem

std::env::args and std::env::current_exe return potentially confusing results when running cargo scripts with the -Zscript unstable feature. While ostensibly correct, returning the actual built executable path is generally less useful to scripts than returning the path to the cargo script file, and leads to antipatterns like using current_dir().join(SCRIPT_NAME) to find the script file. Running the executable from the containing directory and having current_dir() not be a prefix of current_exe() adds another layer of complexity.

#!/usr/bin/env -S cargo +nightly -Z script

use std::env::{args, current_dir, current_exe};

fn main() {
    println!("args: {:?}", args());
    println!("current_dir: {}", current_dir().unwrap().display());
    println!("current_exe: {}", current_exe().unwrap().display());
}
/tmp/test $ ./test.rs
warning: `package.edition` is unspecified, defaulting to `2021`
   Compiling test- v0.0.0 (/tmp/test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.13s
     Running `/home/rhart/.cargo/target/8c/d68b704094916b/debug/test-`
args: Args { inner: ["/home/rhart/.cargo/target/8c/d68b704094916b/debug/test-"] }
current_dir: /tmp/test
current_exe: /home/rhart/.cargo/target/8c/d68b704094916b/debug/test-

Proposed Solution

It seems there are ~3 possible ways to go about this:

  • Leave it as is -- it is correct, despite being a little confusing compared to the typical bash "SCRIPT_DIR" one-liner.
  • Override the behavior of these functions somehow to return the path to the script. std::env::current_exe has a note that it may return the path of a symbolic link instead of a target of a symbolic link, or other platform specific behavior. Treating the script file as a symbolic link-equivalent whose path is returned instead of the actual executable using this escape hatch is the route I'd personally like best.
  • Provide a way of accessing the script environment separately from the executable environment.

Notes

Related to #3502 and #12207.

@novafacing novafacing added C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-triage Status: This issue is waiting on initial triage. labels Oct 23, 2023
@epage epage added the Z-script Nightly: cargo script label Oct 23, 2023
@epage
Copy link
Contributor

epage commented Oct 23, 2023

Override the behavior of these functions somehow to return the path to the script. std::env::current_exe has a note that it may return the path of a symbolic link instead of a target of a symbolic link, or other platform specific behavior. T

The main issue with this is I don't think there is a way to do it in a cross-platform way. For unix-like systems, we have CommandExt::arg0 but I don't think there is an equivalent for Windows.

@ChrisDenton
Copy link
Member

ChrisDenton commented Oct 23, 2023

For unix-like systems, we have CommandExt::arg0 but I don't think there is an equivalent for Windows.

There could be, there's just not std function for it atm. However, current_exe gets the "real" application path and doesn't use the arguments passed to the program.

@kellytk
Copy link
Contributor

kellytk commented Dec 1, 2023

Potentially related, remark by @epage.

@epage
Copy link
Contributor

epage commented Dec 1, 2023

We have CARGO_MANIFEST_DIR, I wonder if a way to resolve this would be to add CARGO_MANIFEST_PATH. It wouldn't be arg0 and it wouldn't be accessible if people directly run the binary but it would still make the original script accessible to the developer.

@novafacing
Copy link
Author

I like the idea, it really seems like if you're directly running the binary with Zscript you're doing it wrong, and the added simplicity of being able to env!("CARGO_MANIFEST_PATH") in the script would be pretty ergonomic.

@kellytk
Copy link
Contributor

kellytk commented Dec 31, 2023

sh: Relative shell script includes with realpath on FreeBSD, 2 are potentially related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-triage Status: This issue is waiting on initial triage. Z-script Nightly: cargo script
Projects
None yet
Development

No branches or pull requests

4 participants