mirror of
				https://github.com/f-droid/fdroidserver.git
				synced 2025-11-04 06:30:27 +03:00 
			
		
		
		
	Merge branch 'flavor' into 'master'
update: match fastlane flavor with all combinations See merge request fdroid/fdroidserver!1647
This commit is contained in:
		
						commit
						2a939bf87f
					
				
					 9 changed files with 92 additions and 48 deletions
				
			
		| 
						 | 
				
			
			@ -803,6 +803,7 @@ include tests/source-files/firebase-allowlisted/app/build.gradle
 | 
			
		|||
include tests/source-files/firebase-allowlisted/build.gradle
 | 
			
		||||
include tests/source-files/firebase-suspect/app/build.gradle
 | 
			
		||||
include tests/source-files/firebase-suspect/build.gradle
 | 
			
		||||
include tests/source-files/flavor.test/build.gradle
 | 
			
		||||
include tests/source-files/info.guardianproject.ripple/build.gradle
 | 
			
		||||
include tests/source-files/lockfile.test/flutter/.dart_tool/flutter_gen/pubspec.yaml
 | 
			
		||||
include tests/source-files/lockfile.test/flutter/pubspec.lock
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -541,13 +541,13 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext
 | 
			
		|||
        if build.preassemble:
 | 
			
		||||
            gradletasks += build.preassemble
 | 
			
		||||
 | 
			
		||||
        flavours = build.gradle
 | 
			
		||||
        if flavours == ['yes']:
 | 
			
		||||
            flavours = []
 | 
			
		||||
        flavors = build.gradle
 | 
			
		||||
        if flavors == ['yes']:
 | 
			
		||||
            flavors = []
 | 
			
		||||
 | 
			
		||||
        flavours_cmd = ''.join([transform_first_char(flav, str.upper) for flav in flavours])
 | 
			
		||||
        flavors_cmd = ''.join([transform_first_char(flav, str.upper) for flav in flavors])
 | 
			
		||||
 | 
			
		||||
        gradletasks += ['assemble' + flavours_cmd + 'Release']
 | 
			
		||||
        gradletasks += ['assemble' + flavors_cmd + 'Release']
 | 
			
		||||
 | 
			
		||||
        cmd = [config['gradle']]
 | 
			
		||||
        if build.gradleprops:
 | 
			
		||||
| 
						 | 
				
			
			@ -763,11 +763,11 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext
 | 
			
		|||
            # really old path
 | 
			
		||||
            os.path.join(root_dir, 'build', 'apk'),
 | 
			
		||||
            ]
 | 
			
		||||
        # If we build with gradle flavours with gradle plugin >= 3.0 the APK will be in
 | 
			
		||||
        # a subdirectory corresponding to the flavour command used, but with different
 | 
			
		||||
        # If we build with gradle flavors with gradle plugin >= 3.0 the APK will be in
 | 
			
		||||
        # a subdirectory corresponding to the flavor command used, but with different
 | 
			
		||||
        # capitalization.
 | 
			
		||||
        if flavours_cmd:
 | 
			
		||||
            apk_dirs.append(os.path.join(root_dir, 'build', 'outputs', 'apk', transform_first_char(flavours_cmd, str.lower), 'release'))
 | 
			
		||||
        if flavors_cmd:
 | 
			
		||||
            apk_dirs.append(os.path.join(root_dir, 'build', 'outputs', 'apk', transform_first_char(flavors_cmd, str.lower), 'release'))
 | 
			
		||||
        for apks_dir in apk_dirs:
 | 
			
		||||
            for apkglob in ['*-release-unsigned.apk', '*-unsigned.apk', '*.apk']:
 | 
			
		||||
                apks = glob.glob(os.path.join(apks_dir, apkglob))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,7 @@ from typing import List
 | 
			
		|||
import git
 | 
			
		||||
import glob
 | 
			
		||||
import io
 | 
			
		||||
import itertools
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
import re
 | 
			
		||||
