Fix #839: Check pkgver after parsing APKBUILD / various small improvements (#854)

Small improvements:
* Allow to specify multiple packages to `pmbootstrap parse_apkbuild`
* Specifying no package will parse all packages (like kconfig_check)
  (also `parse_apkbuild`)
* JSON output is sorted of `parse_apkbuild`
* Make pkgver check optional, so we can disable it in the device wizard test case
* Parse_apk* -> apk*_parse
* Don't let the user mess with globs (disallow '*' in pkgname)
This commit is contained in:
Oliver Smith 2018-01-18 22:05:27 +00:00 committed by GitHub
parent 0bc60138f3
commit 0ae23afa60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 21 deletions

View file

@ -43,6 +43,10 @@ def find_aport(args, package, must_exist=True):
if package in args.cache["find_aport"]: if package in args.cache["find_aport"]:
ret = args.cache["find_aport"][package] ret = args.cache["find_aport"][package]
else: else:
# Sanity check
if "*" in package:
raise RuntimeError("Invalid pkgname: " + package)
# Search in packages # Search in packages
paths = glob.glob(args.aports + "/*/" + package) paths = glob.glob(args.aports + "/*/" + package)
if len(paths) > 2: if len(paths) > 2:

View file

@ -244,13 +244,24 @@ def kconfig_check(args):
raise RuntimeError("kconfig_check failed!") raise RuntimeError("kconfig_check failed!")
def parse_apkbuild(args): def apkbuild_parse(args):
aport = pmb.build.other.find_aport(args, args.package) # Default to all packages
packages = args.packages
if not packages:
for apkbuild in glob.glob(args.aports + "/*/*/APKBUILD"):
packages.append(os.path.basename(os.path.dirname(apkbuild)))
# Iterate over all packages
packages.sort()
for package in packages:
print(package + ":")
aport = pmb.build.other.find_aport(args, package)
path = aport + "/APKBUILD" path = aport + "/APKBUILD"
print(json.dumps(pmb.parse.apkbuild(args, path), indent=4)) print(json.dumps(pmb.parse.apkbuild(args, path), indent=4,
sort_keys=True))
def parse_apkindex(args): def apkindex_parse(args):
result = pmb.parse.apkindex.parse(args, args.apkindex_path) result = pmb.parse.apkindex.parse(args, args.apkindex_path)
if args.package: if args.package:
if args.package not in result: if args.package not in result:

View file

@ -19,6 +19,7 @@ along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
import os import os
import logging import logging
import pmb.config import pmb.config
import pmb.parse.version
def replace_variables(apkbuild): def replace_variables(apkbuild):
@ -80,15 +81,16 @@ def cut_off_function_names(apkbuild):
return apkbuild return apkbuild
def apkbuild(args, path): def apkbuild(args, path, check_pkgver=True):
""" """
Parse relevant information out of the APKBUILD file. This is not meant Parse relevant information out of the APKBUILD file. This is not meant
to be perfect and catch every edge case (for that, a full shell parser to be perfect and catch every edge case (for that, a full shell parser
would be necessary!). Instead, it should just work with the use-cases would be necessary!). Instead, it should just work with the use-cases
covered by pmbootstrap and not take too long. covered by pmbootstrap and not take too long.
:param path: Full path to the APKBUILD :param path: full path to the APKBUILD
:returns: Relevant variables from the APKBUILD. Arrays get returned as :param version_check: verify that the pkgver is valid.
:returns: relevant variables from the APKBUILD. Arrays get returned as
arrays. arrays.
""" """
# Try to get a cached result first (we assume, that the aports don't change # Try to get a cached result first (we assume, that the aports don't change
@ -160,6 +162,14 @@ def apkbuild(args, path):
if not len(ret["arch"]): if not len(ret["arch"]):
raise RuntimeError("Arch must not be empty: " + path) raise RuntimeError("Arch must not be empty: " + path)
# Sanity check: pkgver
if check_pkgver:
if "-r" in ret["pkgver"] or not pmb.parse.version.validate(ret["pkgver"]):
logging.info("NOTE: Valid pkgvers are described here:")
logging.info("<https://wiki.alpinelinux.org/wiki/APKBUILD_Reference#pkgver>")
raise RuntimeError("Invalid pkgver '" + ret["pkgver"] +
"' in APKBUILD: " + path)
# Fill cache # Fill cache
args.cache["apkbuild"][path] = ret args.cache["apkbuild"][path] = ret
return ret return ret

