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