6

RFC: cargo-script by epage · Pull Request #3502 · rust-lang/rfcs · GitHub

 11 months ago
source link: https://github.com/rust-lang/rfcs/pull/3502
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

RFC: cargo-script #3502

Conversation

Contributor

@epage epage

commented

Sep 26, 2023

edited

Rendered

eRFC #3424 was previously approved without any direction on syntax or behavior having been decided. This RFC is to finalize the decisions made through the implementation to prepare the way for stabilization as we work through the remaining tasks in rust-lang/cargo#12207

#3503 covers the T-lang side of this conversation

Example:

#!/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<std::path::PathBuf>,
}

fn main() {
    let args = Args::parse();
    println!("{:?}", args);
}
$ ./prog --config file.toml
Args { config: Some("file.toml") }

Note: most of this is available behind -Zscript (see rust-lang/cargo#12207 for limitations). Support for the code-fence frontmatter was added in rust-lang/cargo#12681 and it may be a couple of days before cargo's submodule in rust-lang/rust gets updated and built into a nightly.

Kobzol, CathalMullan, nicoburns, ThatOneCalculator, audunhalland, ggggggggg, kbknapp, joseluis, futile, azzamsa, and 37 more reacted with hooray emojiBurntSushi, mbStavola, yerke, AidoP, est31, alxpettit, AaronKutch, 0rvar, joshtriplett, marc2332, and 19 more reacted with heart emojiyerke, alxpettit, flappyBug, praveenperera, yamafaktory, runiq, Nemikolh, slerpyyy, xz-dev, shonya3, and 4 more reacted with rocket emoji

epage

added the T-cargo Relevant to the cargo subteam, which will review and decide on the RFC. label

Sep 26, 2023

This comment was marked as resolved.

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

Contributor

Author

@ggggggggg

"These will be accepted with just like Cargo.toml files" doesn't read right.

I've moved this thread to the context to make it easier to follow.

Could you clarify why you feel this isn't right?

Tetita reacted with thumbs up emoji

"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. 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."

Above I've deleted the 3rd sentence. The above paragraph communicates clearly to me the goal of being able to type cargo myfile.rs and have it do something useful. I have no idea what the 3rd sentence is trying to add. I suspect it makes sense only if you are aware of some cargo internal details. Specifically the phrase "with just like X" makes no sense.

Contributor

Author

I've pushed a change that tries to clarify that sentence:

These files will be accepted by cargo commands as --manifest-path just like Cargo.toml files.

Removing things isn't always the best solution when they aren't clear. This isn't focused on some kind of cargo internals but core aspects of how you interact with it. This is saying that these files are interchangeable with Cargo.toml and you can run commands like cargo test --manifest-path foo.rs.

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

And may not have a . in the filename unless they end in .rs:

> cat test.hello
#!/usr/bin/env -S cargo -Zscript

fn main() {
    println!("hello world");
}
> ./test.hello
error: the manifest-path must be a path to a Cargo.toml file

(assuming the current implementation has the intended semantics here)

Contributor

Author

It says it must be foo.rs. I've clarified that by shifting from an example to saying "with a .rs extension".

Member

It still reads to me as if ‘./hello.test‘ would be allowed because it matches the third clause, but it's not because only extensionless filenames are checked for ‘/‘. (OT: fun, they seem to have disabled backticks in the iPad keyboard...)

I don't personally use an iPad so I can't verify that it's impossible but last I checked if you hold ' for a second or so it'll pop up with alternative quote options.

It'll look like so:

Quote options on Apple Keyboard

Contributor

Author

I see. This is specifically referring to disambiguating cargo foo.

When not on mobile, ill need to check if there is another place where we talk about how to parse the file.

Contributor

Author

a4763f1 updated the section on this matching the current implementation in cargo.

Contributor

The frontmatter syntax wouldn't need to be added to Rust's grammar, correct? In other words, the frontmatter parsing would be a preprocessing stage solely within Cargo, which would strip out the frontmatter before passing it to rustc?

joshtriplett reacted with thumbs down emoji

Member

I think it should be forbidden to publish a script crate without an edition specified. Otherwise we're inevitably looking at a crate that builds when it's published and fails to build later on.

alexjago, joshtriplett, and runiq reacted with thumbs up emoji

Contributor

Author

The frontmatter syntax wouldn't need to be added to Rust's grammar, correct? In other words, the frontmatter parsing would be a preprocessing stage solely within Cargo, which would strip out the frontmatter before passing it to rustc?

This is what cargo master is doing but

  • It is no longer rust which is a priority
  • Error messages, cargo-metadata, etc will expose the lie and I do not want to hack around every case.

Contributor

Author

I think it should be forbidden to publish a script crate without an edition specified. Otherwise we're inevitably looking at a crate that builds when it's published and fails to build later on.

Publish is out of scope for this RFC. There are other aspects of the design that will play into this that a conversation will need to consider. For example, I expect it to turn it into a mult-file package which will require setting the edition.

jhpratt reacted with thumbs up emoji

Member

Publish is out of scope for this RFC

I now see that note towards the top. It was the mention of publish = false that left me concerned for the reason stated.

Contributor

This is what cargo master is doing but

Does the "but" here indicate that the goal would be to get this syntax into Rust's grammar? If so, then I'd like to consider the alternative of stuffing this data into comments rather than introducing new syntax.

AidoP, mcobzarenco, TimNN, Nemikolh, and regexident reacted with thumbs up emoji

Example:

````rust

#!/usr/bin/env cargo

```cargo

cargo has been specified in the shebang above already. Why does the user need to specify it twice? It could just allow a naked ``` fence instead (at least if a shebang is present). We know that we are in a cargo-script file in that instance, so we have the freedom to set a "default" case for what to do with fences that have no specifier.

IMO defaulting them to the manifest does not paint us in a corner while saving us character overhead.

Contributor

Author

This is more of a #3503 question. I have it noted as a future possibility to make cargo the default (forgot to put that in originally). We need to positively identify the frontmatter format. We can make cargo the default but we wanted to start with the more strict syntax and loosen it over time as we can't go back the other direction. As for inferring it from the shebang ... I'm trying to avoid being in the business of parsing shebangs (there is a stackoverflow about what perl does for this)

Specifying it leaves us much more room for future expansion, such as embedding other associated files or serving as frontmatter for other purposes. And it will make the job of syntax highlighters much easier.

If we want less appearance of redundancy, at the expense of more characters, we could use manifest or similar. But that doesn't seem worth it.

Nemikolh reacted with thumbs up emoji

Member

The start choice tends to stick around. In response to my suggestion in rust-lang/cargo#12301 , I have seen concerns that it's an unfamiliar way of specifying the edition. compare it to the PR from when the edition mechanism was introduced, there one of the comments against was into a similar direction as the reason you give why cargo defaulting is now rejected: that we don't know if we want to make 2018-pre a thing or not. Not that I agree with them but a similar effect might occur if we require the cargo specifier to be present.

Regarding whether it should be discussed in #3503 or not, IMO that RFC should not be as restricted to precisely what cargo needs, but be more generic. Ideally when we add support for non manifest embeddings, we shouldn't have to make another lang RFC but handle it wholly inside cargo-script.

Contributor

Author

Ideally when we add support for non manifest embeddings, we shouldn't have to make another lang RFC

i doubt we'd need an RFC; likely a change proposal would do.

Contributor

Author

This is what cargo master is doing but

Does the "but" here indicate that the goal would be to get this syntax into Rust's grammar? If so, then I'd like to consider the alternative of stuffing this data into comments rather than introducing new syntax.

#3503 is the RFC for the syntax, as referred to in the PR description and in the embedding syntax section of rationale.

This solution was what we came up with in discussions with a subset of the cargo team, rust educators, and the language team. It was started and finished on zulip with the middle being handled at RustConf.

bstrie and AidoP reacted with thumbs up emoji

Contributor

Author

epage

commented

Sep 27, 2023

edited

I now see that note towards the top. It was the mention of publish = false that left me concerned for the reason stated.

Ah, yes, I missed some sections when removing publish support from the RFC.

Did we can use a cargo script in another cargo script?

If I have more than one cargo script and most of them have common functions/structs/enums/types or traits, it will be more convenient if I can put them into a separate cargo script that doesn't have necessary have a main function and it just defines these common things and export them as pubic items, so I can use them somehow in the other cargo scripts.

I think that we can't use the use keyword (or at least its syntax) because we don't have the crate concept here, and we might want to use the absolute path.

Contributor

Author

Did we can use a cargo script in another cargo script?

If I have more than one cargo script and most of them have common functions/structs/enums/types or traits, it will be more convenient if I can put them into a separate cargo script that doesn't have necessary have a main function and it just defines these common things and export them in the pubic so I can use it somehow in the other cargo scripts.

I think that we can't use the use keyword (or at least its syntax) because we don't have the crate concept here, and we might want to use a cargo script to use its absolute path.

At this point you should either

  • Make a common "script-tools" package and have a dependency on that (could be a path dependency)
  • Use a multi-file package
0x61nas reacted with eyes emoji

Comment on lines

+113 to +117

### 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`:

on first glance I find it confusing to call this a "package"

the def-package link says:

A package is a collection of source files and a Cargo.toml manifest file which describes the package.

granted "a collection of source files" includes just having a single source file, but I still find this a bit confusing. IMHO it would be better to keep the term "script" for this and have "packages" refer to real packages as we've had them up to this point.

Contributor

Author

In other places, I refer to it as a "single file package" and within the context of cargo concepts and literature, these are a form of a package. While we might find places we want to use a term like "script" for these (which I personally am hesitant on, only using it for historical connection to cargo-script), we shying away from calling these "packages" could end up making things more confusing.

Granted, this gets into whether a looser or more strict term is appropriate when we finally document this and I think that is something to work out over time and likely will evolve.

text/3502-cargo-script.md

Outdated Show resolved

text/3502-cargo-script.md

Outdated Show resolved

text/3502-cargo-script.md

Outdated Show resolved

Questions

- Should we do this implicitly with the `.rs` extension?

- If we have a flag, what should we name it?

I'd go with --script, though I'm not sure if cargo new really needs to support it if the goal is to be as boilerplate-free as possible

Contributor

Author

I'd go with --script,

Thats something we can work out if/when we get to this. Personally, I've not liked tying the connotation of this feature to the term "script".

though I'm not sure if cargo new really needs to support it if the goal is to be as boilerplate-free as possible

I originally held off on cargo new to help drive the boiler plate to a minimum. I do admit it can be annoying to write out the shebang and set the executable bit; I tend to copy/paste files (though I also tend to share dependencies).

A single-file package may only be a `[bin]` or a `[lib]` and not both.

We would support depending on these, publishing them, etc.

publishing them means that the packages would be published without readme and license files and most likely other metadata though, so I'm a bit hesitant regarding this...

Contributor

Author

As this is a future possibility, this is more helpful to add flavor / context for discussions and decisions. We can work those issues out if/when we come to this.

text/3502-cargo-script.md

Outdated Show resolved

text/3502-cargo-script.md

Outdated Show resolved

Comment on lines

+1103 to +1104

- We would need to decide what to do for lockfiles and `stdin` (another future possibility) without conflicting

with parallel runs

the current plan is apparently to use a hash of the file path, but that would also be difficult for stdin. would it make sense to hash the file content instead?

Contributor

Author

Yes, that is a possibility As this is a future possibility, the point is more to highlight the idea for us to include in consideration. I don't think we need to work out all the details at this time.

Turbo87 reacted with thumbs up emoji

Contributor

Author

epage

commented

Oct 3, 2023

edited

In case people find it of interest, the Python community has a parallel effort to this with two competing solutions and Microsoft paid for some user interviews to be done. Maybe I overlooked something but unfortunately there wasn't much that seemed relevant to us as it seemed more focused on the differences in formats inside of the frontmatter and is more akin to manifest subset vs cargo-deps: difference from rust-script.

runiq reacted with thumbs up emojitimClicks reacted with heart emojiruniq reacted with eyes emoji

Thank you for your diligence and patience to take on so many points of view.

runiq, tmandry, and xy2i reacted with thumbs up emoji

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Nemo157

Nemo157 left review comments

Turbo87

Turbo87 left review comments

joshtriplett

joshtriplett left review comments

kpreid

kpreid left review comments

jplatte

jplatte left review comments

faho

faho left review comments

ggggggggg

ggggggggg left review comments

est31

est31 left review comments

dvdsk

dvdsk left review comments

Aloso

Aloso left review comments

xxchan

xxchan left review comments

LukeAbby

LukeAbby left review comments
Assignees

No one assigned

Labels
T-cargo Relevant to the cargo subteam, which will review and decide on the RFC.
Projects

Status: Unreviewed

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

None yet

17 participants

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK