Files

96 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""Merge a newly built plugin index with a historical one from OSS.
Used by the ``plugins-release.yml`` workflow to preserve old plugin
versions on the CDN while adding new ones.
Merge rules:
- ``files``: keyed by file_id (``{plugin_id}-{version}``). New entries
overwrite same-id old entries; different ids from old are preserved.
- ``platforms.{kind}.versions``: union of new and old version lists,
new versions first, old versions appended with deduplication.
Usage::
python scripts/pack/merge_plugin_index.py \
--new dist/plugins/index.json \
--old existing-index.json \
--out dist/plugins/index.json
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
def merge_indexes(new_index: dict, old_index: dict) -> dict:
"""Merge *old_index* into *new_index* (mutates and returns *new_index*)."""
# files: same file_id is overwritten by new; different ids preserved.
old_files = old_index.get("files", {})
new_files = new_index.get("files", {})
new_index["files"] = {**old_files, **new_files}
# platforms.versions: union, new first, old appended with dedup.
old_platforms = old_index.get("platforms", {})
all_kinds = set(
list(new_index.get("platforms", {}).keys())
+ list(old_platforms.keys()),
)
for kind in all_kinds:
old_versions = old_platforms.get(kind, {}).get("versions", [])
new_versions = (
new_index.get("platforms", {}).get(kind, {}).get("versions", [])
)
seen = set(new_versions)
merged = list(new_versions)
for v in old_versions:
if v not in seen:
merged.append(v)
seen.add(v)
new_index.setdefault("platforms", {})
new_index["platforms"].setdefault(kind, {})
new_index["platforms"][kind]["versions"] = merged
return new_index
def main(argv: list[str] | None = None) -> None:
parser = argparse.ArgumentParser(
description="Merge new and historical plugin indexes.",
)
parser.add_argument(
"--new",
required=True,
type=Path,
help="Path to the newly generated index.json",
)
parser.add_argument(
"--old",
required=True,
type=Path,
help="Path to the existing (historical) index.json",
)
parser.add_argument(
"--out",
required=True,
type=Path,
help="Output path for the merged index.json",
)
args = parser.parse_args(argv)
with open(args.new, encoding="utf-8") as f:
new_index = json.load(f)
with open(args.old, encoding="utf-8") as f:
old_index = json.load(f)
merged = merge_indexes(new_index, old_index)
with open(args.out, "w", encoding="utf-8") as f:
json.dump(merged, f, indent=2, ensure_ascii=False)
if __name__ == "__main__":
main()