Skip to content

Commit

Permalink
improvements: parent path of Cargo.toml files are now set as current …
Browse files Browse the repository at this point in the history
…directory when invoking commands

This is to address this weird issue in
rust-lang/cargo#10302.

Related issues about `cargo` improvements are tracked here in
rust-lang/cargo#12738.

Currently, to do this manually, it must be set to the parent path
of Cargo.toml.

Signed-off-by: Soc Virnyl Estela <contact@uncomfyhalomacro.pl>
  • Loading branch information
uncomfyhalomacro committed Nov 17, 2024
1 parent bb7019c commit d3354d8
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 57 deletions.
189 changes: 136 additions & 53 deletions cargo/src/cargo_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,16 @@ pub fn cargo_fetch(curdir: &Path, manifest: &str, respect_lockfile: bool) -> io:
info!("⤵️ Running `cargo fetch`...");
let mut default_options: Vec<String> = vec![];
let manifest_path = PathBuf::from(&manifest);
let manifest_path_parent = manifest_path.parent().unwrap_or(curdir);
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
if !manifest_path.is_file() {
let msg = format!(
"There seems to be no manifest at this path `{}`.",
manifest_path.display()
);
error!(msg, ?manifest_path);
return Err(io::Error::new(io::ErrorKind::NotFound, msg));
}
let manifest_path_parent = manifest_path.parent().unwrap_or(curdir).canonicalize()?;
let possible_lockfile = manifest_path_parent.join("Cargo.lock").canonicalize()?;
if possible_lockfile.is_file() {
if respect_lockfile {
default_options.push("--locked".to_string());
Expand All @@ -51,10 +59,6 @@ pub fn cargo_fetch(curdir: &Path, manifest: &str, respect_lockfile: bool) -> io:
cargo_generate_lockfile(curdir, manifest)?;
info!("🔒Regenerated lockfile.");
}
if !manifest.is_empty() {
default_options.push("--manifest-path".to_string());
default_options.push(manifest.to_string());
}
TARGET_TRIPLES.iter().for_each(|target| {
default_options.push("--target".to_string());
default_options.push(target.to_string());
Expand Down Expand Up @@ -109,13 +113,20 @@ pub fn cargo_vendor(
));
}
} else {
return Err(io::Error::new(
io::ErrorKind::NotFound,
"Failed to vendor as their are no manifest files to use.",
));
let msg = "Failed to vendor as their are no manifest files to use.";
error!(msg, ?manifest_paths);
return Err(io::Error::new(io::ErrorKind::NotFound, msg));
};
} else {
let msg = format!(
"There seems to be no manifest at this path `{}`.",
first_manifest.display()
);
error!(msg, ?first_manifest);
return Err(io::Error::new(io::ErrorKind::NotFound, msg));
}
let first_manifest_parent = first_manifest.parent().unwrap_or(curdir);

let first_manifest_parent = first_manifest.parent().unwrap_or(curdir).canonicalize()?;
let possible_lockfile = first_manifest_parent.join("Cargo.lock");
let is_manifest_workspace = is_workspace(&first_manifest)?;
let has_deps = has_dependencies(&first_manifest)?;
Expand Down Expand Up @@ -174,7 +185,7 @@ pub fn cargo_vendor(
false to true."
);
info!("🔓Attempting to regenerate lockfile...");
cargo_generate_lockfile(curdir, &first_manifest.to_string_lossy())?;
cargo_generate_lockfile(&first_manifest_parent, &first_manifest.to_string_lossy())?;
info!("🔒Regenerated lockfile.");
}

Expand All @@ -194,21 +205,23 @@ pub fn cargo_vendor(
if !update {
warn!("😥 Disabled update of dependencies. You should enable this for security updates.");
}

cargo_update(
update,
crates,
curdir,
&first_manifest_parent,
&first_manifest.to_string_lossy(),
respect_lockfile,
)?;

info!("🚝 Attempting to fetch dependencies.");
cargo_fetch(curdir, &first_manifest.to_string_lossy(), respect_lockfile)?;
info!("💼 Fetched dependencies.");

// NOTE: Vendor filterer's default output format is directory so we
// don't need to set that ourselves.
info!("🏪 Running `cargo {}`...", &which_subcommand);
let res = cargo_command(which_subcommand, &default_options, curdir);
let res = cargo_command(which_subcommand, &default_options, first_manifest_parent);

if possible_lockfile.is_file() {
info!(?possible_lockfile, "🔓 Adding lockfile.");
Expand All @@ -223,10 +236,12 @@ pub fn cargo_vendor(
})?;
}
info!("🛡️🙂 All lockfiles are audited");

