Skip to content

Commit

Permalink
Merge pull request #190 from dtolnay/inherit
Browse files Browse the repository at this point in the history
Support inheriting edition from workspace manifest
  • Loading branch information
dtolnay authored Sep 22, 2022
2 parents b449da7 + 5fe80f0 commit 5b5eeea
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ diff = ["dissimilar"]
dissimilar = { version = "1.0", optional = true }
glob = "0.3"
once_cell = "1.9"
serde = "1.0.103"
serde_derive = "1.0.103"
serde = "1.0.139"
serde_derive = "1.0.139"
serde_json = "1.0"
termcolor = "1.0.4"
toml = "0.5.2"
Expand Down
66 changes: 63 additions & 3 deletions src/dependencies.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::directory::Directory;
use crate::error::Error;
use crate::inherit::InheritEdition;
use crate::manifest::Edition;
use serde::de::value::MapAccessDeserializer;
use serde::de::{self, Visitor};
use serde::de::{Deserialize, Deserializer};
use serde::de::value::StrDeserializer;
use serde::de::{self, Deserialize, Deserializer, Visitor};
use serde::ser::{Serialize, Serializer};
use serde_derive::{Deserialize, Serialize};
use std::collections::BTreeMap as Map;
Expand Down Expand Up @@ -71,12 +72,25 @@ fn fix_replacements(replacements: &mut Map<String, Patch>, dir: &Directory) {

#[derive(Deserialize, Default, Debug)]
pub struct WorkspaceManifest {
#[serde(default)]
pub workspace: WorkspaceWorkspace,
#[serde(default)]
pub patch: Map<String, RegistryPatch>,
#[serde(default)]
pub replace: Map<String, Patch>,
}

#[derive(Deserialize, Default, Debug)]
pub struct WorkspaceWorkspace {
#[serde(default)]
pub package: WorkspacePackage,
}

#[derive(Deserialize, Default, Debug)]
pub struct WorkspacePackage {
pub edition: Option<Edition>,
}

#[derive(Deserialize, Default, Debug)]
pub struct Manifest {
#[serde(default)]
Expand All @@ -95,10 +109,16 @@ pub struct Manifest {
pub struct Package {
pub name: String,
#[serde(default)]
pub edition: Edition,
pub edition: EditionOrInherit,
pub resolver: Option<String>,
}

#[derive(Debug)]
pub enum EditionOrInherit {
Edition(Edition),
Inherit,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(remote = "Self")]
pub struct Dependency {
Expand Down Expand Up @@ -168,6 +188,46 @@ fn is_true(boolean: &bool) -> bool {
*boolean
}

impl Default for EditionOrInherit {
fn default() -> Self {
EditionOrInherit::Edition(Edition::default())
}
}

impl<'de> Deserialize<'de> for EditionOrInherit {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct EditionOrInheritVisitor;

impl<'de> Visitor<'de> for EditionOrInheritVisitor {
type Value = EditionOrInherit;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("edition")
}

fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Edition::deserialize(StrDeserializer::new(s)).map(EditionOrInherit::Edition)
}

fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
where
M: de::MapAccess<'de>,
{
InheritEdition::deserialize(MapAccessDeserializer::new(map))?;
Ok(EditionOrInherit::Inherit)
}
}

deserializer.deserialize_any(EditionOrInheritVisitor)
}
}

impl Serialize for Dependency {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub enum Error {
Io(io::Error),
Metadata(serde_json::Error),
Mismatch,
NoWorkspaceManifest,
Open(PathBuf, io::Error),
Pattern(PatternError),
ProjectDir,
Expand All @@ -39,6 +40,7 @@ impl Display for Error {
Io(e) => write!(f, "{}", e),
Metadata(e) => write!(f, "failed to read cargo metadata: {}", e),
Mismatch => write!(f, "compiler error does not match expected error"),
NoWorkspaceManifest => write!(f, "Cargo.toml uses edition.workspace=true, but no edition found in workspace's manifest"),
Open(path, e) => write!(f, "{}: {}", path.display(), e),
Pattern(e) => write!(f, "{}", e),
ProjectDir => write!(f, "failed to determine name of project dir"),
Expand Down
41 changes: 41 additions & 0 deletions src/inherit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use serde::de::{self, Deserialize, Deserializer, Visitor};
use serde_derive::Deserialize;
use std::fmt;

#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
pub struct InheritEdition {
pub workspace: True,
}

pub struct True;

impl<'de> Deserialize<'de> for True {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_bool(True)
}
}

impl<'de> Visitor<'de> for True {
type Value = True;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("bool")
}

fn visit_bool<E>(self, b: bool) -> Result<Self::Value, E>
where
E: de::Error,
{
if b {
Ok(True)
} else {
Err(de::Error::custom(
"workspace=false is unsupported for package.edition",
))
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ mod error;
mod expand;
mod features;
mod flock;
mod inherit;
mod manifest;
mod message;
mod normalize;
Expand Down
19 changes: 14 additions & 5 deletions src/run.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::cargo::{self, Metadata};
use crate::dependencies::{self, Dependency};
use crate::dependencies::{self, Dependency, EditionOrInherit};
use crate::directory::Directory;
use crate::env::Update;
use crate::error::{Error, Result};
Expand Down Expand Up @@ -157,7 +157,7 @@ impl Runner {
&source_dir,
tests,
source_manifest,
);
)?;

if let Some(enabled_features) = &mut features {
enabled_features.retain(|feature| manifest.features.contains_key(feature));
Expand Down Expand Up @@ -207,10 +207,19 @@ impl Runner {
source_dir: &Directory,
tests: &[ExpandedTest],
source_manifest: dependencies::Manifest,
) -> Manifest {
) -> Result<Manifest> {
let crate_name = source_manifest.package.name;
let workspace_manifest = dependencies::get_workspace_manifest(workspace);

let edition = match source_manifest.package.edition {
EditionOrInherit::Edition(edition) => edition,
EditionOrInherit::Inherit => workspace_manifest
.workspace
.package
.edition
.ok_or(Error::NoWorkspaceManifest)?,
};

let features = source_manifest
.features
.keys()
Expand All @@ -224,7 +233,7 @@ impl Runner {
package: Package {
name: project_name.to_owned(),
version: "0.0.0".to_owned(),
edition: source_manifest.package.edition,
edition,
resolver: source_manifest.package.resolver,
publish: false,
},
Expand Down Expand Up @@ -276,7 +285,7 @@ impl Runner {
}
}

manifest
Ok(manifest)
}

fn make_config(&self) -> Config {
Expand Down

0 comments on commit 5b5eeea

Please sign in to comment.