diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index b34ea9acaf8..c2cb23a8fa8 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -829,6 +829,10 @@ impl<'cfg> Workspace<'cfg> { } Ok(()) } + + pub fn set_target_dir(&mut self, target_dir: Filesystem) { + self.target_dir = Some(target_dir); + } } impl<'cfg> Packages<'cfg> { diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index a2c5565e79f..505b940e8d4 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -200,31 +200,35 @@ fn install_one( )? }; - let mut td_opt = None; - let mut needs_cleanup = false; - let overidden_target_dir = if source_id.is_path() { - None - } else if let Some(dir) = config.target_dir()? { - Some(dir) - } else if let Ok(td) = TempFileBuilder::new().prefix("cargo-install").tempdir() { - let p = td.path().to_owned(); - td_opt = Some(td); - Some(Filesystem::new(p)) + let (mut ws, git_package) = if source_id.is_git() { + // Don't use ws.current() in order to keep the package source as a git source so that + // install tracking uses the correct source. + (Workspace::new(pkg.manifest_path(), config)?, Some(&pkg)) + } else if source_id.is_path() { + (Workspace::new(pkg.manifest_path(), config)?, None) } else { - needs_cleanup = true; - Some(Filesystem::new(config.cwd().join("target-install"))) - }; - - let mut ws = match overidden_target_dir { - Some(dir) => Workspace::ephemeral(pkg, config, Some(dir), false)?, - None => { - let mut ws = Workspace::new(pkg.manifest_path(), config)?; - ws.set_require_optional_deps(false); - ws - } + (Workspace::ephemeral(pkg, config, None, false)?, None) }; ws.set_ignore_lock(config.lock_update_allowed()); - let pkg = ws.current()?; + ws.set_require_optional_deps(false); + + let mut td_opt = None; + let mut needs_cleanup = false; + if !source_id.is_path() { + let target_dir = if let Some(dir) = config.target_dir()? { + dir + } else if let Ok(td) = TempFileBuilder::new().prefix("cargo-install").tempdir() { + let p = td.path().to_owned(); + td_opt = Some(td); + Filesystem::new(p) + } else { + needs_cleanup = true; + Filesystem::new(config.cwd().join("target-install")) + }; + ws.set_target_dir(target_dir); + } + + let pkg = git_package.map_or_else(|| ws.current(), |pkg| Ok(pkg))?; if from_cwd { if pkg.manifest().edition() == Edition::Edition2015 { diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index 98dd12fe26c..c2777f85acb 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -316,10 +316,10 @@ fn multiple_crates_git_all() { let p = git::repo(&paths::root().join("foo")) .file( "Cargo.toml", - r#"\ -[workspace] -members = ["bin1", "bin2"] -"#, + r#" + [workspace] + members = ["bin1", "bin2"] + "#, ) .file("bin1/Cargo.toml", &basic_manifest("bin1", "0.1.0")) .file("bin2/Cargo.toml", &basic_manifest("bin2", "0.1.0")) @@ -1422,3 +1422,29 @@ fn install_version_req() { .with_stderr_contains("[INSTALLING] foo v0.0.3") .run(); } + +#[cargo_test] +fn git_install_reads_workspace_manifest() { + let p = git::repo(&paths::root().join("foo")) + .file( + "Cargo.toml", + r#" + [workspace] + members = ["bin1"] + + [profile.release] + incremental = 3 + "#, + ) + .file("bin1/Cargo.toml", &basic_manifest("bin1", "0.1.0")) + .file( + "bin1/src/main.rs", + r#"fn main() { println!("Hello, world!"); }"#, + ) + .build(); + + cargo_process(&format!("install --git {}", p.url().to_string())) + .with_status(101) + .with_stderr_contains(" invalid type: integer `3`[..]") + .run(); +}