-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
feat: Initial support for single-file packages #12245
Conversation
r? @weihanglo (rustbot has picked a reviewer for you, use r? to override) |
This should be more resilient to false positives like in rust-lang#12245 where a string contains `println`.
This should be more resilient to false positives like in rust-lang#12245 where a string contains `println`.
0d27d58
to
382e5db
Compare
I decided to start things off fairly simple. It either looks like the user is specifying a manifest or they aren't. This is assuming we only need to handle `cargo foo.rs` and `cargo ./foo.rs` and not `cargo foo`. I think in most shebang cases, path multiple components will present which makes that a dead giveaway and likely to not overlap with aliases and subcommands. For reference, dlang's dub goes a lot further 1. Checks for the subcommand name being `-` 2. Checks if subcommand name ends with `.d` 3. Checks if subcommand name is built-in 4. Checks if a file with the subcommand name exists 5. Checks if a file with the subcommand name + `.d` exists This would allow a `run.d` to override `dub-run` which doesn't seem good.
a207282
to
199fb6f
Compare
FYI @weihanglo I've finally appeased the CI gods |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just did the first round review, yet I skipped the juicy part — toml/embedded.rs
. Thanks for making this happen. I'll get back in the next few days!
@@ -13,6 +13,7 @@ exclude = [ | |||
[workspace.dependencies] | |||
anyhow = "1.0.47" | |||
base64 = "0.21.0" | |||
blake3 = "1.3.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you clarify that why we need blake3
? Is it only for performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just looking for what a recommended hashing algorithm is. This is used for creating the temporary manifest on disk and will be going away when we get native support for embedded manifests. Similarly, we'll be dropping the regex
dependency when we change up the parsing of embedded manifests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really a blocker but maybe something like this at this moment would better.
diff --git a/src/cargo/util/toml/embedded.rs b/src/cargo/util/toml/embedded.rs
index 875ec6a4b..833f90ce9 100644
--- a/src/cargo/util/toml/embedded.rs
+++ b/src/cargo/util/toml/embedded.rs
@@ -68,7 +68,7 @@ impl RawScript {
config: &Config,
target_dir: &std::path::Path,
) -> CargoResult<std::path::PathBuf> {
- let hash = self.hash().to_string();
+ let hash = self.hash();
assert_eq!(hash.len(), 64);
let mut workspace_root = target_dir.to_owned();
workspace_root.push("eval");
@@ -207,8 +207,8 @@ impl RawScript {
Ok(slug)
}
- fn hash(&self) -> blake3::Hash {
- blake3::hash(self.body.as_bytes())
+ fn hash(&self) -> String {
+ cargo_util::Sha256::new().update(self.body.as_bytes()).finish_hex()
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we defer this out? Scott already has a branch where the hashing can be dropped, so dropping it should be a quick follow on. My hope with this change was to have cargo-script-mvs
as a baseline and would rather not have churn related to throwaway parts of the PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A tiny drawback of introducing new dependendies: need to add license exceptions on Rust side rust-lang/rust#112601.
This is not this PR's fault. It is the license check is out of sync between rust-lang/rust and rust-lang/cargo.
@@ -101,3 +105,16 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { | |||
} | |||
}) | |||
} | |||
|
|||
pub fn is_manifest_command(arg: &str) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not a blocker)
“Manifest commands” is already a term, though its definition is not pretty clear to me.
https://doc.rust-lang.org/nightly/cargo/commands/manifest-commands.html
This will give us a window to collect feedback on if this affects anyone.
This is no where near the implementation we want but I think we should develop incrementally on top of what we already have. See https://github.com/epage/cargo-script-mvs/tree/main
This is written to reflect the current implementation though some parts might read a little weird because I didn't want to write throw-away documentation for when we change this. For example, single-file packages are currently only supported in `cargo <command>` and not as manifest paths but this will change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given this is an implementation for an eRFC, and it has only little impact on the current behavior of Cargo, I am pretty open to merge it as-is.
@epage I left some comment for potential cleanup but feel free to r=weihanglo
if they don't make sense to do at this moment. I think what to should do is writing down the decisions needed to be made and move on.
manifest: String, | ||
body: String, | ||
path: std::path::PathBuf, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not a blocker)
It's not immediately clear to me what these field are for. Could we have a little bit docs for them?
fn extract_manifest(comment: &str) -> CargoResult<Option<String>> { | ||
use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag}; | ||
|
||
// To match librustdoc/html/markdown.rs, opts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we link to a specific commit for traceability?
release | ||
.entry("strip".to_owned()) | ||
.or_insert_with(|| toml::Value::Boolean(true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not a blocker)
We could have a discussion around the default compiler settings for -Zscript
, like this strip = true
.
Ok(manifest) | ||
} | ||
|
||
fn package_name(&self) -> CargoResult<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not a blocker)
Probably need a discussion around this escaping rule?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A follow up PR is planned to deal with escaping rules and I wouldn't be surprised if they are brought up again through the experiment
fn expand_manifest_(&self, config: &Config) -> CargoResult<toml::Table> { | ||
let mut manifest: toml::Table = toml::from_str(&self.manifest)?; | ||
|
||
for key in ["workspace", "lib", "bin", "example", "test", "bench"] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not a blocker)
Should we have an exhaustive list of what we allow instead?
8d638bd
to
6b0b5a8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is generally good to merge. Let's see how big the impact will be on the Rust ecosystem 🎉🎉🎉. Thank you for making this come true!
Before I forget, let me jot down things to do/explore/clean up.
- Dependency clean-up (
blake3
,regex
, etc.) - Official name of the
cargo <script>.rs
. The current choice is “manifest command”. - Internal documentations of new items and modules for this new feature.
- Default set of compiler flags for
-Zscript
. - Escaping rules of the package name generated.
- Whether to use an exhaustive list for allowed manifest fields.
@bors r+ |
I've noted some of those down on #12207 since we'll likely want to review those when the experiment is ready for the next stage |
☀️ Test successful - checks-actions |
Update cargo 11 commits in 49b6d9e179a91cf7645142541c9563443f64bf2b..0c14026aa84ee2ec4c67460c0a18abc8519ca6b2 2023-06-09 17:21:19 +0000 to 2023-06-14 18:43:05 +0000 - fix(embedded): Don't append hash to bin names (rust-lang/cargo#12269) - Fix version requirement example in Dependency Resolution, SemVer compatibility section (rust-lang/cargo#12267) - Update triagebot links. (rust-lang/cargo#12265) - Show a better error when container tests fail. (rust-lang/cargo#12264) - chore: update dependencies (rust-lang/cargo#12261) - refactor(embedded) (rust-lang/cargo#12262) - docs: clarify the use of `default` branch instead of `main` by default (rust-lang/cargo#12251) - docs: update changelog for 1.71 backport and 1.72 (rust-lang/cargo#12256) - feat: Initial support for single-file packages (rust-lang/cargo#12245) - test(z-flags): Verify `-Z` flags list is sorted (rust-lang/cargo#12224) - refactor: registry data kinds cleanup (rust-lang/cargo#12248) --- This commit also update LICENSE exceptions, as Cargo introduced a newer version of `dunce` and `blake3` as dependencies. r? `@ghost`
Update cargo 11 commits in 49b6d9e179a91cf7645142541c9563443f64bf2b..0c14026aa84ee2ec4c67460c0a18abc8519ca6b2 2023-06-09 17:21:19 +0000 to 2023-06-14 18:43:05 +0000 - fix(embedded): Don't append hash to bin names (rust-lang/cargo#12269) - Fix version requirement example in Dependency Resolution, SemVer compatibility section (rust-lang/cargo#12267) - Update triagebot links. (rust-lang/cargo#12265) - Show a better error when container tests fail. (rust-lang/cargo#12264) - chore: update dependencies (rust-lang/cargo#12261) - refactor(embedded) (rust-lang/cargo#12262) - docs: clarify the use of `default` branch instead of `main` by default (rust-lang/cargo#12251) - docs: update changelog for 1.71 backport and 1.72 (rust-lang/cargo#12256) - feat: Initial support for single-file packages (rust-lang/cargo#12245) - test(z-flags): Verify `-Z` flags list is sorted (rust-lang/cargo#12224) - refactor: registry data kinds cleanup (rust-lang/cargo#12248) --- This commit also update LICENSE exceptions, as Cargo introduced a newer version of `dunce` and `blake3` as dependencies. r? `@ghost`
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
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!()`.
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!()`.
What does this PR try to resolve?
This is the first step towards #12207. In particular, this focuses on pulling in the demo 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)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
regex
tosyn
for extracting manifests for greater resiliencecargo new
s logic when sanitizing the inferred package namecargo <name>
to also be aCargo.toml
file (for consistency in where manifests are 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 :)