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

Tracking Issue for cargo-script RFC 3424 #12207

Open
19 of 31 tasks
ehuss opened this issue May 31, 2023 · 85 comments · Fixed by #12258
Open
19 of 31 tasks

Tracking Issue for cargo-script RFC 3424 #12207

ehuss opened this issue May 31, 2023 · 85 comments · Fixed by #12258
Labels
C-tracking-issue Category: A tracking issue for something unstable. S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review S-waiting-on-feedback Status: An implemented feature is waiting on community feedback for bugs or design concerns. Z-script Nightly: cargo script

Comments

@ehuss
Copy link
Contributor

ehuss commented May 31, 2023

Summary

eRFC: #3424
RFC: rust-lang/rfcs#3502, rust-lang/rfcs#3503

Testing steps

Implementation:

Deferred / non-blocking:

Documentation: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#script

Issues: Z-script Nightly: cargo script

More design updates and exploration can be found at: https://github.com/epage/cargo-script-mvs/blob/main/0000-cargo-script.md

This is an experimental feature to add unstable support for single-file packages in cargo so we can explore the design and resolve questions with an implementation to collect feedback on.

Note: third-party support

Unresolved Issues

  • Should the manifest fields use an allowlist or a denylist (current)?
  • Should escaping rules match package validation or cargo-new validation (current)?

See also the Pre-RFC for more discussion

Future Extensions

No response

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

@ehuss ehuss added S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review C-tracking-issue Category: A tracking issue for something unstable. Z-script Nightly: cargo script labels May 31, 2023
@ChrisJefferson

This comment was marked as resolved.

@epage

This comment was marked as resolved.

bors added a commit that referenced this issue Jun 12, 2023
feat: Initial support for single-file packages

### What does this PR try to resolve?

This is the first step towards #12207.  In particular, this focuses on pulling in the [demo](https://github.com/epage/cargo-script-mvs) roughly as-is to serve as a baseline for further PRs.  I have a couple months of runtime (multiple times a week) using the version of the demo included here.

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

Commit-by-commit.  Most likely, the last (docs) commit should be done first to provide context for the others.

