chiark / gitweb /
Merge commit 'refs/merge-requests/117' of git://gitorious.org/f-droid/fdroidserver...
[fdroidserver.git] / fdroidserver / scanner.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # scanner.py - part of the FDroid server tools
5 # Copyright (C) 2010-12, 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 re
24 import urllib
25 import time
26 import subprocess
27 import traceback
28 from optparse import OptionParser
29 import HTMLParser
30 import common
31 from common import BuildException
32 from common import VCSException
33
34 def main():
35
36     # Read configuration...
37     global build_server_always, mvn3
38     globals()['build_server_always'] = False
39     globals()['mvn3'] = "mvn3"
40     execfile('config.py', globals())
41
42
43     # Parse command line...
44     parser = OptionParser()
45     parser.add_option("-v", "--verbose", action="store_true", default=False,
46                       help="Spew out even more information than normal")
47     parser.add_option("-p", "--package", default=None,
48                       help="Scan only the specified package")
49     parser.add_option("--nosvn", action="store_true", default=False,
50                       help="Skip svn repositories - for test purposes, because they are too slow.")
51     (options, args) = parser.parse_args()
52
53     # Get all apps...
54     apps = common.read_metadata(options.verbose)
55
56     # Filter apps according to command-line options
57     if options.package:
58         apps = [app for app in apps if app['id'] == options.package]
59         if len(apps) == 0:
60             print "No such package"
61             sys.exit(1)
62
63     html_parser = HTMLParser.HTMLParser()
64
65     problems = []
66
67     extlib_dir = os.path.join('build', 'extlib')
68
69     for app in apps:
70
71         skip = False
72         if app['Disabled']:
73             print "Skipping %s: disabled" % app['id']
74             skip = True
75         elif not app['builds']:
76             print "Skipping %s: no builds specified" % app['id']
77             skip = True
78         elif options.nosvn and app['Repo Type'] == 'svn':
79             skip = True
80
81         if not skip:
82
83             print "Processing " + app['id']
84
85             try:
86
87                 build_dir = 'build/' + app['id']
88
89                 # Set up vcs interface and make sure we have the latest code...
90                 vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir, sdk_path)
91
92                 for thisbuild in app['builds']:
93
94                     if thisbuild['commit'].startswith('!'):
95                         print ("..skipping version " + thisbuild['version'] + " - " +
96                                 thisbuild['commit'][1:])
97                     else:
98                         print "..scanning version " + thisbuild['version']
99
100                         # Prepare the source code...
101                         root_dir, _ = common.prepare_source(vcs, app, thisbuild,
102                                 build_dir, extlib_dir, sdk_path, ndk_path, javacc_path, mvn3, options.verbose)
103
104                         # Do the scan...
105                         buildprobs = common.scan_source(build_dir, root_dir, thisbuild)
106                         for problem in buildprobs:
107                             problems.append(problem + 
108                                 ' in ' + app['id'] + ' ' + thisbuild['version'])
109
110             except BuildException as be:
111                 msg = "Could not scan app %s due to BuildException: %s" % (app['id'], be)
112                 problems.append(msg)
113             except VCSException as vcse:
114                 msg = "VCS error while scanning app %s: %s" % (app['id'], vcse)
115                 problems.append(msg)
116             except Exception:
117                 msg = "Could not scan app %s due to unknown error: %s" % (app['id'], traceback.format_exc())
118                 problems.append(msg)
119
120     print "Finished:"
121     for problem in problems:
122         print problem
123     print str(len(problems)) + ' problems.'
124
125 if __name__ == "__main__":
126     main()
127