-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rustPlatform.importCargoLock: add support for git dependencies that u…
…se workspace inheritance Rust 1.64.0 added support for workspace inheritance, which allows for crates to inherit values such as dependency version constraints or package metadata information from their workspaces [0]. This works by having workspace members specify a value as a table, with `workspace` set to true. Thus, supporting this in importCargoLock is as simple as walking the crate's Cargo.toml, replacing inherited values with their workspace counterpart. This is also what a forthcoming Cargo release will do for `cargo vendor` [1], but we can get ahead of it ;) [0]: https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#cargo-improvements-workspace-inheritance-and-multi-target-builds [1]: rust-lang/cargo#11414
- Loading branch information
Showing
7 changed files
with
142 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
...build-support/rust/test/import-cargo-lock/git-dependency-workspace-inheritance/crate.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
version = { workspace = true } | ||
|
||
[dependencies] | ||
foo = { workspace = true, features = ["cat"] } | ||
bar = "1.0.0" |
7 changes: 7 additions & 0 deletions
7
...uild-support/rust/test/import-cargo-lock/git-dependency-workspace-inheritance/default.nix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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} | ||
'' |
12 changes: 12 additions & 0 deletions
12
.../build-support/rust/test/import-cargo-lock/git-dependency-workspace-inheritance/want.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
version = "1.0.0" | ||
|
||
[dependencies] | ||
bar = "1.0.0" | ||
|
||
[dependencies.foo] | ||
features = [ | ||
"cat", | ||
"meow", | ||
] | ||
version = "1.0.0" |
5 changes: 5 additions & 0 deletions
5
...d-support/rust/test/import-cargo-lock/git-dependency-workspace-inheritance/workspace.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[workspace.package] | ||
version = "1.0.0" | ||
|
||
[workspace.dependencies] | ||
foo = { version = "1.0.0", features = ["meow"] } |