]> git.pld-linux.org Git - packages/rpm-build-tools.git/blob - sort-pkgs
use cargo-vendor-filterer if available
[packages/rpm-build-tools.git] / sort-pkgs
1 #!/usr/bin/python3
2
3 """
4 This script tries to set ordering in which packages ought to be sent to builders.
5 Input: file with names of packages. If not given packages are read from stdin. One package name per line.
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
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
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'
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
77
78 if __name__ == "__main__":
79     with (len(sys.argv) > 1 and open(sys.argv[1], 'r') or sys.stdin) as f:
80         for line in f:
81             spec = os.path.basename(os.path.normpath(line.rstrip())).removesuffix('.spec')
82             parse_spec(spec)
83
84     for spec in SPECS:
85         print_spec(spec)
This page took 0.046335 seconds and 3 git commands to generate.