diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index a91dc002b746..77c2bb98dc49 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -491,9 +491,9 @@ pub fn cli() -> Command { #[allow(clippy::disallowed_methods)] let is_rustup = std::env::var_os("RUSTUP_HOME").is_some(); let usage = if is_rustup { - "cargo [+toolchain] [OPTIONS] [COMMAND]" + "cargo [+toolchain] [OPTIONS] [COMMAND]\n cargo [+toolchain] [OPTIONS] -Zscript [ARGS]..." } else { - "cargo [OPTIONS] [COMMAND]" + "cargo [OPTIONS] [COMMAND]\n cargo [OPTIONS] -Zscript [ARGS]..." }; Command::new("cargo") // Subcommands all count their args' display order independently (from 0), diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 3e09f1924094..5080c6b5262c 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1397,6 +1397,101 @@ Valid operations are the following: * Tracking Issue: [#12207](https://github.com/rust-lang/cargo/issues/12207) +Cargo can directly run `.rs` files as: +```console +$ cargo -Zscript file.rs +``` +where `file.rs` can be as simple as: +```rust +fn main() {} +``` + +A user may optionally specify a manifest in a `cargo` code fence in a module-level comment, like: +```rust +#!/usr/bin/env cargo + +//! ```cargo +//! [dependencies] +//! clap = { version = "4.2", features = ["derive"] } +//! ``` + +use clap::Parser; + +#[derive(Parser, Debug)] +#[clap(version)] +struct Args { + #[clap(short, long, help = "Path to config")] + config: Option, +} + +fn main() { + let args = Args::parse(); + println!("{:?}", args); +} +``` + +#### Single-file packages + +In addition to today's multi-file packages (`Cargo.toml` file with other `.rs` +files), we are adding the concept of single-file packages which may contain an +embedded manifest. There is no required distinguishment for a single-file +`.rs` package from any other `.rs` file. + +A single-file package may contain an embedded manifest. An embedded manifest +is stored using `TOML` in a markdown code-fence with `cargo` at the start of the +infostring inside a target-level doc-comment. It is an error to have multiple +`cargo` code fences in the target-level doc-comment. We can relax this later, +either merging the code fences or ignoring later code fences. + +Supported forms of embedded manifest are: +``````rust +//! ```cargo +//! ``` +`````` +``````rust +/*! + * ```cargo + * ``` + */ +`````` + +Inferred / defaulted manifest fields: +- `package.name = ` +- `package.version = "0.0.0"` to [call attention to this crate being used in unexpected places](https://matklad.github.io/2021/08/22/large-rust-workspaces.html#Smaller-Tips) +- `package.publish = false` to avoid accidental publishes, particularly if we + later add support for including them in a workspace. +- `package.edition = ` to avoid always having to add an embedded + manifest at the cost of potentially breaking scripts on rust upgrades + - Warn when `edition` is unspecified. While with single-file packages this will be + silenced by default, users wanting stability are also likely to be using + other commands, like `cargo test` and will see it. + +Disallowed manifest fields: +- `[workspace]`, `[lib]`, `[[bin]]`, `[[example]]`, `[[test]]`, `[[bench]]` +- `package.workspace`, `package.build`, `package.links`, `package.autobins`, `package.autoexamples`, `package.autotests`, `package.autobenches` + +As the primary role for these files is exploratory programming which has a high +edit-to-run ratio, building should be fast. Therefore `CARGO_TARGET_DIR` will +be shared between single-file packages to allow reusing intermediate build +artifacts. + +The lockfile for single-file packages will be placed in `CARGO_TARGET_DIR`. In +the future, when workspaces are supported, that will allow a user to have a +persistent lockfile. + +#### Manifest-commands + +You may pass single-file packages directly to the `cargo` command, without subcommand. This is mostly intended for being put in `#!` lines. + +The precedence for how to interpret `cargo ` is +1. Built-in xor single-file packages +2. Aliases +3. External subcommands + +A parameter is identified as a single-file package if it has one of: +- Path separators +- A `.rs` extension + ### `[lints]` * Tracking Issue: [#12115](https://github.com/rust-lang/cargo/issues/12115)