mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2025-12-10 08:44:39 +01:00
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run
Certain existing tooling, such as 'package-metadata.pl', are written to accept the output of 'opkg list' with package manifest delimited by '-'. The 'make-index-json.py --manifest' output was emulating the 'apk list --manifest' format without the delimiting dash, thus breaking these legacy tools. We fix this by adding the dash to the manifest output, which allows all existing tooling to process the output irrespective of whether the build system uses opkg or apk. Signed-off-by: Eric Fahlgren <ericfahlgren@gmail.com> Link: https://github.com/openwrt/openwrt/pull/20094 Signed-off-by: Robert Marko <robimarko@gmail.com>
103 lines
3.2 KiB
Python
Executable file
103 lines
3.2 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("-m", "--manifest", action="store_true", default=False,
|
|
help="Print output in opkg list format, as 'package - version' pairs")
|
|
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)
|
|
if isinstance(data, dict) and "packages" in data:
|
|
# Extract 'apk adbdump' dict field to 'apk query' package list
|
|
data = data["packages"]
|
|
|
|
for package in data:
|
|
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)
|
|
if args.manifest:
|
|
# Emulate the output of 'opkg list' command for compatibility with
|
|
# legacy tooling.
|
|
for name, version in sorted(packages.items()):
|
|
print(name, "-", version)
|
|
else:
|
|
index = {
|
|
"version": 2,
|
|
"architecture": args.architecture,
|
|
"packages": packages,
|
|
}
|
|
print(json.dumps(index, indent=2))
|