Skip to content

Commit d3354d8

Browse files
improvements: parent path of Cargo.toml files are now set as current 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 <[email protected]>
1 parent bb7019c commit d3354d8

File tree

3 files changed

+144
-57
lines changed

3 files changed

+144
-57
lines changed

cargo/src/cargo_commands.rs

Lines changed: 136 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,16 @@ pub fn cargo_fetch(curdir: &Path, manifest: &str, respect_lockfile: bool) -> io:
4040
info!("⤵️ Running `cargo fetch`...");
4141
let mut default_options: Vec<String> = vec![];
4242
let manifest_path = PathBuf::from(&manifest);
43-
let manifest_path_parent = manifest_path.parent().unwrap_or(curdir);
44-
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
43+
if !manifest_path.is_file() {
44+
let msg = format!(
45+
"There seems to be no manifest at this path `{}`.",
46+
manifest_path.display()
47+
);
48+
error!(msg, ?manifest_path);
49+
return Err(io::Error::new(io::ErrorKind::NotFound, msg));
50+
}
51+
let manifest_path_parent = manifest_path.parent().unwrap_or(curdir).canonicalize()?;
52+
let possible_lockfile = manifest_path_parent.join("Cargo.lock").canonicalize()?;
4553
if possible_lockfile.is_file() {
4654
if respect_lockfile {
4755
default_options.push("--locked".to_string());
@@ -51,10 +59,6 @@ pub fn cargo_fetch(curdir: &Path, manifest: &str, respect_lockfile: bool) -> io:
5159
cargo_generate_lockfile(curdir, manifest)?;
5260
info!("🔒Regenerated lockfile.");
5361
}
54-
if !manifest.is_empty() {
55-
default_options.push("--manifest-path".to_string());
56-
default_options.push(manifest.to_string());
57-
}
5862
TARGET_TRIPLES.iter().for_each(|target| {
5963
default_options.push("--target".to_string());
6064
default_options.push(target.to_string());
@@ -109,13 +113,20 @@ pub fn cargo_vendor(
109113
));
110114
}
111115
} else {
112-
return Err(io::Error::new(
113-
io::ErrorKind::NotFound,
114-
"Failed to vendor as their are no manifest files to use.",
115-
));
116+
let msg = "Failed to vendor as their are no manifest files to use.";
117+
error!(msg, ?manifest_paths);
118+
return Err(io::Error::new(io::ErrorKind::NotFound, msg));
116119
};
120+
} else {
121+
let msg = format!(
122+
"There seems to be no manifest at this path `{}`.",
123+
first_manifest.display()
124+
);
125+
error!(msg, ?first_manifest);
126+
return Err(io::Error::new(io::ErrorKind::NotFound, msg));
117127
}
118-
let first_manifest_parent = first_manifest.parent().unwrap_or(curdir);
128+
129+
let first_manifest_parent = first_manifest.parent().unwrap_or(curdir).canonicalize()?;
119130
let possible_lockfile = first_manifest_parent.join("Cargo.lock");
120131
let is_manifest_workspace = is_workspace(&first_manifest)?;
121132
let has_deps = has_dependencies(&first_manifest)?;
@@ -174,7 +185,7 @@ pub fn cargo_vendor(
174185
false to true."
175186
);
176187
info!("🔓Attempting to regenerate lockfile...");
177-
cargo_generate_lockfile(curdir, &first_manifest.to_string_lossy())?;
188+
cargo_generate_lockfile(&first_manifest_parent, &first_manifest.to_string_lossy())?;
178189
info!("🔒Regenerated lockfile.");
179190
}
180191

