openwrt-6.x/scripts/make-index-json.py
Tianling Shen f4e1608464
make-index-json: fix compatibility with python3 < 3.9
'str.removesuffix' is only available in Python 3.9+.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
2025-06-19 14:40:23 +08:00

87 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Parse the native package index files into a json file for use by downstream
tools. See:
https://github.com/openwrt/openwrt/commit/218ce40cd738f3373438aab82467807a8707fb9c
The "version 1" index.json contained ABI-versioned package names, making the
unusable by the ASU server. The version 2 format contains package names that
have been stripped of their ABI version.
"""
import email.parser
import json
def parse_args():
from argparse import ArgumentParser
source_format = "apk", "opkg"
parser = ArgumentParser()
# fmt: off
parser.add_argument("-a", "--architecture", required=True,
help="Required device architecture: like 'x86_64' or 'aarch64_generic'")
parser.add_argument("-f", "--source-format", required=True, choices=source_format,
help="Required source format of input: 'apk' or 'opkg'")
parser.add_argument(dest="source",
help="File name for input, '-' for stdin")
# fmt: on
args = parser.parse_args()
return args
def parse_apk(text: str) -> dict:
packages: dict = {}
data = json.loads(text)
for package in data.get("packages", []):
package_name: str = package["name"]
for tag in package.get("tags", []):
if tag.startswith("openwrt:abiversion="):
package_abi: str = tag.split("=")[-1]
if package_name.endswith(package_abi):
package_name = package_name[:-len(package_abi)]
break
packages[package_name] = package["version"]
return packages
def parse_opkg(text: str) -> dict:
packages: dict = {}
parser: email.parser.Parser = email.parser.Parser()
chunks: list[str] = text.strip().split("\n\n")
for chunk in chunks:
package: dict = parser.parsestr(chunk, headersonly=True)
package_name: str = package["Package"]
if package_abi := package.get("ABIVersion"):
if package_name.endswith(package_abi):
package_name = package_name[:-len(package_abi)]
packages[package_name] = package["Version"]
return packages
if __name__ == "__main__":
import sys
args = parse_args()
input = sys.stdin if args.source == "-" else open(args.source, "r")
with input:
text: str = input.read()
packages = parse_apk(text) if args.source_format == "apk" else parse_opkg(text)
index = {
"version": 2,
"architecture": args.architecture,
"packages": packages,
}
print(json.dumps(index, indent=2))