View file

@ -289,15 +289,13 @@ def arguments():
help="do not overwrite the existing kernel", help="do not overwrite the existing kernel",
action="store_false", dest="recovery_flash_kernel") action="store_false", dest="recovery_flash_kernel")
# Action: menuconfig / parse_apkbuild # Action: menuconfig
menuconfig = sub.add_parser("menuconfig", help="run menuconfig on" menuconfig = sub.add_parser("menuconfig", help="run menuconfig on"
" a kernel aport") " a kernel aport")
menuconfig.add_argument("--arch", choices=arch_choices) menuconfig.add_argument("--arch", choices=arch_choices)
parse_apkbuild = sub.add_parser("parse_apkbuild") menuconfig.add_argument("package")
for action in [menuconfig, parse_apkbuild]:
action.add_argument("package")
# Action: build / checksum / aportgen # Action: checksum / aportgen / build
checksum = sub.add_parser("checksum", help="update aport checksums") checksum = sub.add_parser("checksum", help="update aport checksums")
aportgen = sub.add_parser("aportgen", help="generate a postmarketOS" aportgen = sub.add_parser("aportgen", help="generate a postmarketOS"
" specific package build recipe (aport/APKBUILD)") " specific package build recipe (aport/APKBUILD)")
@ -322,11 +320,13 @@ def arguments():
for action in [checksum, build, aportgen]: for action in [checksum, build, aportgen]:
action.add_argument("packages", nargs="+") action.add_argument("packages", nargs="+")
# Action: kconfig_check # Action: kconfig_check / apkbuild_parse
kconfig_check = sub.add_parser("kconfig_check", help="check, whether all" kconfig_check = sub.add_parser("kconfig_check", help="check, whether all"
" the necessary options are" " the necessary options are"
" enabled/disabled in the kernel config") " enabled/disabled in the kernel config")
kconfig_check.add_argument("packages", nargs="*") apkbuild_parse = sub.add_parser("apkbuild_parse")
for action in [kconfig_check, apkbuild_parse]:
action.add_argument("packages", nargs="*")
# Action: challenge # Action: challenge
challenge = sub.add_parser("challenge", challenge = sub.add_parser("challenge",
@ -343,10 +343,10 @@ def arguments():
" .apk, or must be named" " .apk, or must be named"
" APKINDEX.tar.gz.") " APKINDEX.tar.gz.")
# Action: parse_apkindex # Action: apkindex_parse
parse_apkindex = sub.add_parser("parse_apkindex") apkindex_parse = sub.add_parser("apkindex_parse")
parse_apkindex.add_argument("apkindex_path") apkindex_parse.add_argument("apkindex_path")
parse_apkindex.add_argument("package", default=None, nargs="?") apkindex_parse.add_argument("package", default=None, nargs="?")
# Action: config # Action: config
config = sub.add_parser("config", config = sub.add_parser("config",

View file

@ -87,7 +87,8 @@ def generate(args, monkeypatch, answers):
apkbuild_path_linux = (args.aports + "/device/" apkbuild_path_linux = (args.aports + "/device/"
"linux-testsuite-testdevice/APKBUILD") "linux-testsuite-testdevice/APKBUILD")
apkbuild = pmb.parse.apkbuild(args, apkbuild_path) apkbuild = pmb.parse.apkbuild(args, apkbuild_path)
apkbuild_linux = pmb.parse.apkbuild(args, apkbuild_path_linux) apkbuild_linux = pmb.parse.apkbuild(args, apkbuild_path_linux,
check_pkgver=False)
deviceinfo = pmb.parse.deviceinfo(args, "testsuite-testdevice") deviceinfo = pmb.parse.deviceinfo(args, "testsuite-testdevice")
return (deviceinfo, apkbuild, apkbuild_linux) return (deviceinfo, apkbuild, apkbuild_linux)