mirror of
https://github.com/rust-lang/cargo
synced 2024-10-13 19:22:33 +00:00
Fix error with git repo discovery and symlinks.
This commit is contained in:
parent
ba832aca75
commit
5bd74c41c4
|
@ -197,13 +197,18 @@ impl<'cfg> PathSource<'cfg> {
|
|||
repo.path().display()
|
||||
)
|
||||
})?;
|
||||
let repo_relative_path = root.strip_prefix(repo_root).chain_err(|| {
|
||||
format!(
|
||||
"expected git repo {} to be parent of package {}",
|
||||
repo.path().display(),
|
||||
root.display()
|
||||
)
|
||||
})?;
|
||||
let repo_relative_path = match paths::strip_prefix_canonical(root, repo_root) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
log::warn!(
|
||||
"cannot determine if path `{:?}` is in git repo `{:?}`: {:?}",
|
||||
root,
|
||||
repo_root,
|
||||
e
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
let manifest_path = repo_relative_path.join("Cargo.toml");
|
||||
if index.get_path(&manifest_path, 0).is_some() {
|
||||
return Ok(Some(self.list_files_git(pkg, &repo, filter)?));
|
||||
|
|
|
@ -411,3 +411,25 @@ pub fn set_file_time_no_err<P: AsRef<Path>>(path: P, time: FileTime) {
|
|||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Strips `base` from `path`.
|
||||
///
|
||||
/// This canonicalizes both paths before stripping. This is useful if the
|
||||
/// paths are obtained in different ways, and one or the other may or may not
|
||||
/// have been normalized in some way.
|
||||
pub fn strip_prefix_canonical<P: AsRef<Path>>(
|
||||
path: P,
|
||||
base: P,
|
||||
) -> Result<PathBuf, std::path::StripPrefixError> {
|
||||
// Not all filesystems support canonicalize. Just ignore if it doesn't work.
|
||||
let safe_canonicalize = |path: &Path| match path.canonicalize() {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
log::warn!("cannot canonicalize {:?}: {:?}", path, e);
|
||||
path.to_path_buf()
|
||||
}
|
||||
};
|
||||
let canon_path = safe_canonicalize(path.as_ref());
|
||||
let canon_base = safe_canonicalize(base.as_ref());
|
||||
canon_path.strip_prefix(canon_base).map(|p| p.to_path_buf())
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ use cargo_test_support::install::{
|
|||
};
|
||||
use cargo_test_support::paths;
|
||||
use cargo_test_support::registry::Package;
|
||||
use cargo_test_support::{basic_manifest, cargo_process, project, NO_SUCH_FILE_ERR_MSG};
|
||||
use cargo_test_support::{
|
||||
basic_manifest, cargo_process, project, symlink_supported, t, NO_SUCH_FILE_ERR_MSG,
|
||||
};
|
||||
|
||||
fn pkg(name: &str, vers: &str) {
|
||||
Package::new(name, vers)
|
||||
|
@ -1458,3 +1460,40 @@ fn git_install_reads_workspace_manifest() {
|
|||
.with_stderr_contains(" invalid type: integer `3`[..]")
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn install_git_with_symlink_home() {
|
||||
// Ensure that `cargo install` with a git repo is OK when CARGO_HOME is a
|
||||
// symlink, and uses an build script.
|
||||
if !symlink_supported() {
|
||||
return;
|
||||
}
|
||||
let p = git::new("foo", |p| {
|
||||
p.file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
// This triggers discover_git_and_list_files for detecting changed files.
|
||||
.file("build.rs", "fn main() {}")
|
||||
});
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::symlink;
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::fs::symlink_dir as symlink;
|
||||
|
||||
let actual = paths::root().join("actual-home");
|
||||
t!(std::fs::create_dir(&actual));
|
||||
t!(symlink(&actual, paths::home().join(".cargo")));
|
||||
cargo_process("install --git")
|
||||
.arg(p.url().to_string())
|
||||
.with_stderr(
|
||||
"\
|
||||
[UPDATING] git repository [..]
|
||||
[INSTALLING] foo v1.0.0 [..]
|
||||
[COMPILING] foo v1.0.0 [..]
|
||||
[FINISHED] [..]
|
||||
[INSTALLING] [..]home/.cargo/bin/foo[..]
|
||||
[INSTALLED] package `foo [..]
|
||||
[WARNING] be sure to add [..]
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue