Merge pull request #310579 from K900/workspace-dependencies-are-cursed

build-support/rust: rewrite workspace dependency inheritance

authored by K900 and committed by GitHub f52a41d0 acbbc1cd

+27 -15
+27 -15
pkgs/build-support/rust/replace-workspace-values.py
··· 15 15 return tomli.load(f) 16 16 17 17 18 + # This replicates the dependency merging logic from Cargo. 19 + # See `inner_dependency_inherit_with`: 20 + # https://github.com/rust-lang/cargo/blob/4de0094ac78743d2c8ff682489e35c8a7cafe8e4/src/cargo/util/toml/mod.rs#L982 18 21 def replace_key( 19 22 workspace_manifest: dict[str, Any], table: dict[str, Any], section: str, key: str 20 23 ) -> bool: ··· 25 28 ): 26 29 print("replacing " + key) 27 30 28 - replaced = table[key] 29 - del replaced["workspace"] 31 + local_dep = table[key] 32 + del local_dep["workspace"] 30 33 31 - workspace_copy = workspace_manifest[section][key] 34 + workspace_dep = workspace_manifest[section][key] 32 35 33 36 if section == "dependencies": 34 - crate_features = replaced.get("features") 37 + if isinstance(workspace_dep, str): 38 + workspace_dep = {"version": workspace_dep} 35 39 36 - if type(workspace_copy) is str: 37 - replaced["version"] = workspace_copy 38 - else: 39 - replaced.update(workspace_copy) 40 + final: dict[str, Any] = workspace_dep.copy() 40 41 41 - merged_features = (crate_features or []) + ( 42 - workspace_copy.get("features") or [] 43 - ) 42 + merged_features = local_dep.pop("features", []) + workspace_dep.get("features", []) 43 + if merged_features: 44 + final["features"] = merged_features 44 45 45 - if len(merged_features) > 0: 46 - # Dictionaries are guaranteed to be ordered (https://stackoverflow.com/a/7961425) 47 - replaced["features"] = list(dict.fromkeys(merged_features)) 46 + local_default_features = local_dep.pop("default-features", None) 47 + workspace_default_features = workspace_dep.get("default-features") 48 + 49 + if not workspace_default_features and local_default_features: 50 + final["default-features"] = True 51 + 52 + optional = local_dep.pop("optional", False) 53 + if optional: 54 + final["optional"] = True 55 + 56 + if local_dep: 57 + raise Exception(f"Unhandled keys in inherited dependency {key}: {local_dep}") 58 + 59 + table[key] = final 48 60 elif section == "package": 49 - table[key] = replaced = workspace_copy 61 + table[key] = workspace_dep 50 62 51 63 return True 52 64