guarantee serde
is in lockstep with serde_derive
This commit is contained in:
parent
3c7dd6fc1e
commit
2ea7e1300f
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
@ -156,3 +156,12 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dtolnay/install@cargo-outdated
|
||||
- run: cargo outdated --workspace --exit-code 1
|
||||
|
||||
lockstep:
|
||||
name: Lockstep
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- run: cd test_suite/assert_lockstep && cargo run -- dummy_dependant
|
||||
|
@ -4,6 +4,7 @@ members = [
|
||||
"serde_derive",
|
||||
"serde_derive_internals",
|
||||
"test_suite",
|
||||
"test_suite/assert_lockstep",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
|
@ -31,6 +31,10 @@ features = ["derive"]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
rustdoc-args = ["--generate-link-to-definition"]
|
||||
|
||||
# Even though this `cfg` can never be enabled, it still forces cargo to keep `serde_derive` in lockstep with `serde`.
|
||||
[target.'cfg(any())'.dependencies]
|
||||
serde_derive = { version = "=1.0.185", path = "../serde_derive" }
|
||||
|
||||
|
||||
### FEATURES #################################################################
|
||||
|
||||
|
12
test_suite/assert_lockstep/Cargo.toml
Normal file
12
test_suite/assert_lockstep/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "assert_lockstep"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
rust-version = "1.70"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
cargo-lock = "8.0.0"
|
||||
toml = "0.5"
|
||||
thiserror = "1.0.39"
|
12
test_suite/assert_lockstep/dummy_dependant/Cargo.toml
Normal file
12
test_suite/assert_lockstep/dummy_dependant/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "dummy_dependant"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = { path = "../../../serde" }
|
||||
|
||||
# `workspace.exclude` does not seem to work with doubly nested paths.
|
||||
[workspace]
|
1
test_suite/assert_lockstep/dummy_dependant/src/lib.rs
Normal file
1
test_suite/assert_lockstep/dummy_dependant/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
|
110
test_suite/assert_lockstep/src/main.rs
Normal file
110
test_suite/assert_lockstep/src/main.rs
Normal file
@ -0,0 +1,110 @@
|
||||
use cargo_lock::{Lockfile, Package, Version};
|
||||
use std::convert::Infallible;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum TestError {
|
||||
#[error("Package \"{name}\" not found in the lockfile")]
|
||||
NoPackageFound { name: String },
|
||||
#[error("Package \"{first}\" and \"{second}\" had different versions in the lockfile")]
|
||||
VersionMismatch { first: PackageId, second: PackageId },
|
||||
#[error("I/O error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("Error parsing lockfile: {0}")]
|
||||
Lock(#[from] cargo_lock::Error),
|
||||
}
|
||||
|
||||
impl From<Infallible> for TestError {
|
||||
fn from(value: Infallible) -> Self {
|
||||
match value {}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PackageId {
|
||||
name: String,
|
||||
version: Version,
|
||||
}
|
||||
|
||||
impl PackageId {
|
||||
fn new(package: &Package) -> Self {
|
||||
Self {
|
||||
name: package.name.to_string(),
|
||||
version: package.version.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PackageId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{name}@{version}",
|
||||
name = self.name,
|
||||
version = self.version,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn find_package<'a>(lockfile: &'a Lockfile, package_name: &str) -> Result<&'a Package, TestError> {
|
||||
lockfile
|
||||
.packages
|
||||
.iter()
|
||||
.find(|package| package.name.as_str() == package_name)
|
||||
.ok_or_else(|| TestError::NoPackageFound {
|
||||
name: package_name.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let Err(error) = main_inner() {
|
||||
panic!("{}", error);
|
||||
}
|
||||
}
|
||||
|
||||
fn main_inner() -> Result<(), TestError> {
|
||||
let path = PathBuf::from_str(&std::env::args().nth(1).unwrap())?;
|
||||
|
||||
Command::new("cargo")
|
||||
.arg("clean")
|
||||
.current_dir(&path)
|
||||
.stdout(Stdio::inherit())
|
||||
.output()?;
|
||||
|
||||
Command::new("cargo")
|
||||
.arg("update")
|
||||
.current_dir(&path)
|
||||
.stdout(Stdio::inherit())
|
||||
.output()?;
|
||||
|
||||
let lockfile = Lockfile::load(path.join("Cargo.lock"))?;
|
||||
|
||||
let serde = find_package(&lockfile, "serde")?;
|
||||
|
||||
println!("packages should match {id}", id = PackageId::new(&serde));
|
||||
|
||||
let package_names = &["serde_derive"];
|
||||
|
||||
let packages = package_names
|
||||
.iter()
|
||||
.map(|name| find_package(&lockfile, name));
|
||||
|
||||
for package in packages {
|
||||
let package = package?;
|
||||
|
||||
println!("discovered package {id}", id = PackageId::new(&package));
|
||||
|
||||
if package.version != serde.version {
|
||||
return Err(TestError::VersionMismatch {
|
||||
first: PackageId::new(&serde),
|
||||
second: PackageId::new(&package),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user