| 
						 | 
				
			
			@ -1987,7 +1988,7 @@ def retrieve_string_singleline(app_dir, string, xmlfiles=None):
 | 
			
		|||
    return retrieve_string(app_dir, string, xmlfiles).replace('\n', ' ').strip()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def manifest_paths(app_dir, flavours):
 | 
			
		||||
def manifest_paths(app_dir, flavors):
 | 
			
		||||
    """Return list of existing files that will be used to find the highest vercode."""
 | 
			
		||||
    possible_manifests = \
 | 
			
		||||
        [Path(app_dir) / 'AndroidManifest.xml',
 | 
			
		||||
| 
						 | 
				
			
			@ -1997,18 +1998,18 @@ def manifest_paths(app_dir, flavours):
 | 
			
		|||
         Path(app_dir) / 'build-extras.gradle',
 | 
			
		||||
         Path(app_dir) / 'build.gradle.kts']
 | 
			
		||||
 | 
			
		||||
    for flavour in flavours:
 | 
			
		||||
        if flavour == 'yes':
 | 
			
		||||
    for flavor in flavors:
 | 
			
		||||
        if flavor == 'yes':
 | 
			
		||||
            continue
 | 
			
		||||
        possible_manifests.append(
 | 
			
		||||
            Path(app_dir) / 'src' / flavour / 'AndroidManifest.xml')
 | 
			
		||||
            Path(app_dir) / 'src' / flavor / 'AndroidManifest.xml')
 | 
			
		||||
 | 
			
		||||
    return [path for path in possible_manifests if path.is_file()]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fetch_real_name(app_dir, flavours):
 | 
			
		||||
def fetch_real_name(app_dir, flavors):
 | 
			
		||||
    """Retrieve the package name. Returns the name, or None if not found."""
 | 
			
		||||
    for path in manifest_paths(app_dir, flavours):
 | 
			
		||||
    for path in manifest_paths(app_dir, flavors):
 | 
			
		||||
        if not path.suffix == '.xml' or not path.is_file():
 | 
			
		||||
            continue
 | 
			
		||||
        logging.debug("fetch_real_name: Checking manifest at %s" % path)
 | 
			
		||||
| 
						 | 
				
			
			@ -2126,17 +2127,17 @@ def parse_androidmanifests(paths, app):
 | 
			
		|||
        vercode = None
 | 
			
		||||
        package = None
 | 
			
		||||
 | 
			
		||||
        flavours = None
 | 
			
		||||
        flavors = None
 | 
			
		||||
        temp_app_id = None
 | 
			
		||||
        temp_version_name = None
 | 
			
		||||
        if len(app.get('Builds', [])) > 0 and 'gradle' in app['Builds'][-1] and app['Builds'][-1].gradle:
 | 
			
		||||
            flavours = app['Builds'][-1].gradle
 | 
			
		||||
            flavors = app['Builds'][-1].gradle
 | 
			
		||||
 | 
			
		||||
        if path.suffix == '.gradle' or path.name.endswith('.gradle.kts'):
 | 
			
		||||
            with open(path, 'r', encoding='utf-8') as f:
 | 
			
		||||
                android_plugin_file = False
 | 
			
		||||
                inside_flavour_group = 0
 | 
			
		||||
                inside_required_flavour = 0
 | 
			
		||||
                inside_flavor_group = 0
 | 
			
		||||
                inside_required_flavor = 0
 | 
			
		||||
                for line in f:
 | 
			
		||||
                    if gradle_comment.match(line):
 | 
			
		||||
                        continue
 | 
			
		||||
| 
						 | 
				
			
			@ -2151,8 +2152,8 @@ def parse_androidmanifests(paths, app):
 | 
			
		|||
                        if matches:
 | 
			
		||||
                            temp_version_name = matches
 | 
			
		||||
 | 
			
		||||
                    if inside_flavour_group > 0:
 | 
			
		||||
                        if inside_required_flavour > 1:
 | 
			
		||||
                    if inside_flavor_group > 0:
 | 
			
		||||
                        if inside_required_flavor > 1:
 | 
			
		||||
                            matches = psearch_g(line)
 | 
			
		||||
                            if matches:
 | 
			
		||||
                                s = matches.group(2)
 | 
			
		||||
