2 # vi: encoding=utf-8 ts=8 sts=4 sw=4 et
7 sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
9 from common import checkdir
13 opts, args = getopt.getopt(sys.argv[1:], 'q', [ "quiet" ])
14 except getopt.GetoptError:
15 print >>sys.stderr, "ERR: options error"
16 print >>sys.stderr, "rpmlint.py tree package1 [package2...]"
21 if o == "-q" or o == "--quiet":
25 print >>sys.stderr, "ERR: missing tree name"
26 print >>sys.stderr, "rpmlint.py tree package1 [package2...]"
34 ftpio.connect('rpmlint')
36 if not ftpio.lock(treename, True):
37 print >>sys.stderr, "ERR: %s tree already locked" % treename
47 # if no files specified, grab whole tree contents
48 tree = ftptree.FtpTree(treename, loadall = loadall)
50 # this is hack, should be a param, not access private .loadedpkgs element
51 tree.mark4moving(tree.loadedpkgs)
53 tree.mark4moving(packages)
54 files = tree.rpmfiles(debugfiles = False, sourcefiles = False)
56 except (ftptree.SomeError, KeyboardInterrupt), e:
57 # In case of problems we need to unlock the tree before exiting
58 ftpio.unlock(treename)
61 ftpio.unlock(treename)
64 def __init__(self, cachedir):
66 self.packages = self.specfiles = self.errors = self.warnings = 0
67 # 1 packages and 0 specfiles checked; 0 errors, 0 warnings.
68 self.lintre = re.compile('(?P<packages>\d+) packages and (?P<specfiles>\d+) specfiles checked; (?P<errors>\d+) errors, (?P<warnings>\d+) warnings.')
70 self._rpmlint = '/usr/bin/rpmlint'
72 self.cachedir = os.path.expanduser(cachedir)
73 if not os.path.isdir(self.cachedir):
74 os.makedirs(self.cachedir)
76 def cachefile(self, file):
77 (dirname, filename) = os.path.split(file)
78 return os.path.join(self.cachedir, filename+'.txt')
81 update stats from cachefile
83 def update_stats(self, file):
84 cachefile = self.cachefile(file)
86 # show last line (that contains status)
87 l = (open(cachefile, 'r').readlines())[-1]
88 m = self.lintre.match(l)
92 self.packages += int(m.group('packages'))
93 self.specfiles += int(m.group('specfiles'))
94 self.errors += int(m.group('errors'))
95 self.warnings += int(m.group('warnings'))
98 def print_stats(self, file = None):
100 (dirname, filename) = os.path.split(file)
101 print "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings. [%s]" % (self.packages, self.specfiles, self.errors, self.warnings, filename),
103 print "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings." % (self.packages, self.specfiles, self.errors, self.warnings)
106 def rpmlint(self, file):
107 cachefile = self.cachefile(file)
110 if not os.path.exists(cachefile) or os.stat(file).st_mtime > os.stat(cachefile).st_mtime:
111 cmd = [self._rpmlint, file]
112 outfd = open(cachefile, 'w')
114 rc = subprocess.call(cmd, stdin = subprocess.PIPE, stdout = outfd, stderr = outfd, close_fds = True)
115 except KeyboardInterrupt:
119 if not self.update_stats(file):
125 print "rpmlint of %d files from %d packages" % (len(files), len(tree.loadedpkgs))
126 lint = LintPkg("~/tmp/rpmlint")
130 lint.print_stats(file)