3781: Add crate versions when running cargo -p commands. r=matklad a=o0Ignition0o

If someone (unfortunately) creates a project that happens to have the same name as one of its (future) dependencies, there is [a way for them to change the dependency's alias in the Cargo.toml file](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml), to mitigate the name conflict. Unfortunately cargo -p commands don't seem to pick it up, which seems to put rust-analyzer run commands in a tough situation: 

```
> Executing task: cargo test --package config --example default -- tests --nocapture <

error: There are multiple `config` packages in your project, and the specification `config` is ambiguous.
Please re-run this command with `-p <spec>` where `<spec>` is one of the following:
  config:0.1.0
  config:0.9.3
The terminal process terminated with exit code: 101
```

cargo suggests us to be more specific and refer to a package by its name and version, which this PR achieves.

I passed the version as a String because I don't really understand how the ra_db types work, but I would love to switch it to [a fully fledged Version type](https://steveklabnik.github.io/semver/semver/index.html) if you guide me towards that :)



Co-authored-by: o0Ignition0o <jeremy.lempereur@gmail.com>
This commit is contained in:
bors[bot] 2020-03-31 12:45:39 +00:00 committed by GitHub
commit d63bb8565e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 1 deletions

View File

@ -75,6 +75,7 @@ pub type Target = Idx<TargetData>;
#[derive(Debug, Clone)]
pub struct PackageData {
pub id: String,
pub name: String,
pub manifest: PathBuf,
pub targets: Vec<Target>,
@ -180,6 +181,7 @@ impl CargoWorkspace {
.with_context(|| format!("Failed to parse edition {}", edition))?;
let pkg = packages.alloc(PackageData {
name,
id: id.to_string(),
manifest: manifest_path,
targets: Vec::new(),
is_member,
@ -249,6 +251,18 @@ impl CargoWorkspace {
pub fn workspace_root(&self) -> &Path {
&self.workspace_root
}
pub fn package_flag(&self, package: &PackageData) -> String {
if self.is_unique(&*package.name) {
package.name.clone()
} else {
package.id.clone()
}
}
fn is_unique(&self, name: &str) -> bool {
self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
}
}
#[derive(Debug, Clone, Default)]

View File

@ -77,7 +77,7 @@ impl CargoTargetSpec {
ProjectWorkspace::Cargo { cargo, .. } => {
let tgt = cargo.target_by_root(&path)?;
Some(CargoTargetSpec {
package: cargo[cargo[tgt].package].name.clone(),
package: cargo.package_flag(&cargo[cargo[tgt].package]),
target: cargo[tgt].name.clone(),
target_kind: cargo[tgt].kind,
})