chiark / gitweb /
Start rewriting options and config as common.py globals
[fdroidserver.git] / fdroidserver / verify.py
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3 #
4 # verify.py - part of the FDroid server tools
5 # Copyright (C) 2013, Ciaran Gultnieks, ciaran@ciarang.com
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Affero General Public License for more details.
16 #
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 import sys
21 import os
22 import shutil
23 import subprocess
24 import glob
25 from optparse import OptionParser
26
27 import common
28 from common import BuildException
29
30 options = None
31 config = None
32
33 def main():
34
35     global options, config
36
37     options, args = parse_commandline()
38
39     # Parse command line...
40     parser = OptionParser()
41     parser.add_option("-v", "--verbose", action="store_true", default=False,
42                       help="Spew out even more information than normal")
43     parser.add_option("-p", "--package", default=None,
44                       help="Verify only the specified package")
45     (options, args) = parser.parse_args()
46
47     config = common.read_config(options)
48
49     tmp_dir = 'tmp'
50     if not os.path.isdir(tmp_dir):
51         print "Creating temporary directory"
52         os.makedirs(tmp_dir)
53
54     unsigned_dir = 'unsigned'
55     if not os.path.isdir(unsigned_dir):
56         print "No unsigned directory - nothing to do"
57         sys.exit(0)
58
59     verified = 0
60     notverified = 0
61
62     for apkfile in sorted(glob.glob(os.path.join(unsigned_dir, '*.apk'))):
63
64         apkfilename = os.path.basename(apkfile)
65         i = apkfilename.rfind('_')
66         if i == -1:
67             raise BuildException("Invalid apk name")
68         appid = apkfilename[:i]
69
70         if not options.package or options.package == appid:
71
72             try:
73
74                 print "Processing " + apkfilename
75
76                 remoteapk = os.path.join(tmp_dir, apkfilename)
77                 if os.path.exists(remoteapk):
78                     os.remove(remoteapk)
79                 url = 'https://f-droid.org/repo/' + apkfilename
80                 print "...retrieving " + url
81                 p = subprocess.Popen(['wget', url],
82                     cwd=tmp_dir,
83                     stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
84                 out = p.communicate()[0]
85                 if p.returncode != 0:
86                     raise Exception("Failed to get " + apkfilename)
87
88                 thisdir = os.path.join(tmp_dir, 'this_apk')
89                 thatdir = os.path.join(tmp_dir, 'that_apk')
90                 for d in [thisdir, thatdir]:
91                     if os.path.exists(d):
92                         shutil.rmtree(d)
93                     os.mkdir(d)
94
95                 if subprocess.call(['jar', 'xf',
96                     os.path.join("..", "..", unsigned_dir, apkfilename)],
97                     cwd=thisdir) != 0:
98                     raise Exception("Failed to unpack local build of " + apkfilename)
99                 if subprocess.call(['jar', 'xf', os.path.join("..", "..", remoteapk)],
100                     cwd=thatdir) != 0:
101                     raise Exception("Failed to unpack remote build of " + apkfilename)
102
103                 p = subprocess.Popen(['diff', '-r', 'this_apk', 'that_apk'],
104                     cwd=tmp_dir, stdout=subprocess.PIPE)
105                 out = p.communicate()[0]
106                 lines = out.splitlines()
107                 if len(lines) != 1 or lines[0].find('META-INF') == -1:
108                     raise Exception("Unexpected diff output - " + out)
109
110                 print "...successfully verified"
111                 verified += 1
112
113             except Exception, e:
114                 print "...NOT verified - {0}".format(e)
115                 notverified += 1
116
117     print "\nFinished"
118     print "{0} successfully verified".format(verified)
119     print "{0} NOT verified".format(notverified)
120
121 if __name__ == "__main__":
122     main()
123
124