mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +00:00
Auto merge of #10538 - Muscraft:rfc2906-part3, r=epage
Part 3 of RFC2906 - Add support for inheriting `license-path`, and `depednency.path` Tracking issue: #8415 RFC: rust-lang/rfcs#2906 [Part 1](https://github.com/rust-lang/cargo/pull/10497) [Part 2](https://github.com/rust-lang/cargo/pull/10517) This PR focuses on adding support for inheriting `license-path`, and `depednency.path`: - To adjust the relative paths from being workspace-relative to package-relative, we use `pathdiff` which `cargo-add` is also going to be using for a similar purpose - `ws_path` was added to `InheritableFields` so we can resolve relative paths from workspace-relative to package-relative - Moved `resolve` for toml dependencies from `TomlDependency::<P>` to `TomlDependency` - This was done since resolving a relative path should be a string - You should never inherit from a `.cargo/config.toml` which is the reason `P` was added Remaining implementation work for the RFC - Relative paths for `readme` - Path dependencies infer version directive - Lock workspace dependencies and warn when unused - Optimizations, as needed - Evaluate any new fields for being inheritable (e.g. `rust-version`)
This commit is contained in:
commit
b36cc6ed41
@ -45,6 +45,7 @@ libgit2-sys = "0.13.2"
|
|||||||
memchr = "2.1.3"
|
memchr = "2.1.3"
|
||||||
opener = "0.5"
|
opener = "0.5"
|
||||||
os_info = "3.0.7"
|
os_info = "3.0.7"
|
||||||
|
pathdiff = "0.2.1"
|
||||||
percent-encoding = "2.0"
|
percent-encoding = "2.0"
|
||||||
rustfix = "0.6.0"
|
rustfix = "0.6.0"
|
||||||
semver = { version = "1.0.3", features = ["serde"] }
|
semver = { version = "1.0.3", features = ["serde"] }
|
||||||
|
@ -11,8 +11,8 @@ pub use self::shell::{Shell, Verbosity};
|
|||||||
pub use self::source::{GitReference, Source, SourceId, SourceMap};
|
pub use self::source::{GitReference, Source, SourceId, SourceMap};
|
||||||
pub use self::summary::{FeatureMap, FeatureValue, Summary};
|
pub use self::summary::{FeatureMap, FeatureValue, Summary};
|
||||||
pub use self::workspace::{
|
pub use self::workspace::{
|
||||||
find_workspace_root, InheritableFields, MaybePackage, Workspace, WorkspaceConfig,
|
find_workspace_root, resolve_relative_path, InheritableFields, MaybePackage, Workspace,
|
||||||
WorkspaceRootConfig,
|
WorkspaceConfig, WorkspaceRootConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod compiler;
|
pub mod compiler;
|
||||||
|
@ -27,6 +27,8 @@ use crate::util::toml::{
|
|||||||
};
|
};
|
||||||
use crate::util::{config::ConfigRelativePath, Config, Filesystem, IntoUrl};
|
use crate::util::{config::ConfigRelativePath, Config, Filesystem, IntoUrl};
|
||||||
use cargo_util::paths;
|
use cargo_util::paths;
|
||||||
|
use cargo_util::paths::normalize_path;
|
||||||
|
use pathdiff::diff_paths;
|
||||||
|
|
||||||
/// The core abstraction in Cargo for working with a workspace of crates.
|
/// The core abstraction in Cargo for working with a workspace of crates.
|
||||||
///
|
///
|
||||||
@ -1650,6 +1652,7 @@ pub struct InheritableFields {
|
|||||||
publish: Option<VecStringOrBool>,
|
publish: Option<VecStringOrBool>,
|
||||||
edition: Option<String>,
|
edition: Option<String>,
|
||||||
badges: Option<BTreeMap<String, BTreeMap<String, String>>>,
|
badges: Option<BTreeMap<String, BTreeMap<String, String>>>,
|
||||||
|
ws_root: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InheritableFields {
|
impl InheritableFields {
|
||||||
@ -1669,6 +1672,7 @@ impl InheritableFields {
|
|||||||
publish: Option<VecStringOrBool>,
|
publish: Option<VecStringOrBool>,
|
||||||
edition: Option<String>,
|
edition: Option<String>,
|
||||||
badges: Option<BTreeMap<String, BTreeMap<String, String>>>,
|
badges: Option<BTreeMap<String, BTreeMap<String, String>>>,
|
||||||
|
ws_root: PathBuf,
|
||||||
) -> InheritableFields {
|
) -> InheritableFields {
|
||||||
Self {
|
Self {
|
||||||
dependencies,
|
dependencies,
|
||||||
@ -1686,6 +1690,7 @@ impl InheritableFields {
|
|||||||
publish,
|
publish,
|
||||||
edition,
|
edition,
|
||||||
badges,
|
badges,
|
||||||
|
ws_root,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1780,10 +1785,10 @@ impl InheritableFields {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn license_file(&self) -> CargoResult<String> {
|
pub fn license_file(&self, package_root: &Path) -> CargoResult<String> {
|
||||||
self.license_file.clone().map_or(
|
self.license_file.clone().map_or(
|
||||||
Err(anyhow!("`workspace.license_file` was not defined")),
|
Err(anyhow!("`workspace.license_file` was not defined")),
|
||||||
|d| Ok(d),
|
|d| resolve_relative_path("license-file", &self.ws_root, package_root, &d),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1817,6 +1822,37 @@ impl InheritableFields {
|
|||||||
Ok(d)
|
Ok(d)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ws_root(&self) -> &PathBuf {
|
||||||
|
&self.ws_root
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_relative_path(
|
||||||
|
label: &str,
|
||||||
|
old_root: &Path,
|
||||||
|
new_root: &Path,
|
||||||
|
rel_path: &str,
|
||||||
|
) -> CargoResult<String> {
|
||||||
|
let joined_path = normalize_path(&old_root.join(rel_path));
|
||||||
|
match diff_paths(joined_path, new_root) {
|
||||||
|
None => Err(anyhow!(
|
||||||
|
"`{}` was defined in {} but could not be resolved with {}",
|
||||||
|
label,
|
||||||
|
old_root.display(),
|
||||||
|
new_root.display()
|
||||||
|
)),
|
||||||
|
Some(path) => Ok(path
|
||||||
|
.to_str()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
anyhow!(
|
||||||
|
"`{}` resolved to non-UTF value (`{}`)",
|
||||||
|
label,
|
||||||
|
path.display()
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.to_owned()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_manifest(manifest_path: &Path, config: &Config) -> CargoResult<EitherManifest> {
|
fn parse_manifest(manifest_path: &Path, config: &Config) -> CargoResult<EitherManifest> {
|
||||||
|
@ -20,7 +20,9 @@ use crate::core::compiler::{CompileKind, CompileTarget};
|
|||||||
use crate::core::dependency::{Artifact, ArtifactTarget, DepKind};
|
use crate::core::dependency::{Artifact, ArtifactTarget, DepKind};
|
||||||
use crate::core::manifest::{ManifestMetadata, TargetSourcePath, Warnings};
|
use crate::core::manifest::{ManifestMetadata, TargetSourcePath, Warnings};
|
||||||
use crate::core::resolver::ResolveBehavior;
|
use crate::core::resolver::ResolveBehavior;
|
||||||
use crate::core::{find_workspace_root, Dependency, Manifest, PackageId, Summary, Target};
|
use crate::core::{
|
||||||
|
find_workspace_root, resolve_relative_path, Dependency, Manifest, PackageId, Summary, Target,
|
||||||
|
};
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
Edition, EitherManifest, Feature, Features, InheritableFields, VirtualManifest, Workspace,
|
Edition, EitherManifest, Feature, Features, InheritableFields, VirtualManifest, Workspace,
|
||||||
};
|
};
|
||||||
@ -1021,6 +1023,12 @@ impl<T> MaybeWorkspace<T> {
|
|||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn as_defined(&self) -> Option<&T> {
|
||||||
|
match self {
|
||||||
|
MaybeWorkspace::Workspace(_) => None,
|
||||||
|
MaybeWorkspace::Defined(defined) => Some(defined),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
@ -1069,7 +1077,7 @@ pub struct TomlProject {
|
|||||||
keywords: Option<MaybeWorkspace<Vec<String>>>,
|
keywords: Option<MaybeWorkspace<Vec<String>>>,
|
||||||
categories: Option<MaybeWorkspace<Vec<String>>>,
|
categories: Option<MaybeWorkspace<Vec<String>>>,
|
||||||
license: Option<MaybeWorkspace<String>>,
|
license: Option<MaybeWorkspace<String>>,
|
||||||
license_file: Option<String>,
|
license_file: Option<MaybeWorkspace<String>>,
|
||||||
repository: Option<MaybeWorkspace<String>>,
|
repository: Option<MaybeWorkspace<String>>,
|
||||||
resolver: Option<String>,
|
resolver: Option<String>,
|
||||||
|
|
||||||
@ -1149,19 +1157,22 @@ impl TomlManifest {
|
|||||||
package.workspace = None;
|
package.workspace = None;
|
||||||
package.resolver = ws.resolve_behavior().to_manifest();
|
package.resolver = ws.resolve_behavior().to_manifest();
|
||||||
if let Some(license_file) = &package.license_file {
|
if let Some(license_file) = &package.license_file {
|
||||||
|
let license_file = license_file
|
||||||
|
.as_defined()
|
||||||
|
.context("license file should have been resolved before `prepare_for_publish()`")?;
|
||||||
let license_path = Path::new(&license_file);
|
let license_path = Path::new(&license_file);
|
||||||
let abs_license_path = paths::normalize_path(&package_root.join(license_path));
|
let abs_license_path = paths::normalize_path(&package_root.join(license_path));
|
||||||
if abs_license_path.strip_prefix(package_root).is_err() {
|
if abs_license_path.strip_prefix(package_root).is_err() {
|
||||||
// This path points outside of the package root. `cargo package`
|
// This path points outside of the package root. `cargo package`
|
||||||
// will copy it into the root, so adjust the path to this location.
|
// will copy it into the root, so adjust the path to this location.
|
||||||
package.license_file = Some(
|
package.license_file = Some(MaybeWorkspace::Defined(
|
||||||
license_path
|
license_path
|
||||||
.file_name()
|
.file_name()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let all = |_d: &TomlDependency| true;
|
let all = |_d: &TomlDependency| true;
|
||||||
@ -1340,6 +1351,7 @@ impl TomlManifest {
|
|||||||
config.publish.clone(),
|
config.publish.clone(),
|
||||||
config.edition.clone(),
|
config.edition.clone(),
|
||||||
config.badges.clone(),
|
config.badges.clone(),
|
||||||
|
package_root.to_path_buf(),
|
||||||
);
|
);
|
||||||
|
|
||||||
WorkspaceConfig::Root(WorkspaceRootConfig::new(
|
WorkspaceConfig::Root(WorkspaceRootConfig::new(
|
||||||
@ -1506,13 +1518,12 @@ impl TomlManifest {
|
|||||||
};
|
};
|
||||||
let mut deps: BTreeMap<String, TomlDependency> = BTreeMap::new();
|
let mut deps: BTreeMap<String, TomlDependency> = BTreeMap::new();
|
||||||
for (n, v) in dependencies.iter() {
|
for (n, v) in dependencies.iter() {
|
||||||
let resolved = v.clone().resolve(features, n, || {
|
let resolved = v.clone().resolve(features, n, cx, || {
|
||||||
get_ws(
|
get_ws(
|
||||||
cx.config,
|
cx.config,
|
||||||
cx.root.join("Cargo.toml"),
|
cx.root.join("Cargo.toml"),
|
||||||
workspace_config.clone(),
|
workspace_config.clone(),
|
||||||
)?
|
)
|
||||||
.get_dependency(n)
|
|
||||||
})?;
|
})?;
|
||||||
let dep = resolved.to_dependency(n, cx, kind)?;
|
let dep = resolved.to_dependency(n, cx, kind)?;
|
||||||
validate_package_name(dep.name_in_toml().as_str(), "dependency name", "")?;
|
validate_package_name(dep.name_in_toml().as_str(), "dependency name", "")?;
|
||||||
@ -1702,7 +1713,16 @@ impl TomlManifest {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
license_file: project.license_file.clone(),
|
license_file: project
|
||||||
|
.license_file
|
||||||
|
.clone()
|
||||||
|
.map(|mw| {
|
||||||
|
mw.resolve(&features, "license", || {
|
||||||
|
get_ws(config, resolved_path.clone(), workspace_config.clone())?
|
||||||
|
.license_file(package_root)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.transpose()?,
|
||||||
repository: project
|
repository: project
|
||||||
.repository
|
.repository
|
||||||
.clone()
|
.clone()
|
||||||
@ -1766,6 +1786,10 @@ impl TomlManifest {
|
|||||||
.license
|
.license
|
||||||
.clone()
|
.clone()
|
||||||
.map(|license| MaybeWorkspace::Defined(license));
|
.map(|license| MaybeWorkspace::Defined(license));
|
||||||
|
project.license_file = metadata
|
||||||
|
.license_file
|
||||||
|
.clone()
|
||||||
|
.map(|license_file| MaybeWorkspace::Defined(license_file));
|
||||||
project.repository = metadata
|
project.repository = metadata
|
||||||
.repository
|
.repository
|
||||||
.clone()
|
.clone()
|
||||||
@ -1999,6 +2023,7 @@ impl TomlManifest {
|
|||||||
config.publish.clone(),
|
config.publish.clone(),
|
||||||
config.edition.clone(),
|
config.edition.clone(),
|
||||||
config.badges.clone(),
|
config.badges.clone(),
|
||||||
|
root.to_path_buf(),
|
||||||
);
|
);
|
||||||
WorkspaceConfig::Root(WorkspaceRootConfig::new(
|
WorkspaceConfig::Root(WorkspaceRootConfig::new(
|
||||||
root,
|
root,
|
||||||
@ -2240,13 +2265,16 @@ impl<P: ResolveToPath + Clone> TomlDependency<P> {
|
|||||||
TomlDependency::Workspace(w) => w.optional.unwrap_or(false),
|
TomlDependency::Workspace(w) => w.optional.unwrap_or(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TomlDependency {
|
||||||
fn resolve<'a>(
|
fn resolve<'a>(
|
||||||
self,
|
self,
|
||||||
cargo_features: &Features,
|
cargo_features: &Features,
|
||||||
label: &str,
|
label: &str,
|
||||||
get_ws_dependency: impl FnOnce() -> CargoResult<TomlDependency<P>>,
|
cx: &mut Context<'_, '_>,
|
||||||
) -> CargoResult<TomlDependency<P>> {
|
get_inheritable: impl FnOnce() -> CargoResult<InheritableFields>,
|
||||||
|
) -> CargoResult<TomlDependency> {
|
||||||
match self {
|
match self {
|
||||||
TomlDependency::Detailed(d) => Ok(TomlDependency::Detailed(d)),
|
TomlDependency::Detailed(d) => Ok(TomlDependency::Detailed(d)),
|
||||||
TomlDependency::Simple(s) => Ok(TomlDependency::Simple(s)),
|
TomlDependency::Simple(s) => Ok(TomlDependency::Simple(s)),
|
||||||
@ -2256,28 +2284,30 @@ impl<P: ResolveToPath + Clone> TomlDependency<P> {
|
|||||||
optional,
|
optional,
|
||||||
}) => {
|
}) => {
|
||||||
cargo_features.require(Feature::workspace_inheritance())?;
|
cargo_features.require(Feature::workspace_inheritance())?;
|
||||||
get_ws_dependency().context(format!(
|
let inheritable = get_inheritable()?;
|
||||||
|
inheritable.get_dependency(label).context(format!(
|
||||||
"error reading `dependencies.{}` from workspace root manifest's `workspace.dependencies.{}`",
|
"error reading `dependencies.{}` from workspace root manifest's `workspace.dependencies.{}`",
|
||||||
label, label
|
label, label
|
||||||
)).map(|dep| {
|
)).map(|dep| {
|
||||||
match dep {
|
match dep {
|
||||||
TomlDependency::Simple(s) => {
|
TomlDependency::Simple(s) => {
|
||||||
if optional.is_some() || features.is_some() {
|
if optional.is_some() || features.is_some() {
|
||||||
TomlDependency::Detailed(DetailedTomlDependency::<P> {
|
Ok(TomlDependency::Detailed(DetailedTomlDependency {
|
||||||
version: Some(s),
|
version: Some(s),
|
||||||
optional,
|
optional,
|
||||||
features,
|
features,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
}))
|
||||||
} else {
|
} else {
|
||||||
TomlDependency::Simple(s)
|
Ok(TomlDependency::Simple(s))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TomlDependency::Detailed(d) => {
|
TomlDependency::Detailed(d) => {
|
||||||
let mut dep = d.clone();
|
let mut dep = d.clone();
|
||||||
dep.add_features(features);
|
dep.add_features(features);
|
||||||
dep.update_optional(optional);
|
dep.update_optional(optional);
|
||||||
TomlDependency::Detailed(dep)
|
dep.resolve_path(label,inheritable.ws_root(), cx.root)?;
|
||||||
|
Ok(TomlDependency::Detailed(dep))
|
||||||
},
|
},
|
||||||
TomlDependency::Workspace(_) => {
|
TomlDependency::Workspace(_) => {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
@ -2288,7 +2318,7 @@ impl<P: ResolveToPath + Clone> TomlDependency<P> {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})?
|
||||||
}
|
}
|
||||||
TomlDependency::Workspace(TomlWorkspaceDependency {
|
TomlDependency::Workspace(TomlWorkspaceDependency {
|
||||||
workspace: false, ..
|
workspace: false, ..
|
||||||
@ -2543,7 +2573,9 @@ impl<P: ResolveToPath + Clone> DetailedTomlDependency<P> {
|
|||||||
}
|
}
|
||||||
Ok(dep)
|
Ok(dep)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DetailedTomlDependency {
|
||||||
fn add_features(&mut self, features: Option<Vec<String>>) {
|
fn add_features(&mut self, features: Option<Vec<String>>) {
|
||||||
self.features = match (self.features.clone(), features.clone()) {
|
self.features = match (self.features.clone(), features.clone()) {
|
||||||
(Some(dep_feat), Some(inherit_feat)) => Some(
|
(Some(dep_feat), Some(inherit_feat)) => Some(
|
||||||
@ -2561,6 +2593,23 @@ impl<P: ResolveToPath + Clone> DetailedTomlDependency<P> {
|
|||||||
fn update_optional(&mut self, optional: Option<bool>) {
|
fn update_optional(&mut self, optional: Option<bool>) {
|
||||||
self.optional = optional;
|
self.optional = optional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_path(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
root_path: &Path,
|
||||||
|
package_root: &Path,
|
||||||
|
) -> CargoResult<()> {
|
||||||
|
if let Some(rel_path) = &self.path {
|
||||||
|
self.path = Some(resolve_relative_path(
|
||||||
|
name,
|
||||||
|
root_path,
|
||||||
|
package_root,
|
||||||
|
rel_path,
|
||||||
|
)?)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
|
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
//! Tests for inheriting Cargo.toml fields with { workspace = true }
|
//! Tests for inheriting Cargo.toml fields with { workspace = true }
|
||||||
use cargo_test_support::registry::{Dependency, Package};
|
use cargo_test_support::registry::{Dependency, Package};
|
||||||
use cargo_test_support::{basic_lib_manifest, git, path2url, paths, project, publish, registry};
|
use cargo_test_support::{
|
||||||
|
basic_lib_manifest, basic_manifest, git, path2url, paths, project, publish, registry,
|
||||||
|
};
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn permit_additional_workspace_fields() {
|
fn permit_additional_workspace_fields() {
|
||||||
@ -581,6 +583,8 @@ fn inherit_workspace_fields() {
|
|||||||
documentation = "https://www.rust-lang.org/learn"
|
documentation = "https://www.rust-lang.org/learn"
|
||||||
homepage = "https://www.rust-lang.org"
|
homepage = "https://www.rust-lang.org"
|
||||||
repository = "https://github.com/example/example"
|
repository = "https://github.com/example/example"
|
||||||
|
license = "MIT"
|
||||||
|
license-file = "LICENSE"
|
||||||
keywords = ["cli"]
|
keywords = ["cli"]
|
||||||
categories = ["development-tools"]
|
categories = ["development-tools"]
|
||||||
publish = true
|
publish = true
|
||||||
@ -604,12 +608,15 @@ fn inherit_workspace_fields() {
|
|||||||
documentation = { workspace = true }
|
documentation = { workspace = true }
|
||||||
homepage = { workspace = true }
|
homepage = { workspace = true }
|
||||||
repository = { workspace = true }
|
repository = { workspace = true }
|
||||||
|
license = { workspace = true }
|
||||||
|
license-file = { workspace = true }
|
||||||
keywords = { workspace = true }
|
keywords = { workspace = true }
|
||||||
categories = { workspace = true }
|
categories = { workspace = true }
|
||||||
publish = { workspace = true }
|
publish = { workspace = true }
|
||||||
edition = { workspace = true }
|
edition = { workspace = true }
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
|
.file("LICENSE", "license")
|
||||||
.file("bar/src/main.rs", "fn main() {}")
|
.file("bar/src/main.rs", "fn main() {}")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -631,8 +638,8 @@ fn inherit_workspace_fields() {
|
|||||||
"features": {},
|
"features": {},
|
||||||
"homepage": "https://www.rust-lang.org",
|
"homepage": "https://www.rust-lang.org",
|
||||||
"keywords": ["cli"],
|
"keywords": ["cli"],
|
||||||
"license": null,
|
"license": "MIT",
|
||||||
"license_file": null,
|
"license_file": "../LICENSE",
|
||||||
"links": null,
|
"links": null,
|
||||||
"name": "bar",
|
"name": "bar",
|
||||||
"readme": null,
|
"readme": null,
|
||||||
@ -647,6 +654,7 @@ fn inherit_workspace_fields() {
|
|||||||
"Cargo.toml",
|
"Cargo.toml",
|
||||||
"Cargo.toml.orig",
|
"Cargo.toml.orig",
|
||||||
"src/main.rs",
|
"src/main.rs",
|
||||||
|
"LICENSE",
|
||||||
".cargo_vcs_info.json",
|
".cargo_vcs_info.json",
|
||||||
],
|
],
|
||||||
&[(
|
&[(
|
||||||
@ -666,6 +674,8 @@ homepage = "https://www.rust-lang.org"
|
|||||||
documentation = "https://www.rust-lang.org/learn"
|
documentation = "https://www.rust-lang.org/learn"
|
||||||
keywords = ["cli"]
|
keywords = ["cli"]
|
||||||
categories = ["development-tools"]
|
categories = ["development-tools"]
|
||||||
|
license = "MIT"
|
||||||
|
license-file = "LICENSE"
|
||||||
repository = "https://github.com/example/example"
|
repository = "https://github.com/example/example"
|
||||||
|
|
||||||
[badges.gitlab]
|
[badges.gitlab]
|
||||||
@ -1038,6 +1048,52 @@ fn inherit_detailed_dependencies() {
|
|||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn inherit_path_dependencies() {
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[workspace]
|
||||||
|
members = ["bar"]
|
||||||
|
[workspace.dependencies]
|
||||||
|
dep = { path = "dep" }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"bar/Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["workspace-inheritance"]
|
||||||
|
|
||||||
|
[project]
|
||||||
|
workspace = ".."
|
||||||
|
name = "bar"
|
||||||
|
version = "0.2.0"
|
||||||
|
authors = []
|
||||||
|
[dependencies]
|
||||||
|
dep = { workspace = true }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("bar/src/main.rs", "fn main() {}")
|
||||||
|
.file("dep/Cargo.toml", &basic_manifest("dep", "0.9.0"))
|
||||||
|
.file("dep/src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("build")
|
||||||
|
.masquerade_as_nightly_cargo()
|
||||||
|
.with_stderr(
|
||||||
|
"\
|
||||||
|
[COMPILING] dep v0.9.0 ([CWD]/dep)
|
||||||
|
[COMPILING] bar v0.2.0 ([CWD]/bar)
|
||||||
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
let lockfile = p.read_lockfile();
|
||||||
|
assert!(lockfile.contains("dep"));
|
||||||
|
}
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn error_workspace_false() {
|
fn error_workspace_false() {
|
||||||
registry::init();
|
registry::init();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user