mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-10-02 13:00:23 +00:00
Merge pull request #223804 from figsoda/backport
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
{ fetchgit, fetchurl, lib, runCommand, cargo, jq }:
|
||||
{ fetchgit, fetchurl, lib, writers, python3Packages, runCommand, cargo, jq }:
|
||||
|
||||
{
|
||||
# Cargo lock file
|
||||
@@ -89,6 +89,11 @@ let
|
||||
sha256 = pkg.checksum;
|
||||
};
|
||||
|
||||
# Replaces values inherited by workspace members.
|
||||
replaceWorkspaceValues = writers.writePython3 "replace-workspace-values"
|
||||
{ libraries = with python3Packages; [ tomli tomli-w ]; flakeIgnore = [ "E501" ]; }
|
||||
(builtins.readFile ./replace-workspace-values.py);
|
||||
|
||||
# Fetch and unpack a crate.
|
||||
mkCrate = pkg:
|
||||
let
|
||||
@@ -158,6 +163,11 @@ let
|
||||
cp -prvd "$tree/" $out
|
||||
chmod u+w $out
|
||||
|
||||
if grep -q workspace "$out/Cargo.toml"; then
|
||||
chmod u+w "$out/Cargo.toml"
|
||||
${replaceWorkspaceValues} "$out/Cargo.toml" "${tree}/Cargo.toml"
|
||||
fi
|
||||
|
||||
# Cargo is happy with empty metadata.
|
||||
printf '{"files":{},"package":null}' > "$out/.cargo-checksum.json"
|
||||
|
||||
|
||||
95
pkgs/build-support/rust/replace-workspace-values.py
Normal file
95
pkgs/build-support/rust/replace-workspace-values.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# This script implements the workspace inheritance mechanism described
|
||||
# here: https://doc.rust-lang.org/cargo/reference/workspaces.html#the-package-table
|
||||
#
|
||||
# Please run `mypy --strict`, `black`, and `isort --profile black` on this after editing, thanks!
|
||||
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
import tomli
|
||||
import tomli_w
|
||||
|
||||
|
||||
def load_file(path: str) -> dict[str, Any]:
|
||||
with open(path, "rb") as f:
|
||||
return tomli.load(f)
|
||||
|
||||
|
||||
def replace_key(
|
||||
workspace_manifest: dict[str, Any], table: dict[str, Any], section: str, key: str
|
||||
) -> bool:
|
||||
if "workspace" in table[key] and table[key]["workspace"] is True:
|
||||
print("replacing " + key)
|
||||
|
||||
replaced = table[key]
|
||||
del replaced["workspace"]
|
||||
|
||||
workspace_copy = workspace_manifest[section][key]
|
||||
|
||||
if section == "dependencies":
|
||||
crate_features = replaced.get("features")
|
||||
|
||||
if type(workspace_copy) is str:
|
||||
replaced["version"] = workspace_copy
|
||||
else:
|
||||
replaced.update(workspace_copy)
|
||||
|
||||
merged_features = (crate_features or []) + (
|
||||
workspace_copy.get("features") or []
|
||||
)
|
||||
|
||||
if len(merged_features) > 0:
|
||||
# Dictionaries are guaranteed to be ordered (https://stackoverflow.com/a/7961425)
|
||||
replaced["features"] = list(dict.fromkeys(merged_features))
|
||||
elif section == "package":
|
||||
table[key] = replaced = workspace_copy
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def replace_dependencies(
|
||||
workspace_manifest: dict[str, Any], root: dict[str, Any]
|
||||
) -> bool:
|
||||
changed = False
|
||||
|
||||
for key in ["dependencies", "dev-dependencies", "build-dependencies"]:
|
||||
if key in root:
|
||||
for k in root[key].keys():
|
||||
changed |= replace_key(workspace_manifest, root[key], "dependencies", k)
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
def main() -> None:
|
||||
crate_manifest = load_file(sys.argv[1])
|
||||
workspace_manifest = load_file(sys.argv[2])["workspace"]
|
||||
|
||||
if "workspace" in crate_manifest:
|
||||
return
|
||||
|
||||
changed = False
|
||||
|
||||
for key in crate_manifest["package"].keys():
|
||||
changed |= replace_key(
|
||||
workspace_manifest, crate_manifest["package"], "package", key
|
||||
)
|
||||
|
||||
changed |= replace_dependencies(workspace_manifest, crate_manifest)
|
||||
|
||||
if "target" in crate_manifest:
|
||||
for key in crate_manifest["target"].keys():
|
||||
changed |= replace_dependencies(
|
||||
workspace_manifest, crate_manifest["target"][key]
|
||||
)
|
||||
|
||||
if not changed:
|
||||
return
|
||||
|
||||
with open(sys.argv[1], "wb") as f:
|
||||
tomli_w.dump(crate_manifest, f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +1,4 @@
|
||||
{ callPackage }:
|
||||
{ callPackage, writers, python3Packages }:
|
||||
|
||||
# Build like this from nixpkgs root:
|
||||
# $ nix-build -A tests.importCargoLock
|
||||
@@ -11,4 +11,9 @@
|
||||
gitDependencyTag = callPackage ./git-dependency-tag { };
|
||||
gitDependencyBranch = callPackage ./git-dependency-branch { };
|
||||
maturin = callPackage ./maturin { };
|
||||
gitDependencyWorkspaceInheritance = callPackage ./git-dependency-workspace-inheritance {
|
||||
replaceWorkspaceValues = writers.writePython3 "replace-workspace-values"
|
||||
{ libraries = with python3Packages; [ tomli tomli-w ]; flakeIgnore = [ "E501" ]; }
|
||||
(builtins.readFile ../../replace-workspace-values.py);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
version = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
foo = { workspace = true, features = ["cat"] }
|
||||
bar = "1.0.0"
|
||||
@@ -0,0 +1,7 @@
|
||||
{ replaceWorkspaceValues, runCommand }:
|
||||
|
||||
runCommand "git-dependency-workspace-inheritance-test" { } ''
|
||||
cp --no-preserve=mode ${./crate.toml} "$out"
|
||||
${replaceWorkspaceValues} "$out" ${./workspace.toml}
|
||||
diff -u "$out" ${./want.toml}
|
||||
''
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
version = "1.0.0"
|
||||
|
||||
[dependencies]
|
||||
bar = "1.0.0"
|
||||
|
||||
[dependencies.foo]
|
||||
features = [
|
||||
"cat",
|
||||
"meow",
|
||||
]
|
||||
version = "1.0.0"
|
||||
@@ -0,0 +1,5 @@
|
||||
[workspace.package]
|
||||
version = "1.0.0"
|
||||
|
||||
[workspace.dependencies]
|
||||
foo = { version = "1.0.0", features = ["meow"] }
|
||||
Reference in New Issue
Block a user