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
21 of 33 tasks
ehuss opened this issue May 31, 2023 · 89 comments · Fixed by #12258
Open
21 of 33 tasks

Tracking Issue for cargo-script RFC 3424 #12207

ehuss opened this issue May 31, 2023 · 89 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.

@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

bogeholm added a commit to bogeholm/dotfiles that referenced this issue May 17, 2024
@Rustin170506
Copy link
Member

Hi @epage, as a daily user of cargo-script, I really want to help advance and stabilize this feature. (Thank you all for working on this feature.) What can I do to help? Is there anything you would suggest for me to get started?

@epage
Copy link
Contributor

epage commented Sep 18, 2024

@Rustin170506 any of the tasks in the task list without a PR is good for grabbing.

Some clarifications

Resolve symlinks in cargo ?

The use case for this is that we allow cargo Cargo.toml but putting a #! in Cargo.toml only works well if you symlink it into path with the name of the bin.

I had wondered if we should do just always resolve symlinks but that breaks some use cases. Instead, when determining whether its embedded or not and there is no extension, we should resolve it to see what the

Change config paths to only check CARGO_HOME

// 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");
gctx.reload_rooted_at(parent_path)?;

When we talked about this as a Cargo team, we decided this need to reload to cargo home, like cargo install does, to avoid downloading a script and being subject to spurious files in your ~/Downloads, at the cost of losing the config from your repo.

#14476

This might require an RFC but likely a trivial one

cargo pkgid support

This will be messy. We'll likely need to change SourceId to include the file name if it has an embedded manifest.

@Skgland
Copy link

Skgland commented Sep 18, 2024

One thing that occurred to me while just reading this is as you mention downloaded files :

Should cargo check for a Mark of the Web when running/building scripts on Wwindows/NTFS-drives?

@pirafrank
Copy link

One thing that occurred to me while just reading this is as you mention downloaded files :

Should cargo check for a Mark of the Web when running/building scripts on Wwindows/NTFS-drives?

I don't think so, but if it does, it should do it on macOS too, by checking additional file attributes.

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.