Skip to content

refactor(toml): Split out an explicit step to resolve Cargo.toml #13693

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6ad9769
refactor(toml): Rely on resolved version
epage Mar 19, 2024
b318359
refactor(toml): Rely on resolved rust-version
epage Mar 19, 2024
102b589
refactor(toml): Rely on resolved edition
epage Mar 19, 2024
f96638e
refactor(toml): Rely on resolved description
epage Mar 19, 2024
5b5f644
refactor(toml): Rely on resolved homepage
epage Mar 19, 2024
c62a559
refactor(toml): Rely on resolved documentation
epage Mar 19, 2024
d435d0e
refactor(toml): Rely on resolved readme
epage Mar 19, 2024
258d844
refactor(toml): Rely on resolved keywords
epage Mar 19, 2024
047c1fe
refactor(toml): Rely on resolved categories
epage Mar 19, 2024
b942be5
refactor(toml): Rely on resolved license
epage Mar 19, 2024
18550b2
refactor(toml): Rely on resolved license-file
epage Mar 19, 2024
425a8ae
refactor(toml): Rely on resolved repository
epage Mar 19, 2024
00ba578
refactor(toml): Rely on resolved authors
epage Mar 19, 2024
20302b3
refactor(toml): Rely on resolved include/exclude
epage Mar 19, 2024
2ea1ac6
refactor(toml): Rely on resolved publish
epage Mar 19, 2024
a203396
refactor(toml): Directly initialize TomlPackage
epage Mar 19, 2024
772539a
refactor(toml): Group resolving of lints with package
epage Mar 19, 2024
b517320
refactor(toml): Remove ManifestContext from default_feature_msg
epage Mar 19, 2024
21ca8ab
refactor(toml): Remove ManifestContext from dependency_inherit_with
epage Mar 19, 2024
611b688
refactor(toml): Separate resolve/validate dependencies
epage Mar 19, 2024
3d1da63
refactor(toml): Rely on resolved badges
epage Mar 26, 2024
5d8bdf4
refactor(toml): Separate resolving from other in same fn
epage Mar 26, 2024
0f5b562
refactor(toml): Centralize cargo-features parsing
epage Apr 1, 2024
c921f52
refactor(toml): Centralize creation of workspace_config
epage Apr 2, 2024
9cc5b90
refactor(toml): Extract resolve_toml
epage Apr 2, 2024
e9d28d8
refactor(toml): Simplify how we pass around inheritable data
epage Apr 2, 2024
8a6fa8b
refactor(toml): Extract package resolving
epage Apr 2, 2024
2811c15
refactor(toml): Build up resolved manifest as we go
epage Apr 2, 2024
9eb7c09
refactor(toml): Scope package-related tables to package scope
epage Apr 2, 2024
7640081
Group logic for fields dependent on package
epage Apr 2, 2024
70ad920
refactor(toml): Prefer making a Manifest from resolved_toml
epage Apr 2, 2024
ecf97cf
refactor(toml): Simplify dependency validation
epage Apr 2, 2024
1e761a1
refactor(toml): Gather dependency gathering
epage Apr 2, 2024
58b6501
refactor(toml): Attempt to logically group everything
epage Apr 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions crates/cargo-util-schemas/src/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ impl TomlManifest {
pub fn features(&self) -> Option<&BTreeMap<FeatureName, Vec<String>>> {
self.features.as_ref()
}

pub fn resolved_badges(
&self,
) -> Result<Option<&BTreeMap<String, BTreeMap<String, String>>>, UnresolvedError> {
self.badges.as_ref().map(|l| l.resolved()).transpose()
}

pub fn resolved_lints(&self) -> Result<Option<&TomlLints>, UnresolvedError> {
self.lints.as_ref().map(|l| l.resolved()).transpose()
}
}

#[derive(Debug, Deserialize, Serialize, Clone)]
Expand Down Expand Up @@ -194,6 +204,83 @@ pub struct TomlPackage {
pub _invalid_cargo_features: Option<InvalidCargoFeatures>,
}

