From c8205013e117f5984760dd4605f450059fa276d8 Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Sat, 27 Oct 2018 16:04:36 +0200 Subject: [PATCH] Guess main packages when we don't know them Find the main package by assuming it is a prefix of the subpkgname. We do that, because in some APKBUILDs the subpkgname="" variable gets filled with a shell loop and the APKBUILD parser in pmbootstrap can't parse this right. (Intentionally, we don't want to implement a full shell parser.) --- pmb/build/other.py | 37 +++++++++++++++++++++++++++-- test/test_find_aport.py | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 test/test_find_aport.py diff --git a/pmb/build/other.py b/pmb/build/other.py index 9259979a..7754b8c5 100644 --- a/pmb/build/other.py +++ b/pmb/build/other.py @@ -30,6 +30,34 @@ import pmb.parse.apkindex import pmb.parse.version +def find_aport_guess_main(args, subpkgname): + """ + Find the main package by assuming it is a prefix of the subpkgname. + We do that, because in some APKBUILDs the subpkgname="" variable gets + filled with a shell loop and the APKBUILD parser in pmbootstrap can't + parse this right. (Intentionally, we don't want to implement a full shell + parser.) + + :param subpkgname: subpackage name (e.g. "u-boot-some-device") + :returns: * full path to the aport, e.g.: + "/home/user/code/pmbootstrap/aports/main/u-boot" + * None when we couldn't find a main package + """ + # Iterate until the cut up subpkgname is gone + words = subpkgname.split("-") + while len(words) > 1: + # Remove one dash-separated word at a time ("a-b-c" -> "a-b") + words.pop() + pkgname = "-".join(words) + + # Look in pmaports + paths = glob.glob(args.aports + "/*/" + pkgname) + if paths: + logging.debug(subpkgname + ": guessed to be a subpackage of " + + pkgname) + return paths[0] + + def find_aport(args, package, must_exist=True): """ Find the aport, that provides a certain subpackage. @@ -55,8 +83,9 @@ def find_aport(args, package, must_exist=True): " folder.") elif len(paths) == 1: ret = paths[0] - else: - # Search in subpackages + + # Search in subpackages + if not ret: for path_current in glob.glob(args.aports + "/*/*/APKBUILD"): apkbuild = pmb.parse.apkbuild(args, path_current) if (package in apkbuild["subpackages"] or @@ -64,6 +93,10 @@ def find_aport(args, package, must_exist=True): ret = os.path.dirname(path_current) break + # Guess a main package + if not ret: + ret = find_aport_guess_main(args, package) + # Crash when necessary if ret is None and must_exist: raise RuntimeError("Could not find aport for package: " + diff --git a/test/test_find_aport.py b/test/test_find_aport.py new file mode 100644 index 00000000..49a84e63 --- /dev/null +++ b/test/test_find_aport.py @@ -0,0 +1,52 @@ +""" +Copyright 2018 Oliver Smith + +This file is part of pmbootstrap. + +pmbootstrap is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +pmbootstrap is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with pmbootstrap. If not, see . +""" + +import os +import pytest +import sys + +# Import from parent directory +sys.path.insert(0, os.path.realpath( + os.path.join(os.path.dirname(__file__) + "/.."))) +import pmb.build.other + + +@pytest.fixture +def args(request): + import pmb.parse + sys.argv = ["pmbootstrap", "init"] + args = pmb.parse.arguments() + args.log = args.work + "/log_testsuite.txt" + pmb.helpers.logging.init(args) + request.addfinalizer(args.logfd.close) + return args + + +def test_find_aport_guess_main(args, tmpdir): + # Fake pmaports folder + tmpdir = str(tmpdir) + args.aports = tmpdir + for aport in ["temp/qemu", "main/some-pkg"]: + os.makedirs(tmpdir + "/" + aport) + + func = pmb.build.other.find_aport_guess_main + assert func(args, "qemu-x86_64") == tmpdir + "/temp/qemu" + assert func(args, "qemu-system-x86_64") == tmpdir + "/temp/qemu" + assert func(args, "some-pkg-sub-pkg") == tmpdir + "/main/some-pkg" + assert func(args, "qemuPackageWithoutDashes") is None