| 
						 | 
				
			
			@ -2182,29 +2183,29 @@ def parse_androidmanifests(paths, app):
 | 
			
		|||
                            if matches:
 | 
			
		||||
                                vercode = version_code_string_to_int(matches.group(1))
 | 
			
		||||
 | 
			
		||||
                        if inside_required_flavour > 0:
 | 
			
		||||
                        if inside_required_flavor > 0:
 | 
			
		||||
                            if '{' in line:
 | 
			
		||||
                                inside_required_flavour += 1
 | 
			
		||||
                                inside_required_flavor += 1
 | 
			
		||||
                            if '}' in line:
 | 
			
		||||
                                inside_required_flavour -= 1
 | 
			
		||||
                                if inside_required_flavour == 1:
 | 
			
		||||
                                    inside_required_flavour -= 1
 | 
			
		||||
                        elif flavours:
 | 
			
		||||
                            for flavour in flavours:
 | 
			
		||||
                                if re.match(r'.*[\'"\s]{flavour}[\'"\s].*\{{.*'.format(flavour=flavour), line):
 | 
			
		||||
                                    inside_required_flavour = 2
 | 
			
		||||
                                inside_required_flavor -= 1
 | 
			
		||||
                                if inside_required_flavor == 1:
 | 
			
		||||
                                    inside_required_flavor -= 1
 | 
			
		||||
                        elif flavors:
 | 
			
		||||
                            for flavor in flavors:
 | 
			
		||||
                                if re.match(r'.*[\'"\s]{flavor}[\'"\s].*\{{.*'.format(flavor=flavor), line):
 | 
			
		||||
                                    inside_required_flavor = 2
 | 
			
		||||
                                    break
 | 
			
		||||
                                if re.match(r'.*[\'"\s]{flavour}[\'"\s].*'.format(flavour=flavour), line):
 | 
			
		||||
                                    inside_required_flavour = 1
 | 
			
		||||
                                if re.match(r'.*[\'"\s]{flavor}[\'"\s].*'.format(flavor=flavor), line):
 | 
			
		||||
                                    inside_required_flavor = 1
 | 
			
		||||
                                    break
 | 
			
		||||
 | 
			
		||||
                        if '{' in line:
 | 
			
		||||
                            inside_flavour_group += 1
 | 
			
		||||
                            inside_flavor_group += 1
 | 
			
		||||
                        if '}' in line:
 | 
			
		||||
                            inside_flavour_group -= 1
 | 
			
		||||
                            inside_flavor_group -= 1
 | 
			
		||||
                    else:
 | 
			
		||||
                        if "productFlavors" in line:
 | 
			
		||||
                            inside_flavour_group = 1
 | 
			
		||||
                            inside_flavor_group = 1
 | 
			
		||||
                        if not package:
 | 
			
		||||
                            matches = psearch_g(line)
 | 
			
		||||
                            if matches:
 | 
			
		||||
| 
						 | 
				
			
			@ -2548,9 +2549,9 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
 | 
			
		|||
        with open(path, 'w', encoding='iso-8859-1') as f:
 | 
			
		||||
            f.write(props)
 | 
			
		||||
 | 
			
		||||
    flavours = []
 | 
			
		||||
    flavors = []
 | 
			
		||||
    if build.build_method() == 'gradle':
 | 
			
		||||
        flavours = build.gradle
 | 
			
		||||
        flavors = build.gradle
 | 
			
		||||
 | 
			
		||||
        if build.target:
 | 
			
		||||
            n = build.target.split('-')[1]
 | 
			
		||||
| 
						 | 
				
			
			@ -2572,7 +2573,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
 | 
			
		|||
    # Insert version code and number into the manifest if necessary
 | 
			
		||||
    if build.forceversion:
 | 
			
		||||
        logging.info("Changing the version name")
 | 
			
		||||
        for path in manifest_paths(root_dir, flavours):
 | 
			
		||||
        for path in manifest_paths(root_dir, flavors):
 | 
			
		||||
            if not os.path.isfile(path):
 | 
			
		||||
                continue
 | 
			
		||||
            if path.suffix == '.xml':
 | 
			
		||||
