diff --git a/pmb/parse/apkindex.py b/pmb/parse/apkindex.py index 38ac5531..a1c64d1e 100644 --- a/pmb/parse/apkindex.py +++ b/pmb/parse/apkindex.py @@ -37,9 +37,16 @@ def parse_next_block(args, path, lines, start): :returns: a dictionary with the following structure: { "arch": "noarch", "depends": ["busybox-extras", "lddtree", ... ], + "origin": "postmarketos-mkinitfs", "pkgname": "postmarketos-mkinitfs", "provides": ["mkinitfs=0.0.1"], + "timestamp": "1500000000", "version": "0.0.4-r10" } + NOTE: "depends" is not set for packages without any dependencies, + e.g. musl. + NOTE: "timestamp" and "origin" are not set for virtual packages + (#1273). We use that information to skip these virtual + packages in parse(). :returns: None, when there are no more blocks """ @@ -77,7 +84,7 @@ def parse_next_block(args, path, lines, start): # Format and return the block if end_of_block_found: # Check for required keys - for key in ["pkgname", "version", "timestamp"]: + for key in ["arch", "pkgname", "version"]: if key not in ret: raise RuntimeError("Missing required key '" + key + "' in block " + str(ret) + ", file: " + path) @@ -209,6 +216,12 @@ def parse(args, path, multiple_providers=True): if not block: break + # Skip virtual packages + if "timestamp" not in block: + logging.verbose("Skipped virtual package " + str(block) + " in" + " file: " + path) + continue + # Add the next package and all aliases parse_add_block(ret, block, None, multiple_providers) if "provides" in block: diff --git a/test/test_parse_apkindex.py b/test/test_parse_apkindex.py index f964aa31..7424e2b2 100644 --- a/test/test_parse_apkindex.py +++ b/test/test_parse_apkindex.py @@ -101,6 +101,42 @@ def test_parse_next_block_no_error(args): assert start == [45] +def test_parse_next_block_virtual(args): + """ + Test parsing a virtual package from an APKINDEX. + """ + # Read the file + func = pmb.parse.apkindex.parse_next_block + path = pmb.config.pmb_src + "/test/testdata/apkindex/virtual_package" + with open(path, "r", encoding="utf-8") as handle: + lines = handle.readlines() + + # First block + start = [0] + block = {'arch': 'x86_64', + 'depends': ['so:libc.musl-x86_64.so.1'], + 'origin': 'hello-world', + 'pkgname': 'hello-world', + 'provides': ['cmd:hello-world'], + 'timestamp': '1500000000', + 'version': '2-r0'} + assert func(args, path, lines, start) == block + assert start == [20] + + # Second block: virtual package + block = {'arch': 'noarch', + 'depends': ['hello-world'], + 'pkgname': '.pmbootstrap', + 'provides': [], + 'version': '0'} + assert func(args, path, lines, start) == block + assert start == [31] + + # No more blocks + assert func(args, path, lines, start) is None + assert start == [31] + + def test_parse_add_block(args): func = pmb.parse.apkindex.parse_add_block multiple_providers = False @@ -231,6 +267,24 @@ def test_parse(args): assert args.cache["apkindex"][path]["multiple"] == ret_multiple +def test_parse_virtual(args): + """ + This APKINDEX contains a virtual package .pbmootstrap. It must not be part + of the output. + """ + path = pmb.config.pmb_src + "/test/testdata/apkindex/virtual_package" + block = {'arch': 'x86_64', + 'depends': ['so:libc.musl-x86_64.so.1'], + 'origin': 'hello-world', + 'pkgname': 'hello-world', + 'provides': ['cmd:hello-world'], + 'timestamp': '1500000000', + 'version': '2-r0'} + ret = {"hello-world": block, "cmd:hello-world": block} + assert pmb.parse.apkindex.parse(args, path, False) == ret + assert args.cache["apkindex"][path]["single"] == ret + + def test_providers_invalid_package(args, tmpdir): # Create empty APKINDEX path = str(tmpdir) + "/APKINDEX" diff --git a/test/testdata/apkindex/virtual_package b/test/testdata/apkindex/virtual_package new file mode 100644 index 00000000..fa2f24d1 --- /dev/null +++ b/test/testdata/apkindex/virtual_package @@ -0,0 +1,31 @@ +C:Q1XaZzCVZ9mvH8djPyEb5aUYhG3r4= +P:hello-world +V:2-r0 +A:x86_64 +S:2897 +I:20480 +T:hello world program to be built in the testsuite +U:https://en.wikipedia.org/wiki/%22Hello,_World!%22_program +L:MIT +o:hello-world +t:1500000000 +c: +D:so:libc.musl-x86_64.so.1 +p:cmd:hello-world +F:usr +F:usr/bin +R:hello-world +a:0:0:755 +Z:Q1ZjTpsnMchSsSwEPB1cTjihYuJvo= + +C:Q127l1Ui9vzedbeR3BMelZnSa4pwY= +P:.pmbootstrap +V:0 +A:noarch +S:0 +I:0 +T:virtual meta package +U: +L: +D:hello-world +