]> git.pld-linux.org Git - packages/rpm-build-tools.git/blob - sort-pkgs
sort-pkgs: for packages dir try evaluting %_topdir
[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 (without the .spec suffix). 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     if len(sys.argv) < 2:
80         print("Usage: %s filename" % sys.argv[0])
81         sys.exit(1)
82     with open(sys.argv[1], 'r') as f:
83         for line in f:
84             spec = line.rstrip()
85             parse_spec(spec)
86
87     for spec in SPECS:
88         print_spec(spec)
This page took 0.035357 seconds and 3 git commands to generate.