if !global_has_deps {
info!("🎉 Nothing to vendor.");
return Ok(None);
}

match res {
Ok(output_cargo_configuration) => {
info!("🏪 `cargo {}` finished.", &which_subcommand);
Expand Down Expand Up @@ -289,9 +304,9 @@ pub fn cargo_update(
let mut default_options = vec![];
if global_update {
info!("⏫ Updating dependencies...");
let manifest_path = PathBuf::from(&manifest);
let manifest_path = PathBuf::from(&manifest).canonicalize()?;
let manifest_path_parent = manifest_path.parent().unwrap_or(curdir);
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
let possible_lockfile = manifest_path_parent.join("Cargo.lock").canonicalize()?;
if !manifest.is_empty() {
default_options.push("--manifest-path".to_string());
default_options.push(manifest.to_string());
Expand All @@ -311,55 +326,123 @@ pub fn cargo_update(
// and user might have specified specific crates to update
if !crates.is_empty() {
for crate_ in crates.iter() {
if let Some((crate_name, crate_ver)) = crate_.split_once("@") {
let mut new_cur_dir = curdir.to_path_buf();
if let Some((crate_name, string_tail)) = crate_.split_once("@") {
default_options.push(crate_name.to_string());
if !crate_ver.trim().is_empty() {
if *crate_ver == *"recursive" {
info!(
"📦🔄 Applying recursive update for crate dependency {}",
crate_name
);
default_options.push("--recursive".to_string());
} else if semver::Version::parse(crate_ver)
.map_err(|err| {
error!(?err);
let msg = format!("Expected a valid version string. Got {}", crate_ver);
io::Error::new(io::ErrorKind::InvalidInput, msg)
})
.is_ok()
{
info!(
if let Some((crate_ver, dependent)) = string_tail.split_once("+") {
if !crate_ver.trim().is_empty() {
if *crate_ver == *"recursive" {
info!(
"📦🔄 Applying recursive update for crate dependency {}",
crate_name
);
default_options.push("--recursive".to_string());
} else if semver::Version::parse(crate_ver)
.map_err(|err| {
error!(?err);
let msg =
format!("Expected a valid version string. Got {}", crate_ver);
io::Error::new(io::ErrorKind::InvalidInput, msg)
})
.is_ok()
{
info!(
"📦🥄 Applying precise update for crate dependency {} to version {}",
crate_name, crate_ver
);
default_options.push("--precise".to_string());
default_options.push(crate_ver.to_string());
} else {
let msg = format!(
"Expected a valid `cargo update` option for {}. Got {}",
default_options.push("--precise".to_string());
default_options.push(crate_ver.to_string());
} else {
let msg = format!(
"Expected a valid `cargo update` option for {}. Got {}",
crate_name, crate_ver
);
return Err(io::Error::new(io::ErrorKind::InvalidInput, msg));
}
}

if !dependent.trim().is_empty() {
info!("🏗️ Updating {} at {}.", crate_name, dependent);
let dependent_manifest_path = curdir.join(dependent).canonicalize()?;
default_options.push("--manifest-path".to_string());
default_options.push(dependent_manifest_path.to_string_lossy().to_string());
let manifest_path_parent =
dependent_manifest_path.parent().unwrap_or(curdir);
new_cur_dir = manifest_path_parent.to_path_buf();
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
if possible_lockfile.is_file() && respect_lockfile {
default_options.push("--locked".to_string());
}
}
}
// NOTE: `+` can be first then `@` second.
} else if let Some((crate_name, string_tail)) = crate_.split_once("+") {
default_options.push(crate_name.to_string());
if let Some((dependent, crate_ver)) = string_tail.split_once("@") {
if !crate_ver.trim().is_empty() {
if *crate_ver == *"recursive" {
info!(
"📦🔄 Applying recursive update for crate dependency {}",
crate_name
);
default_options.push("--recursive".to_string());
} else if semver::Version::parse(crate_ver)
.map_err(|err| {
error!(?err);
let msg =
format!("Expected a valid version string. Got {}", crate_ver);
io::Error::new(io::ErrorKind::InvalidInput, msg)
})
.is_ok()
{
info!(
"📦🥄 Applying precise update for crate dependency {} to version {}",
crate_name, crate_ver
);
return Err(io::Error::new(io::ErrorKind::InvalidInput, msg));
default_options.push("--precise".to_string());
default_options.push(crate_ver.to_string());
} else {
let msg = format!(
"Expected a valid `cargo update` option for {}. Got {}",
crate_name, crate_ver
);
return Err(io::Error::new(io::ErrorKind::InvalidInput, msg));
}
}

if !dependent.trim().is_empty() {
info!("🏗️ Updating {} at {}.", crate_name, dependent);
let dependent_manifest_path = curdir.join(dependent).canonicalize()?;
default_options.push("--manifest-path".to_string());
default_options.push(dependent_manifest_path.to_string_lossy().to_string());
let manifest_path_parent =
dependent_manifest_path.parent().unwrap_or(curdir);
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
new_cur_dir = manifest_path_parent.to_path_buf();
if possible_lockfile.is_file() && respect_lockfile {
default_options.push("--locked".to_string());
}
}
}
}
cargo_command("update", &default_options, new_cur_dir)
.inspect(|_| {
info!("✅ Updated dependencies.");
})
.inspect_err(|err| {
error!(?err);
// There is no point of handling error if a PKGID or crate does not exist for a particular manifest path
// because at the end of the day, if two manifest paths do have the same crate that was specified to update
// then the one in the registry or vendor gets updated with the same version as well.
// NOTE: Maybe in the future we can add ways to be specific on each manifest path
warn!("This error will be ignored.");
})?;
}
let _ = cargo_command("update", &default_options, curdir)
.inspect(|_| {
info!("✅ Updated dependencies.");
})
.inspect_err(|err| {
error!(?err);
// There is no point of handling error if a PKGID or crate does not exist for a particular manifest path
// because at the end of the day, if two manifest paths do have the same crate that was specified to update
// then the one in the registry or vendor gets updated with the same version as well.
// NOTE: Maybe in the future we can add ways to be specific on each manifest path
warn!("This error will be ignored.");
});
Ok("".to_string())
let success_msg = "ℹ️ Finished updating specified crate dependencies.".to_string();
Ok(success_msg)
} else {
let msg = "🫠 Nothing to update.".to_string();
info!("{}", &msg);
Ok(msg)
return Ok(msg);
}
}
2 changes: 1 addition & 1 deletion cargo/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub struct Opts {
pub i_accept_the_risk: Vec<String>,
#[arg(
long,
help = "Set of specific crates to update. If not empty, it will set the global update flag to false. You can specify a valid version string by adding a `@` after the crate name e.g. `foo@1.2.3`. You can also do recursive updates of a crate by appending `recursive` to `@` e.g. `foo@recursive`. However, recursive can't be used with precise. See `cargo help update` for info about how to update specific crates."
help = "Set of specific crates to update. If not empty, it will set the global update flag to false. You can specify a valid version string by adding a `@` after the crate name e.g. `foo@1.2.3`. You can also do recursive updates of a crate by appending `recursive` to `@` e.g. `foo@recursive`. However, recursive can't be used with precise. You can specify a manifest path to update a package with `+` e.g. `foo@1.0+foo/better/Cargo.toml`. See `cargo help update` for info about how to update specific crates."
)]
pub update_crate: Vec<String>,
#[clap(flatten)]
Expand Down
10 changes: 7 additions & 3 deletions cargo/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,21 @@ pub fn run_cargo_vendor_home_registry(
}
}
global_has_deps = has_deps || global_has_deps;
let possible_root_manifest_parent = possible_root_manifest
.parent()
.unwrap_or(custom_root)
.canonicalize()?;
cargo_update(
registry.update,
&registry.update_crate,
custom_root,
&possible_root_manifest_parent,
&possible_root_manifest.to_string_lossy(),
registry.respect_lockfile,
)?;
info!(?setup_workdir, "🌳 Finished setting up workdir.");
info!("🚝 Attempting to fetch dependencies.");
cargo_fetch(
custom_root,
&possible_root_manifest_parent,
&possible_root_manifest.to_string_lossy(),
registry.respect_lockfile,
)?;
Expand Down Expand Up @@ -119,7 +123,7 @@ pub fn run_cargo_vendor_home_registry(
"🚝 Attempting to fetch dependencies at extra manifest path..."
);
cargo_fetch(
custom_root,
full_manifest_path_parent,
&full_manifest_path.to_string_lossy(),
registry.respect_lockfile,
)?;
Expand Down

0 comments on commit d3354d8

Please sign in to comment.