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