From 577e6503a6558e8680de5c85aa1de21306ef945e Mon Sep 17 00:00:00 2001 From: Francis Nixon Date: Tue, 15 Jun 2021 14:52:33 -0400 Subject: [PATCH 1/6] Initial failing test creation. --- Cargo.toml | 2 + crates/cargo-test-support/src/git.rs | 5 ++- tests/testsuite/git.rs | 57 ++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index af1946dd8ad..8e1d666d1f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,6 +101,8 @@ features = [ [dev-dependencies] cargo-test-macro = { path = "crates/cargo-test-macro" } cargo-test-support = { path = "crates/cargo-test-support" } +pathdiff = "0.2.0" +regex = "1" [build-dependencies] flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] } diff --git a/crates/cargo-test-support/src/git.rs b/crates/cargo-test-support/src/git.rs index 18c4646b37d..0cdf5c24829 100644 --- a/crates/cargo-test-support/src/git.rs +++ b/crates/cargo-test-support/src/git.rs @@ -211,7 +211,10 @@ pub fn add_submodule<'a>( default_repo_cfg(&subrepo); t!(subrepo.remote_add_fetch("origin", "refs/heads/*:refs/heads/*")); let mut origin = t!(subrepo.find_remote("origin")); - t!(origin.fetch(&Vec::::new(), None, None)); + dbg!(path); + let fetch = origin.fetch(&Vec::::new(), None, None); + dbg!(&fetch); + t!(fetch); t!(subrepo.checkout_head(None)); t!(s.add_finalize()); s diff --git a/tests/testsuite/git.rs b/tests/testsuite/git.rs index d7974a3ef87..c53abf81276 100644 --- a/tests/testsuite/git.rs +++ b/tests/testsuite/git.rs @@ -13,6 +13,9 @@ use std::thread; use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project}; use cargo_test_support::{sleep_ms, t, Project}; +use pathdiff::diff_paths; +use std::fs::File; +use regex::Regex; fn disable_git_cli() -> bool { // mingw git on Windows does not support Windows-style file URIs. @@ -943,6 +946,60 @@ fn dep_with_submodule() { .run(); } +#[cargo_test] +fn dep_with_relative_submodule() { + + + let foo = project(); + let base = git::new("base/base", |project| { + project.file("Cargo.toml", &basic_lib_manifest("base")) + .file("src/lib.rs", "pub fn dep() {}") + }); + let deployment = git::new("deployment", |project| project.file("src/lib.rs", "pub fn dep() {}")); + + let base_repo = git2::Repository::open(&base.root()).unwrap(); + let temp = base.root().join("../../deployment").canonicalize().unwrap(); + let deployment_url = temp.to_str().unwrap(); + git::add_submodule(&base_repo, "../../deployment", Path::new("deployment")); + git::commit(&base_repo); + + let project = foo + .file( + "Cargo.toml", + &format!( + r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.base] + + git = '{}' + "#, + base.url() + ), + ) + .file( + "src/lib.rs", + "pub fn foo() { }", + ) + .build(); + + project + .cargo("build") + .with_stderr( + "\ +[UPDATING] git repository [..] +[UPDATING] git submodule `file://[..]/dep2` +[COMPILING] dep1 [..] +[COMPILING] foo [..] +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", + ) + .run(); +} + #[cargo_test] fn dep_with_bad_submodule() { let project = project(); From 42edf9f14d6f1b80ace9318965d357aceb91f10b Mon Sep 17 00:00:00 2001 From: Francis Nixon Date: Wed, 16 Jun 2021 16:39:52 -0400 Subject: [PATCH 2/6] Initial hacky fix. --- src/cargo/sources/git/source.rs | 4 ++- src/cargo/sources/git/utils.rs | 61 +++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 9d7c42b829f..87ba64c4bbf 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -173,7 +173,9 @@ impl<'cfg> Source for GitSource<'cfg> { .join("checkouts") .join(&self.ident) .join(short_id.as_str()); - db.copy_to(actual_rev, &checkout_path, self.config)?; + let parent_remote_url = self.url(); + dbg!(parent_remote_url); + db.copy_to(actual_rev, &checkout_path, self.config,parent_remote_url)?; let source_id = self.source_id.with_precise(Some(actual_rev.to_string())); let path_source = PathSource::new_recursive(&checkout_path, source_id, self.config); diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 507ba90bb1b..7679505fbaf 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -16,7 +16,8 @@ use std::fmt; use std::path::{Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; -use url::Url; +use url::{Url, ParseError}; +use cargo_util::paths::normalize_path; fn serialize_str(t: &T, s: S) -> Result where @@ -150,6 +151,7 @@ impl GitDatabase { rev: git2::Oid, dest: &Path, cargo_config: &Config, + parent_remote_url: &Url ) -> CargoResult> { let mut checkout = None; if let Ok(repo) = git2::Repository::open(dest) { @@ -177,7 +179,7 @@ impl GitDatabase { Some(c) => c, None => GitCheckout::clone_into(dest, self, rev, cargo_config)?, }; - checkout.update_submodules(cargo_config)?; + checkout.update_submodules(cargo_config, parent_remote_url)?; Ok(checkout) } @@ -343,14 +345,14 @@ impl<'a> GitCheckout<'a> { Ok(()) } - fn update_submodules(&self, cargo_config: &Config) -> CargoResult<()> { - return update_submodules(&self.repo, cargo_config); + fn update_submodules(&self, cargo_config: &Config, parent_remote_url: &Url) -> CargoResult<()> { + return update_submodules(&self.repo, cargo_config,parent_remote_url); - fn update_submodules(repo: &git2::Repository, cargo_config: &Config) -> CargoResult<()> { + fn update_submodules(repo: &git2::Repository, cargo_config: &Config, parent_remote_url: &Url) -> CargoResult<()> { info!("update submodules for: {:?}", repo.workdir().unwrap()); for mut child in repo.submodules()? { - update_submodule(repo, &mut child, cargo_config).with_context(|| { + update_submodule(repo, &mut child, cargo_config, parent_remote_url).with_context(|| { format!( "failed to update submodule `{}`", child.name().unwrap_or("") @@ -364,12 +366,49 @@ impl<'a> GitCheckout<'a> { parent: &git2::Repository, child: &mut git2::Submodule<'_>, cargo_config: &Config, + parent_remote_url: &Url ) -> CargoResult<()> { child.init(false)?; - let url = child.url().ok_or_else(|| { + + let child_url = Url::parse(child.url().ok_or_else(|| { anyhow::format_err!("non-utf8 url for submodule {:?}?", child.path()) - })?; + })?); + + + + let url = match child_url{ + Ok(child_url) => { + if Path::new(child_url.path()).is_relative(){ + let s = parent_remote_url.path(); + dbg!(&s); + normalize_path(&Path::new(s).join(Path::new(child_url.path()))).to_string_lossy().to_string() + } else { + child_url.to_string() + } + } + Err(ParseError::RelativeUrlWithoutBase) => { + let path = parent_remote_url.path(); + let mut new_parent_remote_url = parent_remote_url.clone(); + new_parent_remote_url.set_path(format!("{}/", path).as_str()); + dbg!(&new_parent_remote_url); + new_parent_remote_url = new_parent_remote_url.join(child.url().unwrap()).unwrap(); + dbg!(&new_parent_remote_url); + new_parent_remote_url.to_string() + } + Err(err) => panic!()//todo actually an error + }; + + + /*if Path::new(child_url.path()).is_relative(){ + dbg!(parent_remote_url); + // dbg!(child_url); + let s = parent_remote_url.path(); + normalize_path(&Path::new(s).join(Path::new(child_url.path()))).to_string_lossy().to_string() + }else{ + child_url.to_string() + };*/ + dbg!(&url); // A submodule which is listed in .gitmodules but not actually // checked out will not have a head id, so we should ignore it. let head = match child.head_id() { @@ -388,7 +427,7 @@ impl<'a> GitCheckout<'a> { let mut repo = match head_and_repo { Ok((head, repo)) => { if child.head_id() == head { - return update_submodules(&repo, cargo_config); + return update_submodules(&repo, cargo_config, parent_remote_url); } repo } @@ -403,7 +442,7 @@ impl<'a> GitCheckout<'a> { cargo_config .shell() .status("Updating", format!("git submodule `{}`", url))?; - fetch(&mut repo, url, &reference, cargo_config).with_context(|| { + fetch(&mut repo, &url, &reference, cargo_config).with_context(|| { format!( "failed to fetch submodule `{}` from {}", child.name().unwrap_or(""), @@ -413,7 +452,7 @@ impl<'a> GitCheckout<'a> { let obj = repo.find_object(head, None)?; reset(&repo, &obj, cargo_config)?; - update_submodules(&repo, cargo_config) + update_submodules(&repo, cargo_config, parent_remote_url) } } } From ca756fb03d5831ebe2445c8e3796a8961c32545c Mon Sep 17 00:00:00 2001 From: Francis Nixon Date: Thu, 17 Jun 2021 10:00:29 -0400 Subject: [PATCH 3/6] Some commenting and cleanup. --- Cargo.toml | 2 - crates/cargo-test-support/src/git.rs | 5 +- src/cargo/sources/git/source.rs | 3 +- src/cargo/sources/git/utils.rs | 91 ++++++++++++++++------------ tests/testsuite/git.rs | 25 +++----- 5 files changed, 64 insertions(+), 62 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8e1d666d1f9..af1946dd8ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,8 +101,6 @@ features = [ [dev-dependencies] cargo-test-macro = { path = "crates/cargo-test-macro" } cargo-test-support = { path = "crates/cargo-test-support" } -pathdiff = "0.2.0" -regex = "1" [build-dependencies] flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] } diff --git a/crates/cargo-test-support/src/git.rs b/crates/cargo-test-support/src/git.rs index 0cdf5c24829..18c4646b37d 100644 --- a/crates/cargo-test-support/src/git.rs +++ b/crates/cargo-test-support/src/git.rs @@ -211,10 +211,7 @@ pub fn add_submodule<'a>( default_repo_cfg(&subrepo); t!(subrepo.remote_add_fetch("origin", "refs/heads/*:refs/heads/*")); let mut origin = t!(subrepo.find_remote("origin")); - dbg!(path); - let fetch = origin.fetch(&Vec::::new(), None, None); - dbg!(&fetch); - t!(fetch); + t!(origin.fetch(&Vec::::new(), None, None)); t!(subrepo.checkout_head(None)); t!(s.add_finalize()); s diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 87ba64c4bbf..1dbabe6e79c 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -174,8 +174,7 @@ impl<'cfg> Source for GitSource<'cfg> { .join(&self.ident) .join(short_id.as_str()); let parent_remote_url = self.url(); - dbg!(parent_remote_url); - db.copy_to(actual_rev, &checkout_path, self.config,parent_remote_url)?; + db.copy_to(actual_rev, &checkout_path, self.config, parent_remote_url)?; let source_id = self.source_id.with_precise(Some(actual_rev.to_string())); let path_source = PathSource::new_recursive(&checkout_path, source_id, self.config); diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 7679505fbaf..0fccf2d6588 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -5,6 +5,7 @@ use crate::core::GitReference; use crate::util::errors::CargoResult; use crate::util::{network, Config, IntoUrl, MetricsCounter, Progress}; use anyhow::{anyhow, Context as _}; +use cargo_util::paths::normalize_path; use cargo_util::{paths, ProcessBuilder}; use curl::easy::List; use git2::{self, ErrorClass, ObjectType}; @@ -16,8 +17,7 @@ use std::fmt; use std::path::{Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; -use url::{Url, ParseError}; -use cargo_util::paths::normalize_path; +use url::{ParseError, Url}; fn serialize_str(t: &T, s: S) -> Result where @@ -151,7 +151,7 @@ impl GitDatabase { rev: git2::Oid, dest: &Path, cargo_config: &Config, - parent_remote_url: &Url + parent_remote_url: &Url, ) -> CargoResult> { let mut checkout = None; if let Ok(repo) = git2::Repository::open(dest) { @@ -346,18 +346,24 @@ impl<'a> GitCheckout<'a> { } fn update_submodules(&self, cargo_config: &Config, parent_remote_url: &Url) -> CargoResult<()> { - return update_submodules(&self.repo, cargo_config,parent_remote_url); + return update_submodules(&self.repo, cargo_config, parent_remote_url); - fn update_submodules(repo: &git2::Repository, cargo_config: &Config, parent_remote_url: &Url) -> CargoResult<()> { + fn update_submodules( + repo: &git2::Repository, + cargo_config: &Config, + parent_remote_url: &Url, + ) -> CargoResult<()> { info!("update submodules for: {:?}", repo.workdir().unwrap()); for mut child in repo.submodules()? { - update_submodule(repo, &mut child, cargo_config, parent_remote_url).with_context(|| { - format!( - "failed to update submodule `{}`", - child.name().unwrap_or("") - ) - })?; + update_submodule(repo, &mut child, cargo_config, parent_remote_url).with_context( + || { + format!( + "failed to update submodule `{}`", + child.name().unwrap_or("") + ) + }, + )?; } Ok(()) } @@ -366,22 +372,35 @@ impl<'a> GitCheckout<'a> { parent: &git2::Repository, child: &mut git2::Submodule<'_>, cargo_config: &Config, - parent_remote_url: &Url + parent_remote_url: &Url, ) -> CargoResult<()> { child.init(false)?; - let child_url = Url::parse(child.url().ok_or_else(|| { + let child_url_str = child.url().ok_or_else(|| { anyhow::format_err!("non-utf8 url for submodule {:?}?", child.path()) - })?); - - + })?; - let url = match child_url{ + //There are a few possible cases here: + // 1. Submodule URL is not relative. + // Happy path, Url is just the submodule url. + // 2. Submodule URL is relative and does specify ssh/https/file/etc. + // We combine the parent path and relative path. + // 3. Submodule URL is relative and does not specify ssh/https/file/etc. + // In which case we fail to parse with the error ParseError::RelativeUrlWithoutBase. + // We then combine the relative url with the host/protocol from the parent url. + // 4. We fail to parse submodule url for some reason. + // Error. Gets passed up. + let url = match Url::parse(child_url_str) { Ok(child_url) => { - if Path::new(child_url.path()).is_relative(){ - let s = parent_remote_url.path(); - dbg!(&s); - normalize_path(&Path::new(s).join(Path::new(child_url.path()))).to_string_lossy().to_string() + if Path::new(child_url.path()).is_relative() { + let parent_remote_path = Path::new(parent_remote_url.path()); + let child_remote_path = Path::new(child_url.path()); + let normalized_path_buf = + normalize_path(&parent_remote_path.join(child_remote_path)); + normalized_path_buf + .to_str() + .expect("We had a utf-8 url earlier, but now we don't?") + .to_string() } else { child_url.to_string() } @@ -390,25 +409,21 @@ impl<'a> GitCheckout<'a> { let path = parent_remote_url.path(); let mut new_parent_remote_url = parent_remote_url.clone(); new_parent_remote_url.set_path(format!("{}/", path).as_str()); - dbg!(&new_parent_remote_url); - new_parent_remote_url = new_parent_remote_url.join(child.url().unwrap()).unwrap(); - dbg!(&new_parent_remote_url); + new_parent_remote_url = match new_parent_remote_url.join(child_url_str) { + Ok(x) => x, + Err(err) => Err(err) + .with_context(|| format!("Failed to parse child submodule url"))?, + }; new_parent_remote_url.to_string() } - Err(err) => panic!()//todo actually an error + Err(err) => { + return Err(anyhow::format_err!( + "Error parsing submodule url: {:?}?", + err + )) + } }; - - /*if Path::new(child_url.path()).is_relative(){ - dbg!(parent_remote_url); - // dbg!(child_url); - let s = parent_remote_url.path(); - normalize_path(&Path::new(s).join(Path::new(child_url.path()))).to_string_lossy().to_string() - }else{ - child_url.to_string() - };*/ - - dbg!(&url); // A submodule which is listed in .gitmodules but not actually // checked out will not have a head id, so we should ignore it. let head = match child.head_id() { @@ -441,12 +456,12 @@ impl<'a> GitCheckout<'a> { let reference = GitReference::Rev(head.to_string()); cargo_config .shell() - .status("Updating", format!("git submodule `{}`", url))?; + .status("Updating", format!("git submodule `{}`", url.as_str()))?; fetch(&mut repo, &url, &reference, cargo_config).with_context(|| { format!( "failed to fetch submodule `{}` from {}", child.name().unwrap_or(""), - url + url.as_str() ) })?; diff --git a/tests/testsuite/git.rs b/tests/testsuite/git.rs index c53abf81276..9212295884a 100644 --- a/tests/testsuite/git.rs +++ b/tests/testsuite/git.rs @@ -13,9 +13,6 @@ use std::thread; use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project}; use cargo_test_support::{sleep_ms, t, Project}; -use pathdiff::diff_paths; -use std::fs::File; -use regex::Regex; fn disable_git_cli() -> bool { // mingw git on Windows does not support Windows-style file URIs. @@ -938,8 +935,8 @@ fn dep_with_submodule() { .with_stderr( "\ [UPDATING] git repository [..] -[UPDATING] git submodule `file://[..]/dep2` -[COMPILING] dep1 [..] +[UPDATING] git submodule `file://[..]/deployment` +[COMPILING] base [..] [COMPILING] foo [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", ) @@ -947,19 +944,18 @@ fn dep_with_submodule() { } #[cargo_test] -fn dep_with_relative_submodule() { - - +fn dep_with_relative_submodule() { let foo = project(); let base = git::new("base/base", |project| { - project.file("Cargo.toml", &basic_lib_manifest("base")) + project + .file("Cargo.toml", &basic_lib_manifest("base")) .file("src/lib.rs", "pub fn dep() {}") }); - let deployment = git::new("deployment", |project| project.file("src/lib.rs", "pub fn dep() {}")); + let _deployment = git::new("deployment", |project| { + project.file("src/lib.rs", "pub fn dep() {}") + }); let base_repo = git2::Repository::open(&base.root()).unwrap(); - let temp = base.root().join("../../deployment").canonicalize().unwrap(); - let deployment_url = temp.to_str().unwrap(); git::add_submodule(&base_repo, "../../deployment", Path::new("deployment")); git::commit(&base_repo); @@ -981,10 +977,7 @@ fn dep_with_relative_submodule() { base.url() ), ) - .file( - "src/lib.rs", - "pub fn foo() { }", - ) + .file("src/lib.rs", "pub fn foo() { }") .build(); project From 4cae394ee2872d49b68801cfffa42bc91edf16f7 Mon Sep 17 00:00:00 2001 From: Francis Nixon Date: Mon, 21 Jun 2021 14:47:51 -0400 Subject: [PATCH 4/6] Acted on making deployment a dependency of base to verify it was checked out correctly --- tests/testsuite/git.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/tests/testsuite/git.rs b/tests/testsuite/git.rs index 9212295884a..f63c84f2b04 100644 --- a/tests/testsuite/git.rs +++ b/tests/testsuite/git.rs @@ -936,6 +936,7 @@ fn dep_with_submodule() { "\ [UPDATING] git repository [..] [UPDATING] git submodule `file://[..]/deployment` +[COMPILING] deployment [..] [COMPILING] base [..] [COMPILING] foo [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", @@ -946,17 +947,36 @@ fn dep_with_submodule() { #[cargo_test] fn dep_with_relative_submodule() { let foo = project(); - let base = git::new("base/base", |project| { + let base = git::new("base", |project| { project - .file("Cargo.toml", &basic_lib_manifest("base")) - .file("src/lib.rs", "pub fn dep() {}") + .file( + "Cargo.toml", + r#" + [package] + name = "base" + version = "0.5.0" + + [dependencies] + deployment.path = "deployment" + "#, + ) + .file( + "src/lib.rs", + r#" + pub fn dep() { + deployment::deployment_func(); + } + "#, + ) }); let _deployment = git::new("deployment", |project| { - project.file("src/lib.rs", "pub fn dep() {}") + project + .file("src/lib.rs", "pub fn deployment_func() {}") + .file("Cargo.toml", &basic_lib_manifest("deployment")) }); let base_repo = git2::Repository::open(&base.root()).unwrap(); - git::add_submodule(&base_repo, "../../deployment", Path::new("deployment")); + git::add_submodule(&base_repo, "../deployment", Path::new("deployment")); git::commit(&base_repo); let project = foo @@ -965,13 +985,10 @@ fn dep_with_relative_submodule() { &format!( r#" [project] - name = "foo" version = "0.5.0" - authors = ["wycats@example.com"] [dependencies.base] - git = '{}' "#, base.url() From 3f34aab9f3ae116830b1a8bcbda1310d33ae3c31 Mon Sep 17 00:00:00 2001 From: Francis Nixon Date: Fri, 10 Sep 2021 15:07:09 -0400 Subject: [PATCH 5/6] update tests for rebase --- tests/testsuite/git.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/testsuite/git.rs b/tests/testsuite/git.rs index f63c84f2b04..4b86b5d9492 100644 --- a/tests/testsuite/git.rs +++ b/tests/testsuite/git.rs @@ -935,9 +935,8 @@ fn dep_with_submodule() { .with_stderr( "\ [UPDATING] git repository [..] -[UPDATING] git submodule `file://[..]/deployment` -[COMPILING] deployment [..] -[COMPILING] base [..] +[UPDATING] git submodule `file://[..]/dep2` +[COMPILING] dep1 [..] [COMPILING] foo [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", ) @@ -1002,8 +1001,9 @@ fn dep_with_relative_submodule() { .with_stderr( "\ [UPDATING] git repository [..] -[UPDATING] git submodule `file://[..]/dep2` -[COMPILING] dep1 [..] +[UPDATING] git submodule `file://[..]/deployment` +[COMPILING] deployment [..] +[COMPILING] base [..] [COMPILING] foo [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", ) From 552dca11d6e8482d07b1f278b3311700af1eb412 Mon Sep 17 00:00:00 2001 From: Francis Nixon <13nixonf@gmail.com> Date: Sun, 12 Sep 2021 23:51:15 -0400 Subject: [PATCH 6/6] hopefully fix things on windows. --- src/cargo/sources/git/utils.rs | 41 +++++++++++++++++++--------------- tests/testsuite/config.rs | 2 ++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 0fccf2d6588..715799368da 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -1,9 +1,13 @@ //! Utilities for handling git repositories, mainly around //! authentication/cloning. -use crate::core::GitReference; -use crate::util::errors::CargoResult; -use crate::util::{network, Config, IntoUrl, MetricsCounter, Progress}; +use std::env; +use std::fmt; +use std::fs::canonicalize; +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::time::{Duration, Instant}; + use anyhow::{anyhow, Context as _}; use cargo_util::paths::normalize_path; use cargo_util::{paths, ProcessBuilder}; @@ -12,13 +16,12 @@ use git2::{self, ErrorClass, ObjectType}; use log::{debug, info}; use serde::ser; use serde::Serialize; -use std::env; -use std::fmt; -use std::path::{Path, PathBuf}; -use std::process::Command; -use std::time::{Duration, Instant}; use url::{ParseError, Url}; +use crate::core::GitReference; +use crate::util::errors::CargoResult; +use crate::util::{network, Config, IntoUrl, MetricsCounter, Progress}; + fn serialize_str(t: &T, s: S) -> Result where T: fmt::Display, @@ -395,12 +398,12 @@ impl<'a> GitCheckout<'a> { if Path::new(child_url.path()).is_relative() { let parent_remote_path = Path::new(parent_remote_url.path()); let child_remote_path = Path::new(child_url.path()); - let normalized_path_buf = - normalize_path(&parent_remote_path.join(child_remote_path)); - normalized_path_buf - .to_str() - .expect("We had a utf-8 url earlier, but now we don't?") - .to_string() + let canonical = canonicalize(normalize_path( + &parent_remote_path.join(child_remote_path), + ))?; + let mut final_path = parent_remote_url.clone(); + final_path.set_path(canonical.to_string_lossy().as_ref()); + final_path.to_string() } else { child_url.to_string() } @@ -414,13 +417,15 @@ impl<'a> GitCheckout<'a> { Err(err) => Err(err) .with_context(|| format!("Failed to parse child submodule url"))?, }; + let final_path = canonicalize(Path::new(new_parent_remote_url.path()))?; + new_parent_remote_url.set_path(final_path.to_string_lossy().as_ref()); new_parent_remote_url.to_string() } Err(err) => { return Err(anyhow::format_err!( "Error parsing submodule url: {:?}?", err - )) + )); } }; @@ -700,9 +705,9 @@ where msg.push_str("https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli"); err = err.context(msg); - // Otherwise if we didn't even get to the authentication phase them we may - // have failed to set up a connection, in these cases hint on the - // `net.git-fetch-with-cli` configuration option. + // Otherwise if we didn't even get to the authentication phase them we may + // have failed to set up a connection, in these cases hint on the + // `net.git-fetch-with-cli` configuration option. } else if let Some(e) = err.downcast_ref::() { match e.class() { ErrorClass::Net diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs index 1468cdef39a..aaf8e1affa5 100644 --- a/tests/testsuite/config.rs +++ b/tests/testsuite/config.rs @@ -655,6 +655,7 @@ Caused by: invalid value: integer `123456789`, expected i8", ); + #[allow(dead_code)] #[derive(Debug, Deserialize)] struct S { f1: i64, @@ -1154,6 +1155,7 @@ fn table_merge_failure() { ", ); + #[allow(dead_code)] #[derive(Debug, Deserialize)] struct Table { key: StringList,