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

feat: Initial support for single-file packages #12245

Merged
merged 10 commits into from
Jun 12, 2023
65 changes: 58 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exclude = [
[workspace.dependencies]
anyhow = "1.0.47"
base64 = "0.21.0"
blake3 = "1.3.3"
Copy link
Member

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?

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

Copy link
Member

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()
     }
 }

Copy link
Contributor Author

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

Copy link
Member

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.

bytesize = "1.0"
cargo = { path = "" }
cargo-credential = { version = "0.2.0", path = "credential/cargo-credential" }
Expand Down Expand Up @@ -66,6 +67,7 @@ pretty_env_logger = "0.4"
proptest = "1.1.0"
pulldown-cmark = { version = "0.9.2", default-features = false }
rand = "0.8.5"
regex = "1.8.3"
rustfix = "0.6.0"
same-file = "1.0.6"
security-framework = "2.0.0"
Expand All @@ -79,6 +81,7 @@ sha2 = "0.10.6"
shell-escape = "0.1.4"
snapbox = { version = "0.4.0", features = ["diff", "path"] }
strip-ansi-escapes = "0.1.0"
syn = { version = "2.0.14", features = ["extra-traits", "full"] }
tar = { version = "0.4.38", default-features = false }
tempfile = "3.1.0"
termcolor = "1.1.2"
Expand Down Expand Up @@ -112,6 +115,7 @@ path = "src/cargo/lib.rs"
[dependencies]
anyhow.workspace = true
base64.workspace = true
blake3.workspace = true
bytesize.workspace = true
cargo-platform.workspace = true
cargo-util.workspace = true
Expand Down Expand Up @@ -147,7 +151,9 @@ os_info.workspace = true
pasetors.workspace = true
pathdiff.workspace = true
pretty_env_logger = { workspace = true, optional = true }
pulldown-cmark.workspace = true
rand.workspace = true
regex.workspace = true
rustfix.workspace = true
semver.workspace = true
serde = { workspace = true, features = ["derive"] }
Expand All @@ -157,6 +163,7 @@ serde_json = { workspace = true, features = ["raw_value"] }
sha1.workspace = true
shell-escape.workspace = true
strip-ansi-escapes.workspace = true
syn.workspace = true
tar.workspace = true
tempfile.workspace = true
termcolor.workspace = true
Expand Down
4 changes: 3 additions & 1 deletion crates/cargo-test-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ impl FileBuilder {

fn mk(&mut self) {
if self.executable {
self.path.set_extension(env::consts::EXE_EXTENSION);
let mut path = self.path.clone().into_os_string();
write!(path, "{}", env::consts::EXE_SUFFIX).unwrap();
self.path = path.into();
weihanglo marked this conversation as resolved.
Show resolved Hide resolved
}

self.dirname().mkdir_p();
Expand Down
1 change: 1 addition & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ allow = [
"MIT-0",
"Apache-2.0",
"BSD-3-Clause",
"BSD-2-Clause",
weihanglo marked this conversation as resolved.
Show resolved Hide resolved
"MPL-2.0",
"Unicode-DFS-2016",
"CC0-1.0",
Expand Down
91 changes: 77 additions & 14 deletions src/bin/cargo/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ fn expand_aliases(
args: ArgMatches,
mut already_expanded: Vec<String>,
) -> Result<(ArgMatches, GlobalArgs), CliError> {
if let Some((cmd, args)) = args.subcommand() {
if let Some((cmd, sub_args)) = args.subcommand() {
let exec = commands::builtin_exec(cmd);
let aliased_cmd = super::aliased_command(config, cmd);

Expand All @@ -274,7 +274,7 @@ fn expand_aliases(
// Here we ignore errors from aliasing as we already favor built-in command,
// and alias doesn't involve in this context.

if let Some(values) = args.get_many::<OsString>("") {
if let Some(values) = sub_args.get_many::<OsString>("") {
// Command is built-in and is not conflicting with alias, but contains ignored values.
return Err(anyhow::format_err!(
"\
Expand Down Expand Up @@ -305,17 +305,34 @@ For more information, see issue #10049 <https://github.com/rust-lang/cargo/issue
))?;
}
}
if commands::run::is_manifest_command(cmd) {
if config.cli_unstable().script {
return Ok((args, GlobalArgs::default()));
} else {
config.shell().warn(format_args!(
"\
user-defined alias `{cmd}` has the appearance of a manfiest-command
This was previously accepted but will be phased out when `-Zscript` is stabilized.
For more information, see issue #12207 <https://github.com/rust-lang/cargo/issues/12207>."
))?;
}
}

let mut alias = alias
.into_iter()
.map(|s| OsString::from(s))
.collect::<Vec<_>>();
alias.extend(args.get_many::<OsString>("").unwrap_or_default().cloned());
alias.extend(
sub_args
.get_many::<OsString>("")
.unwrap_or_default()
.cloned(),
);
// new_args strips out everything before the subcommand, so
// capture those global options now.
// Note that an alias to an external command will not receive
// these arguments. That may be confusing, but such is life.
let global_args = GlobalArgs::new(args);
let global_args = GlobalArgs::new(sub_args);
let new_args = cli().no_binary_name(true).try_get_matches_from(alias)?;

let new_cmd = new_args.subcommand_name().expect("subcommand is required");
Expand Down Expand Up @@ -382,19 +399,54 @@ fn config_configure(
Ok(())
}

/// Precedence isn't the most obvious from this function because
/// - Some is determined by `expand_aliases`
/// - Some is enforced by `avoid_ambiguity_between_builtins_and_manifest_commands`
///
/// In actuality, it is:
/// 1. built-ins xor manifest-command
/// 2. aliases
weihanglo marked this conversation as resolved.
Show resolved Hide resolved
/// 3. external subcommands
fn execute_subcommand(config: &mut Config, cmd: &str, subcommand_args: &ArgMatches) -> CliResult {
if let Some(exec) = commands::builtin_exec(cmd) {
return exec(config, subcommand_args);
}

let mut ext_args: Vec<&OsStr> = vec![OsStr::new(cmd)];
ext_args.extend(
subcommand_args
.get_many::<OsString>("")
.unwrap_or_default()
.map(OsString::as_os_str),
);
super::execute_external_subcommand(config, cmd, &ext_args)
if commands::run::is_manifest_command(cmd) {
weihanglo marked this conversation as resolved.
Show resolved Hide resolved
let ext_path = super::find_external_subcommand(config, cmd);
if !config.cli_unstable().script && ext_path.is_some() {
config.shell().warn(format_args!(
"\
external subcommand `{cmd}` has the appearance of a manfiest-command
This was previously accepted but will be phased out when `-Zscript` is stabilized.
For more information, see issue #12207 <https://github.com/rust-lang/cargo/issues/12207>.",
))?;
let mut ext_args = vec![OsStr::new(cmd)];
ext_args.extend(
subcommand_args
.get_many::<OsString>("")
.unwrap_or_default()
.map(OsString::as_os_str),
);
super::execute_external_subcommand(config, cmd, &ext_args)
} else {
let ext_args: Vec<OsString> = subcommand_args
.get_many::<OsString>("")
.unwrap_or_default()
.cloned()
.collect();
commands::run::exec_manifest_command(config, cmd, &ext_args)
}
} else {
let mut ext_args = vec![OsStr::new(cmd)];
ext_args.extend(
subcommand_args
.get_many::<OsString>("")
.unwrap_or_default()
.map(OsString::as_os_str),
);
super::execute_external_subcommand(config, cmd, &ext_args)
}
}

#[derive(Default)]
Expand Down Expand Up @@ -438,9 +490,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 <MANIFEST_RS> [ARGS]..."
weihanglo marked this conversation as resolved.
Show resolved Hide resolved
} else {
"cargo [OPTIONS] [COMMAND]"
"cargo [OPTIONS] [COMMAND]\n cargo [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]..."
};
Command::new("cargo")
// Subcommands all count their args' display order independently (from 0),
Expand Down Expand Up @@ -570,3 +622,14 @@ impl LazyConfig {
fn verify_cli() {
cli().debug_assert();
}

#[test]
fn avoid_ambiguity_between_builtins_and_manifest_commands() {
for cmd in commands::builtin() {
let name = cmd.get_name();
assert!(
!commands::run::is_manifest_command(&name),
"built-in command {name} is ambiguous with manifest-commands"
)
}
}
Loading