]> git.pld-linux.org Git - projects/pld-ftp-admin.git/blob - bin/pfa-lintpkg
- unlock tree on ^C
[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 subprocess
6 sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
7 import ftptree
8 from common import checkdir
9 import ftpio
10
11 if len(sys.argv) < 2:
12     print >>sys.stderr, "ERR: not enough parameters given"
13     print >>sys.stderr, "rpmlint.py tree package1 [package2...]"
14     sys.exit(1)
15
16 checkdir(sys.argv[1])
17
18 ftpio.connect('rpmlint')
19
20 if not ftpio.lock(sys.argv[1], True):
21     print >>sys.stderr, "ERR: %s tree already locked" % sys.argv[1]
22     sys.exit(1)
23
24 files = []
25 try:
26     if len(sys.argv) < 3:
27         loadall = True
28     else:
29         loadall = False
30
31     # if no files specified, grab whole tree contents
32     tree = ftptree.FtpTree(sys.argv[1], loadall = loadall)
33     if loadall:
34         # this is hack, should be a param, not access private .loadedpkgs element
35         tree.mark4moving(tree.loadedpkgs)
36     else:
37         tree.mark4moving(sys.argv[2:])
38     files = tree.rpmfiles(debugfiles = False, sourcefiles = False)
39
40 except (ftptree.SomeError, KeyboardInterrupt), e:
41     # In case of problems we need to unlock the tree before exiting
42     ftpio.unlock(sys.argv[1])
43     sys.exit(1)
44
45 ftpio.unlock(sys.argv[1])
46
47 class LintPkg:
48     def __init__(self, cachedir):
49         # for rpmlint stats
50         self.packages = self.specfiles = self.errors = self.warnings = 0
51         # 1 packages and 0 specfiles checked; 0 errors, 0 warnings.
52         self.lintre = re.compile('(?P<packages>\d+) packages and (?P<specfiles>\d+) specfiles checked; (?P<errors>\d+) errors, (?P<warnings>\d+) warnings.')
53
54         self._rpmlint = '/usr/bin/rpmlint'
55
56         self.cachedir = os.path.expanduser(cachedir)
57         if not os.path.isdir(self.cachedir):
58             os.makedirs(self.cachedir)
59
60     def cachefile(self, file):
61         (dirname, filename) = os.path.split(file)
62         return os.path.join(self.cachedir, filename+'.txt')
63
64     """
65     update stats from cachefile
66     """
67     def update_stats(self, file):
68         cachefile = self.cachefile(file)
69
70         # show last line (that contains status)
71         l = (open(cachefile, 'r').readlines())[-1]
72         m = self.lintre.match(l)
73         if not m:
74             return False
75
76         self.packages += int(m.group('packages'))
77         self.specfiles += int(m.group('specfiles'))
78         self.errors += int(m.group('errors'))
79         self.warnings += int(m.group('warnings'))
80         return True
81
82     def print_stats(self, file = None):
83         if file:
84             (dirname, filename) = os.path.split(file)
85             print "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings. [%s]" % (self.packages, self.specfiles, self.errors, self.warnings, filename),
86         else:
87             print "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings." % (self.packages, self.specfiles, self.errors, self.warnings)
88         sys.stdout.flush()
89
90     def rpmlint(self, file):
91         cachefile = self.cachefile(file)
92
93         rc = None
94         if not os.path.exists(cachefile) or os.stat(file).st_mtime > os.stat(cachefile).st_mtime:
95             cmd = [self._rpmlint, file]
96             outfd = open(cachefile, 'w')
97             try:
98                 rc = subprocess.call(cmd, stdin = subprocess.PIPE, stdout = outfd, stderr = outfd, close_fds = True)
99             except KeyboardInterrupt:
100                 os.unlink(cachefile)
101                 raise
102             outfd.close()
103         if not self.update_stats(file):
104             os.unlink(cachefile)
105             rc = 1
106         return rc == 0
107
108 print "rpmlint of %d files from %d packages" % (len(files), len(tree.loadedpkgs))
109 lint = LintPkg("~/tmp/rpmlint")
110 for file in files:
111     lint.rpmlint(file)
112     lint.print_stats(file)
113
114 lint.print_stats()
This page took 0.040684 seconds and 4 git commands to generate.