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

Tracking Issue for cargo-script RFC 3424 #12207

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

Known Issues

  • You can't run cargo foo.rs -Zsomething, only cargo -Zsomething cargo.rs (true for any global flag in Cargo) because anything after the script name is assumed to be an argument to the script, like third-party subcommands.

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.

@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 Windows/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.

bors added a commit that referenced this issue Sep 26, 2024
feat: add CARGO_MANIFEST_PATH env variable

Adds `CARGO_MANIFEST_PATH` variable as part of #12207
Context: `CARGO_MANIFEST_DIR` is not very useful, because there is no `Cargo.toml` file when running a cargo script. In cases when multiple scripts are stored in the same folder, we can't tell which script exactly is being run using `CARGO_MANIFEST_DIR`
@Rustin170506
Copy link
Member

Rustin170506 commented Oct 31, 2024

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

I will give this one a try.

lgarron added a commit to lgarron/dotfiles that referenced this issue Nov 7, 2024
This avoids syntax errors until Rust supports the syntax in its tooling: rust-lang/cargo#12207 (comment)
lgarron added a commit to lgarron/dotfiles that referenced this issue Nov 7, 2024
This avoids syntax errors until Rust supports the syntax in its tooling: rust-lang/cargo#12207 (comment)
@Rustin170506
Copy link
Member

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

Not sure if this is the right place to discuss implementation details, but I wanted to ask if the output makes sense.

$pwd
/Users/rustin/code/rs-scripts

$ls
sql.rs  sql1.rs sql2.rs sql3.rs sql4.rs sql5.rs sql6.rs sql7.rs sql8.rs sql9.rs

$cargo pkgid sql2.rs
path+file:///Users/rustin/code/rs-scripts/sql2.rs#embedded

@epage
Copy link
Contributor

epage commented Nov 11, 2024

@Rustin170506 I feel like there might be enough discussion on that that maybe we should create a dedicated issue?

github-merge-queue bot pushed a commit that referenced this issue Nov 15, 2024
### What does this PR try to resolve?

We removed rejected syntax in #13861 haven't update frontmatter parsing
to what [RFC
3503](https://rust-lang.github.io/rfcs/3503-frontmatter.html#reference-level-explanation)
says.

This adds tests and fixes various cases to ensure we correctly detect
the frontmatter and the infostring.

This is part of #12207

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

### Additional information
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.