]>
Commit | Line | Data |
---|---|---|
94e9b4e3 | 1 | #!/usr/bin/python3 |
1859b517 WF |
2 | |
3 | """ | |
4 | This script tries to set ordering in which packages ought to be sent to builders. | |
1481cd8e | 5 | Input: file with names of packages. If not given packages are read from stdin. One package name per line. |
1859b517 WF |
6 | Output: sorted packages on stdout. |
7 | ||
8 | If the script goes in a infinite loop, that means there is a cycle or other bug. | |
9 | """ | |
10 | ||
11 | import os | |
12 | import re | |
13 | import sys | |
14 | ||
94e9b4e3 WF |
15 | BR_PATTERN = re.compile('BuildRequires:\s+(.*?)(\s|$)') |
16 | PACKAGE_PATTERN_WITH_N = re.compile('%package\s+-n\s+(.*)') | |
17 | PACKAGE_PATTERN = re.compile('%package\s+(.*)') | |
18 | ||
3fc1a823 JP |
19 | try: |
20 | import rpm | |
21 | DIR = rpm.expandMacro('%_topdir') | |
22 | except ModuleNotFoundError: | |
23 | try: | |
24 | import subprocess | |
25 | DIR = subprocess.check_output(['rpm', '-E', '%_topdir']).decode('utf-8').strip() | |
26 | except: | |
27 | DIR = os.getenv("HOME") + '/rpm/packages' | |
94e9b4e3 WF |
28 | |
29 | BUILD_REQUIRES = {} | |
30 | PACKAGES = {} | |
31 | SPECS = {} | |
32 | VISITED = {} | |
33 | ||
34 | ||
35 | def parse_spec(name): | |
36 | global PACKAGES, SPECS, BUILD_REQUIRES, VISITED | |
37 | res = [] | |
38 | try: | |
39 | with open(os.path.join(DIR, name, name + '.spec'), 'r') as f: | |
40 | for line in f: | |
41 | br = BR_PATTERN.match(line) | |
42 | if br: | |
43 | p = br.group(1) | |
44 | res.append(p) | |
45 | if line.startswith('%package'): | |
46 | pn = PACKAGE_PATTERN_WITH_N.match(line) | |
47 | if pn: | |
48 | package = pn.group(1) | |
49 | PACKAGES[package] = name | |
50 | else: | |
51 | pn = PACKAGE_PATTERN.match(line) | |
52 | if pn: | |
53 | ext = pn.group(1) | |
54 | if ext: | |
55 | package = name + '-' + ext | |
56 | PACKAGES[package] = name | |
57 | BUILD_REQUIRES[name] = res[:] | |
58 | PACKAGES[name] = name | |
59 | SPECS[name] = True | |
60 | VISITED[name] = False | |
61 | except: | |
62 | pass | |
63 | ||
64 | ||
65 | def print_spec(spec): | |
66 | global PACKAGES, SPECS, BUILD_REQUIRES, VISITED | |
67 | ||
68 | if not VISITED[spec]: | |
69 | VISITED[spec] = True | |
70 | for br in BUILD_REQUIRES[spec]: | |
71 | name = PACKAGES.get(br, '') | |
72 | if name in SPECS: | |
73 | if not VISITED[name]: | |
74 | print_spec(name) | |
75 | print(spec) | |
76 | ||
1859b517 WF |
77 | |
78 | if __name__ == "__main__": | |
1481cd8e | 79 | with (len(sys.argv) > 1 and open(sys.argv[1], 'r') or sys.stdin) as f: |
94e9b4e3 | 80 | for line in f: |
258a4bea | 81 | spec = os.path.basename(os.path.normpath(line.rstrip())).removesuffix('.spec') |
94e9b4e3 WF |
82 | parse_spec(spec) |
83 | ||
84 | for spec in SPECS: | |
85 | print_spec(spec) |