chiark / gitweb /
aapt 26.0.0 is required to properly parse permissions and label
[fdroidserver.git] / fdroidserver / common.py
index aa81cb914ea3c51300c3fd4f6dec5361a007b2b1..6fce3340f12632251673cbd2010d0c88bac5ebbd 100644 (file)
@@ -57,6 +57,9 @@ from fdroidserver.exception import FDroidException, VCSException, NoSubmodulesEx
     BuildException, VerificationException
 from .asynchronousfilereader import AsynchronousFileReader
 
+# this is the build-tools version, aapt has a separate version that
+# has to be manually set in test_aapt_version()
+MINIMUM_AAPT_VERSION = '26.0.0'
 
 # A signature block file with a .DSA, .RSA, or .EC extension
 CERT_PATH_REGEX = re.compile(r'^META-INF/.*\.(DSA|EC|RSA)$')
@@ -84,7 +87,7 @@ default_config = {
         'r16': None,
     },
     'qt_sdk_path': None,
-    'build_tools': "25.0.2",
+    'build_tools': MINIMUM_AAPT_VERSION,
     'force_build_tools': False,
     'java_paths': None,
     'ant': "ant",
@@ -397,13 +400,13 @@ def test_aapt_version(aapt):
             # the Debian package has the version string like "v0.2-23.0.2"
             too_old = False
             if '.' in bugfix:
-                if LooseVersion(bugfix) < LooseVersion('24.0.0'):
+                if LooseVersion(bugfix) < LooseVersion(MINIMUM_AAPT_VERSION):
                     too_old = True
-            elif LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.2964546'):
+            elif LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.4062713'):
                 too_old = True
             if too_old:
-                logging.warning(_("'{aapt}' is too old, fdroid requires build-tools-24.0.0 or newer!")
-                                .format(aapt=aapt))
+                logging.warning(_("'{aapt}' is too old, fdroid requires build-tools-{version} or newer!")
+                                .format(aapt=aapt, version=MINIMUM_AAPT_VERSION))
         else:
             logging.warning(_('Unknown version of aapt, might cause problems: ') + output)
 
@@ -1336,27 +1339,63 @@ def parse_androidmanifests(paths, app):
         vercode = None
         package = None
 
+        flavour = None
+        if app.builds and 'gradle' in app.builds[-1] and app.builds[-1].gradle:
+            flavour = app.builds[-1].gradle[-1]
+
         if has_extension(path, 'gradle'):
             with open(path, 'r') as f:
+                inside_flavour_group = 0
+                inside_required_flavour = 0
                 for line in f:
                     if gradle_comment.match(line):
                         continue
-                    # Grab first occurence of each to avoid running into
-                    # alternative flavours and builds.
-                    if not package:
-                        matches = psearch_g(line)
-                        if matches:
-                            s = matches.group(2)
-                            if app_matches_packagename(app, s):
-                                package = s
-                    if not version:
-                        matches = vnsearch_g(line)
-                        if matches:
-                            version = matches.group(2)
-                    if not vercode:
-                        matches = vcsearch_g(line)
-                        if matches:
-                            vercode = matches.group(1)
+
+                    if inside_flavour_group > 0:
+                        if inside_required_flavour > 0:
+                            matches = psearch_g(line)
+                            if matches:
+                                s = matches.group(2)
+                                if app_matches_packagename(app, s):
+                                    package = s
+
+                            matches = vnsearch_g(line)
+                            if matches:
+                                version = matches.group(2)
+
+                            matches = vcsearch_g(line)
+                            if matches:
+                                vercode = matches.group(1)
+
+                            if '{' in line:
+                                inside_required_flavour += 1
+                            if '}' in line:
+                                inside_required_flavour -= 1
+                        else:
+                            if flavour and (flavour in line):
+                                inside_required_flavour = 1
+
+                        if '{' in line:
+                            inside_flavour_group += 1
+                        if '}' in line:
+                            inside_flavour_group -= 1
+                    else:
+                        if "productFlavors" in line:
+                            inside_flavour_group = 1
+                        if not package:
+                            matches = psearch_g(line)
+                            if matches:
+                                s = matches.group(2)
+                                if app_matches_packagename(app, s):
+                                    package = s
+                        if not version:
+                            matches = vnsearch_g(line)
+                            if matches:
+                                version = matches.group(2)
+                        if not vercode:
+                            matches = vcsearch_g(line)
+                            if matches:
+                                vercode = matches.group(1)
         else:
             try:
                 xml = parse_xml(path)