mirror of
https://github.com/ipetkov/crane.git
synced 2024-11-22 05:36:09 +03:00
crane-utils: fix workspace dependency merge when it is not a table (#529)
This commit is contained in:
parent
2c653e4478
commit
f23ae17543
@ -13,6 +13,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
dummified sources which might have violated a lint marked as `deny` or
|
||||
`forbid`
|
||||
|
||||
### Fixed
|
||||
* Fixed an edge case with inheriting workspace dependencies where the workspace
|
||||
dependency is a string (e.g. `foo = "0.1.2"`) but the crate definition is a
|
||||
table (e.g. `foo = { workspace = true, optional = true }`)
|
||||
|
||||
## [0.16.1] - 2024-01-28
|
||||
|
||||
### Changed
|
||||
|
36
pkgs/crane-utils/Cargo.lock
generated
36
pkgs/crane-utils/Cargo.lock
generated
@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.79"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
|
||||
|
||||
[[package]]
|
||||
name = "crane-utils"
|
||||
@ -39,9 +39,9 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.0"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf2a4f498956c7723dc280afc6a37d0dec50b39a29e232c6187ce4503703e8c2"
|
||||
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@ -89,24 +89,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.16"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.196"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.196"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -115,9 +115,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.112"
|
||||
version = "1.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed"
|
||||
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -126,9 +126,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.48"
|
||||
version = "2.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -143,9 +143,9 @@ checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.21.0"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
|
||||
checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
@ -160,9 +160,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.35"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1931d78a9c73861da0134f453bb1f790ce49b2e30eba8410b4b79bac72b46a2d"
|
||||
checksum = "7a4191c47f15cc3ec71fcb4913cb83d58def65dd3787610213c649283b5ce178"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -8,7 +8,7 @@ publish = false
|
||||
anyhow = "1"
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
toml_edit = "0.21.0"
|
||||
toml_edit = "0.22.6"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.3.0"
|
||||
|
@ -8,5 +8,5 @@ rustPlatform.buildRustPackage {
|
||||
|
||||
src = lib.sourceFilesBySuffices ./. [ ".rs" ".toml" ".lock" ];
|
||||
|
||||
cargoSha256 = "sha256-/ybcjLrjLBuL8jYN0thBQtqyrpKDPAltF9sRqc98Yw0=";
|
||||
cargoSha256 = "sha256-sRVk7OrdIYaNBU6gA1etLTVWQvS+HW5DwJaa2xbNqiA=";
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use std::{
|
||||
process::{Command, Stdio},
|
||||
str::FromStr,
|
||||
};
|
||||
use toml_edit::Item;
|
||||
use toml_edit::{Item, Table};
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
@ -90,33 +90,28 @@ fn merge(cargo_toml: &mut toml_edit::Document, root: &toml_edit::Document) {
|
||||
};
|
||||
|
||||
// https://doc.rust-lang.org/cargo/reference/workspaces.html#workspaces
|
||||
for (key, ws_key, inherit) in [
|
||||
("package", "package", false),
|
||||
("dependencies", "dependencies", false),
|
||||
("dev-dependencies", "dependencies", false),
|
||||
("build-dependencies", "dependencies", false),
|
||||
("lints", "lints", true),
|
||||
] {
|
||||
if let Some((cargo_toml, root)) = cargo_toml.get_mut(key).zip(w.get(ws_key)) {
|
||||
if inherit {
|
||||
try_inherit_cargo_table(cargo_toml, root);
|
||||
} else {
|
||||
try_merge_cargo_tables(cargo_toml, root);
|
||||
}
|
||||
let w_deps = w.get("dependencies");
|
||||
for key in ["dependencies", "dev-dependencies", "build-dependencies"] {
|
||||
if let Some((cargo_toml, root)) = cargo_toml.get_mut(key).zip(w_deps) {
|
||||
try_merge_dependencies_tables(cargo_toml, root);
|
||||
};
|
||||
|
||||
if let Some(targets) = cargo_toml.get_mut("target").and_then(try_as_table_like_mut) {
|
||||
for (_, tp) in targets.iter_mut() {
|
||||
if let Some((cargo_toml, root)) = tp.get_mut(key).zip(w.get(ws_key)) {
|
||||
if inherit {
|
||||
try_inherit_cargo_table(cargo_toml, root);
|
||||
} else {
|
||||
try_merge_cargo_tables(cargo_toml, root);
|
||||
}
|
||||
if let Some((cargo_toml, root)) = tp.get_mut(key).zip(w_deps) {
|
||||
try_merge_dependencies_tables(cargo_toml, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((cargo_toml, root)) = cargo_toml.get_mut("package").zip(w.get("package")) {
|
||||
try_merge_cargo_tables(cargo_toml, root);
|
||||
};
|
||||
|
||||
if let Some((cargo_toml, root)) = cargo_toml.get_mut("lints").zip(w.get("lints")) {
|
||||
try_inherit_cargo_table(cargo_toml, root);
|
||||
};
|
||||
}
|
||||
|
||||
/// Return a [`toml_edit::TableLike`] representation of the [`Item`] (if any)
|
||||
@ -186,6 +181,54 @@ where
|
||||
});
|
||||
}
|
||||
|
||||
/// Merge the specified `cargo_toml` and workspace `root` if both are dependency tables
|
||||
fn try_merge_dependencies_tables(cargo_toml: &mut Item, root: &Item) {
|
||||
let cargo_toml = try_as_table_like_mut(cargo_toml);
|
||||
let root = try_as_table_like(root);
|
||||
|
||||
if let Some((cargo_toml, root)) = cargo_toml.zip(root) {
|
||||
merge_dependencies_tables(cargo_toml, root);
|
||||
}
|
||||
}
|
||||
|
||||
/// Merge the specified `cargo_toml` and workspace `root` dependencies tables
|
||||
fn merge_dependencies_tables<T, U>(cargo_toml: &mut T, root: &U)
|
||||
where
|
||||
T: toml_edit::TableLike + ?Sized,
|
||||
U: toml_edit::TableLike + ?Sized,
|
||||
{
|
||||
use toml_edit::Value;
|
||||
|
||||
cargo_toml.iter_mut().for_each(|(k, v)| {
|
||||
// Bail if:
|
||||
// - cargo_toml isn't a table (otherwise `workspace = true` can't show up
|
||||
// - the workspace root doesn't have this key
|
||||
let (t, root_val) = match try_as_table_like_mut(&mut *v).zip(root.get(&k)) {
|
||||
Some((t, root_val)) => (t, root_val),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if let Some(Item::Value(toml_edit::Value::Boolean(bool_value))) = t.get("workspace") {
|
||||
if *bool_value.value() {
|
||||
t.remove("workspace");
|
||||
let orig_val = mem::replace(
|
||||
v,
|
||||
match root_val.clone() {
|
||||
s @ Item::Value(Value::String(_)) => {
|
||||
let mut table = Table::new();
|
||||
table.insert("version", s);
|
||||
Item::Table(table)
|
||||
}
|
||||
v => v,
|
||||
},
|
||||
);
|
||||
|
||||
merge_items(v, orig_val);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Recursively merge the `additional` item into the specified `dest`
|
||||
fn merge_items(dest: &mut Item, additional: Item) {
|
||||
use toml_edit::Value;
|
||||
@ -343,6 +386,8 @@ mod tests {
|
||||
grault = { version = "grault-vers" }
|
||||
garply = "garply-vers"
|
||||
waldo = "waldo-vers"
|
||||
fred.workspace = true
|
||||
plugh = { workspace = true, optional = true }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
unix = { workspace = true, features = ["some"] }
|
||||
@ -407,6 +452,8 @@ mod tests {
|
||||
garply = "garply-workspace-vers"
|
||||
waldo = { version = "waldo-workspace-vers" }
|
||||
unix = { version = "unix-vers" }
|
||||
fred = "0.1.3"
|
||||
plugh = "0.2.4"
|
||||
|
||||
[workspace.lints.rust]
|
||||
unused_extern_crates = 'warn'
|
||||
@ -421,34 +468,40 @@ mod tests {
|
||||
// in cargo_toml
|
||||
let expected_toml_str = r#"
|
||||
[package]
|
||||
authors= ["first author", "second author"]
|
||||
categories= ["first category", "second category" ]
|
||||
description= "some description"
|
||||
documentation= "some doc url"
|
||||
edition= "2021"
|
||||
exclude= ["first exclusion", "second exclusion"]
|
||||
homepage= "some home page"
|
||||
include= ["first inclusion", "second inclusion"]
|
||||
keyword= ["first keyword", "second keyword"]
|
||||
license= "some license"
|
||||
license-file= "some license-file"
|
||||
publish= true
|
||||
readme= "some readme"
|
||||
repository= "some repository"
|
||||
rust-version= "some rust-version"
|
||||
version= "some version"
|
||||
authors = ["first author", "second author"]
|
||||
categories = ["first category", "second category" ]
|
||||
description = "some description"
|
||||
documentation = "some doc url"
|
||||
edition = "2021"
|
||||
exclude = ["first exclusion", "second exclusion"]
|
||||
homepage = "some home page"
|
||||
include = ["first inclusion", "second inclusion"]
|
||||
keyword = ["first keyword", "second keyword"]
|
||||
license = "some license"
|
||||
license-file = "some license-file"
|
||||
publish = true
|
||||
readme = "some readme"
|
||||
repository = "some repository"
|
||||
rust-version = "some rust-version"
|
||||
version = "some version"
|
||||
|
||||
[dependencies]
|
||||
# the `foo` dependency is most imporant, so it goes first
|
||||
foo= { version = "foo-vers" }
|
||||
bar= { version = "bar-vers", default-features = false }
|
||||
baz= { version = "baz-vers", features = ["baz-feat", "baz-feat2"] }
|
||||
foo = { version = "foo-vers" }
|
||||
bar = { version = "bar-vers", default-features = false }
|
||||
baz = { version = "baz-vers", features = ["baz-feat", "baz-feat2"] }
|
||||
qux = { version = "qux-vers", features = ["qux-feat","qux-additional"] }
|
||||
corge = { version = "corge-vers-override" , features = ["qux-feat"] }
|
||||
grault = { version = "grault-vers" }
|
||||
garply = "garply-vers"
|
||||
waldo = "waldo-vers"
|
||||
|
||||
[dependencies.fred]
|
||||
version = "0.1.3"
|
||||
|
||||
[ dependencies.plugh ]
|
||||
version = "0.2.4"
|
||||
optional = true
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
unix = { version = "unix-vers" , features = ["some"] }
|
||||
|
||||
@ -456,9 +509,9 @@ mod tests {
|
||||
unused_extern_crates = 'warn'
|
||||
|
||||
[dev-dependencies]
|
||||
foo= { version = "foo-vers" }
|
||||
bar= { version = "bar-vers", default-features = false }
|
||||
baz= { version = "baz-vers", features = ["baz-feat", "baz-feat2"] }
|
||||
foo = { version = "foo-vers" }
|
||||
bar = { version = "bar-vers", default-features = false }
|
||||
baz = { version = "baz-vers", features = ["baz-feat", "baz-feat2"] }
|
||||
qux = { version = "qux-vers", features = ["qux-feat","qux-additional"] }
|
||||
corge = { version = "corge-vers-override" , features = ["qux-feat"] }
|
||||
grault = { version = "grault-vers" }
|
||||
@ -469,9 +522,9 @@ mod tests {
|
||||
all = 'allow'
|
||||
|
||||
[build-dependencies]
|
||||
foo= { version = "foo-vers" }
|
||||
bar= { version = "bar-vers", default-features = false }
|
||||
baz= { version = "baz-vers", features = ["baz-feat", "baz-feat2"] }
|
||||
foo = { version = "foo-vers" }
|
||||
bar = { version = "bar-vers", default-features = false }
|
||||
baz = { version = "baz-vers", features = ["baz-feat", "baz-feat2"] }
|
||||
qux = { version = "qux-vers", features = ["qux-feat","qux-additional"] }
|
||||
corge = { version = "corge-vers-override" , features = ["qux-feat"] }
|
||||
grault = { version = "grault-vers" }
|
||||
|
Loading…
Reference in New Issue
Block a user