| 
						 | 
				
			
			@ -2586,7 +2587,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
 | 
			
		|||
 | 
			
		||||
    if build.forcevercode:
 | 
			
		||||
        logging.info("Changing the version code")
 | 
			
		||||
        for path in manifest_paths(root_dir, flavours):
 | 
			
		||||
        for path in manifest_paths(root_dir, flavors):
 | 
			
		||||
            if not path.is_file():
 | 
			
		||||
                continue
 | 
			
		||||
            if path.suffix == '.xml':
 | 
			
		||||
| 
						 | 
				
			
			@ -4823,6 +4824,20 @@ def calculate_archive_policy(app, default):
 | 
			
		|||
    return archive_policy
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def calculate_gradle_flavor_combination(flavors):
 | 
			
		||||
    """Calculate all combinations of gradle flavors."""
 | 
			
		||||
    combination_lists = itertools.product(*[[flavor, ''] for flavor in flavors])
 | 
			
		||||
    combinations = [
 | 
			
		||||
        re.sub(
 | 
			
		||||
            r' +\w',
 | 
			
		||||
            lambda pat: pat.group(0)[-1].upper(),
 | 
			
		||||
            ' '.join(combination_list).strip(),
 | 
			
		||||
        )
 | 
			
		||||
        for combination_list in combination_lists
 | 
			
		||||
    ]
 | 
			
		||||
    return combinations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FDROIDORG_MIRRORS = [
 | 
			
		||||
    {
 | 
			
		||||
        'isPrimary': True,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ __license__ = "Python License 2.0"
 | 
			
		|||
# been done in the StrictVersion class above.  This works great as long
 | 
			
		||||
# as everyone can go along with bondage and discipline.  Hopefully a
 | 
			
		||||
# (large) subset of Python module programmers will agree that the
 | 
			
		||||
# particular flavour of bondage and discipline provided by StrictVersion
 | 
			
		||||
# particular flavor of bondage and discipline provided by StrictVersion
 | 
			
		||||
# provides enough benefit to be worth using, and will submit their
 | 
			
		||||
# version numbering scheme to its domination.  The free-thinking
 | 
			
		||||
# anarchists in the lot will never give in, though, and something needs
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -270,9 +270,10 @@ def get_gradle_compile_commands(build):
 | 
			
		|||
        'runtimeOnly',
 | 
			
		||||
    ]
 | 
			
		||||
    buildTypes = ['', 'release']
 | 
			
		||||
    flavors = ['']
 | 
			
		||||
    if build.gradle and build.gradle != ['yes']:
 | 
			
		||||
        flavors += build.gradle
 | 
			
		||||
        flavors = common.calculate_gradle_flavor_combination(build.gradle)
 | 
			
		||||
    else:
 | 
			
		||||
        flavors = ['']
 | 
			
		||||
 | 
			
		||||
    return [''.join(c) for c in itertools.product(flavors, buildTypes, compileCommands)]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1179,17 +1179,20 @@ def insert_localized_app_metadata(apps):
 | 
			
		|||
            locale = segments[-1]
 | 
			
		||||
            destdir = os.path.join('repo', packageName, locale)
 | 
			
		||||
 | 
			
		||||
            # flavours specified in build receipt
 | 
			
		||||
            build_flavours = ""
 | 
			
		||||
            # flavors specified in build receipt
 | 
			
		||||
            build_flavors = []
 | 
			
		||||
            if (
 | 
			
		||||
                apps[packageName]
 | 
			
		||||
                and len(apps[packageName].get('Builds', [])) > 0
 | 
			
		||||
                and 'gradle' in apps[packageName]['Builds'][-1]
 | 
			
		||||
                and apps[packageName]['Builds'][-1]['gradle'] != ['yes']
 | 
			
		||||
            ):
 | 
			
		||||
                build_flavours = apps[packageName]['Builds'][-1]['gradle']
 | 
			
		||||
                build_flavors = common.calculate_gradle_flavor_combination(
 | 
			
		||||
                    apps[packageName]['Builds'][-1]['gradle']
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            if len(segments) >= 5 and segments[4] == "fastlane" and segments[3] not in build_flavours:
 | 
			
		||||
                logging.debug("ignoring due to wrong flavour")
 | 
			
		||||
            if len(segments) >= 5 and segments[4] == "fastlane" and segments[3] not in build_flavors:
 | 
			
		||||
                logging.debug("ignoring due to wrong flavor")
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            for f in files:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								tests/source-files/flavor.test/build.gradle
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/source-files/flavor.test/build.gradle
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
dependenies {
 | 
			
		||||
    /// dependencies for app building
 | 
			
		||||
    fossImplementation 'com.android.support:multidex:1.0.2'
 | 
			
		||||
    implementation 'com.github.nextcloud:android-library:1.0.33'
 | 
			
		||||
    devImplementation 'com.github.nextcloud:android-library:master-SNAPSHOT' // use always latest master
 | 
			
		||||
    implementation "com.android.support:support-v4:${supportLibraryVersion}"
 | 
			
		||||
    prodImplementation "com.android.support:design:${supportLibraryVersion}"
 | 
			
		||||
    gplayImplementation 'com.jakewharton:disklrucache:2.0.2'
 | 
			
		||||
    implementation "com.android.support:appcompat-v7:${supportLibraryVersion}"
 | 
			
		||||
    gplayProdImplementation "com.android.support:cardview-v7:${supportLibraryVersion}"
 | 
			
		||||
    implementation "com.android.support:exifinterface:${supportLibraryVersion}"
 | 
			
		||||
    fossDevImplementation 'com.github.tobiasKaminsky:android-floating-action-button:1.10.2'
 | 
			
		||||
    gplayDevImplementation 'com.github.albfernandez:juniversalchardet:v2.0.0'
 | 
			
		||||
    fossProdImplementation 'com.google.code.findbugs:annotations:2.0.1'
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3040,6 +3040,11 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase):
 | 
			
		|||
        p = fdroidserver.common.FDroidPopen(['printenv', 'SOURCE_DATE_EPOCH'])
 | 
			
		||||
        self.assertEqual(int(p.output), int(now.timestamp()))
 | 
			
		||||
 | 
			
		||||
    def test_calculate_gradle_flavor_combination(self):
 | 
			
		||||
        flavors = ['aa', 'BB', 'δδ']
 | 
			
		||||
        combinations = ['aaBBΔδ', 'aaBB', 'aaΔδ', 'aa', 'BBΔδ', 'BB', 'δδ', '']
 | 
			
		||||
        self.assertEqual(fdroidserver.common.calculate_gradle_flavor_combination(flavors), combinations)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
APKS_WITH_JAR_SIGNATURES = (
 | 
			
		||||
    (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,12 +107,16 @@ class ScannerTest(unittest.TestCase):
 | 
			
		|||
            ('source-files/eu.siacs.conversations/build.gradle', 'free', 21),
 | 
			
		||||
            ('source-files/org.mozilla.rocket/app/build.gradle', 'focus', 40),
 | 
			
		||||
            ('source-files/com.jens.automation2/app/build.gradle', 'fdroidFlavor', 5),
 | 
			
		||||
            ('source-files/flavor.test/build.gradle', ['foss', 'prod'], 7),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        for f, flavor, count in test_files:
 | 
			
		||||
            i = 0
 | 
			
		||||
            build = fdroidserver.metadata.Build()
 | 
			
		||||
            build.gradle = [flavor]
 | 
			
		||||
            if isinstance(flavor, list):
 | 
			
		||||
                build.gradle = flavor
 | 
			
		||||
            else:
 | 
			
		||||
                build.gradle = [flavor]
 | 
			
		||||
            regexs = fdroidserver.scanner.get_gradle_compile_commands_without_catalog(
 | 
			
		||||
                build
 | 
			
		||||
            )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue