chiark / gitweb /
Merge branch 'master' into logging
[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 os
21 import traceback
22 from optparse import OptionParser
23 import logging
24
25 import common, metadata
26 from common import BuildException
27 from common import VCSException
28
29 config = None
30 options = None
31
32 def main():
33
34     global config, options
35
36     # Parse command line...
37     parser = OptionParser(usage="Usage: %prog [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]")
38     parser.add_option("-v", "--verbose", action="store_true", default=False,
39                       help="Spew out even more information than normal")
40     parser.add_option("--nosvn", action="store_true", default=False,
41                       help="Skip svn repositories - for test purposes, because they are too slow.")
42     (options, args) = parser.parse_args()
43
44     config = common.read_config(options)
45
46     # Get all apps...
47     allapps = metadata.read_metadata()
48     apps = common.read_app_args(args, allapps, True)
49
50     problems = []
51
52     build_dir = 'build'
53     if not os.path.isdir(build_dir):
54         logging.info("Creating build directory")
55         os.makedirs(build_dir)
56     srclib_dir = os.path.join(build_dir, 'srclib')
57     extlib_dir = os.path.join(build_dir, 'extlib')
58
59     for app in apps:
60
61         if app['Disabled']:
62             logging.info("Skipping %s: disabled" % app['id'])
63             continue
64         if not app['builds']:
65             logging.info("Skipping %s: no builds specified" % app['id'])
66             continue
67         elif options.nosvn and app['Repo Type'] == 'svn':
68             continue
69
70         logging.info("Processing " + app['id'])
71
72         try:
73
74             build_dir = 'build/' + app['id']
75
76             # Set up vcs interface and make sure we have the latest code...
77             vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir)
78
79             for thisbuild in app['builds']:
80
81                 if 'disable' in thisbuild:
82                     logging.info("...skipping version %s - %s" % (
83                         thisbuild['version'], thisbuild.get('disable', thisbuild['commit'][1:])))
84                 else:
85                     logging.info("...scanning version " + thisbuild['version'])
86
87                     # Prepare the source code...
88                     root_dir, _ = common.prepare_source(vcs, app, thisbuild,
89                             build_dir, srclib_dir, extlib_dir, False)
90
91                     # Do the scan...
92                     buildprobs = common.scan_source(build_dir, root_dir, thisbuild)
93                     for problem in buildprobs:
94                         problems.append(problem +
95                             ' in ' + app['id'] + ' ' + thisbuild['version'])
96
97         except BuildException as be:
98             msg = "Could not scan app %s due to BuildException: %s" % (app['id'], be)
99             problems.append(msg)
100         except VCSException as vcse:
101             msg = "VCS error while scanning app %s: %s" % (app['id'], vcse)
102             problems.append(msg)
103         except Exception:
104             msg = "Could not scan app %s due to unknown error: %s" % (app['id'], traceback.format_exc())
105             problems.append(msg)
106
107     logging.info("Finished:")
108     for problem in problems:
109         print problem
110     print str(len(problems)) + ' problems.'
111
112 if __name__ == "__main__":
113     main()
114