Skip to content

Commit 75e56b9

Browse files
committed
Add a basic command for searching through BUILDINFO files
In this case to search for packages that were built when a certain version of mingw-w64 was installed. TODO: add a proper CLI interface
1 parent 59ed458 commit 75e56b9

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

msys2-repo-buildinfo

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/bin/env python3
2+
3+
import argparse
4+
import fnmatch
5+
import os
6+
import sys
7+
8+
from msys2_devtools.db import ExtTarFile
9+
from fastprogress.fastprogress import progress_bar
10+
11+
12+
def find_dbs(target_dir: str) -> list[str]:
13+
db_paths = set()
14+
target_dir = os.path.realpath(target_dir)
15+
for root, dirs, files in os.walk(target_dir):
16+
for name in files:
17+
if fnmatch.fnmatch(name, "*.db"):
18+
db_paths.add(os.path.realpath(os.path.join(root, name)))
19+
20+
return sorted(db_paths)
21+
22+
23+
def get_package_paths(root_path: str) -> list[str]:
24+
dbs = find_dbs(root_path)
25+
paths = set()
26+
for db_path in dbs:
27+
28+
with ExtTarFile.open(db_path, mode="r") as tar:
29+
for info in tar.getmembers():
30+
file_name = info.name.rsplit("/", 1)[-1]
31+
if file_name == "desc":
32+
infodata = tar.extractfile(info).read().decode()
33+
lines = infodata.splitlines()
34+
filename = lines[lines.index("%FILENAME%") + 1]
35+
paths.add(os.path.join(os.path.dirname(db_path), filename))
36+
return sorted(paths)
37+
38+
39+
def parse_buildinfo(buildinfo: str) -> dict[str, list[str]]:
40+
res: dict[str, list[str]] = {}
41+
for line in buildinfo.splitlines():
42+
line = line.strip()
43+
if not line:
44+
continue
45+
46+
key, value = line.split(" =", 1)
47+
value = value.strip()
48+
values = [value] if value else []
49+
res.setdefault(key, []).extend(values)
50+
51+
return res
52+
53+
54+
def get_buildinfo(path: str) -> dict:
55+
buildinfo = None
56+
files = set()
57+
with ExtTarFile.open(path, mode="r") as tar:
58+
for info in tar.getmembers():
59+
if info.name == ".BUILDINFO":
60+
buildinfo = tar.extractfile(info).read().decode()
61+
if info.isfile() and not info.name.startswith("."):
62+
files.add(info.name)
63+
64+
if buildinfo is None:
65+
raise RuntimeError(f"Cannot find .BUILDINFO in {path}")
66+
67+
return parse_buildinfo(buildinfo), files
68+
69+
70+
def main(argv):
71+
parser = argparse.ArgumentParser(
72+
description="List things about the package contents", allow_abbrev=False
73+
)
74+
parser.add_argument("root", help="path to root dir")
75+
args = parser.parse_args(argv[1:])
76+
77+
something = "mingw-w64-ucrt-x86_64-crt-git-12.0.0.r619.g850703ae4-1-any"
78+
79+
found = set()
80+
paths = get_package_paths(args.root)
81+
for p in progress_bar(paths, leave=False):
82+
buildinfo, files = get_buildinfo(p)
83+
has_archive = any(f.endswith(".a") for f in files)
84+
if something in buildinfo["installed"] and has_archive:
85+
found.update(buildinfo["pkgbase"])
86+
87+
for f in sorted(found):
88+
print(f)
89+
90+
91+
if __name__ == "__main__":
92+
main(sys.argv)

0 commit comments

Comments
 (0)