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
@ -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-allowlisted/build.gradle
|
||||||
include tests/source-files/firebase-suspect/app/build.gradle
|
include tests/source-files/firebase-suspect/app/build.gradle
|
||||||
include tests/source-files/firebase-suspect/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/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/.dart_tool/flutter_gen/pubspec.yaml
|
||||||
include tests/source-files/lockfile.test/flutter/pubspec.lock
|
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:
|
if build.preassemble:
|
||||||
gradletasks += build.preassemble
|
gradletasks += build.preassemble
|
||||||
|
|
||||||
flavours = build.gradle
|
flavors = build.gradle
|
||||||
if flavours == ['yes']:
|
if flavors == ['yes']:
|
||||||
flavours = []
|
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']]
|
cmd = [config['gradle']]
|
||||||
if build.gradleprops:
|
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
|
# really old path
|
||||||
os.path.join(root_dir, 'build', 'apk'),
|
os.path.join(root_dir, 'build', 'apk'),
|
||||||
]
|
]
|
||||||
# If we build with gradle flavours with gradle plugin >= 3.0 the APK will be in
|
# If we build with gradle flavors with gradle plugin >= 3.0 the APK will be in
|
||||||
# a subdirectory corresponding to the flavour command used, but with different
|
# a subdirectory corresponding to the flavor command used, but with different
|
||||||
# capitalization.
|
# capitalization.
|
||||||
if flavours_cmd:
|
if flavors_cmd:
|
||||||
apk_dirs.append(os.path.join(root_dir, 'build', 'outputs', 'apk', transform_first_char(flavours_cmd, str.lower), 'release'))
|
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 apks_dir in apk_dirs:
|
||||||
for apkglob in ['*-release-unsigned.apk', '*-unsigned.apk', '*.apk']:
|
for apkglob in ['*-release-unsigned.apk', '*-unsigned.apk', '*.apk']:
|
||||||
apks = glob.glob(os.path.join(apks_dir, apkglob))
|
apks = glob.glob(os.path.join(apks_dir, apkglob))
|
||||||
|
@ -58,6 +58,7 @@ from typing import List
|
|||||||
import git
|
import git
|
||||||
import glob
|
import glob
|
||||||
import io
|
import io
|
||||||
|
import itertools
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
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()
|
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."""
|
"""Return list of existing files that will be used to find the highest vercode."""
|
||||||
possible_manifests = \
|
possible_manifests = \
|
||||||
[Path(app_dir) / 'AndroidManifest.xml',
|
[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-extras.gradle',
|
||||||
Path(app_dir) / 'build.gradle.kts']
|
Path(app_dir) / 'build.gradle.kts']
|
||||||
|
|
||||||
for flavour in flavours:
|
for flavor in flavors:
|
||||||
if flavour == 'yes':
|
if flavor == 'yes':
|
||||||
continue
|
continue
|
||||||
possible_manifests.append(
|
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()]
|
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."""
|
"""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():
|
if not path.suffix == '.xml' or not path.is_file():
|
||||||
continue
|
continue
|
||||||
logging.debug("fetch_real_name: Checking manifest at %s" % path)
|
logging.debug("fetch_real_name: Checking manifest at %s" % path)
|
||||||
@ -2126,17 +2127,17 @@ def parse_androidmanifests(paths, app):
|
|||||||
vercode = None
|
vercode = None
|
||||||
package = None
|
package = None
|
||||||
|
|
||||||
flavours = None
|
flavors = None
|
||||||
temp_app_id = None
|
temp_app_id = None
|
||||||
temp_version_name = None
|
temp_version_name = None
|
||||||
if len(app.get('Builds', [])) > 0 and 'gradle' in app['Builds'][-1] and app['Builds'][-1].gradle:
|
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'):
|
if path.suffix == '.gradle' or path.name.endswith('.gradle.kts'):
|
||||||
with open(path, 'r', encoding='utf-8') as f:
|
with open(path, 'r', encoding='utf-8') as f:
|
||||||
android_plugin_file = False
|
android_plugin_file = False
|
||||||
inside_flavour_group = 0
|
inside_flavor_group = 0
|
||||||
inside_required_flavour = 0
|
inside_required_flavor = 0
|
||||||
for line in f:
|
for line in f:
|
||||||
if gradle_comment.match(line):
|
if gradle_comment.match(line):
|
||||||
continue
|
continue
|
||||||
@ -2151,8 +2152,8 @@ def parse_androidmanifests(paths, app):
|
|||||||
if matches:
|
if matches:
|
||||||
temp_version_name = matches
|
temp_version_name = matches
|
||||||
|
|
||||||
if inside_flavour_group > 0:
|
if inside_flavor_group > 0:
|
||||||
if inside_required_flavour > 1:
|
if inside_required_flavor > 1:
|
||||||
matches = psearch_g(line)
|
matches = psearch_g(line)
|
||||||
if matches:
|
if matches:
|
||||||
s = matches.group(2)
|
s = matches.group(2)
|
||||||
@ -2182,29 +2183,29 @@ def parse_androidmanifests(paths, app):
|
|||||||
if matches:
|
if matches:
|
||||||
vercode = version_code_string_to_int(matches.group(1))
|
vercode = version_code_string_to_int(matches.group(1))
|
||||||
|
|
||||||
if inside_required_flavour > 0:
|
if inside_required_flavor > 0:
|
||||||
if '{' in line:
|
if '{' in line:
|
||||||
inside_required_flavour += 1
|
inside_required_flavor += 1
|
||||||
if '}' in line:
|
if '}' in line:
|
||||||
inside_required_flavour -= 1
|
inside_required_flavor -= 1
|
||||||
if inside_required_flavour == 1:
|
if inside_required_flavor == 1:
|
||||||
inside_required_flavour -= 1
|
inside_required_flavor -= 1
|
||||||
elif flavours:
|
elif flavors:
|
||||||
for flavour in flavours:
|
for flavor in flavors:
|
||||||
if re.match(r'.*[\'"\s]{flavour}[\'"\s].*\{{.*'.format(flavour=flavour), line):
|
if re.match(r'.*[\'"\s]{flavor}[\'"\s].*\{{.*'.format(flavor=flavor), line):
|
||||||
inside_required_flavour = 2
|
inside_required_flavor = 2
|
||||||
break
|
break
|
||||||
if re.match(r'.*[\'"\s]{flavour}[\'"\s].*'.format(flavour=flavour), line):
|
if re.match(r'.*[\'"\s]{flavor}[\'"\s].*'.format(flavor=flavor), line):
|
||||||
inside_required_flavour = 1
|
inside_required_flavor = 1
|
||||||
break
|
break
|
||||||
|
|
||||||
if '{' in line:
|
if '{' in line:
|
||||||
inside_flavour_group += 1
|
inside_flavor_group += 1
|
||||||
if '}' in line:
|
if '}' in line:
|
||||||
inside_flavour_group -= 1
|
inside_flavor_group -= 1
|
||||||
else:
|
else:
|
||||||
if "productFlavors" in line:
|
if "productFlavors" in line:
|
||||||
inside_flavour_group = 1
|
inside_flavor_group = 1
|
||||||
if not package:
|
if not package:
|
||||||
matches = psearch_g(line)
|
matches = psearch_g(line)
|
||||||
if matches:
|
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:
|
with open(path, 'w', encoding='iso-8859-1') as f:
|
||||||
f.write(props)
|
f.write(props)
|
||||||
|
|
||||||
flavours = []
|
flavors = []
|
||||||
if build.build_method() == 'gradle':
|
if build.build_method() == 'gradle':
|
||||||
flavours = build.gradle
|
flavors = build.gradle
|
||||||
|
|
||||||
if build.target:
|
if build.target:
|
||||||
n = build.target.split('-')[1]
|
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
|
# Insert version code and number into the manifest if necessary
|
||||||
if build.forceversion:
|
if build.forceversion:
|
||||||
logging.info("Changing the version name")
|
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):
|
if not os.path.isfile(path):
|
||||||
continue
|
continue
|
||||||
if path.suffix == '.xml':
|
if path.suffix == '.xml':
|
||||||
@ -2586,7 +2587,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
|
|||||||
|
|
||||||
if build.forcevercode:
|
if build.forcevercode:
|
||||||
logging.info("Changing the version code")
|
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():
|
if not path.is_file():
|
||||||
continue
|
continue
|
||||||
if path.suffix == '.xml':
|
if path.suffix == '.xml':
|
||||||
@ -4823,6 +4824,20 @@ def calculate_archive_policy(app, default):
|
|||||||
return archive_policy
|
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 = [
|
FDROIDORG_MIRRORS = [
|
||||||
{
|
{
|
||||||
'isPrimary': True,
|
'isPrimary': True,
|
||||||
|
@ -115,7 +115,7 @@ __license__ = "Python License 2.0"
|
|||||||
# been done in the StrictVersion class above. This works great as long
|
# been done in the StrictVersion class above. This works great as long
|
||||||
# as everyone can go along with bondage and discipline. Hopefully a
|
# as everyone can go along with bondage and discipline. Hopefully a
|
||||||
# (large) subset of Python module programmers will agree that the
|
# (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
|
# provides enough benefit to be worth using, and will submit their
|
||||||
# version numbering scheme to its domination. The free-thinking
|
# version numbering scheme to its domination. The free-thinking
|
||||||
# anarchists in the lot will never give in, though, and something needs
|
# anarchists in the lot will never give in, though, and something needs
|
||||||
|
@ -270,9 +270,10 @@ def get_gradle_compile_commands(build):
|
|||||||
'runtimeOnly',
|
'runtimeOnly',
|
||||||
]
|
]
|
||||||
buildTypes = ['', 'release']
|
buildTypes = ['', 'release']
|
||||||
flavors = ['']
|
|
||||||
if build.gradle and build.gradle != ['yes']:
|
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)]
|
return [''.join(c) for c in itertools.product(flavors, buildTypes, compileCommands)]
|
||||||
|
|
||||||
|
@ -1179,17 +1179,20 @@ def insert_localized_app_metadata(apps):
|
|||||||
locale = segments[-1]
|
locale = segments[-1]
|
||||||
destdir = os.path.join('repo', packageName, locale)
|
destdir = os.path.join('repo', packageName, locale)
|
||||||
|
|
||||||
# flavours specified in build receipt
|
# flavors specified in build receipt
|
||||||
build_flavours = ""
|
build_flavors = []
|
||||||
if (
|
if (
|
||||||
apps[packageName]
|
apps[packageName]
|
||||||
and len(apps[packageName].get('Builds', [])) > 0
|
and len(apps[packageName].get('Builds', [])) > 0
|
||||||
and 'gradle' in apps[packageName]['Builds'][-1]
|
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:
|
if len(segments) >= 5 and segments[4] == "fastlane" and segments[3] not in build_flavors:
|
||||||
logging.debug("ignoring due to wrong flavour")
|
logging.debug("ignoring due to wrong flavor")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for f in files:
|
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'])
|
p = fdroidserver.common.FDroidPopen(['printenv', 'SOURCE_DATE_EPOCH'])
|
||||||
self.assertEqual(int(p.output), int(now.timestamp()))
|
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 = (
|
APKS_WITH_JAR_SIGNATURES = (
|
||||||
(
|
(
|
||||||
|
@ -107,12 +107,16 @@ class ScannerTest(unittest.TestCase):
|
|||||||
('source-files/eu.siacs.conversations/build.gradle', 'free', 21),
|
('source-files/eu.siacs.conversations/build.gradle', 'free', 21),
|
||||||
('source-files/org.mozilla.rocket/app/build.gradle', 'focus', 40),
|
('source-files/org.mozilla.rocket/app/build.gradle', 'focus', 40),
|
||||||
('source-files/com.jens.automation2/app/build.gradle', 'fdroidFlavor', 5),
|
('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:
|
for f, flavor, count in test_files:
|
||||||
i = 0
|
i = 0
|
||||||
build = fdroidserver.metadata.Build()
|
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(
|
regexs = fdroidserver.scanner.get_gradle_compile_commands_without_catalog(
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user