diff --git a/pmb/build/__init__.py b/pmb/build/__init__.py index 9e66bc6d..57b575a5 100644 --- a/pmb/build/__init__.py +++ b/pmb/build/__init__.py @@ -22,6 +22,6 @@ from pmb.build.checksum import checksum from pmb.build.menuconfig import menuconfig from pmb.build.newapkbuild import newapkbuild from pmb.build.other import copy_to_buildpath, is_necessary, \ - find_aport, index_repo + index_repo from pmb.build._package import package from pmb.build.qemu_workaround_aarch64 import qemu_workaround_aarch64 diff --git a/pmb/build/_package.py b/pmb/build/_package.py index 4ca06850..6ea36759 100644 --- a/pmb/build/_package.py +++ b/pmb/build/_package.py @@ -25,6 +25,7 @@ import pmb.build.autodetect import pmb.chroot import pmb.chroot.apk import pmb.chroot.distccd +import pmb.helpers.pmaports import pmb.helpers.repo import pmb.parse import pmb.parse.arch @@ -59,7 +60,7 @@ def get_apkbuild(args, pkgname, arch): pmb.helpers.repo.update(args, arch) # Get aport, skip upstream only packages - aport = pmb.build.find_aport(args, pkgname, False) + aport = pmb.helpers.pmaports.find(args, pkgname, False) if aport: return pmb.parse.apkbuild(args, aport + "/APKBUILD") if pmb.parse.apkindex.providers(args, pkgname, arch, False): diff --git a/pmb/build/autodetect.py b/pmb/build/autodetect.py index 03d409eb..2c931a43 100644 --- a/pmb/build/autodetect.py +++ b/pmb/build/autodetect.py @@ -22,6 +22,7 @@ import os import pmb.config import pmb.chroot.apk +import pmb.helpers.pmaports import pmb.parse.arch @@ -59,7 +60,7 @@ def arch(args, pkgname): * device arch * first arch in the APKBUILD """ - aport = pmb.build.find_aport(args, pkgname) + aport = pmb.helpers.pmaports.find(args, pkgname) ret = arch_from_deviceinfo(args, pkgname, aport) if ret: return ret diff --git a/pmb/build/checksum.py b/pmb/build/checksum.py index 6a7489da..efb2877b 100644 --- a/pmb/build/checksum.py +++ b/pmb/build/checksum.py @@ -21,7 +21,7 @@ import logging import pmb.chroot import pmb.build import pmb.helpers.run -import pmb.build.other +import pmb.helpers.pmaports def checksum(args, pkgname): @@ -33,5 +33,5 @@ def checksum(args, pkgname): # Copy modified APKBUILD back source = args.work + "/chroot_native/home/pmos/build/APKBUILD" - target = pmb.build.other.find_aport(args, pkgname) + "/" + target = pmb.helpers.pmaports.find(args, pkgname) + "/" pmb.helpers.run.user(args, ["cp", source, target]) diff --git a/pmb/build/menuconfig.py b/pmb/build/menuconfig.py index ac5c9ea4..6a5190ae 100644 --- a/pmb/build/menuconfig.py +++ b/pmb/build/menuconfig.py @@ -25,6 +25,7 @@ import pmb.build.checksum import pmb.chroot import pmb.chroot.apk import pmb.chroot.other +import pmb.helpers.pmaports import pmb.helpers.run import pmb.parse @@ -97,7 +98,7 @@ def menuconfig(args, pkgname): pkgname = "linux-" + pkgname # Read apkbuild - aport = pmb.build.find_aport(args, pkgname) + aport = pmb.helpers.pmaports.find(args, pkgname) apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD") arch = get_arch(args, apkbuild) kopt = "menuconfig" diff --git a/pmb/build/other.py b/pmb/build/other.py index 92dc3269..94920e50 100644 --- a/pmb/build/other.py +++ b/pmb/build/other.py @@ -21,95 +21,18 @@ import logging import os import shlex -import pmb.build.other import pmb.chroot import pmb.helpers.file import pmb.helpers.git +import pmb.helpers.pmaports import pmb.helpers.run 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. - - :param must_exist: Raise an exception, when not found - :returns: the full path to the aport folder - """ - # Try to get a cached result first (we assume, that the aports don't change - # in one pmbootstrap call) - ret = None - if package in args.cache["find_aport"]: - ret = args.cache["find_aport"][package] - else: - # Sanity check - if "*" in package: - raise RuntimeError("Invalid pkgname: " + package) - - # Search in packages - paths = glob.glob(args.aports + "/*/" + package) - if len(paths) > 1: - raise RuntimeError("Package " + package + " found in multiple" - " aports subfolders. Please put it only in one" - " folder.") - elif len(paths) == 1: - ret = paths[0] - - # 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 - package in apkbuild["provides"]): - 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: " + - package) - - # Save result in cache - args.cache["find_aport"][package] = ret - return ret - - def copy_to_buildpath(args, package, suffix="native"): # Sanity check - aport = find_aport(args, package) + aport = pmb.helpers.pmaports.find(args, package) if not os.path.exists(aport + "/APKBUILD"): raise ValueError("Path does not contain an APKBUILD file:" + aport) diff --git a/pmb/chroot/apk.py b/pmb/chroot/apk.py index 29be8cdf..ac46aa44 100644 --- a/pmb/chroot/apk.py +++ b/pmb/chroot/apk.py @@ -22,6 +22,7 @@ import shlex import pmb.chroot import pmb.config +import pmb.helpers.pmaports import pmb.parse.apkindex import pmb.parse.arch import pmb.parse.depends @@ -166,7 +167,7 @@ def replace_aports_packages_with_path(args, packages, suffix, arch): """ ret = [] for package in packages: - aport = pmb.build.find_aport(args, package, False) + aport = pmb.helpers.pmaports.find(args, package, False) if aport: data_repo = pmb.parse.apkindex.package(args, package, arch, False) apk_path = ("/mnt/pmbootstrap-packages/" + arch + "/" + diff --git a/pmb/chroot/zap.py b/pmb/chroot/zap.py index d78763f9..14b4b507 100644 --- a/pmb/chroot/zap.py +++ b/pmb/chroot/zap.py @@ -22,6 +22,7 @@ import math import os import pmb.chroot +import pmb.helpers.pmaports import pmb.helpers.run import pmb.parse.apkindex @@ -121,7 +122,7 @@ def zap_pkgs_local_mismatch(args, confirm=True, dry=False): continue # Aport path - aport_path = pmb.build.other.find_aport(args, origin, False) + aport_path = pmb.helpers.pmaports.find(args, origin, False) if not aport_path: logging.info("% rm " + apk_path_short + " (" + origin + " aport not found)") diff --git a/pmb/helpers/frontend.py b/pmb/helpers/frontend.py index 45879032..7ecd7d65 100644 --- a/pmb/helpers/frontend.py +++ b/pmb/helpers/frontend.py @@ -35,8 +35,8 @@ import pmb.chroot.other import pmb.export import pmb.flasher import pmb.helpers.logging -import pmb.helpers.other import pmb.helpers.pkgrel_bump +import pmb.helpers.pmaports import pmb.helpers.repo import pmb.helpers.run import pmb.install @@ -266,7 +266,7 @@ def apkbuild_parse(args): packages.sort() for package in packages: print(package + ":") - aport = pmb.build.other.find_aport(args, package) + aport = pmb.helpers.pmaports.find(args, package) path = aport + "/APKBUILD" print(json.dumps(pmb.parse.apkbuild(args, path), indent=4, sort_keys=True)) @@ -289,7 +289,7 @@ def pkgrel_bump(args): else: # Each package must exist for package in args.packages: - pmb.build.other.find_aport(args, package) + pmb.helpers.pmaports.find(args, package) # Increase pkgrel for package in args.packages: diff --git a/pmb/helpers/other.py b/pmb/helpers/other.py index e2d65215..328e152f 100644 --- a/pmb/helpers/other.py +++ b/pmb/helpers/other.py @@ -21,6 +21,7 @@ import os import re import pmb.chroot import pmb.config +import pmb.helpers.pmaports import pmb.helpers.run diff --git a/pmb/helpers/pkgrel_bump.py b/pmb/helpers/pkgrel_bump.py index 3b131ba9..d1f8f3da 100644 --- a/pmb/helpers/pkgrel_bump.py +++ b/pmb/helpers/pkgrel_bump.py @@ -19,8 +19,8 @@ along with pmbootstrap. If not, see . import logging import os -import pmb.build.other import pmb.helpers.file +import pmb.helpers.pmaports import pmb.helpers.repo import pmb.parse @@ -34,7 +34,7 @@ def package(args, pkgname, reason="", dry=False): :param dry: don't modify the APKBUILD, just print the message """ # Current and new pkgrel - path = pmb.build.other.find_aport(args, pkgname) + "/APKBUILD" + path = pmb.helpers.pmaports.find(args, pkgname) + "/APKBUILD" apkbuild = pmb.parse.apkbuild(args, path) pkgrel = int(apkbuild["pkgrel"]) pkgrel_new = pkgrel + 1 @@ -128,7 +128,7 @@ def auto_apkindex_package(args, arch, aport, apk, dry=False): # (which means dynamic libraries that the package was linked # against) and packages for which no aport exists. if (depend.startswith("so:") or - not pmb.build.other.find_aport(args, depend, False)): + not pmb.helpers.pmaports.find(args, depend, False)): missing.append(depend) # Increase pkgrel @@ -154,7 +154,7 @@ def auto(args, dry=False): logging.verbose("{}: origin '{}' found again".format(pkgname, origin)) continue - aport_path = pmb.build.other.find_aport(args, origin, False) + aport_path = pmb.helpers.pmaports.find(args, origin, False) if not aport_path: logging.warning("{}: origin '{}' aport not found".format( pkgname, origin)) diff --git a/pmb/helpers/pmaports.py b/pmb/helpers/pmaports.py new file mode 100644 index 00000000..8c37b722 --- /dev/null +++ b/pmb/helpers/pmaports.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +""" +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 glob +import logging +import os + +import pmb.parse + + +def 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(args, package, must_exist=True): + """ + Find the aport, that provides a certain subpackage. + + :param must_exist: Raise an exception, when not found + :returns: the full path to the aport folder + """ + # Try to get a cached result first (we assume, that the aports don't change + # in one pmbootstrap call) + ret = None + if package in args.cache["find_aport"]: + ret = args.cache["find_aport"][package] + else: + # Sanity check + if "*" in package: + raise RuntimeError("Invalid pkgname: " + package) + + # Search in packages + paths = glob.glob(args.aports + "/*/" + package) + if len(paths) > 1: + raise RuntimeError("Package " + package + " found in multiple" + " aports subfolders. Please put it only in one" + " folder.") + elif len(paths) == 1: + ret = paths[0] + + # 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 + package in apkbuild["provides"]): + ret = os.path.dirname(path_current) + break + + # Guess a main package + if not ret: + ret = guess_main(args, package) + + # Crash when necessary + if ret is None and must_exist: + raise RuntimeError("Could not find aport for package: " + + package) + + # Save result in cache + args.cache["find_aport"][package] = ret + return ret diff --git a/pmb/parse/depends.py b/pmb/parse/depends.py index a846a3e3..6eaf8384 100644 --- a/pmb/parse/depends.py +++ b/pmb/parse/depends.py @@ -19,6 +19,7 @@ along with pmbootstrap. If not, see . import logging import pmb.chroot import pmb.chroot.apk +import pmb.helpers.pmaports import pmb.parse.apkindex import pmb.parse.arch @@ -29,7 +30,7 @@ def package_from_aports(args, pkgname_depend): depends, version. The version is the combined pkgver and pkgrel. """ # Get the aport - aport = pmb.build.find_aport(args, pkgname_depend, False) + aport = pmb.helpers.pmaports.find(args, pkgname_depend, False) if not aport: return None diff --git a/pmb/parse/kconfig.py b/pmb/parse/kconfig.py index 1b50b922..99aca0e6 100644 --- a/pmb/parse/kconfig.py +++ b/pmb/parse/kconfig.py @@ -24,6 +24,7 @@ import os import pmb.build import pmb.config import pmb.parse +import pmb.helpers.pmaports def is_set(config, option): @@ -50,7 +51,7 @@ def check(args, pkgname, details=False): # Read all kernel configs in the aport ret = True - aport = pmb.build.find_aport(args, "linux-" + flavor) + aport = pmb.helpers.pmaports.find(args, "linux-" + flavor) for config_path in glob.glob(aport + "/config-*"): logging.debug("Check kconfig: " + config_path) with open(config_path) as handle: diff --git a/test/test_build_is_necessary.py b/test/test_build_is_necessary.py index 421fe831..3a00f25a 100644 --- a/test/test_build_is_necessary.py +++ b/test/test_build_is_necessary.py @@ -23,8 +23,8 @@ import pytest # Import from parent directory sys.path.insert(0, os.path.realpath( os.path.join(os.path.dirname(__file__) + "/.."))) -import pmb.build.other import pmb.helpers.logging +import pmb.helpers.pmaports @pytest.fixture @@ -59,7 +59,7 @@ def cache_apkindex(args, version): def test_build_is_necessary(args): # Prepare APKBUILD and APKINDEX data - aport = pmb.build.other.find_aport(args, "hello-world") + aport = pmb.helpers.pmaports.find(args, "hello-world") apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD") apkbuild["pkgver"] = "1" apkbuild["pkgrel"] = "2" @@ -88,6 +88,6 @@ def test_build_is_necessary_no_binary_available(args): hello-world package has not been built yet. """ indexes = list(args.cache["apkindex"].keys()) - aport = pmb.build.other.find_aport(args, "hello-world") + aport = pmb.helpers.pmaports.find(args, "hello-world") apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD") assert pmb.build.is_necessary(args, None, apkbuild, indexes) is True diff --git a/test/test_find_aport.py b/test/test_helpers_pmaports.py similarity index 94% rename from test/test_find_aport.py rename to test/test_helpers_pmaports.py index 49a84e63..475b1793 100644 --- a/test/test_find_aport.py +++ b/test/test_helpers_pmaports.py @@ -38,14 +38,14 @@ def args(request): return args -def test_find_aport_guess_main(args, tmpdir): +def test_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 + func = pmb.helpers.pmaports.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"