blob: a536dc297641467a1a0351eaced0c38f451e5957 [file]
#!/usr/bin/env python3
"""Merges multiple modules_mapping.json files into a single file."""
import argparse
import json
from pathlib import Path
def simplify(mapping: dict) -> dict:
"""Collapse entries for submodules into entries for their parents
where possible. For example, "a.b" and "a.c" become "a".
This must run over the fully merged mapping; a submodule is redundant only
when some ancestor resolves to the same wheel, and we can determine that
only once every wheel has contributed.
Args:
mapping: The fully merged module-to-wheel mapping to simplify.
Returns:
A new, simplified module-to-wheel mapping.
"""
simplified = {}
for module, wheel_name in sorted(mapping.items(), key=lambda x: x[0]):
mod = module
while True:
if mod in simplified:
if simplified[mod] != wheel_name:
break
wheel_name = ""
break
if mod.count(".") == 0:
break
mod = mod.rsplit(".", 1)[0]
if wheel_name:
simplified[module] = wheel_name
return simplified
def merge_modules_mappings(input_files: list[Path], output_file: Path) -> None:
"""Merge multiple modules_mapping.json files into one.
Args:
input_files: List of paths to input JSON files to merge
output_file: Path where the merged output should be written
"""
merged_mapping = {}
for input_file in input_files:
mapping = json.loads(input_file.read_text())
# Merge the mappings, with later files overwriting earlier ones
# if there are conflicts
merged_mapping.update(mapping)
output_file.write_text(json.dumps(simplify(merged_mapping)))
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Merge multiple modules_mapping.json files"
)
parser.add_argument(
"--output",
required=True,
type=Path,
help="Output file path for merged mapping",
)
parser.add_argument(
"--inputs",
required=True,
nargs="+",
type=Path,
help="Input JSON files to merge",
)
args = parser.parse_args()
merge_modules_mappings(args.inputs, args.output)