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",
 | 
			
		||||
    "destroy",
 | 
			
		||||
    "exec",
 | 
			
		||||
    "install_ndk",
 | 
			
		||||
    "prepare_source",
 | 
			
		||||
    "pull",
 | 
			
		||||
    "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