]> git.pld-linux.org Git - projects/pld-ftp-admin.git/blob - bin/pfa-lintpkg
- add show option
[projects/pld-ftp-admin.git] / bin / pfa-lintpkg
1 #!/usr/bin/env python
2 # vi: encoding=utf-8 ts=8 sts=4 sw=4 et
3
4 import sys, os, re
5 import getopt
6 import subprocess
7 sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
8 import ftptree
9 from common import checkdir
10 import ftpio
11
12 try:
13     opts, args = getopt.getopt(sys.argv[1:], 'qs', [ "quiet" ])
14 except getopt.GetoptError:
15     print >>sys.stderr, "ERR: options error"
16     print >>sys.stderr, "rpmlint.py tree package1 [package2...]"
17     sys.exit(1)
18
19 quiet = False
20 show = False
21 for o, a in opts:
22     if o == "-q" or o == "--quiet":
23         quiet = True
24     if o == "-s":
25         show = True
26
27 if len(args) < 1:
28     print >>sys.stderr, "ERR: missing tree name"
29     print >>sys.stderr, "rpmlint.py tree package1 [package2...]"
30     sys.exit(1)
31
32 treename = args[0]
33 packages = args[1:]
34
35 checkdir(treename)
36
37 ftpio.connect('rpmlint')
38
39 if not ftpio.lock(treename, True):
40     print >>sys.stderr, "ERR: %s tree already locked" % treename
41     sys.exit(1)
42
43 files = []
44 try:
45     if len(packages) < 1:
46         loadall = True
47     else:
48         loadall = False
49
50     # if no files specified, grab whole tree contents
51     tree = ftptree.FtpTree(treename, loadall = loadall)
52     tree.do_checkbuild = False
53     if loadall:
54         # this is hack, should be a param, not access private .loadedpkgs element
55         tree.mark4moving(tree.loadedpkgs)
56     else:
57         tree.mark4moving(packages)
58     files = tree.rpmfiles(debugfiles = False, sourcefiles = False)
59
60 except (ftptree.SomeError, KeyboardInterrupt), e:
61     # In case of problems we need to unlock the tree before exiting
62     ftpio.unlock(treename)
63     sys.exit(1)
64
65 ftpio.unlock(treename)
66
67 class LintPkg:
68     def __init__(self, cachedir):
69         # for rpmlint stats
70         self.packages = self.specfiles = self.errors = self.warnings = 0
71         # 1 packages and 0 specfiles checked; 0 errors, 0 warnings.
72         self.lintre = re.compile('(?P<packages>\d+) packages and (?P<specfiles>\d+) specfiles checked; (?P<errors>\d+) errors, (?P<warnings>\d+) warnings.')
73
74         self._rpmlint = '/usr/bin/rpmlint'
75
76         self.cachedir = os.path.expanduser(cachedir)
77         if not os.path.isdir(self.cachedir):
78             os.makedirs(self.cachedir)
79
80     def cachefile(self, file):
81         (dirname, filename) = os.path.split(file)
82         return os.path.join(self.cachedir, filename+'.txt')
83
84     def get_stats(self, file):
85         cachefile = self.cachefile(file)
86
87         # show last line (that contains status)
88         l = (open(cachefile, 'r').readlines())[-1]
89         m = self.lintre.match(l)
90         if not m:
91             return None
92
93         return {
94             'packages': int(m.group('packages')),
95             'specfiles': int(m.group('specfiles')),
96             'errors': int(m.group('errors')),
97             'warnings': int(m.group('warnings')),
98         }
99
100     """
101     update stats from cachefile
102     """
103     def update_stats(self, file):
104         m = self.get_stats(file)
105         if not m:
106             return False
107         self.packages += m['packages']
108         self.specfiles += m['specfiles']
109         self.errors += m['errors']
110         self.warnings += m['warnings']
111         return True
112
113     def print_stats(self, file = None):
114         if file:
115             (dirname, filename) = os.path.split(file)
116             print "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings. [%s]" % (self.packages, self.specfiles, self.errors, self.warnings, filename),
117         else:
118             print "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings." % (self.packages, self.specfiles, self.errors, self.warnings)
119         sys.stdout.flush()
120
121     def show_results(self, file):
122         m = self.get_stats(file)
123         if not m:
124             return False
125
126         cachefile = self.cachefile(file)
127         if m['errors'] > 0 or m['warnings'] > 0:
128             print "".join(open(cachefile, 'r').readlines())
129
130     def rpmlint(self, file):
131         cachefile = self.cachefile(file)
132
133         rc = None
134         if not os.path.exists(cachefile) or os.stat(file).st_mtime > os.stat(cachefile).st_mtime:
135             cmd = [self._rpmlint, file]
136             outfd = open(cachefile, 'w')
137             try:
138                 rc = subprocess.call(cmd, stdin = subprocess.PIPE, stdout = outfd, stderr = outfd, close_fds = True)
139             except KeyboardInterrupt:
140                 os.unlink(cachefile)
141                 raise
142             outfd.close()
143         if not self.update_stats(file):
144             os.unlink(cachefile)
145             rc = 1
146         return rc == 0
147
148 if not quiet:
149     print "rpmlint of %d files from %d packages" % (len(files), len(tree.loadedpkgs))
150 lint = LintPkg("~/tmp/rpmlint")
151 for file in files:
152     lint.rpmlint(file)
153     if not quiet:
154         lint.print_stats(file)
155     if show:
156         lint.show_results(file)
157
158 if not quiet:
159     lint.print_stats()
This page took 0.037392 seconds and 3 git commands to generate.