impl TomlPackage {
pub fn resolved_edition(&self) -> Result<Option<&String>, UnresolvedError> {
self.edition.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_rust_version(&self) -> Result<Option<&RustVersion>, UnresolvedError> {
self.rust_version.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_version(&self) -> Result<Option<&semver::Version>, UnresolvedError> {
self.version.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_authors(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
self.authors.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_exclude(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
self.exclude.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_include(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
self.include.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_publish(&self) -> Result<Option<&VecStringOrBool>, UnresolvedError> {
self.publish.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_description(&self) -> Result<Option<&String>, UnresolvedError> {
self.description.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_homepage(&self) -> Result<Option<&String>, UnresolvedError> {
self.homepage.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_documentation(&self) -> Result<Option<&String>, UnresolvedError> {
self.documentation
.as_ref()
.map(|v| v.resolved())
.transpose()
}

pub fn resolved_readme(&self) -> Result<Option<&String>, UnresolvedError> {
self.readme
.as_ref()
.map(|v| {
v.resolved().and_then(|sb| match sb {
StringOrBool::Bool(_) => Err(UnresolvedError),
StringOrBool::String(value) => Ok(value),
})
})
.transpose()
}

pub fn resolved_keywords(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
self.keywords.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_categories(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
self.categories.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_license(&self) -> Result<Option<&String>, UnresolvedError> {
self.license.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_license_file(&self) -> Result<Option<&String>, UnresolvedError> {
self.license_file.as_ref().map(|v| v.resolved()).transpose()
}

pub fn resolved_repository(&self) -> Result<Option<&String>, UnresolvedError> {
self.repository.as_ref().map(|v| v.resolved()).transpose()
}
}

/// An enum that allows for inheriting keys from a workspace in a Cargo.toml.
#[derive(Serialize, Copy, Clone, Debug)]
#[serde(untagged)]
Expand All @@ -205,6 +292,10 @@ pub enum InheritableField<T> {
}

impl<T> InheritableField<T> {
pub fn resolved(&self) -> Result<&T, UnresolvedError> {
self.as_value().ok_or(UnresolvedError)
}

pub fn as_value(&self) -> Option<&T> {
match self {
InheritableField::Inherit(_) => None,
Expand Down Expand Up @@ -504,6 +595,13 @@ impl InheritableDependency {
InheritableDependency::Inherit(w) => w._unused_keys.keys().cloned().collect(),
}
}

pub fn resolved(&self) -> Result<&TomlDependency, UnresolvedError> {
match self {
InheritableDependency::Value(d) => Ok(d),
InheritableDependency::Inherit(_) => Err(UnresolvedError),
}
}
}

impl<'de> de::Deserialize<'de> for InheritableDependency {
Expand Down Expand Up @@ -1297,6 +1395,16 @@ pub struct InheritableLints {
pub lints: TomlLints,
}

impl InheritableLints {
pub fn resolved(&self) -> Result<&TomlLints, UnresolvedError> {
if self.workspace {
Err(UnresolvedError)
} else {
Ok(&self.lints)
}
}
}

fn is_false(b: &bool) -> bool {
!b
}
Expand Down Expand Up @@ -1512,3 +1620,9 @@ impl<'de> de::Deserialize<'de> for PathValue {
Ok(PathValue(String::deserialize(deserializer)?.into()))
}
}

/// Error validating names in Cargo.
#[derive(Debug, thiserror::Error)]
#[error("manifest field was not resolved")]
#[non_exhaustive]
pub struct UnresolvedError;
4 changes: 2 additions & 2 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ pub type AllowFeatures = BTreeSet<String>;
/// - Update [`CLI_VALUES`] to include the new edition.
/// - Set [`LATEST_UNSTABLE`] to Some with the new edition.
/// - Add an unstable feature to the [`features!`] macro invocation below for the new edition.
/// - Gate on that new feature in [`toml::to_real_manifest`].
/// - Gate on that new feature in [`toml`].
/// - Update the shell completion files.
/// - Update any failing tests (hopefully there are very few).
/// - Update unstable.md to add a new section for this new edition (see [this example]).
Expand All @@ -178,7 +178,7 @@ pub type AllowFeatures = BTreeSet<String>;
/// [`LATEST_STABLE`]: Edition::LATEST_STABLE
/// [this example]: https://github.com/rust-lang/cargo/blob/3ebb5f15a940810f250b68821149387af583a79e/src/doc/src/reference/unstable.md?plain=1#L1238-L1264
/// [`is_stable`]: Edition::is_stable
/// [`toml::to_real_manifest`]: crate::util::toml::to_real_manifest
/// [`toml`]: crate::util::toml
/// [`features!`]: macro.features.html
#[derive(
Default, Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq, Serialize, Deserialize,
Expand Down
1 change: 0 additions & 1 deletion src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ impl<'gctx> Workspace<'gctx> {
// NOTE: Since we use ConfigRelativePath, this root isn't used as
// any relative paths are resolved before they'd be joined with root.
Path::new("unused-relative-path"),
self.unstable_features(),
/* kind */ None,
)
})
Expand Down
Loading