diff --git a/pmb/build/_package.py b/pmb/build/_package.py index 8fce4360..aa46801c 100644 --- a/pmb/build/_package.py +++ b/pmb/build/_package.py @@ -30,6 +30,23 @@ import pmb.parse import pmb.parse.arch +def skip_already_built(args, pkgname, arch): + """ + Check if the package was already built in this session, and add it + to the cache in case it was not built yet. + + :returns: True when it can be skipped or False + """ + if arch not in args.cache["built"]: + args.cache["built"][arch] = [] + if pkgname in args.cache["built"][arch]: + logging.verbose(pkgname + ": already checked this session," + " no need to build it or its dependencies") + return True + args.cache["built"][arch].append(pkgname) + return False + + def get_apkbuild(args, pkgname, arch): """ Find the APKBUILD path for pkgname. When there is none, try to find it in @@ -276,8 +293,12 @@ def package(args, pkgname, arch=None, force=False, buildinfo=False, :returns: None if the build was not necessary output path relative to the packages folder ("armhf/ab-1-r2.apk") """ - # Only build when APKBUILD exists + # Once per session is enough arch = arch or args.arch_native + if skip_already_built(args, pkgname, arch): + return + + # Only build when APKBUILD exists apkbuild = get_apkbuild(args, pkgname, arch) if not apkbuild: return diff --git a/pmb/parse/arguments.py b/pmb/parse/arguments.py index 1e51981a..11e5cfe4 100644 --- a/pmb/parse/arguments.py +++ b/pmb/parse/arguments.py @@ -347,6 +347,7 @@ def arguments(): "apk_min_version_checked": [], "apk_repository_list_updated": [], "aports_files_out_of_sync_with_git": None, + "built": {}, "find_aport": {}}) # Add and verify the deviceinfo (only after initialization) diff --git a/test/test_build_package.py b/test/test_build_package.py index a4c35eeb..032ae531 100644 --- a/test/test_build_package.py +++ b/test/test_build_package.py @@ -75,6 +75,14 @@ def args_patched(monkeypatch, argv): return pmb.parse.arguments() +def test_skip_already_built(args): + func = pmb.build._package.skip_already_built + assert args.cache["built"] == {} + assert func(args, "test-package", "armhf") is False + assert args.cache["built"] == {"armhf": ["test-package"]} + assert func(args, "test-package", "armhf") is True + + def test_get_apkbuild(args): func = pmb.build._package.get_apkbuild @@ -256,9 +264,11 @@ def test_package(args): assert pmb.build.package(args, "hello-world", force=True) # Package exists + args.cache["built"] = {} assert pmb.build.package(args, "hello-world") is None # Force building again + args.cache["built"] = {} assert pmb.build.package(args, "hello-world", force=True) # Build for another architecture @@ -293,6 +303,7 @@ def test_build_depends_high_level(args, monkeypatch): # Remove hello-world pmb.helpers.run.root(args, ["rm", output_hello_outside]) pmb.build.index_repo(args, args.arch_native) + args.cache["built"] = {} # Ask to build the wrapper. It should not build the wrapper (it exists, not # using force), but build/update its missing dependency "hello-world" diff --git a/test/test_challenge_build.py b/test/test_challenge_build.py index 7132f611..cb65bc57 100644 --- a/test/test_challenge_build.py +++ b/test/test_challenge_build.py @@ -65,6 +65,7 @@ def test_challenge_build(args): apk_path + ".buildinfo.json"]) # Challenge, output changes into a file + args.cache["built"] = {} setattr(args, "output_repo_changes", args.work + "/chroot_native/tmp/" "test_challenge_build_output.txt") pmb.challenge.build(args, args.work + "/chroot_native/" + temp_path + "/" +