From 1f40980c119ad75d1575907add39ab5e70353c64 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 26 Sep 2023 12:18:17 -0500 Subject: [PATCH 01/59] feat: Add skeleton --- text/0000-cargo-script.md | 97 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 text/0000-cargo-script.md diff --git a/text/0000-cargo-script.md b/text/0000-cargo-script.md new file mode 100644 index 00000000000..a2ab4c4c8a6 --- /dev/null +++ b/text/0000-cargo-script.md @@ -0,0 +1,97 @@ +- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) +- Start Date: (fill me in with today's date, YYYY-MM-DD) +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +# Summary +[summary]: #summary + +One paragraph explanation of the feature. + +# Motivation +[motivation]: #motivation + +Why are we doing this? What use cases does it support? What is the expected outcome? + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: + +- Introducing new named concepts. +- Explaining the feature largely in terms of examples. +- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible. +- If applicable, provide sample error messages, deprecation warnings, or migration guidance. +- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. +- Discuss how this impacts the ability to read, understand, and maintain Rust code. Code is read and modified far more often than written; will the proposed feature make code easier to maintain? + +For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +This is the technical portion of the RFC. Explain the design in sufficient detail that: + +- Its interaction with other features is clear. +- It is reasonably clear how the feature would be implemented. +- Corner cases are dissected by example. + +The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. + +# Drawbacks +[drawbacks]: #drawbacks + +Why should we *not* do this? + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +- Why is this design the best in the space of possible designs? +- What other designs have been considered and what is the rationale for not choosing them? +- What is the impact of not doing this? +- If this is a language proposal, could this be done in a library or macro instead? Does the proposed change make Rust code easier or harder to read, understand, and maintain? + +# Prior art +[prior-art]: #prior-art + +Discuss prior art, both the good and the bad, in relation to this proposal. +A few examples of what this can include are: + +- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? +- For community proposals: Is this done by some other community and what were their experiences with it? +- For other teams: What lessons can we learn from what other communities have done here? +- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background. + +This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. +If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. + +Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. +Please also take into consideration that rust sometimes intentionally diverges from common language features. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +- What parts of the design do you expect to resolve through the RFC process before this gets merged? +- What parts of the design do you expect to resolve through the implementation of this feature before stabilization? +- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC? + +# Future possibilities +[future-possibilities]: #future-possibilities + +Think about what the natural extension and evolution of your proposal would +be and how it would affect the language and project as a whole in a holistic +way. Try to use this section as a tool to more fully consider all possible +interactions with the project and language in your proposal. +Also consider how this all fits into the roadmap for the project +and of the relevant sub-team. + +This is also a good place to "dump ideas", if they are out of scope for the +RFC you are writing but otherwise related. + +If you have tried and cannot think of any future possibilities, +you may simply state that you cannot think of anything. + +Note that having something written down in the future-possibilities section +is not a reason to accept the current or a future RFC; such notes should be +in the section on motivation or rationale in this or subsequent RFCs. +The section merely provides additional information. From a763b10245c41b069718b9dfdd8386450da402f9 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 26 Sep 2023 14:34:12 -0500 Subject: [PATCH 02/59] feat: Initial RFC draft --- text/0000-cargo-script.md | 1213 +++++++++++++++++++++++++++++++++++-- 1 file changed, 1163 insertions(+), 50 deletions(-) diff --git a/text/0000-cargo-script.md b/text/0000-cargo-script.md index a2ab4c4c8a6..fa35adae35b 100644 --- a/text/0000-cargo-script.md +++ b/text/0000-cargo-script.md @@ -1,97 +1,1210 @@ -- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) -- Start Date: (fill me in with today's date, YYYY-MM-DD) +- Feature Name: `cargo-script` +- Start Date: 2023-03-31 +- Pre-RFC: [internals](https://internals.rust-lang.org/t/pre-rfc-cargo-script-for-everyone/18639) +- eRFC PR: [rust-lang/rfcs#3424](https://github.com/rust-lang/rfcs/pull/3424) + - Rust Issue: [rust-lang/cargo#12207](https://github.com/rust-lang/cargo/issues/12207) - RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) # Summary [summary]: #summary -One paragraph explanation of the feature. +This RFC adds support for single-file bin packages in cargo. +Single-file bin packages are `.rs` files with an embedded manifest and a +`main`. +These will be accepted with just like `Cargo.toml` files with +`--manifest-path`. +`cargo` will be modified to accept `cargo .rs` as a shortcut to `cargo +run --manifest-path .rs`. +This allows placing `cargo` in a `#!` line for directly running these files. + +Support for single-file lib packages, publishing, and workspace support is +deferred out. + +Example: +````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); +} +```` +```console +$ ./prog --config file.toml +Args { config: Some("file.toml") } +``` + +See [`-Zscript`](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#script) for a working implementation. # Motivation [motivation]: #motivation -Why are we doing this? What use cases does it support? What is the expected outcome? +**Collaboration:** + +When sharing reproduction cases, it is much easier when everything exists in a +single code snippet to copy/paste. +Alternatively, people will either leave off the manifest or underspecify the +details of it. + +This similarly makes it easier to share code samples with coworkers or in books +/ blogs when teaching. + +**Interoperability:** + +One angle to look at including something is if there is a single obvious +solution. +While there isn't in the case for single-file packages, there is enough of a +subset of one. +By standardizing that subset, we allow greater interoperability between +solutions +(e.g. [playground could gain support](https://users.rust-lang.org/t/call-for-contributors-to-the-rust-playground-for-upcoming-features/87110/14?u=epage)). +This would make it easier to collaborate.. + +**Prototyping:** + +Currently to prototype or try experiment with APIs or the language, you need to either +- Use the playground + - Can't access local resources + - Limited in the crates supported + - *Note:* there are alternatives to the playground that might have fewer + restrictions but are either less well known or have additional + complexities. +- Find a place to do `cargo new`, edit `Cargo.toml` and `main.rs` as necessary, and `cargo run` it, then delete it + - This is a lot of extra steps, increasing the friction to trying things out + - This will fail if you create in a place that `cargo` will think it should be a workspace member + +By having a single-file package, +- It is easier to setup and tear down these experiments, making it more likely to happen +- All crates will be available +- Local resources are available + +**One-Off Utilities:** + +It is fairly trivial to create a bunch of single-file bash or python scripts +into a directory and add it to the path. +Compare this to rust where +- `cargo new` each of the "scripts" into individual directories +- Create wrappers for each so you can access it in your path, passing `--manifest-path` to `cargo run` + +**Non-Goals:** + +With that said, this doesn't have to completely handle every use case for +Collaboration, Interoperability, Prototuping, or One-off Utilities. +Users can always scale up to normal packages with an explicit `Cargo.toml` file. # Guide-level explanation [guide-level-explanation]: #guide-level-explanation -Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: +### Creating a New Package + +*(Adapted from [the cargo book](https://doc.rust-lang.org/cargo/guide/creating-a-new-project.html))* + +To start a new [package][def-package] with Cargo, create a file named `hello_world.rs`: +```rust +#!/usr/bin/env cargo + +fn main() { + println!("Hello, world!"); +} +``` + +Let's run it +```console +$ chmod +x hello_world.rs +$ ./hello_world.rs +Hello, world! +``` + +### Dependencies + +*(Adapted from [the cargo book](https://doc.rust-lang.org/cargo/guide/dependencies.html))* + +[crates.io] is the Rust community's central [*package registry*][def-package-registry] +that serves as a location to discover and download +[packages][def-package]. `cargo` is configured to use it by default to find +requested packages. + +#### Adding a dependency + +To depend on a library hosted on [crates.io], you modify `hello_world.rs`: +````rust +#!/usr/bin/env cargo +```cargo +[dependencies] +time = "0.1.12" +``` + +fn main() { + println!("Hello, world!"); +} +```` + +The data inside the `cargo` frontmatter 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 +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. -- Introducing new named concepts. -- Explaining the feature largely in terms of examples. -- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible. -- If applicable, provide sample error messages, deprecation warnings, or migration guidance. -- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. -- Discuss how this impacts the ability to read, understand, and maintain Rust code. Code is read and modified far more often than written; will the proposed feature make code easier to maintain? +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: -For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms. +````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`: +```console +$ cargo eval --verbose ./hello_world.rs + Updating crates.io index + Downloading memchr v0.1.5 + Downloading libc v0.1.10 + Downloading regex-syntax v0.2.1 + Downloading memchr v0.1.5 + Downloading aho-corasick v0.3.0 + Downloading regex v0.1.41 + Compiling memchr v0.1.5 + Compiling libc v0.1.10 + Compiling regex-syntax v0.2.1 + Compiling memchr v0.1.5 + Compiling aho-corasick v0.3.0 + Compiling regex v0.1.41 + Compiling hello_world v0.1.0 (file:///path/to/package/hello_world) +Did our date match? true +``` + +## Package Layout + +*(Adapted from [the cargo book](https://doc.rust-lang.org/cargo/guide/project-layout.html))* + +When a single file is not enough, you can separately define a `Cargo.toml` file along with the `src/main.rs` file. Run +```console +$ cargo new hello_world --bin +``` + +We’re passing `--bin` because we’re making a binary program: if we +were making a library, we’d pass `--lib`. +This also initializes a new `git` repository by default. +If you don't want it to do that, pass `--vcs none`. + +Let’s check out what Cargo has generated for us: +```console +$ cd hello_world +$ tree . +. +├── Cargo.toml +└── src + └── main.rs + +1 directory, 2 files +``` +Unlike the `hello_world.rs`, a little more context is needed in `Cargo.toml`: +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2021" + +[dependencies] + +``` + +Cargo uses conventions for file placement to make it easy to dive into a new +Cargo [package][def-package]: + +```text +. +├── Cargo.lock +├── Cargo.toml +├── src/ +│   ├── lib.rs +│   ├── main.rs +│   └── bin/ +│ ├── named-executable.rs +│      ├── another-executable.rs +│      └── multi-file-executable/ +│      ├── main.rs +│      └── some_module.rs +├── benches/ +│   ├── large-input.rs +│   └── multi-file-bench/ +│   ├── main.rs +│   └── bench_module.rs +├── examples/ +│   ├── simple.rs +│   └── multi-file-example/ +│   ├── main.rs +│   └── ex_module.rs +└── tests/ + ├── some-integration-tests.rs + └── multi-file-test/ + ├── main.rs + └── test_module.rs +``` + +* `Cargo.toml` and `Cargo.lock` are stored in the root of your package (*package + root*). +* Source code goes in the `src` directory. +* The default library file is `src/lib.rs`. +* The default executable file is `src/main.rs`. + * Other executables can be placed in `src/bin/`. +* Benchmarks go in the `benches` directory. +* Examples go in the `examples` directory. +* Integration tests go in the `tests` directory. + +If a binary, example, bench, or integration test consists of multiple source +files, place a `main.rs` file along with the extra [*modules*][def-module] +within a subdirectory of the `src/bin`, `examples`, `benches`, or `tests` +directory. The name of the executable will be the directory name. + +You can learn more about Rust's module system in [the book][book-modules]. + +See [Configuring a target] for more details on manually configuring targets. +See [Target auto-discovery] for more information on controlling how Cargo +automatically infers target names. + +[book-modules]: https://doc.rust-lang.org/cargo/guide/../../book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html +[Configuring a target]: https://doc.rust-lang.org/cargo/guide/../reference/cargo-targets.html#configuring-a-target +[def-package]: https://doc.rust-lang.org/cargo/guide/../appendix/glossary.html#package '"package" (glossary entry)' +[Target auto-discovery]: https://doc.rust-lang.org/cargo/guide/../reference/cargo-targets.html#target-auto-discovery +[TOML]: https://toml.io/ +[crates.io]: https://crates.io/ +[SemVer]: https://semver.org +[def-crate]: https://doc.rust-lang.org/cargo/guide/../appendix/glossary.html#crate '"crate" (glossary entry)' +[def-package]: https://doc.rust-lang.org/cargo/guide/../appendix/glossary.html#package '"package" (glossary entry)' +[def-package-registry]: https://doc.rust-lang.org/cargo/guide/../appendix/glossary.html#package-registry '"package-registry" (glossary entry)' +[def-manifest]: https://doc.rust-lang.org/cargo/guide/../appendix/glossary.html#manifest '"manifest" (glossary entry)' # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -This is the technical portion of the RFC. Explain the design in sufficient detail that: +**Reminder:** This serves as a starting point for experimentation and +[Unresolved questions](#unresolved-questions) will be worked out through the +tracking issues. + +Initial guidelines for evaluating decisions: +- Single-file packages should have a first-class experience + - Provides a higher quality of experience (doesn't feel like a hack or tacked on) + - Transferable knowledge, whether experience, stackoverflow answers, etc + - Easier unassisted migration between single-file and multi-file packages + - The more the workflows deviate, the higher the maintenance and support costs for the cargo team + - Example implications: + - Workflows, like running tests, should be the same as multi-file packages rather than being bifurcated + - Manifest formats should be the same rather than using a specialized schema or data format +- Friction for starting a new single-file package should be minimal + - Easy to remember, minimal syntax so people are more likely to use it in + one-off cases, experimental or prototyping use cases without tool assistance + - Example implications: + - Embedded manifest is optional which also means we can't require users specifying `edition` + - See also the implications for first-class experience + - Workspaces for single-file packages should not be auto-discovered as that + will break unless the workspaces also owns the single-file package which + will break workflows for just creating a file anywhere to try out an + idea. +- Cargo/rustc diagnostics and messages (including `cargo metadata`) should be + in terms of single-file packages and not any temporary files + - Easier to understand the messages + - Provides a higher quality of experience (doesn't feel like a hack or tacked on) + - Example implications: + - Most likely, we'll need single-file packages to be understood directly by + rustc so cargo doesn't have to split out the `.rs` content into a temp + file that gets passed to cargo which will cause errors to point to the + wrong file + - Most likely, we'll want to muck with the errors returned by `toml_edit` + so we render manifest errors based on the original source code which will require accurate span information. + + +## 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 rust "frontmatter", a markdown code-fence with `cargo` +at the start of the infostring at the top of the file. + +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. + - Based on feedback, we might add `cargo--edition` proxies to put in `#!` as a shorthand + - Based on feedback, we can switch to "edition is required as of edition" + +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. + +A single-file package is accepted by cargo commands as a `--manifest-path` +- This is distinguished by the file extension (`.rs`) and that it is a file. +- This allows running `cargo test --manifest-path single.rs` +- `cargo package` / `cargo publish` will normalize this into a multi-file package +- `cargo add` and `cargo remove` may not support editing embedded manifests initially +- Path-dependencies may not refer to single-file packages at this time (they don't have a `lib` target anyways) + +Single-file packages will not be accepted as `path` or `git` dependencies. + +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. +We may also allow customizing the non-workspace lockfile location in the [future](#future-possibilities). -- Its interaction with other features is clear. -- It is reasonably clear how the feature would be implemented. -- Corner cases are dissected by example. +## `cargo .rs` -The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. +`cargo` is intended for putting in the `#!` for single-file packages: +```rust +#!/usr/bin/env cargo + +fn main() { + println!("Hello world"); +} +``` +- Like with `cargo install`, `.cargo/config.toml` will be read based on the + scripts location rather than the current-dir. + - And like `cargo install`, the current-dir rustup-toolchain is respected +- `--release` is not passed in because the primary use case is for exploratory + programming, so the emphasis will be on build-time performance, rather than + runtime performance + +Most other flags and behavior will be similar to `cargo run`. + +The precedence for `cargo foo` will change from: +1. built-in commands +2. user aliases +3. third-party commands + +to: +1. built-in command xor manifest +2. user aliases +3. third-party commands + +To allow the xor, we enforce that +- manifests must be passed in as `Cargo.toml`, `foo.rs`, or have a `/` in them +- no built-in command may look like an accepted manifest + +When piping `cargo .rs`, `--quiet` will be assumed. # Drawbacks [drawbacks]: #drawbacks -Why should we *not* do this? +At the moment, the doc-comment parsing is brittle, relying on regexes, to +extract it and then requires a heavy dependency (a markdown parser) to get the +code fence. + +The implicit content of the manifest will be unclear for users. +We can patch over this as best we can in documentation but the result won't be +ideal. +A user can workaround this with `cargo metadata --manifest-path .rs`. + +The `bin.name` assigned to the script included a hash as an implementation +detail of the shared cache (for improving build times). +This makes programmatic choices off of `argv[0]` not work like normal (e.g. +multi-call binaries). +We could settings +[`argv[0]` on unix-like systems](https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.arg0) +but could not find something similar for Windows. + +This increases the maintenance and support burden for the cargo team, a team +that is already limited in its availability. + +Like with all cargo packages, the `target/` directory grows unbounded. +Some prior art include a cache GC but that is also to clean up the temp files +stored in other locations +(our temp files are inside the `target/` dir and should be rarer). + +Syntax is not reserved for `build.rs`, `[lib]` support, proc-maros, embedding +additional packages, or other functionality to be added later with the +assumption that if these features are needed, a user should be using a +multi-file package. +As stated in the Motivation, this doesn't have to perfectly cover every use +case that a `Cargo.toml` would. # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives -- Why is this design the best in the space of possible designs? -- What other designs have been considered and what is the rationale for not choosing them? -- What is the impact of not doing this? -- If this is a language proposal, could this be done in a library or macro instead? Does the proposed change make Rust code easier or harder to read, understand, and maintain? +## Misc + +- Rejected: Defaulting to `RUST_BACKTRACE=1` for `cargo foo.rs` runs + - Enabling backtraces provides more context to problems, much like Python scripts, which helps with experiments + - This comes at the cost of making things worse for scripts + - Decided against it to minimize special casing + - See also [t-cargo zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/Smarter.20.60RUST_BACKTRACE.60.20behavior.3F) +- The package name is slugified according the stricter `cargo new` validation + rules, making it consistent across platforms as some names are invalid on + some platforms + - See [rust-lang/cargo#12255](https://github.com/rust-lang/cargo/pull/12255) + +## Scope + +The `cargo-script` family of tools has a single command +- Run `.rs` files with embedded manifests +- Evaluate command-line arguments (`--expr`, `--loop`) + +This behavior (minus embedded manifests) mirrors what you might expect from a +scripting environment, minus a REPL. We could design this with the future possibility of a REPL. + +However +- The needs of `.rs` files and REPL / CLI args are different, e.g. where they get their dependency definitions +- A REPL is a lot larger of a problem, needing to pull in a lot of interactive behavior that is unrelated to `.rs` files +- A REPL for Rust is a lot more nebulous of a future possibility, making it pre-mature to design for it in mind + +Therefore, this RFC proposes we limit the scope of the new command to `cargo run` for single-file rust packages. + +## Naming +[naming]: #naming + +Considerations: +- The name should tie it back to `cargo` to convey that relationship +- The command that is run in a `#!` line should not require arguments (e.g. not + `#!/usr/bin/env cargo `) because it will fail. `env` treats the + rest of the line as the bin name, spaces included. You need to use `env -S` + but that wasn't supported on macOS at least, last I tested. +- Either don't have a name that looks like a cargo-plugin (e.g. not + `cargo-`) to avoid confusion or make it work (by default, `cargo + something` translates to `cargo-something something` which would be ambiguous + of whether `something` is a script or subcommand) + +Candidates +- `cargo-script`: + - Out of scope + - Verb preferred +- `cargo-shell`: + - Out of scope + - Verb preferred +- `cargo-run`: + - This would be shorthand for `cargo run --manifest-path