From ba5c78d45f408d9f6e270c033fe621b18dfc0eb7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 8 Jul 2025 20:44:21 +0200 Subject: [PATCH 1/2] update: fetch Builds one time and reuse --- fdroidserver/update.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 95adfc66..3106b7aa 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1185,14 +1185,9 @@ def insert_localized_app_metadata(apps): # 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'] - ): + if builds and 'gradle' in builds[-1] and builds[-1]['gradle'] != ['yes']: build_flavors = common.calculate_gradle_flavor_combination( - apps[packageName]['Builds'][-1]['gradle'] + builds[-1]['gradle'] ) if len(segments) >= 5 and segments[4] == "fastlane" and segments[3] not in build_flavors: @@ -1234,9 +1229,7 @@ def insert_localized_app_metadata(apps): try: versionCode = int(base) locale = segments[-2] - if versionCode in [ - a["versionCode"] for a in apps[packageName]["Builds"] - ]: + if versionCode in [b["versionCode"] for b in builds]: _set_localized_text_entry( apps[packageName], locale, From 96c0d928daca6682e55cd96737dee8b63a9407ff Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 8 Jul 2025 22:32:49 +0200 Subject: [PATCH 2/2] update: support fastlane/ dir in subdir: GNU Taler apps use this. * https://git.taler.net/taler-android.git/tree/merchant-terminal/fastlane/metadata/android/en-US?h=pos-1.0.2 --- fdroidserver/update.py | 25 +++++++++++++-- tests/test_update.py | 69 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 3106b7aa..6369a8b8 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1167,7 +1167,7 @@ def insert_localized_app_metadata(apps): https://f-droid.org/en/docs/All_About_Descriptions_Graphics_and_Screenshots/#in-the-apps-build-metadata-in-an-fdroiddata-collection """ sourcedirs = glob.glob(os.path.join('build', '[A-Za-z]*', 'src', '[A-Za-z]*', 'fastlane', 'metadata', 'android', '[a-z][a-z]*')) - sourcedirs += glob.glob(os.path.join('build', '[A-Za-z]*', 'fastlane', 'metadata', 'android', '[a-z][a-z]*')) + sourcedirs += glob.glob(os.path.join('build', '[A-Za-z]*', '**', 'fastlane', 'metadata', 'android', '[a-z][a-z]*'), recursive=True) sourcedirs += glob.glob(os.path.join('build', '[A-Za-z]*', 'metadata', '[a-z][a-z]*')) sourcedirs += glob.glob(os.path.join('metadata', '[A-Za-z]*', '[a-z][a-z]*')) @@ -1183,6 +1183,16 @@ def insert_localized_app_metadata(apps): locale = segments[-1] destdir = os.path.join('repo', packageName, locale) + builds = apps.get(packageName, {}).get('Builds', []) + found_in_subdir = ( + builds + and len(segments) > 7 + and segments[-4] == "fastlane" + and segments[-3] == "metadata" + and segments[-2] == "android" + and '/'.join(segments[2:-4]) == builds[-1].get('subdir') + ) + # flavors specified in build receipt build_flavors = [] if builds and 'gradle' in builds[-1] and builds[-1]['gradle'] != ['yes']: @@ -1190,8 +1200,17 @@ def insert_localized_app_metadata(apps): builds[-1]['gradle'] ) - if len(segments) >= 5 and segments[4] == "fastlane" and segments[3] not in build_flavors: - logging.debug("ignoring due to wrong flavor") + if ( + not found_in_subdir + and len(segments) >= 5 + and segments[4] == "fastlane" + and segments[3] not in build_flavors + ): + logging.debug( + 'Not scanning "{dir}" with unknown subdir or gradle flavor "{value}"'.format( + dir=os.path.relpath(root), value=segments[3] + ) + ) continue for f in files: diff --git a/tests/test_update.py b/tests/test_update.py index de39d8fd..f17667e2 100755 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -253,6 +253,75 @@ class UpdateTest(unittest.TestCase): fdroidserver.update.insert_localized_app_metadata(apps) self.assertEqual('42', apps[app.id]['localized']['en-US']['whatsNew']) + def test_fastlane_with_subdir(self): + """Test if fastlane in simple one-level subdir is found.""" + os.chdir(self.testdir) + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.update.config = config + + app = fdroidserver.metadata.App() + app.id = 'com.example.app' + build_dir = f'build/{app.id}' + flavor = 'flavor' + subdir = 'subproject' + apps = {app.id: app} + build = fdroidserver.metadata.Build() + build.versionCode = 42 + build.gradle = [flavor] + build.subdir = subdir + app['Builds'] = [build] + + first_value = 'first' + first_dir = Path(f'{build_dir}/src/{flavor}/fastlane/metadata/android/en-US') + first_dir.mkdir(parents=True) + (first_dir / 'title.txt').write_text(first_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(first_value, apps[app.id]['localized']['en-US']['name']) + + second_value = 'second' + second_dir = Path(f'{build_dir}/{subdir}/fastlane/metadata/android/en-US') + second_dir.mkdir(parents=True) + (second_dir / 'title.txt').write_text(second_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(second_value, apps[app.id]['localized']['en-US']['name']) + + def test_fastlane_with_multi_level_subdir(self): + """Test if fastlane in multi-level subdir is found.""" + os.chdir(self.testdir) + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.update.config = config + + app = fdroidserver.metadata.App() + app.id = 'org.videolan.vlc' + build_dir = f'build/{app.id}' + subdir = 'application/app' + apps = {app.id: app} + build = fdroidserver.metadata.Build() + build.versionCode = 42 + build.gradle = ['yes'] + build.subdir = subdir + app['Builds'] = [build] + + first_value = 'first' + first_dir = Path(f'{build_dir}/{subdir}/fastlane/metadata/android/en-US') + first_dir.mkdir(parents=True) + (first_dir / 'title.txt').write_text(first_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(first_value, apps[app.id]['localized']['en-US']['name']) + + # I'm not sure that it is correct behavior for this path to + # override the above path, but it is how it is working now. It + # seems to me it should be the other way around, but that is + # really hard to implement using the current algorithm. + second_value = 'second' + second_dir = Path(f'{build_dir}/fastlane/metadata/android/en-US') + second_dir.mkdir(parents=True) + (second_dir / 'title.txt').write_text(second_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(second_value, apps[app.id]['localized']['en-US']['name']) + def test_name_title_scraping(self): """metadata file --> fdroiddata localized files --> fastlane/triple-t in app source --> APK""" shutil.copytree(basedir, self.testdir, dirs_exist_ok=True)