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

eRFC: single-file packages ("cargo script") integration #3424

Merged
merged 13 commits into from
May 31, 2023
35 changes: 11 additions & 24 deletions text/3424-cargo-script.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,44 +137,26 @@ To depend on a library hosted on [crates.io], you modify `hello_world.rs`:

//! ```cargo
//! [dependencies]
//! time = "0.1.12"
//! regex = "1.8.0"
//! ```

fn main() {
println!("Hello, world!");
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
println!("Did our date match? {}", re.is_match("2014-01-01"));
}
```

The `cargo` section is called a [***manifest***][def-manifest], and it contains all of the
metadata that Cargo needs to compile your package. This is written in the
[TOML] format (pronounced /tɑməl/).

`time = "0.1.12"` is the name of the [crate][def-crate] and a [SemVer] version
`regex = "1.8.0"` is the name of the [crate][def-crate] and a [SemVer] version
requirement. The [specifying
dependencies](https://doc.rust-lang.org/cargo/guide/../reference/specifying-dependencies.html) docs have more
information about the options you have here.

If we also wanted to add a dependency on the `regex` crate, we would not need
to add `[dependencies]` for each crate listed. Here's what your whole
`hello_world.rs` file would look like with dependencies on the `time` and `regex`
crates:

```rust
#!/usr/bin/env cargo

//! ```cargo
//! [dependencies]
//! time = "0.1.12"
//! regex = "0.1.41"
//! ```

fn main() {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
println!("Did our date match? {}", re.is_match("2014-01-01"));
}
```

You can then re-run this and Cargo will fetch the new dependencies and all of their dependencies. You can see this by passing in `--verbose`:
You can then re-run this and Cargo will fetch the new dependencies and all of
their dependencies. You can see this by passing in `--verbose`:
```console
$ cargo --verbose ./hello_world.rs
Updating crates.io index
Expand All @@ -194,6 +176,11 @@ $ cargo --verbose ./hello_world.rs
Did our date match? true
```

Cargo will cache the exact information about which revision of all of these dependencies we used.

Now, if `regex` gets updated, we will still build with the same revision until
we choose to `cargo update --manifest-path hello_world.rs`.
Comment on lines +183 to +184
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work? Where is this cached? Where does the equivalent of the lockfile live?

This seems a little too opaque.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was intentional as lockfiles are another big area for us to try to figure out the right way to handle them is. The Pre-RFC also has a section for this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not suggesting the eRFC has to fully specify embedded lockfiles or any of the many other aspects discussed in the internals thread. I just think if we're going to state that this is cached and updated, we should give some idea of whether this is stored in the cargo home directory (which I'd expect), or next to the script (which I hope it isn't), or similar.

(Also, on a separate note, can we make just cargo update hello_world.rs work?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not suggesting the eRFC has to fully specify embedded lockfiles or any of the many other aspects discussed in the internals thread. I just think if we're going to state that this is cached and updated, we should give some idea of whether this is stored in the cargo home directory (which I'd expect), or next to the script (which I hope it isn't), or similar.

Done

(Also, on a separate note, can we make just cargo update hello_world.rs work?)

My understanding was that cargo intentionally avoided positional arguments (cargo add being an exception) and one reason for this is due to the heavy use of num_args(0..=1) arguments like --timings.

In the Pre-RFC, I did bring up whether we should provide a short-flag for --manifest-path because of how cumbersome it is to use for these files that aren't auto-discovered.

I'll at least call this out as another area to explore.

Copy link

@yerke yerke Apr 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epage I just read https://github.com/epage/rfcs/blob/cargo-script/text/3424-cargo-script.md, but couldn't find a place where it mentions what happens with lock files at all. I was searching for lock string after reading the whole document. Did I somehow miss it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. I didn’t use cargo metadata before. It will do the trick, albeit in a format that will be unfamiliar for many people.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at both cargo metadata and cargo tree to see if everything contained in a lock file is present. The one thing that I see missing is checksum field. I think it can be pretty useful.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out that checksum is internal implementation checksum useful only to cargo, and is not that useful to end users.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I don't see mentioned is whether there's only a single lockfile per system, or one per script. If there's a lockfile per script, what happens if a script is renamed? Does that reset all the dependency versions? What about moving a script file to a different directory without renaming it?

Phrased differently, the document says "Cargo will cache the exact information" but doesn't specify what key the cache is indexed by.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds like we'll need cargo venv lol


## Package Layout

*(Adapted from [the cargo book](https://doc.rust-lang.org/cargo/guide/project-layout.html))*
Expand Down