mirror of
				https://github.com/f-droid/fdroidserver.git
				synced 2025-11-04 06:30:27 +03:00 
			
		
		
		
	🪗 get auto NDK installs working in vm builds
This commit is contained in:
		
							parent
							
								
									751df0275e
								
							
						
					
					
						commit
						cd3ca7dc57
					
				
					 3 changed files with 144 additions and 0 deletions
				
			
		| 
						 | 
					@ -68,6 +68,7 @@ COMMANDS_INTERNAL = [
 | 
				
			||||||
    "build_local_run",
 | 
					    "build_local_run",
 | 
				
			||||||
    "destroy",
 | 
					    "destroy",
 | 
				
			||||||
    "exec",
 | 
					    "exec",
 | 
				
			||||||
 | 
					    "install_ndk",
 | 
				
			||||||
    "prepare_source",
 | 
					    "prepare_source",
 | 
				
			||||||
    "pull",
 | 
					    "pull",
 | 
				
			||||||
    "push",
 | 
					    "push",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										75
									
								
								fdroidserver/install_ndk.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								fdroidserver/install_ndk.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,75 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# install_ndk.py - part of the F-Droid server tools
 | 
				
			||||||
 | 
					# Copyright (C) 2024-2025 Michael Pöhn <michael@poehn.at>
 | 
				
			||||||
 | 
					# Copyright (C) 2025 Hans-Christoph Steiner <hans@eds.org>
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""Read the "ndk:" field from the build metadata and install the right NDK packages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more info, see:
 | 
				
			||||||
 | 
					https://f-droid.org/docs/Build_Metadata_Reference/#build_ndk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from fdroidserver import common, exception, metadata
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def install_ndk_wrapper(build, ndk_paths=dict()):
 | 
				
			||||||
 | 
					    """Make sure the requested NDK version is or gets installed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Parameters
 | 
				
			||||||
 | 
					    ----------
 | 
				
			||||||
 | 
					    build
 | 
				
			||||||
 | 
					        metadata.Build instance entry that may contain the
 | 
				
			||||||
 | 
					        requested NDK version
 | 
				
			||||||
 | 
					    ndk_paths
 | 
				
			||||||
 | 
					        dictionary holding the currently installed NDKs
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    ndk_path = build.ndk_path()
 | 
				
			||||||
 | 
					    if build.ndk or (build.buildjni and build.buildjni != ['no']):
 | 
				
			||||||
 | 
					        if not ndk_path:
 | 
				
			||||||
 | 
					            for k, v in ndk_paths.items():
 | 
				
			||||||
 | 
					                if k.endswith("_orig"):
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					            common.auto_install_ndk(build)
 | 
				
			||||||
 | 
					        ndk_path = build.ndk_path()
 | 
				
			||||||
 | 
					        if not os.path.isdir(ndk_path):
 | 
				
			||||||
 | 
					            logging.critical("Android NDK '%s' is not installed!" % ndk_path)
 | 
				
			||||||
 | 
					            raise exception.FDroidException()
 | 
				
			||||||
 | 
					    return ndk_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    parser = argparse.ArgumentParser(description=__doc__)
 | 
				
			||||||
 | 
					    common.setup_global_opts(parser)
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "APPID:VERCODE",
 | 
				
			||||||
 | 
					        help="Application ID with Version Code in the form APPID:VERCODE",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options = common.parse_args(parser)
 | 
				
			||||||
 | 
					    config = common.get_config()
 | 
				
			||||||
 | 
					    appid, versionCode = common.split_pkg_arg(options.__dict__['APPID:VERCODE'])
 | 
				
			||||||
 | 
					    app, build = metadata.get_single_build(appid, versionCode)
 | 
				
			||||||
 | 
					    install_ndk_wrapper(build, config.get('ndk_paths', dict()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
							
								
								
									
										68
									
								
								tests/test_install_ndk.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										68
									
								
								tests/test_install_ndk.py
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					from unittest import mock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from fdroidserver import common, metadata, install_ndk
 | 
				
			||||||
 | 
					from .shared_test_code import mkdtemp, APPID, VERCODE, APPID_VERCODE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NDK_RELEASE = 'r24'
 | 
				
			||||||
 | 
					NDK_REVISION = '24.0.8215888'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InstallNdkTest(unittest.TestCase):
 | 
				
			||||||
 | 
					    basedir = Path(__file__).resolve().parent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        self._td = mkdtemp()
 | 
				
			||||||
 | 
					        self.testdir = self._td.name
 | 
				
			||||||
 | 
					        os.chdir(self.testdir)
 | 
				
			||||||
 | 
					        common.config = {'ndk_paths': {}, 'sdk_path': self.testdir}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def tearDown(self):
 | 
				
			||||||
 | 
					        self._td.cleanup()
 | 
				
			||||||
 | 
					        common.config = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def mock_sdkmanager_install(to_install, android_home=None):
 | 
				
			||||||
 | 
					    path = f'{android_home}/{to_install.replace(";", "/")}'
 | 
				
			||||||
 | 
					    ndk_dir = Path(path)
 | 
				
			||||||
 | 
					    ndk_dir.mkdir(parents=True)
 | 
				
			||||||
 | 
					    (ndk_dir / 'source.properties').write_text(f'Pkg.Revision = {NDK_REVISION}\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock.patch('sdkmanager.build_package_list', lambda use_net: None)
 | 
				
			||||||
 | 
					class InstallNdk_wrapper(InstallNdkTest):
 | 
				
			||||||
 | 
					    @mock.patch('sdkmanager.install')
 | 
				
			||||||
 | 
					    def test_with_ndk(self, sdkmanager_install):
 | 
				
			||||||
 | 
					        sdkmanager_install.side_effect = mock_sdkmanager_install
 | 
				
			||||||
 | 
					        build = metadata.Build({'versionCode': VERCODE, 'ndk': NDK_RELEASE})
 | 
				
			||||||
 | 
					        install_ndk.install_ndk_wrapper(build)
 | 
				
			||||||
 | 
					        sdkmanager_install.assert_called_once()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @mock.patch('fdroidserver.common.auto_install_ndk')
 | 
				
			||||||
 | 
					    def test_without_ndk(self, auto_install_ndk):
 | 
				
			||||||
 | 
					        build = metadata.Build({'versionCode': VERCODE})
 | 
				
			||||||
 | 
					        install_ndk.install_ndk_wrapper(build)
 | 
				
			||||||
 | 
					        auto_install_ndk.assert_not_called()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock.patch('sys.argv', ['fdroid ndk', APPID_VERCODE])
 | 
				
			||||||
 | 
					@mock.patch('sdkmanager.build_package_list', lambda use_net: None)
 | 
				
			||||||
 | 
					@mock.patch('sdkmanager.install')
 | 
				
			||||||
 | 
					class InstallNdk_main(InstallNdkTest):
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super().setUp()
 | 
				
			||||||
 | 
					        metadatapath = Path(common.get_metadatapath(APPID))
 | 
				
			||||||
 | 
					        metadatapath.parent.mkdir()
 | 
				
			||||||
 | 
					        metadatapath.write_text(
 | 
				
			||||||
 | 
					            f'Builds:\n - versionCode: {VERCODE}\n   ndk: {NDK_RELEASE}\n'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_ndk_main(self, sdkmanager_install):
 | 
				
			||||||
 | 
					        sdkmanager_install.side_effect = mock_sdkmanager_install
 | 
				
			||||||
 | 
					        install_ndk.main()
 | 
				
			||||||
 | 
					        sdkmanager_install.assert_called_once()
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue