diff --git a/scanner.py b/scanner.py new file mode 100755 index 00000000..843c287f --- /dev/null +++ b/scanner.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# +# scanner.py - part of the FDroid server tools +# Copyright (C) 2010-12, Ciaran Gultnieks, ciaran@ciarang.com +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import sys +import os +import shutil +import re +import urllib +import time +import subprocess +from optparse import OptionParser +import HTMLParser +import common + +#Read configuration... +execfile('config.py') + + +# Parse command line... +parser = OptionParser() +parser.add_option("-v", "--verbose", action="store_true", default=False, + help="Spew out even more information than normal") +(options, args) = parser.parse_args() + +# Get all apps... +apps = common.read_metadata(options.verbose) + +html_parser = HTMLParser.HTMLParser() + +problems = [] + +for app in apps: + + if app['disabled']: + print "Skipping %s: disabled" % app['id'] + elif not app['builds']: + print "Skipping %s: no builds specified" % app['id'] + + if (app['disabled'] is None and app['repo'] != '' + and app['repotype'] != '' and len(app['builds']) > 0): + + print "Processing " + app['id'] + + build_dir = 'build/' + app['id'] + + # Set up vcs interface and make sure we have the latest code... + vcs = common.getvcs(app['repotype'], app['repo'], build_dir) + + refreshed_source = False + + + for thisbuild in app['builds']: + + if thisbuild['commit'].startswith('!'): + print ("..skipping version " + thisbuild['version'] + " - " + + thisbuild['commit'][1:]) + else: + print "..scanning version " + thisbuild['version'] + + if not refreshed_source: + vcs.refreshlocal() + refreshed_source = True + + # Optionally, the actual app source can be in a subdirectory... + if thisbuild.has_key('subdir'): + root_dir = os.path.join(build_dir, thisbuild['subdir']) + else: + root_dir = build_dir + + # Get a working copy of the right revision... + if options.verbose: + print "Resetting repository to " + thisbuild['commit'] + vcs.reset(thisbuild['commit']) + + # Initialise submodules if requred... + if thisbuild.get('submodules', 'no') == 'yes': + vcs.initsubmodules() + + # Generate (or update) the ant build file, build.xml... + if (thisbuild.get('update', 'yes') == 'yes' and + not thisbuild.has_key('maven')): + parms = [os.path.join(sdk_path, 'tools', 'android'), + 'update', 'project', '-p', '.'] + parms.append('--subprojects') + if thisbuild.has_key('target'): + parms.append('-t') + parms.append(thisbuild['target']) + if subprocess.call(parms, cwd=root_dir) != 0: + print "Failed to update project" + sys.exit(1) + + # Delete unwanted file... + if thisbuild.has_key('rm'): + os.remove(os.path.join(build_dir, thisbuild['rm'])) + + # Run a pre-build command if one is required... + if thisbuild.has_key('prebuild'): + if subprocess.call(thisbuild['prebuild'], + cwd=root_dir, shell=True) != 0: + print "Error running pre-build command" + sys.exit(1) + + # Apply patches if any + if 'patch' in thisbuild: + for patch in thisbuild['patch'].split(';'): + print "Applying " + patch + patch_path = os.path.join('metadata', app['id'], patch) + if subprocess.call(['patch', '-p1', + '-i', os.path.abspath(patch_path)], cwd=build_dir) != 0: + print "Failed to apply patch %s" % patch_path + sys.exit(1) + + # Scan for common known non-free blobs: + usual_suspects = ['flurryagent.jar', 'paypal_mpl.jar'] + for r,d,f in os.walk(build_dir): + for curfile in f: + if curfile.lower() in usual_suspects: + msg = 'Found probable non-free blob ' + os.path.join(r,file) + msg += ' in ' + app['id'] + ' ' + thisbuild['version'] + problems.append(msg) + +print "Finished:" +for problem in problems: + print problem +print str(len(problems)) + ' problems.' +