Naming is hard.  I came up with these terms just so we can have ways to refer to them.  Feedback is welcome.
- `-Zscript`  for this general feature (not great but didn't want to spend too long coming up with a throwaway name)
- "single-file package": Rust code and a cargo manifest in a single file
- "embedded manifest": the explicit manifest inside of a single-file package
- "manifest command": when we interpret `cargo <name>` as referring to a single-file package, and similar to "built-in commands" and "external commands".

Keep in mind that this is a very hacky solution with many deficiencies and is mostly starting as a baseline for implementing and reviewing those improvements, including
- Switching from `regex` to `syn` for extracting manifests for greater resilience
- Matching `cargo new`s logic when sanitizing the inferred package name
- Allowing `cargo <name>` to also be a `Cargo.toml` file (for consistency in where manifests are accepted)
- Allowing single-file packages to be used wherever a manifest is accepted

To minimize conflict pain, I would ask that we consider what feedback can be handled in a follow up (though still mention it!).  It'll be much easier creating multiple, independent PRs once this baseline is merged to address concerns.

### Additional information

The only affect for people on stable is that they may get a warning if they have an external subcommand that will be shadowed when this feature is implemented.  This will allow us to collect feedback, without blocking people, so we can have an idea of how "safe" our precedence scheme is for interpreting `cargo <name>`.

As of right now, aliases with a `.` in them will be ignored (well, technically their suffix will be exposed as an alias).    We directly inject the name into a lookup string into the config  that uses `.` as the separator, so we drill down until we get to the leaf element.  Ideally, we would be generating / parsing the lookup key using TOML key syntax so we can better report that this won't be supported after this change :)
@XOR-op

This comment was marked as resolved.

@epage

This comment was marked as resolved.

bors added a commit that referenced this issue Jun 17, 2023
fix(embedded): Align package name sanitization with cargo-new

### What does this PR try to resolve?

This is a follow up to #12245 which is working to resolve the tracking issue #12207

This first aligns sanitization of package names with the central package name validation logic, putting the code next to each other so they can more easily stay in sync.

Oddly enough, cargo-new is stricter than our normal package-name validation.  I went ahead and sanitized along with that as well.

In working on this, I was bothered by
- the mix of `-` and `_` in file names because of sanitization, so I made it more consistent by detecting which the user is using
- -using `_` in bins, so I switched the default to `-`

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

One existing test covers a variety of sanitization needs

Another existing test hit one of the other cases (`test` being reserved)

### Additional information

For implementation convenience, I changed the directory we write the manifest to.  The impact of this should be minimal since
- We reuse the full file name, so if it worked for the user it should work for us
- We should be moving away from the temp manifest in future commits
bors added a commit that referenced this issue Jun 17, 2023
refactor(embedded): Switch to `syn` for parsing doc comments

This is a follow up to #12245 which is working to resolve #12207

The hope is this will result in more resilient comment handling, being more consistent with rustdoc.

I also hoped for less code but `syn` is doing less than I had expected, requiring us to copy code over from other parts of rust.  It seems every proc macro has to do this but there is no guide to it, so they all do it differently, only covering the cases they thought to test for.

Note that this still won't support `include_str!()`.
@bors bors closed this as completed in a581ca2 Jun 17, 2023
@bjorn3

This comment was marked as resolved.

@weihanglo weihanglo reopened this Jun 17, 2023
@epage

This comment was marked as resolved.

bors added a commit that referenced this issue Jun 17, 2023
fix(embeded): Don't pollute the scripts dir with `target/`

### What does this PR try to resolve?

This PR is part of #12207.

This specific behavior was broken in #12268 when we stopped using an intermediate
`Cargo.toml` file.

Unlike pre-#12268,
- We are hashing the path, rather than the content, with the assumption
  that people change content more frequently than the path
- We are using a simpler hash than `blake3` in the hopes that we can get
  away with it

Unlike the Pre-RFC demo
- We are not forcing a single target dir for all scripts in the hopes
  that we get #5931

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

A new test was added specifically to show the target dir behavior, rather than overloading an existing test or making all tests sensitive to changes in this behavior.

### Additional information

In the future, we might want to resolve symlinks before we get to this point
@est31

This comment was marked as resolved.

@epage

This comment was marked as resolved.

@est31

This comment was marked as resolved.

@programmerjake

This comment was marked as resolved.

@azzamsa
Copy link

azzamsa commented Feb 21, 2024

Worked like like a charm. Thank you!

@heaths
Copy link

heaths commented Feb 27, 2024

I've written a couple rust scripts now in cases where I need more consistent, programmatic control than a (more often easier) shell script could provide in a few cases e.g., parsing TOML without acquisition of additional tools.

In those cases, however, it's incredibly useful to write the source in an editor e.g., VSCode + rust-analyzer to have the benefits of an LSP, linting etc. To that end, neither front matter supported now allow for that because of syntax errors:

```cargo
[package]
edition = "2021"
```

Or:

---
[package]
edition = "2021"
---

Unless the eventual idea is that all tools including rustc, rust-analyzer, etc., support - even just ignore - this front matter section, writing scripts in an editor is impossible. At leat you have to comment it out and, if you have dependencies, need a Cargo.toml. From the current tracking items, it seems solving the latter is on the radar, but it'd be great to consider solving the former. As of now, it seems the idea is to not support commands, depending on what "Remove doc-comment support" means exactly.

Given the use of code fences in the first case above (though it seems the second case is the way forward, yes?), couldn't cargo support triple slashes e.g.,

#!/usr/bin/env -S cargo +nightly -Zscript
/// ```cargo
/// [package]
/// edition = "2021"
/// ```

fn main() {
    todo!()
}

At least until dependency resolution is sorted, this would support opening scripts in an editor using an LSP.

@epage
Copy link
Contributor

epage commented Feb 27, 2024

The plan is to add the syntax to the Rust language. An RFC exists for this. Once one more T-lang team member checks a box, FCP will start.

bors added a commit that referenced this issue Mar 1, 2024
feat(toml): Warn on unset Edition

### What does this PR try to resolve?

On [Internals](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309), the idea came up for warning on unset Edition.

Besides helping people who forget to set the Edition, this creates symmetry between `Cargo.toml` and cargo scripts (#12207).  While the default is different in each case, we are making the default obvious and guiding people away from it.

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

There are separate commits for adding tests (and refactors) so the changes in behavior will be more obvious

### Additional information

This builds on
- #13499
- #13504
@jcbhmr
Copy link

jcbhmr commented Mar 8, 2024

is there a way to use features or other cfg stuff when using cargo +nightly -Zscript ./hello_world.rs? like if I have this:

#!/usr/bin/env -S cargo +nightly -Zscript
```cargo
[features]
hi = []
```
fn main() {
  #[cfg(feature = "hi")]
  println!("hi");
  println!("hello world");
}

how would I run it with the --features=hi flag?

jcbhmr@PIG2016:~/Documents/test343$ ./hello_world.rs --features=hi
warning: `package.edition` is unspecified, defaulting to `2021`
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
     Running `/home/jcbhmr/.cargo/target/aa/3b09aa9f783bc3/debug/hello_world --features=hi`
hello world
jcbhmr@PIG2016:~/Documents/test343$ cargo +nightly -Zscript --features=hi ./hello_world.rs
error: unexpected argument '--features' found

Usage: cargo [+toolchain] [OPTIONS] [COMMAND]
       cargo [+toolchain] [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]...

For more information, try '--help'.

☝️ particularly the cargo +nightly -Zscript --features=hi ./hello_world.rs one; that one i really hoped would work

i looked at the env var list https://doc.rust-lang.org/cargo/reference/environment-variables.html and couldn't find a Ctrl+F match for "feature" that would let me do like CARGO_FEATURES=hi ./hello_world.rs either 🤷‍♀️

if there is a way, how would I use it in the shebang? like

#!/usr/bin/env -S cargo +nightly -Zscript --features=hi
```cargo
[features]
hi = []
```
fn main() {
  #[cfg(feature = "hi")]
  println!("hi");
  println!("hello world");
}

EDIT UPDATE

I found a way! ...but it doesn't seem to work with #! shebang. 😢

cargo +nightly -Zscript run --features=hi --manifest-path ./hello_world.rs #
cargo +nightly -Zscript run --features=hi --manifest-path ./hello_world.rs pos1 --flag1 #
cargo +nightly -Zscript run --features=hi --manifest-path ./hello_world.rs -- pos1 --flag1 #
./hello_world.rs #
./hello_world.rs pos1 --flag1 #
./hello_world.rs -- pos1 --flag1 #

you need something like this which i haven't found a way to do yet:

#!/usr/bin/env -S cargo +nightly -Zscript run --features=hi --manifest-path $THE_FILE --
```cargo
[features]
hi = []
```
fn main() {
  #[cfg(feature = "hi")]
  println!("hi");
  println!("hello world");
}
./hello_world.rs pos1 --flag1 # the dream lol

@epage
Copy link
Contributor

epage commented Mar 9, 2024

Yes, cargo scripts are meant to work with any cargo command, so cargo run works.

What is your use case for wanting this on the shebang? My assumption is if you want it when you run it should be a default feature and likely if you use features, you're use case is likely big enough for a multi-file package.

@beckend
Copy link

beckend commented Apr 4, 2024

How would one maintain the dependencies?
How would you import a module from foo.rs?

@epage
Copy link
Contributor

epage commented Apr 4, 2024

Could you clarify what you mean by "maintain dependencies"? In general, we expect tooling to manage embedded manifests like regular ones.

As for importing a foo.rs, that is broken right now when dependencies are used due to a hack we use to get dependencies working. You would mod foo; just like from a main.rs. However, that would be discouraged as the point of these is to be single file. If you need to mod something, why not have a full package?

@beckend
Copy link

beckend commented Apr 4, 2024

"maintain dependencies"
Can I do:

once_cell = { workspace = true, default-features = false }

Can I use cargo update?

I would disagree on the limitation of not having the ability to use a module, to be able to externalize some code and import that module makes it much cleaner. I mean why is is necessary to impose this limitation, if there are difficulties implementing this, okay fine, but it's not necessary.

@epage
Copy link
Contributor

epage commented Apr 4, 2024

cargo update should already work.

workspace = true does not work yet because workspace support is out of scope for the initial release.

cargo add will be supported on release. Support is waiting on the syntax RFC being approved.

As for mod, I did not say it wouldn't be supported. I said it would be discouraged. Its still not clear why you'd use an embedded manifest over Cargo.toml if you are using external files. A large point of these is to be single file for easy sharing and there are features we are explicitly not supporting, like build.rs.

@dmyTRUEk
Copy link

dmyTRUEk commented Apr 4, 2024

I see almost no discussion around release/optimized mode (except "This is under discussion in the RFC" (above) and merged commit adding "option to generate release mode profile") which I find pretty important, so I want to express my view on this subject:

While manually setting all parameters in the [profile.dev] section to be the same as in release mode or just using the "option to generate release mode profile" kinda does that, I don't think this is an optimal solution.

Adding --release and -r flags looks to me like a much more solid solution to the problem. Or perhaps maybe even add support for arbitrary profiles (using --profile), same as for the usual cargo run, for maximum flexibility.

This allows users to iterate much faster when developing or experimenting with a script, while not compromising performance when the script is done, and all of this is just by simply adding or removing the --release flag to the shebang, unlike the current solution, where you have to manually edit all of the desired flags in "Cargo.toml part" of the script.

@epage
Copy link
Contributor

epage commented Apr 4, 2024

Rather than dividing the conversation, I'd recommend focusing it at rust-lang/rfcs#3502 (comment)

@surban
Copy link

surban commented May 2, 2024

How is this supposed to work on Windows?

Will rustup extend PATHEXT upon installation and associate .rs files with cargo?

In this case all Rust source files would become executable, which is confusing, especially when using Windows Explorer.

I think it might be better to use a separate extension, for example .rsc for Rust SCript, to ensure that the experience on Windows will not lack behind.

@bjorn3
Copy link
Member

bjorn3 commented May 2, 2024

How does python handle this on Windows? They don't use a separate extension for executable and non-executable files either.

@surban
Copy link

surban commented May 2, 2024

How does python handle this on Windows? They don't use a separate extension for executable and non-executable files either.

True, but it doesn't mean we have to follow them if we can do better.

@Rudxain
Copy link

Rudxain commented May 2, 2024

How does python handle this[...]?

All *.py files are executable, scripts and modules alike. So I would be hesitant to suggest taking inspiration from Py, but I'm unsure if there's a better alternative than simply using a different file-ext.

MS should definitely add shebang (and magic-numbers) support to Windows! It's overdue since many years ago

@epage
Copy link
Contributor

epage commented May 2, 2024

This might be a better conversation on the relevant section in the RFC: https://github.com/epage/rfcs/blob/script/text/3502-cargo-script.md#file-association-on-windows

@surban
Copy link

surban commented May 2, 2024

This might be a better conversation on the relevant section in the RFC: https://github.com/epage/rfcs/blob/script/text/3502-cargo-script.md#file-association-on-windows

I sent you a PR.

@surban
Copy link

surban commented May 2, 2024

MS should definitely add shebang (and magic-numbers) support to Windows! It's overdue since many years ago

They won't do that because it does not make sense on Windows, since the interpreter can be in an installation-dependent place and is not necessarily found in PATH. The Windows mechanism is not inherently bad, just different from UNIX.

@programmerjake
Copy link
Member

MS should definitely add shebang (and magic-numbers) support to Windows! It's overdue since many years ago

They won't do that because it does not make sense on Windows, since the interpreter can be in an installation-dependent place and is not necessarily found in PATH. The Windows mechanism is not inherently bad, just different from UNIX.

well, magic number support can look for a file starting with #!/usr/bin/env cargo and send that to wherever cargo is installed, no shebang support needed

@istudyatuni
Copy link

Please stop, many people watching for progress, not for discussion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: A tracking issue for something unstable. S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review S-waiting-on-feedback Status: An implemented feature is waiting on community feedback for bugs or design concerns. Z-script Nightly: cargo script
Projects
Status: In Progress
Development

Successfully merging a pull request may close this issue.