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