@@ -194,21 +205,23 @@ pub fn cargo_vendor(
194205
if !update {
195206
warn!("😥 Disabled update of dependencies. You should enable this for security updates.");
196207
}
208+
197209
cargo_update(
198210
update,
199211
crates,
200-
curdir,
212+
&first_manifest_parent,
201213
&first_manifest.to_string_lossy(),
202214
respect_lockfile,
203215
)?;
216+
204217
info!("🚝 Attempting to fetch dependencies.");
205218
cargo_fetch(curdir, &first_manifest.to_string_lossy(), respect_lockfile)?;
206219
info!("💼 Fetched dependencies.");
207220

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

213226
if possible_lockfile.is_file() {
214227
info!(?possible_lockfile, "🔓 Adding lockfile.");
@@ -223,10 +236,12 @@ pub fn cargo_vendor(
223236
})?;
224237
}
225238
info!("🛡️🙂 All lockfiles are audited");
239+
226240
if !global_has_deps {
227241
info!("🎉 Nothing to vendor.");
228242
return Ok(None);
229243
}
244+
230245
match res {
231246
Ok(output_cargo_configuration) => {
232247
info!("🏪 `cargo {}` finished.", &which_subcommand);
@@ -289,9 +304,9 @@ pub fn cargo_update(
289304
let mut default_options = vec![];
290305
if global_update {
291306
info!("⏫ Updating dependencies...");
292-
let manifest_path = PathBuf::from(&manifest);
307+
let manifest_path = PathBuf::from(&manifest).canonicalize()?;
293308
let manifest_path_parent = manifest_path.parent().unwrap_or(curdir);
294-
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
309+
let possible_lockfile = manifest_path_parent.join("Cargo.lock").canonicalize()?;
295310
if !manifest.is_empty() {
296311
default_options.push("--manifest-path".to_string());
297312
default_options.push(manifest.to_string());
@@ -311,55 +326,123 @@ pub fn cargo_update(
311326
// and user might have specified specific crates to update
312327
if !crates.is_empty() {
313328
for crate_ in crates.iter() {
314-
if let Some((crate_name, crate_ver)) = crate_.split_once("@") {
329+
let mut new_cur_dir = curdir.to_path_buf();
330+
if let Some((crate_name, string_tail)) = crate_.split_once("@") {
315331
default_options.push(crate_name.to_string());
316-
if !crate_ver.trim().is_empty() {
317-
if *crate_ver == *"recursive" {
318-
info!(
319-
"📦🔄 Applying recursive update for crate dependency {}",
320-
crate_name
321-
);
322-
default_options.push("--recursive".to_string());
323-
} else if semver::Version::parse(crate_ver)
324-
.map_err(|err| {
325-
error!(?err);
326-
let msg = format!("Expected a valid version string. Got {}", crate_ver);
327-
io::Error::new(io::ErrorKind::InvalidInput, msg)
328-
})
329-
.is_ok()
330-
{
331-
info!(
332+
if let Some((crate_ver, dependent)) = string_tail.split_once("+") {
333+
if !crate_ver.trim().is_empty() {
334+
if *crate_ver == *"recursive" {
335+
info!(
336+
"📦🔄 Applying recursive update for crate dependency {}",
337+
crate_name
338+
);
339+
default_options.push("--recursive".to_string());
340+
} else if semver::Version::parse(crate_ver)
341+
.map_err(|err| {
342+
error!(?err);
343+
let msg =
344+
format!("Expected a valid version string. Got {}", crate_ver);
345+
io::Error::new(io::ErrorKind::InvalidInput, msg)
346+
})
347+
.is_ok()
348+
{
349+
info!(
332350
"📦🥄 Applying precise update for crate dependency {} to version {}",
333351
crate_name, crate_ver
334352
);
335-
default_options.push("--precise".to_string());
336-
default_options.push(crate_ver.to_string());
337-
} else {
338-
let msg = format!(
339-
"Expected a valid `cargo update` option for {}. Got {}",
353+
default_options.push("--precise".to_string());
354+
default_options.push(crate_ver.to_string());
355+
} else {
356+
let msg = format!(
357+
"Expected a valid `cargo update` option for {}. Got {}",
358+
crate_name, crate_ver
359+
);
360+
return Err(io::Error::new(io::ErrorKind::InvalidInput, msg));
361+
}
362+
}
363+
364+
if !dependent.trim().is_empty() {
365+
info!("🏗️ Updating {} at {}.", crate_name, dependent);
366+
let dependent_manifest_path = curdir.join(dependent).canonicalize()?;
367+
default_options.push("--manifest-path".to_string());
368+
default_options.push(dependent_manifest_path.to_string_lossy().to_string());
369+
let manifest_path_parent =
370+
dependent_manifest_path.parent().unwrap_or(curdir);
371+
new_cur_dir = manifest_path_parent.to_path_buf();
372+
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
373+
if possible_lockfile.is_file() && respect_lockfile {
374+
default_options.push("--locked".to_string());
375+
}
376+
}
377+
}
378+
// NOTE: `+` can be first then `@` second.
379+
} else if let Some((crate_name, string_tail)) = crate_.split_once("+") {
380+
default_options.push(crate_name.to_string());
381+
if let Some((dependent, crate_ver)) = string_tail.split_once("@") {
382+
if !crate_ver.trim().is_empty() {
383+
if *crate_ver == *"recursive" {
384+
info!(
385+
"📦🔄 Applying recursive update for crate dependency {}",
386+
crate_name
387+
);
388+
default_options.push("--recursive".to_string());
389+
} else if semver::Version::parse(crate_ver)
390+
.map_err(|err| {
391+
error!(?err);
392+
let msg =
393+
format!("Expected a valid version string. Got {}", crate_ver);
394+
io::Error::new(io::ErrorKind::InvalidInput, msg)
395+
})
396+
.is_ok()
397+
{
398+
info!(
399+
"📦🥄 Applying precise update for crate dependency {} to version {}",
340400
crate_name, crate_ver
341401
);
342-
return Err(io::Error::new(io::ErrorKind::InvalidInput, msg));
402+
default_options.push("--precise".to_string());
403+
default_options.push(crate_ver.to_string());
404+
} else {
405+
let msg = format!(
406+
"Expected a valid `cargo update` option for {}. Got {}",
407+
crate_name, crate_ver
408+
);
409+
return Err(io::Error::new(io::ErrorKind::InvalidInput, msg));
410+
}
411+
}
412+
413+
if !dependent.trim().is_empty() {
414+
info!("🏗️ Updating {} at {}.", crate_name, dependent);
415+
let dependent_manifest_path = curdir.join(dependent).canonicalize()?;
416+
default_options.push("--manifest-path".to_string());
417+
default_options.push(dependent_manifest_path.to_string_lossy().to_string());
418+
let manifest_path_parent =
419+
dependent_manifest_path.parent().unwrap_or(curdir);
420+
let possible_lockfile = manifest_path_parent.join("Cargo.lock");
421+
new_cur_dir = manifest_path_parent.to_path_buf();
422+
if possible_lockfile.is_file() && respect_lockfile {
423+
default_options.push("--locked".to_string());
424+
}
343425
}
344426
}
345427
}
428+
cargo_command("update", &default_options, new_cur_dir)
429+
.inspect(|_| {
430+
info!("✅ Updated dependencies.");
431+
})
432+
.inspect_err(|err| {
433+
error!(?err);
434+
// There is no point of handling error if a PKGID or crate does not exist for a particular manifest path
435+
// because at the end of the day, if two manifest paths do have the same crate that was specified to update
436+
// then the one in the registry or vendor gets updated with the same version as well.
437+
// NOTE: Maybe in the future we can add ways to be specific on each manifest path
438+
warn!("This error will be ignored.");
439+
})?;
346440
}
347-
let _ = cargo_command("update", &default_options, curdir)
348-
.inspect(|_| {
349-
info!("✅ Updated dependencies.");
350-
})
351-
.inspect_err(|err| {
352-
error!(?err);
353-
// There is no point of handling error if a PKGID or crate does not exist for a particular manifest path
354-
// because at the end of the day, if two manifest paths do have the same crate that was specified to update
355-
// then the one in the registry or vendor gets updated with the same version as well.
356-
// NOTE: Maybe in the future we can add ways to be specific on each manifest path
357-
warn!("This error will be ignored.");
358-
});
359-
Ok("".to_string())
441+
let success_msg = "ℹ️ Finished updating specified crate dependencies.".to_string();
442+
Ok(success_msg)
360443
} else {
361444
let msg = "🫠 Nothing to update.".to_string();
362445
info!("{}", &msg);
363-
Ok(msg)
446+
return Ok(msg);
364447
}
365448
}

cargo/src/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ pub struct Opts {
113113
pub i_accept_the_risk: Vec<String>,
114114
#[arg(
115115
long,
116-
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. `[email protected]`. 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."
116+
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. `[email protected]`. 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. `[email protected]+foo/better/Cargo.toml`. See `cargo help update` for info about how to update specific crates."
117117
)]
118118
pub update_crate: Vec<String>,
119119
#[clap(flatten)]

cargo/src/registry.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,21 @@ pub fn run_cargo_vendor_home_registry(
5454
}
5555
}
5656
global_has_deps = has_deps || global_has_deps;
57+
let possible_root_manifest_parent = possible_root_manifest
58+
.parent()
59+
.unwrap_or(custom_root)
60+
.canonicalize()?;
5761
cargo_update(
5862
registry.update,
5963
&registry.update_crate,
60-
custom_root,
64+
&possible_root_manifest_parent,
6165
&possible_root_manifest.to_string_lossy(),
6266
registry.respect_lockfile,
6367
)?;
6468
info!(?setup_workdir, "🌳 Finished setting up workdir.");
6569
info!("🚝 Attempting to fetch dependencies.");
6670
cargo_fetch(
67-
custom_root,
71+
&possible_root_manifest_parent,
6872
&possible_root_manifest.to_string_lossy(),
6973
registry.respect_lockfile,
7074
)?;
@@ -119,7 +123,7 @@ pub fn run_cargo_vendor_home_registry(
119123
"🚝 Attempting to fetch dependencies at extra manifest path..."
120124
);
121125
cargo_fetch(
122-
custom_root,
126+
full_manifest_path_parent,
123127
&full_manifest_path.to_string_lossy(),
124128
registry.respect_lockfile,
125129
)?;

0 commit comments

Comments
 (0)