openwrt/scripts/make-index-json.py
Eric Fahlgren 0c7d564b1d scripts: make-index-json: rework for old Python versions
The current code uses functions and features only found in newer
versions of Python, so rework to allow use on systems only supporting
older Python.  Tested on Python 3.8 (released Oct 2019), but should
work on 3.7 also.

Suggested-by: Chen Minqiang <ptpt52@gmail.com>
Signed-off-by: Eric Fahlgren <ericfahlgren@gmail.com>
2025-06-24 23:59:06 +02:00

92 lines
2.6 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 removesuffix(src, suffix):
# For compatibility with Python < 3.9.
suffix_length = len(suffix)
return src[:-suffix_length] if suffix_length and src.endswith(suffix) else src
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]
package_name = removesuffix(package_name, 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"]
package_abi = package.get("ABIVersion")
if package_abi:
package_name = removesuffix(package_name, 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))