chiark / gitweb /
remove dependency on wget for 'build' and 'verify'
[fdroidserver.git] / fdroidserver / common.py
index f031b1939c250ef4893f96ca639c5d20bb8fb529..9daddb9c7b7e852e6448234926ed2de25f49531d 100644 (file)
@@ -22,6 +22,7 @@ import sys
 import re
 import shutil
 import glob
+import requests
 import stat
 import subprocess
 import time
@@ -51,9 +52,9 @@ default_config = {
     'sdk_path': "$ANDROID_HOME",
     'ndk_paths': {
         'r9b': None,
-        'r10d': "$ANDROID_NDK"
+        'r10e': "$ANDROID_NDK"
     },
-    'build_tools': "22.0.0",
+    'build_tools': "22.0.1",
     'ant': "ant",
     'mvn3': "mvn",
     'gradle': 'gradle',
@@ -70,8 +71,8 @@ default_config = {
     'keystore': 'keystore.jks',
     'smartcardoptions': [],
     'char_limits': {
-        'Summary': 50,
-        'Description': 1500
+        'Summary': 80,
+        'Description': 4000
     },
     'keyaliases': {},
     'repo_url': "https://MyFirstFDroidRepo.org/fdroid/repo",
@@ -194,7 +195,7 @@ def read_config(opts, config_file='config.py'):
 
 def get_ndk_path(version):
     if version is None:
-        version = 'r10d'  # latest
+        version = 'r10e'  # latest
     paths = config['ndk_paths']
     if version not in paths:
         return ''
@@ -567,12 +568,14 @@ class vcs_git(vcs):
         else:
             self.checkrepo()
             # Discard any working tree changes
-            p = FDroidPopen(['git', 'reset', '--hard'], cwd=self.local, output=False)
+            p = FDroidPopen(['git', 'submodule', 'foreach', '--recursive',
+                             'git', 'reset', '--hard'], cwd=self.local, output=False)
             if p.returncode != 0:
                 raise VCSException("Git reset failed", p.output)
             # Remove untracked files now, in case they're tracked in the target
             # revision (it happens!)
-            p = FDroidPopen(['git', 'clean', '-dffx'], cwd=self.local, output=False)
+            p = FDroidPopen(['git', 'submodule', 'foreach', '--recursive',
+                             'git', 'clean', '-dffx'], cwd=self.local, output=False)
             if p.returncode != 0:
                 raise VCSException("Git clean failed", p.output)
             if not self.refreshed:
@@ -620,13 +623,6 @@ class vcs_git(vcs):
                     line = line.replace('git@github.com:', 'https://github.com/')
                 f.write(line)
 
-        for cmd in [
-                ['git', 'reset', '--hard'],
-                ['git', 'clean', '-dffx'],
-                ]:
-            p = FDroidPopen(['git', 'submodule', 'foreach', '--recursive'] + cmd, cwd=self.local, output=False)
-            if p.returncode != 0:
-                raise VCSException("Git submodule reset failed", p.output)
         p = FDroidPopen(['git', 'submodule', 'sync'], cwd=self.local, output=False)
         if p.returncode != 0:
             raise VCSException("Git submodule sync failed", p.output)
@@ -894,6 +890,10 @@ def retrieve_string(app_dir, string, xmlfiles=None):
     return ''
 
 
+def retrieve_string_singleline(app_dir, string, xmlfiles=None):
+    return retrieve_string(app_dir, string, xmlfiles).replace('\n', ' ').strip()
+
+
 # Return list of existing files that will be used to find the highest vercode
 def manifest_paths(app_dir, flavours):
 
@@ -923,24 +923,13 @@ def fetch_real_name(app_dir, flavours):
         if "{http://schemas.android.com/apk/res/android}label" not in app.attrib:
             continue
         label = app.attrib["{http://schemas.android.com/apk/res/android}label"].encode('utf-8')
-        result = retrieve_string(app_dir, label)
+        result = retrieve_string_singleline(app_dir, label)
         if result:
             result = result.strip()
         return result
     return None
 
 
-# Retrieve the version name
-def version_name(original, app_dir, flavours):
-    for path in manifest_paths(app_dir, flavours):
-        if not has_extension(path, 'xml'):
-            continue
-        string = retrieve_string(app_dir, original)
-        if string:
-            return string
-    return original
-
-
 def get_library_references(root_dir):
     libraries = []
     proppath = os.path.join(root_dir, 'project.properties')
@@ -1030,6 +1019,8 @@ def parse_androidmanifests(paths, ignoreversions=None):
                 package = xml.attrib["package"].encode('utf-8')
             if "{http://schemas.android.com/apk/res/android}versionName" in xml.attrib:
                 version = xml.attrib["{http://schemas.android.com/apk/res/android}versionName"].encode('utf-8')
+                base_dir = os.path.dirname(path)
+                version = retrieve_string_singleline(base_dir, version)
             if "{http://schemas.android.com/apk/res/android}versionCode" in xml.attrib:
                 a = xml.attrib["{http://schemas.android.com/apk/res/android}versionCode"].encode('utf-8')
                 if string_is_integer(a):
@@ -1193,7 +1184,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
     logging.info("Getting source for revision " + build['commit'])
     vcs.gotorevision(build['commit'])
 
-    # Initialise submodules if requred
+    # Initialise submodules if required
     if build['submodules']:
         logging.info("Initialising submodules")
         vcs.initsubmodules()
@@ -1456,21 +1447,21 @@ def scan_source(build_dir, root_dir, thisbuild):
 
     # Common known non-free blobs (always lower case):
     usual_suspects = [
-        re.compile(r'flurryagent', re.IGNORECASE),
-        re.compile(r'paypal.*mpl', re.IGNORECASE),
-        re.compile(r'google.*analytics', re.IGNORECASE),
-        re.compile(r'admob.*sdk.*android', re.IGNORECASE),
-        re.compile(r'google.*ad.*view', re.IGNORECASE),
-        re.compile(r'google.*admob', re.IGNORECASE),
-        re.compile(r'google.*play.*services', re.IGNORECASE),
-        re.compile(r'crittercism', re.IGNORECASE),
-        re.compile(r'heyzap', re.IGNORECASE),
-        re.compile(r'jpct.*ae', re.IGNORECASE),
-        re.compile(r'youtube.*android.*player.*api', re.IGNORECASE),
-        re.compile(r'bugsense', re.IGNORECASE),
-        re.compile(r'crashlytics', re.IGNORECASE),
-        re.compile(r'ouya.*sdk', re.IGNORECASE),
-        re.compile(r'libspen23', re.IGNORECASE),
+        re.compile(r'.*flurryagent', re.IGNORECASE),
+        re.compile(r'.*paypal.*mpl', re.IGNORECASE),
+        re.compile(r'.*google.*analytics', re.IGNORECASE),
+        re.compile(r'.*admob.*sdk.*android', re.IGNORECASE),
+        re.compile(r'.*google.*ad.*view', re.IGNORECASE),
+        re.compile(r'.*google.*admob', re.IGNORECASE),
+        re.compile(r'.*google.*play.*services', re.IGNORECASE),
+        re.compile(r'.*crittercism', re.IGNORECASE),
+        re.compile(r'.*heyzap', re.IGNORECASE),
+        re.compile(r'.*jpct.*ae', re.IGNORECASE),
+        re.compile(r'.*youtube.*android.*player.*api', re.IGNORECASE),
+        re.compile(r'.*bugsense', re.IGNORECASE),
+        re.compile(r'.*crashlytics', re.IGNORECASE),
+        re.compile(r'.*ouya.*sdk', re.IGNORECASE),
+        re.compile(r'.*libspen23', re.IGNORECASE),
     ]
 
     scanignore = getpaths(build_dir, thisbuild, 'scanignore')
@@ -1573,13 +1564,21 @@ def scan_source(build_dir, root_dir, thisbuild):
                 else:
                     warnproblem('unknown compressed or binary file', fd)
 
-            elif has_extension(fp, 'java') and os.path.isfile(fp):
+            elif has_extension(fp, 'java'):
                 if not os.path.isfile(fp):
                     continue
                 for line in file(fp):
                     if 'DexClassLoader' in line:
                         count += handleproblem('DexClassLoader', fd, fp)
                         break
+
+            elif has_extension(fp, 'gradle'):
+                if not os.path.isfile(fp):
+                    continue
+                for i, line in enumerate(file(fp)):
+                    if any(suspect.match(line) for suspect in usual_suspects):
+                        count += handleproblem('usual suspect at line %d' % i, fd, fp)
+                        break
     if ms is not None:
         ms.close()
 
@@ -2072,3 +2071,17 @@ def string_is_integer(string):
         return True
     except ValueError:
         return False
+
+
+def download_file(url, local_filename=None, dldir='tmp'):
+    filename = url.split('/')[-1]
+    if local_filename is None:
+        local_filename = os.path.join(dldir, filename)
+    # the stream=True parameter keeps memory usage low
+    r = requests.get(url, stream=True)
+    with open(local_filename, 'wb') as f:
+        for chunk in r.iter_content(chunk_size=1024):
+            if chunk:  # filter out keep-alive new chunks
+                f.write(chunk)
+                f.flush()
+    return local_filename