diff --git a/buildozer/buildsupport.py b/buildozer/buildsupport.py index efadccbb4..87b312c6b 100644 --- a/buildozer/buildsupport.py +++ b/buildozer/buildsupport.py @@ -28,7 +28,7 @@ import buildozer.buildops as buildops from buildozer.jsonstore import JsonStore from buildozer.logger import Logger -from buildozer.pathatlas import PathAtlas, TargetedPathAtlas +from buildozer.pathatlas import GenericPaths, TargetPaths class GenericBuildSupporter: @@ -36,7 +36,7 @@ class GenericBuildSupporter: logger = Logger() - def __init__(self, config, paths: PathAtlas): + def __init__(self, config, paths: GenericPaths): self.config = config self.paths = paths @@ -105,11 +105,13 @@ def serve(self): class TargetedBuildSupporter(GenericBuildSupporter): - """Handles all build operations, - including those that do require a target.""" + """Handles all build operations, including those that do require a + target.""" - def __init__(self, config, paths: TargetedPathAtlas, target_cls): + def __init__(self, config, paths, target_cls): super().__init__(config, paths) + + self.target_paths = TargetPaths(paths, target_cls.targetname) self._ensure_target_directories_exist() # Create the target instance. @@ -123,11 +125,9 @@ def __init__(self, config, paths: TargetedPathAtlas, target_cls): self._build_done = False def _ensure_target_directories_exist(self): - assert isinstance(self.paths, TargetedPathAtlas) - - buildops.mkdir(self.paths.global_platform_path) - buildops.mkdir(self.paths.platform_path) - buildops.mkdir(self.paths.app_path) + buildops.mkdir(self.target_paths.global_platform_path) + buildops.mkdir(self.target_paths.platform_path) + buildops.mkdir(self.target_paths.app_path) def prepare_for_build(self): """Prepare the build.""" @@ -268,10 +268,8 @@ def _ensure_virtualenv(self): self.env_venv["CXX"] = "/bin/false" def clean_platform(self): - assert isinstance(self.paths, TargetedPathAtlas) - self.logger.info("Cleaning the platform build directory") - buildops.rmdir(self.paths.platform_path) + buildops.rmdir(self.target_paths.platform_path) def get_app_version(self): c = self.config @@ -316,8 +314,6 @@ def build_application(self): self._add_sitecustomize() def _copy_application_sources(self): - assert isinstance(self.paths, TargetedPathAtlas) - # XXX clean the inclusion/exclusion algo. source_dir = realpath( expanduser(self.config.getdefault("app", "source.dir", ".")) @@ -340,7 +336,7 @@ def _copy_application_sources(self): self.logger.debug("Copy application source from {}".format(source_dir)) - buildops.rmdir(self.paths.app_path) + buildops.rmdir(self.target_paths.app_path) for root, dirs, files in walk(source_dir, followlinks=True): # avoid hidden directory @@ -411,7 +407,7 @@ def _copy_application_sources(self): sfn = join(root, fn) rfn = ( - self.paths.app_path / root[len(source_dir) + 1 :] / fn + self.target_paths.app_path / root[len(source_dir) + 1 :] / fn ).resolve() # ensure the directory exists @@ -423,20 +419,17 @@ def _copy_application_sources(self): def _copy_application_libs(self): # copy also the libs - assert isinstance(self.paths, TargetedPathAtlas) buildops.file_copytree( - self.paths.applibs_path, self.paths.app_path / "_applibs" + self.paths.applibs_path, self.target_paths.app_path / "_applibs" ) def _add_sitecustomize(self): - assert isinstance(self.paths, TargetedPathAtlas) - buildops.file_copy( Path(__file__).parent / "sitecustomize.py", - self.paths.app_path / "sitecustomize.py", + self.target_paths.app_path / "sitecustomize.py", ) - main_py = join(self.paths.app_path, "service", "main.py") + main_py = join(self.target_paths.app_path, "service", "main.py") if not buildops.file_exists(main_py): return diff --git a/buildozer/commandline.py b/buildozer/commandline.py index 06e19eec4..63608faa9 100644 --- a/buildozer/commandline.py +++ b/buildozer/commandline.py @@ -27,7 +27,7 @@ import buildozer.buildops as buildops from buildozer.jsonstore import JsonStore from buildozer.logger import Logger -from buildozer.pathatlas import PathAtlas, TargetedPathAtlas +from buildozer.pathatlas import GenericPaths, TargetPaths from buildozer.specparser import SpecParser logger = Logger() @@ -38,9 +38,9 @@ def run(args): Parse the command line arguments, handle the basic operations. Handle any options first. - Set up a ConfigSpec and PathAtlas and handle any generic commands (that - need no target). - Otherwise, set up a Buildozer instance, and handle target commands. + Set up a ConfigSpec and GenericPaths instance and handle any generic + commands (that have no target). + Otherwise, set up a Builder instance, and handle target commands. """ # Profiles can be used to customise buildozer.spec on some runs. @@ -72,31 +72,19 @@ def run(args): elif arg in ("-p", "--profile"): profile = args.pop(0) - # Start function - config = SpecParser(profile) - - spec_name = "buildozer.spec" - if buildops.file_exists(spec_name): - config.read(spec_name, "utf-8") - _check_and_migrate_config(config) - - # End function + config = _load_spec() if not log_level_set_by_command_line: - try: - logger.set_level( - int(config.getdefault("buildozer", "log_level", "2")) - ) - except Exception: - pass + _set_log_level_from_config(config) _check_if_root_user(config) + paths = GenericPaths(base_dir=".", config=config) + # If no arguments are given, see if default arguments were provided # (else exit). if not args: - path_atlas = PathAtlas(".", config) - args = _get_default_args(path_atlas) + args = _get_default_args(paths) # There are three types of remaining commands: # @@ -105,13 +93,12 @@ def run(args): available_targets = _targets() - command = args[0] + command = args.pop(0) # Generic commands don't need a target. if command in GENERIC_COMMANDS: - path_atlas = PathAtlas(".", config) action = GENERIC_COMMANDS[command][2] - action(config, path_atlas, args[1:]) + action(config, paths, args) return command = command.lower() @@ -122,17 +109,96 @@ def run(args): exit(1) # We have a target. - tpa = TargetedPathAtlas( - specfile_path=".", config=config, target_name=command + + if not args: + logger.error('Missing target command') + _usage() + exit(1) + + _run_target_command( + config=config, + paths=paths, + target_cls=available_targets[command], + args=args[1:], ) - _run_target_command(config, tpa, available_targets[command], args[1:]) -def _run_target_command(config, paths, target_cls, *args): +def _load_spec(profile): + """Load spec file, if present.""" + config = SpecParser(profile) + + spec_name = "buildozer.spec" + if buildops.file_exists(spec_name): + config.read(spec_name, "utf-8") + _check_and_migrate_config(config) + return config + + +def _set_log_level_from_config(config): + try: + logger.set_level(int(config.getdefault("buildozer", "log_level", "2"))) + except Exception: + pass + + +def _run_target_command(config, paths, target_cls, args): + + # Parse a list of commands. Each command is a single word, optionally + # followed by --options. A "--" token indicates the rest of the arguments + # on the line should be passed to the command (even if they don't start + # with "--") + + valid_command_names = set(target_cls.get_custom_commands() + GENERIC_COMMANDS) + + # Commands that have been parsed. + complete_commands = [] + + # Latest command that is partially parsed. + partial_command = [] + + while args: + arg = args.pop(0) + if arg == '--': + if partial_command: + # Rest of arguments are part of the current command. + partial_command += args + break + else: + logger.error('-- arguments passed without a command') + _usage() + exit(1) + + if not arg.startswith('--'): + # New command starting. + if arg.lower() not in valid_command_names: + logger.error('Unrecognised command: {}'.format(arg)) + _usage() + exit(1) + + # Previous command, if any, is completed. + if partial_command: + complete_commands.append(partial_command) + partial_command = [] + + partial_command.append(arg.lower()) + else: + if not partial_command: + logger.error('Argument passed without a command') + _usage() + exit(1) + partial_command.append(arg) + if partial_command: + complete_commands.append(partial_command) + + if not complete_commands: + logger.error('No command for target provided') + _usage() + exit(1) + # Create the target instance, and ask it to run the command. buildsupport = TargetedBuildSupporter(config, paths, target_cls) target = target_cls(buildsupport) - target.run_commands(*args) + target.run_commands(complete_commands) def _check_if_root_user(config): diff --git a/buildozer/pathatlas.py b/buildozer/pathatlas.py index a94f0f136..af333e284 100644 --- a/buildozer/pathatlas.py +++ b/buildozer/pathatlas.py @@ -1,20 +1,19 @@ from pathlib import Path -class PathAtlas: - """ - The PathAtlas maintains a lookup table of directories relevant to the build. - It ensures that the folders exist. - """ +class GenericPaths: + """Responsible for the structure of directories relevant to all builds.""" - def __init__(self, specfile_path, config): - self.specfile_path = Path(specfile_path) + def __init__(self, base_dir, config): + # base_dir is the directory in which the spec_file was found was + # expected to be in. - # The path the specfile is in. - self.root_path = self.specfile_path.parent.expanduser().resolve() + # The folder the specfile is in (or was expected to be in). + self.root_path = Path(base_dir).expanduser().resolve() # The user-provided build dir, if any. # Check the (deprecated) builddir option, for backwards compatibility + # ToDo: Move this code in commandline's migrate functinality. old_style_build_dir = config.getdefault("buildozer", "builddir", None) if old_style_build_dir: # for backwards compatibility, append .buildozer to builddir @@ -54,23 +53,21 @@ def __init__(self, specfile_path, config): self.global_cache_path = self.global_buildozer_path / "cache" -class TargetedPathAtlas(PathAtlas): - """ - Subclass of PathAtlas that also handles directories once target has been - provided. - """ +class TargetPaths: + """Responsible for the structure of directories relevant to all targeted + builds.""" - def __init__(self, specfile_path, config, target_name): - super().__init__(specfile_path, config) - - self.platform_path = self.buildozer_path / target_name / "platform" + def __init__(self, generic_paths, target_name): + self.platform_path = ( + generic_paths.buildozer_path / target_name / "platform" + ) - self.app_path = self.buildozer_path / target_name / "app" + self.app_path = generic_paths.buildozer_path / target_name / "app" self.global_platform_path = ( - self.global_buildozer_path / target_name / "platform" + generic_paths.global_buildozer_path / target_name / "platform" ) self.global_packages_path = ( - self.global_platform_path / target_name / "packages" + generic_paths.global_platform_path / target_name / "packages" ) diff --git a/buildozer/target.py b/buildozer/target.py index a89901f2a..1cb4ef037 100644 --- a/buildozer/target.py +++ b/buildozer/target.py @@ -18,7 +18,7 @@ class Target: 'deploy', 'run', 'serve') def __init__(self, buildsupporter): - self.buildozer = buildsupporter + self.buildsupporter = buildsupporter self.build_mode = 'debug' self.artifact_format = 'apk' self.platform_update = False @@ -57,42 +57,12 @@ def get_custom_commands(cls): def get_available_packages(self): return ['kivy'] - def run_commands(self, args): - if not args: - self.logger.error('Missing target command') - self.buildozer.usage() - exit(1) - - result = [] - last_command = [] - while args: - arg = args.pop(0) - if arg == '--': - if last_command: - last_command += args - break - elif not arg.startswith('--'): - if last_command: - result.append(last_command) - last_command = [] - last_command.append(arg) - else: - if not last_command: - self.logger.error('Argument passed without a command') - self.buildozer.usage() - exit(1) - last_command.append(arg) - if last_command: - result.append(last_command) - + def run_commands(self, commands): config_check = False - for item in result: + for item in commands: command, args = item[0], item[1:] - if not hasattr(self, 'cmd_{0}'.format(command)): - self.logger.error('Unknown command {0}'.format(command)) - exit(1) - + assert hasattr(self, 'cmd_{0}'.format(command)) func = getattr(self, 'cmd_{0}'.format(command)) need_config_check = not hasattr(func, '__no_config') @@ -103,22 +73,21 @@ def run_commands(self, args): func(args) def cmd_clean(self, *args): - self.buildozer.clean_platform() + self.buildsupporter.clean_platform() def cmd_update(self, *args): self.platform_update = True - self.buildozer.prepare_for_build() + self.buildsupporter.prepare_for_build() def cmd_debug(self, *args): - self.buildozer.prepare_for_build() + self.buildsupporter.prepare_for_build() self.build_mode = 'debug' - self.artifact_format = self.buildozer.config.getdefault('app', 'android.debug_artifact', 'apk') - self.buildozer.build() + self.buildsupporter.build() def cmd_release(self, *args): error = self.logger.error - self.buildozer.prepare_for_build() - if self.buildozer.config.get("app", "package.domain") == "org.test": + self.buildsupporter.prepare_for_build() + if self.buildsupporter.config.get("app", "package.domain") == "org.test": error("") error("ERROR: Trying to release a package that starts with org.test") error("") @@ -135,7 +104,7 @@ def cmd_release(self, *args): if "BUILDOZER_ALLOW_ORG_TEST_DOMAIN" not in os.environ: exit(1) - if self.buildozer.config.get("app", "package.domain") == "org.kivy": + if self.buildsupporter.config.get("app", "package.domain") == "org.kivy": error("") error("ERROR: Trying to release a package that starts with org.kivy") error("") @@ -149,17 +118,16 @@ def cmd_release(self, *args): exit(1) self.build_mode = 'release' - self.artifact_format = self.buildozer.config.getdefault('app', 'android.release_artifact', 'aab') - self.buildozer.build() + self.buildsupporter.build() def cmd_deploy(self, *args): - self.buildozer.prepare_for_build() + self.logger.error("Deploy not implemented for this platform") def cmd_run(self, *args): - self.buildozer.prepare_for_build() + self.logger.error("Deploy not implemented for this platform") def cmd_serve(self, *args): - self.buildozer.cmd_serve() + self.buildsupporter.cmd_serve() def path_or_git_url(self, repo, owner='kivy', branch='master', url_format='https://github.com/{owner}/{repo}.git', @@ -227,11 +195,11 @@ def path_or_git_url(self, repo, owner='kivy', branch='master', key = repo if platform: key = "{}.{}".format(platform, key) - config = self.buildozer.config + config = self.buildsupporter.config path = config.getdefault('app', '{}_dir'.format(key), None) if path is not None: - path = join(self.buildozer.root_dir, path) + path = join(self.buildsupporter.root_dir, path) url = None branch = None else: @@ -255,7 +223,7 @@ def install_or_update_repo(self, repo, **kwargs): :Returns: fully qualified path to updated git repo """ - install_dir = join(self.buildozer.platform_dir, repo) + install_dir = join(self.buildsupporter.platform_dir, repo) custom_dir, clone_url, clone_branch = self.path_or_git_url(repo, **kwargs) if not buildops.file_exists(install_dir): if custom_dir: @@ -264,8 +232,8 @@ def install_or_update_repo(self, repo, **kwargs): else: buildops.cmd( ["git", "clone", "--branch", clone_branch, clone_url], - cwd=self.buildozer.platform_dir, - env=self.buildozer.environ) + cwd=self.buildsupporter.platform_dir, + env=self.buildsupporter.environ) elif self.platform_update: if custom_dir: buildops.file_copytree(custom_dir, install_dir) @@ -273,9 +241,9 @@ def install_or_update_repo(self, repo, **kwargs): buildops.cmd( ["git", "clean", "-dxf"], cwd=install_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) buildops.cmd( ["git", "pull", "origin", clone_branch], cwd=install_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) return install_dir diff --git a/buildozer/targets/android.py b/buildozer/targets/android.py index 696286606..31224a9a1 100644 --- a/buildozer/targets/android.py +++ b/buildozer/targets/android.py @@ -72,46 +72,46 @@ class TargetAndroid(Target): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if self.buildozer.config.has_option( + if self.buildsupporter.config.has_option( "app", "android.arch" - ) and not self.buildozer.config.has_option("app", "android.archs"): + ) and not self.buildsupporter.config.has_option("app", "android.archs"): self.logger.error("`android.archs` not detected, instead `android.arch` is present.") self.logger.error("`android.arch` will be removed and ignored in future.") self.logger.error("If you're seeing this error, please migrate to `android.archs`.") - self._archs = self.buildozer.config.getlist( + self._archs = self.buildsupporter.config.getlist( 'app', 'android.arch', DEFAULT_ARCHS) else: - self._archs = self.buildozer.config.getlist( + self._archs = self.buildsupporter.config.getlist( 'app', 'android.archs', DEFAULT_ARCHS) self._build_dir = join( - self.buildozer.paths.platform_path, 'build-{}'.format(self.archs_snake)) + self.buildsupporter.paths.platform_path, 'build-{}'.format(self.archs_snake)) executable = sys.executable or 'python' self._p4a_cmd = [executable, "-m", "pythonforandroid.toolchain"] - self._p4a_bootstrap = self.buildozer.config.getdefault( + self._p4a_bootstrap = self.buildsupporter.config.getdefault( 'app', 'p4a.bootstrap', 'sdl2') color = 'always' if USE_COLOR else 'never' self.extra_p4a_args = [f"--color={color}", f"--storage-dir={self._build_dir}"] # minapi should match ndk-api, so can use the same default if # nothing is specified - ndk_api = self.buildozer.config.getdefault( + ndk_api = self.buildsupporter.config.getdefault( 'app', 'android.ndk_api', self.android_minapi) self.extra_p4a_args.append(f"--ndk-api={ndk_api}") - hook = self.buildozer.config.getdefault("app", "p4a.hook", None) + hook = self.buildsupporter.config.getdefault("app", "p4a.hook", None) if hook is not None: self.extra_p4a_args.append(f"--hook={realpath(expanduser(hook))}") - port = self.buildozer.config.getdefault('app', 'p4a.port', None) + port = self.buildsupporter.config.getdefault('app', 'p4a.port', None) if port is not None: self.extra_p4a_args.append(f"--port={port}") - setup_py = self.buildozer.config.getdefault('app', 'p4a.setup_py', False) + setup_py = self.buildsupporter.config.getdefault('app', 'p4a.setup_py', False) if setup_py: self.extra_p4a_args.append("--use-setup-py") else: self.extra_p4a_args.append("--ignore-setup-py") - activity_class_name = self.buildozer.config.getdefault( + activity_class_name = self.buildsupporter.config.getdefault( 'app', 'android.activity_class_name', 'org.kivy.android.PythonActivity') if activity_class_name != 'org.kivy.android.PythonActivity': self.extra_p4a_args.append(f"--activity-class-name={activity_class_name}") @@ -119,14 +119,14 @@ def __init__(self, *args, **kwargs): if self.logger.log_level >= 2: self.extra_p4a_args.append("--debug") - user_extra_p4a_args = self.buildozer.config.getdefault('app', 'p4a.extra_args', "") + user_extra_p4a_args = self.buildsupporter.config.getdefault('app', 'p4a.extra_args', "") self.extra_p4a_args.extend(shlex.split(user_extra_p4a_args)) self.warn_on_deprecated_tokens() def warn_on_deprecated_tokens(self): for section, token in DEPRECATED_TOKENS: - value = self.buildozer.config.getdefault(section, token, None) + value = self.buildsupporter.config.getdefault(section, token, None) if value is not None: error = ('WARNING: Config token {} {} is deprecated and ignored, ' 'but you set value {}').format(section, token, value) @@ -144,10 +144,10 @@ def p4a_dir(self): """The directory where python-for-android is/will be installed.""" # Default p4a dir - p4a_dir = join(self.buildozer.paths.platform_path, self.p4a_directory_name) + p4a_dir = join(self.buildsupporter.paths.platform_path, self.p4a_directory_name) # Possibly overridden by user setting - system_p4a_dir = self.buildozer.config.getdefault('app', 'p4a.source_dir') + system_p4a_dir = self.buildsupporter.config.getdefault('app', 'p4a.source_dir') if system_p4a_dir: p4a_dir = expanduser(system_p4a_dir) @@ -198,55 +198,55 @@ def _sdkmanager(self, *args, **kwargs): if kwargs.pop('return_child', False): return buildops.cmd_expect( - command, env=self.buildozer.environ, **kwargs) + command, env=self.buildsupporter.environ, **kwargs) else: kwargs['get_stdout'] = kwargs.get('get_stdout', True) - return buildops.cmd(command, env=self.buildozer.environ, **kwargs) + return buildops.cmd(command, env=self.buildsupporter.environ, **kwargs) @property def android_ndk_version(self): - return self.buildozer.config.getdefault('app', 'android.ndk', - self.p4a_recommended_android_ndk) + return self.buildsupporter.config.getdefault('app', 'android.ndk', + self.p4a_recommended_android_ndk) @property def android_api(self): - return self.buildozer.config.getdefault('app', 'android.api', - ANDROID_API) + return self.buildsupporter.config.getdefault('app', 'android.api', + ANDROID_API) @property def android_minapi(self): - return self.buildozer.config.getdefault('app', 'android.minapi', - ANDROID_MINAPI) + return self.buildsupporter.config.getdefault('app', 'android.minapi', + ANDROID_MINAPI) @property def android_sdk_dir(self): - directory = expanduser(self.buildozer.config.getdefault( + directory = expanduser(self.buildsupporter.config.getdefault( 'app', 'android.sdk_path', '')) if directory: return realpath(directory) - return join(self.buildozer.paths.global_platform_path, + return join(self.buildsupporter.paths.global_platform_path, 'android-sdk') @property def android_ndk_dir(self): - directory = expanduser(self.buildozer.config.getdefault( + directory = expanduser(self.buildsupporter.config.getdefault( 'app', 'android.ndk_path', '')) if directory: return realpath(directory) - version = self.buildozer.config.getdefault('app', 'android.ndk', - self.android_ndk_version) - return join(self.buildozer.paths.global_platform_path, + version = self.buildsupporter.config.getdefault('app', 'android.ndk', + self.android_ndk_version) + return join(self.buildsupporter.paths.global_platform_path, 'android-ndk-r{0}'.format(version)) @property def apache_ant_dir(self): - directory = expanduser(self.buildozer.config.getdefault( + directory = expanduser(self.buildsupporter.config.getdefault( 'app', 'android.ant_path', '')) if directory: return realpath(directory) - version = self.buildozer.config.getdefault('app', 'android.ant', - APACHE_ANT_VERSION) - return join(self.buildozer.paths.global_platform_path, + version = self.buildsupporter.config.getdefault('app', 'android.ant', + APACHE_ANT_VERSION) + return join(self.buildsupporter.paths.global_platform_path, 'apache-ant-{0}'.format(version)) @property @@ -298,18 +298,18 @@ def check_requirements(self): os.environ['REPO_OS_OVERRIDE'] = 'linux' # Adb arguments: - adb_args = self.buildozer.config.getdefault( + adb_args = self.buildsupporter.config.getdefault( "app", "android.adb_args", "") self.adb_args = shlex.split(adb_args) # Need to add internally installed ant to path for external tools # like adb to use path = [join(self.apache_ant_dir, 'bin')] - if 'PATH' in self.buildozer.environ: - path.append(self.buildozer.environ['PATH']) + if 'PATH' in self.buildsupporter.environ: + path.append(self.buildsupporter.environ['PATH']) else: path.append(os.environ['PATH']) - self.buildozer.environ['PATH'] = ':'.join(path) + self.buildsupporter.environ['PATH'] = ':'.join(path) buildops.checkbin('Git (git)', 'git') buildops.checkbin('Cython (cython)', 'cython') buildops.checkbin('Java compiler (javac)', self.javac_cmd) @@ -319,14 +319,14 @@ def _p4a_have_aab_support(self): returncode = self._p4a( ["aab", "-h"], break_on_error=False, - env=self.buildozer.environ).return_code + env=self.buildsupporter.environ).return_code if returncode == 0: return True else: return False def _set_win32_java_home(self): - if 'JAVA_HOME' in self.buildozer.environ: + if 'JAVA_HOME' in self.buildsupporter.environ: return import winreg with winreg.OpenKey( @@ -337,14 +337,14 @@ def _set_win32_java_home(self): with winreg.OpenKey(jdk, current_version) as cv: # @UndefinedVariable java_home, _type = winreg.QueryValueEx( cv, "JavaHome") # @UndefinedVariable - self.buildozer.environ['JAVA_HOME'] = java_home + self.buildsupporter.environ['JAVA_HOME'] = java_home def _locate_java(self, s): '''If JAVA_HOME is in the environ, return $JAVA_HOME/bin/s. Otherwise, return s. ''' - if 'JAVA_HOME' in self.buildozer.environ: - return join(self.buildozer.environ['JAVA_HOME'], 'bin', s) + if 'JAVA_HOME' in self.buildsupporter.environ: + return join(self.buildsupporter.environ['JAVA_HOME'], 'bin', s) else: return s @@ -367,7 +367,7 @@ def _install_apache_ant(self): buildops.file_extract( archive, cwd=ant_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) self.logger.info('Apache ANT installation done.') return ant_dir @@ -400,7 +400,7 @@ def _install_android_sdk(self): buildops.file_extract( archive, cwd=sdk_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) self.logger.info('Android SDK tools base installation done.') @@ -457,18 +457,18 @@ def _install_android_ndk(self): url = 'https://dl.google.com/android/ndk/' buildops.download(url, - archive, - cwd=self.buildozer.paths.global_platform_path) + archive, + cwd=self.buildsupporter.paths.global_platform_path) self.logger.info('Unpacking Android NDK') buildops.file_extract( archive, - cwd=self.buildozer.global_platform_path, - env=self.buildozer.environ) + cwd=self.buildsupporter.global_platform_path, + env=self.buildsupporter.environ) buildops.rename( unpacked, ndk_dir, - cwd=self.buildozer.global_platform_path) + cwd=self.buildsupporter.global_platform_path) self.logger.info('Android NDK installation done.') return ndk_dir @@ -493,7 +493,7 @@ def _android_list_build_tools_versions(self): def _android_update_sdk(self, *sdkmanager_commands): """Update the tools and package-tools if possible""" - auto_accept_license = self.buildozer.config.getbooldefault( + auto_accept_license = self.buildsupporter.config.getbooldefault( 'app', 'android.accept_sdk_license', False) kwargs = {} @@ -550,12 +550,12 @@ def _install_android_packages(self): self.android_api, self.android_minapi, self.android_ndk_version, self.android_sdk_dir, self.android_ndk_dir ] - if self.buildozer.state.get(cache_key, None) == cache_value: + if self.buildsupporter.state.get(cache_key, None) == cache_value: return True # 1. update the platform-tools package if needed - skip_upd = self.buildozer.config.getbooldefault( + skip_upd = self.buildsupporter.config.getbooldefault( 'app', 'android.skip_update', False) if not skip_upd: @@ -603,8 +603,8 @@ def _install_android_packages(self): self.logger.info('Android packages installation done.') - self.buildozer.state[cache_key] = cache_value - self.buildozer.state.sync() + self.buildsupporter.state[cache_key] = cache_value + self.buildsupporter.state.sync() def _check_aidl(self, v_build_tools): self.logger.debug('Check that aidl can be executed') @@ -617,7 +617,7 @@ def _check_aidl(self, v_build_tools): [aidl_cmd], break_on_error=False, show_output=False, - env=self.buildozer.environ).return_code + env=self.buildsupporter.environ).return_code if returncode != 1: self.logger.error('Aidl cannot be executed') if architecture()[0] == '64bit': @@ -651,8 +651,8 @@ def install_platform(self): ) raise BuildozerException() - self.buildozer.environ.update({ - 'PACKAGES_PATH': self.buildozer.paths.global_packages_path, + self.buildsupporter.environ.update({ + 'PACKAGES_PATH': self.buildsupporter.paths.global_packages_path, 'ANDROIDSDK': self.android_sdk_dir, 'ANDROIDNDK': self.android_ndk_dir, 'ANDROIDAPI': self.android_api, @@ -660,21 +660,21 @@ def install_platform(self): }) def _install_p4a(self): - p4a_fork = self.buildozer.config.getdefault( + p4a_fork = self.buildsupporter.config.getdefault( 'app', 'p4a.fork', self.p4a_fork ) - p4a_url = self.buildozer.config.getdefault( + p4a_url = self.buildsupporter.config.getdefault( 'app', 'p4a.url', f'https://github.com/{p4a_fork}/python-for-android.git' ) - p4a_branch = self.buildozer.config.getdefault( + p4a_branch = self.buildsupporter.config.getdefault( 'app', 'p4a.branch', self.p4a_branch ) - p4a_commit = self.buildozer.config.getdefault( + p4a_commit = self.buildsupporter.config.getdefault( 'app', 'p4a.commit', self.p4a_commit ) p4a_dir = self.p4a_dir - system_p4a_dir = self.buildozer.config.getdefault('app', + system_p4a_dir = self.buildsupporter.config.getdefault('app', 'p4a.source_dir') if system_p4a_dir: # Don't install anything, just check that the dir does exist @@ -690,13 +690,13 @@ def _install_p4a(self): ["git", "config", "--get", "remote.origin.url"], get_stdout=True, cwd=p4a_dir, - env=self.buildozer.environ + env=self.buildsupporter.environ ).stdout.strip() cur_branch = buildops.cmd( ["git", "branch", "-vv"], get_stdout=True, cwd=p4a_dir, - env=self.buildozer.environ + env=self.buildsupporter.environ ).stdout.split()[1] if any([cur_url != p4a_url, cur_branch != p4a_branch]): self.logger.info( @@ -715,38 +715,38 @@ def _install_p4a(self): p4a_url, self.p4a_directory_name, ], - cwd=self.buildozer.paths.platform_path, - env=self.buildozer.environ + cwd=self.buildsupporter.paths.platform_path, + env=self.buildsupporter.environ ) elif self.platform_update: buildops.cmd( ["git", "clean", "-dxf"], cwd=p4a_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) current_branch = buildops.cmd( ["git", "rev-parse", "--abbrev-ref", "HEAD"], get_stdout=True, cwd=p4a_dir, - env=self.buildozer.environ).stdout.strip() + env=self.buildsupporter.environ).stdout.strip() if current_branch == p4a_branch: buildops.cmd( ["git", "pull"], cwd=p4a_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) else: buildops.cmd( ["git", "fetch", "--tags", "origin", "{0}:{0}".format(p4a_branch)], cwd=p4a_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) buildops.cmd( ["git", "checkout", p4a_branch], cwd=p4a_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) if p4a_commit != 'HEAD': buildops.cmd( ["git", "reset", "--hard", p4a_commit], cwd=p4a_dir, - env=self.buildozer.environ) + env=self.buildsupporter.environ) # also install dependencies (currently, only setup.py knows about it) # let's extract them. @@ -766,28 +766,28 @@ def _install_p4a(self): options = [] buildops.cmd( [executable, "-m", "pip", "install", "-q", *options, *deps], - env=self.buildozer.environ) + env=self.buildsupporter.environ) def compile_platform(self): - app_requirements = self.buildozer.config.getlist( + app_requirements = self.buildsupporter.config.getlist( 'app', 'requirements', '') - dist_name = self.buildozer.config.get('app', 'package.name') + dist_name = self.buildsupporter.config.get('app', 'package.name') local_recipes = self.get_local_recipes_dir() requirements = ','.join(app_requirements) options = [] source_dirs = { 'P4A_{}_DIR'.format(name[20:]): realpath(expanduser(value)) - for name, value in self.buildozer.config.items('app') + for name, value in self.buildsupporter.config.items('app') if name.startswith('requirements.source.') } if source_dirs: - self.buildozer.environ.update(source_dirs) + self.buildsupporter.environ.update(source_dirs) self.logger.info('Using custom source dirs:\n {}'.format( '\n '.join(['{} = {}'.format(k, v) for k, v in source_dirs.items()]))) - if self.buildozer.config.getbooldefault('app', 'android.copy_libs', True): + if self.buildsupporter.config.getbooldefault('app', 'android.copy_libs', True): options.append("--copy-libs") # support for recipes in a local directory within the project if local_recipes: @@ -801,7 +801,7 @@ def compile_platform(self): p4a_create.extend(options) - self._p4a(p4a_create, get_stdout=True, env=self.buildozer.environ) + self._p4a(p4a_create, get_stdout=True, env=self.buildsupporter.environ) def get_available_packages(self): return True @@ -821,12 +821,12 @@ def get_dist_dir(self, dist_name): return expected_dist_dir def get_local_recipes_dir(self): - local_recipes = self.buildozer.config.getdefault('app', 'p4a.local_recipes') + local_recipes = self.buildsupporter.config.getdefault('app', 'p4a.local_recipes') return realpath(expanduser(local_recipes)) if local_recipes else None def execute_build_package(self, build_cmd): # wrapper from previous old_toolchain to new toolchain - dist_name = self.buildozer.config.get('app', 'package.name') + dist_name = self.buildsupporter.config.get('app', 'package.name') local_recipes = self.get_local_recipes_dir() cmd = [self.artifact_format, "--bootstrap", self._p4a_bootstrap, "--dist_name", dist_name] for args in build_cmd: @@ -847,23 +847,23 @@ def execute_build_package(self, build_cmd): cmd.extend(args) # support for presplash background color - presplash_color = self.buildozer.config.getdefault('app', 'android.presplash_color', None) + presplash_color = self.buildsupporter.config.getdefault('app', 'android.presplash_color', None) if presplash_color: cmd.append('--presplash-color') cmd.append("{}".format(presplash_color)) # support for services - services = self.buildozer.config.getlist('app', 'services', []) + services = self.buildsupporter.config.getlist('app', 'services', []) for service in services: cmd.append("--service") cmd.append(service) # support for copy-libs - if self.buildozer.config.getbooldefault('app', 'android.copy_libs', True): + if self.buildsupporter.config.getbooldefault('app', 'android.copy_libs', True): cmd.append("--copy-libs") # Home-app usage - if self.buildozer.config.getbooldefault('app', 'android.home_app', False): + if self.buildsupporter.config.getbooldefault('app', 'android.home_app', False): cmd.append("--home-app") # support for recipes in a local directory within the project @@ -872,8 +872,8 @@ def execute_build_package(self, build_cmd): cmd.append(local_recipes) # support for blacklist/whitelist filename - whitelist_src = self.buildozer.config.getdefault('app', 'android.whitelist_src', None) - blacklist_src = self.buildozer.config.getdefault('app', 'android.blacklist_src', None) + whitelist_src = self.buildsupporter.config.getdefault('app', 'android.whitelist_src', None) + blacklist_src = self.buildsupporter.config.getdefault('app', 'android.blacklist_src', None) if whitelist_src: cmd.append('--whitelist') cmd.append(realpath(expanduser(whitelist_src))) @@ -882,19 +882,19 @@ def execute_build_package(self, build_cmd): cmd.append(realpath(expanduser(blacklist_src))) # support for java directory - javadirs = self.buildozer.config.getlist('app', 'android.add_src', []) + javadirs = self.buildsupporter.config.getlist('app', 'android.add_src', []) for javadir in javadirs: cmd.append('--add-source') cmd.append(realpath(expanduser(javadir))) # support for aars - aars = self.buildozer.config.getlist('app', 'android.add_aars', []) + aars = self.buildsupporter.config.getlist('app', 'android.add_aars', []) for aar in aars: cmd.append('--add-aar') cmd.append(realpath(expanduser(aar))) # support for assets folder - assets = self.buildozer.config.getlist('app', 'android.add_assets', []) + assets = self.buildsupporter.config.getlist('app', 'android.add_assets', []) for asset in assets: cmd.append('--add-asset') if ':' in asset: @@ -905,7 +905,7 @@ def execute_build_package(self, build_cmd): cmd.append(realpath(expanduser(asset_src)) + ':' + asset_dest) # support for res folder - resources = self.buildozer.config.getlist('app', 'android.add_resources', []) + resources = self.buildsupporter.config.getlist('app', 'android.add_resources', []) for resource in resources: cmd.append('--add-resource') if ':' in resource: @@ -916,51 +916,51 @@ def execute_build_package(self, build_cmd): cmd.append(realpath(expanduser(resource_src)) + ':' + resource_dest) # support for uses-lib - uses_library = self.buildozer.config.getlist( + uses_library = self.buildsupporter.config.getlist( 'app', 'android.uses_library', '') for lib in uses_library: cmd.append('--uses-library={}'.format(lib)) # support for activity-class-name - activity_class_name = self.buildozer.config.getdefault( + activity_class_name = self.buildsupporter.config.getdefault( 'app', 'android.activity_class_name', 'org.kivy.android.PythonActivity') if activity_class_name != 'org.kivy.android.PythonActivity': cmd.append('--activity-class-name={}'.format(activity_class_name)) # support for service-class-name - service_class_name = self.buildozer.config.getdefault( + service_class_name = self.buildsupporter.config.getdefault( 'app', 'android.service_class_name', 'org.kivy.android.PythonService') if service_class_name != 'org.kivy.android.PythonService': cmd.append('--service-class-name={}'.format(service_class_name)) # support for extra-manifest-xml - extra_manifest_xml = self.buildozer.config.getdefault( + extra_manifest_xml = self.buildsupporter.config.getdefault( 'app', 'android.extra_manifest_xml', '') if extra_manifest_xml: cmd.append('--extra-manifest-xml') cmd.append('{}'.format(open(extra_manifest_xml, 'rt').read())) # support for extra-manifest-application-arguments - extra_manifest_application_arguments = self.buildozer.config.getdefault( + extra_manifest_application_arguments = self.buildsupporter.config.getdefault( 'app', 'android.extra_manifest_application_arguments', '') if extra_manifest_application_arguments: cmd.append('--extra-manifest-application-arguments') cmd.append('{}'.format(open(extra_manifest_application_arguments, 'rt').read())) # support for gradle dependencies - gradle_dependencies = self.buildozer.config.getlist('app', 'android.gradle_dependencies', []) + gradle_dependencies = self.buildsupporter.config.getlist('app', 'android.gradle_dependencies', []) for gradle_dependency in gradle_dependencies: cmd.append('--depend') cmd.append(gradle_dependency) # support for manifestPlaceholders - manifest_placeholders = self.buildozer.config.getdefault('app', 'android.manifest_placeholders', None) + manifest_placeholders = self.buildsupporter.config.getdefault('app', 'android.manifest_placeholders', None) if manifest_placeholders: cmd.append('--manifest-placeholders') cmd.append("{}".format(manifest_placeholders)) # support disabling of byte compile for .py files - no_byte_compile = self.buildozer.config.getdefault('app', 'android.no-byte-compile-python', False) + no_byte_compile = self.buildsupporter.config.getdefault('app', 'android.no-byte-compile-python', False) if no_byte_compile: cmd.append('--no-byte-compile-python') @@ -968,7 +968,7 @@ def execute_build_package(self, build_cmd): cmd.append('--arch') cmd.append(arch) - self._p4a(cmd, env=self.buildozer.environ) + self._p4a(cmd, env=self.buildsupporter.environ) def get_release_mode(self): # aab, also if unsigned is named as *-release @@ -990,21 +990,21 @@ def check_p4a_sign_env(self, error=False): return check def cmd_run(self, *args): - entrypoint = self.buildozer.config.getdefault( + entrypoint = self.buildsupporter.config.getdefault( 'app', 'android.entrypoint') if not entrypoint: - self.buildozer.config.set('app', 'android.entrypoint', 'org.kivy.android.PythonActivity') + self.buildsupporter.config.set('app', 'android.entrypoint', 'org.kivy.android.PythonActivity') super().cmd_run(*args) - entrypoint = self.buildozer.config.getdefault( + entrypoint = self.buildsupporter.config.getdefault( 'app', 'android.entrypoint', 'org.kivy.android.PythonActivity') package = self._get_package() # push on the device for serial in self.serials: - self.buildozer.environ['ANDROID_SERIAL'] = serial + self.buildsupporter.environ['ANDROID_SERIAL'] = serial self.logger.info('Run on {}'.format(serial)) buildops.cmd( [ @@ -1018,10 +1018,10 @@ def cmd_run(self, *args): "-a", entrypoint, ], - cwd=self.buildozer.paths.global_platform_path, - env=self.buildozer.environ + cwd=self.buildsupporter.paths.global_platform_path, + env=self.buildsupporter.environ ) - self.buildozer.environ.pop('ANDROID_SERIAL', None) + self.buildsupporter.environ.pop('ANDROID_SERIAL', None) while True: if self._get_pid(): @@ -1045,17 +1045,17 @@ def cmd_p4a(self, *args): .format(self.targetname)) sys.stderr.write('PYTHONPATH={} {}\n'.format(self.p4a_dir, self._p4a_cmd)) else: - self._p4a(args, env=self.buildozer.environ) + self._p4a(args, env=self.buildsupporter.environ) def cmd_clean(self, *args): ''' Clean the build and distribution ''' - self._p4a(["clean_builds"], env=self.buildozer.environ) - self._p4a(["clean_dists"], env=self.buildozer.environ) + self._p4a(["clean_builds"], env=self.buildsupporter.environ) + self._p4a(["clean_dists"], env=self.buildsupporter.environ) def _get_package(self): - config = self.buildozer.config + config = self.buildsupporter.config package_domain = config.getdefault('app', 'package.domain', '') package = config.get('app', 'package.name') if package_domain: @@ -1063,7 +1063,7 @@ def _get_package(self): return package.lower() def _generate_whitelist(self, dist_dir): - p4a_whitelist = self.buildozer.config.getlist( + p4a_whitelist = self.buildsupporter.config.getlist( 'app', 'android.whitelist') or [] whitelist_fn = join(dist_dir, 'whitelist.txt') with open(whitelist_fn, 'w') as fd: @@ -1071,11 +1071,11 @@ def _generate_whitelist(self, dist_dir): fd.write(wl + '\n') def build_package(self): - dist_name = self.buildozer.config.get('app', 'package.name') + dist_name = self.buildsupporter.config.get('app', 'package.name') dist_dir = self.get_dist_dir(dist_name) - config = self.buildozer.config + config = self.buildsupporter.config package = self._get_package() - version = self.buildozer.get_version() + version = self.buildsupporter.get_version() # add extra libs/armeabi files in dist/default/libs/armeabi # (same for armeabi-v7a, arm64-v8a, x86, mips) @@ -1095,7 +1095,7 @@ def build_package(self): self.logger.debug('Search and copy libs for {}'.format(lib_dir)) for fn in buildops.file_matches(patterns): buildops.file_copy( - join(self.buildozer.root_dir, fn), + join(self.buildsupporter.root_dir, fn), join(dist_dir, 'libs', lib_dir, basename(fn))) # update the project.properties libraries references @@ -1113,7 +1113,7 @@ def build_package(self): self.android_minapi)), ("--ndk-api", config.getdefault('app', 'android.minapi', self.android_minapi)), - ("--private", self.buildozer.app_dir), + ("--private", self.buildsupporter.app_dir), ] # add permissions @@ -1129,8 +1129,8 @@ def build_package(self): # add res_xml xmlfiles = config.getlist('app', 'android.res_xml', []) for xmlfile in xmlfiles: - build_cmd += [("--res_xml", join(self.buildozer.paths.root_path, - xmlfile))] + build_cmd += [("--res_xml", join(self.buildsupporter.paths.root_path, + xmlfile))] # android.entrypoint entrypoint = config.getdefault('app', 'android.entrypoint', 'org.kivy.android.PythonActivity') @@ -1165,7 +1165,7 @@ def build_package(self): # add extra Java jar files add_jars = config.getlist('app', 'android.add_jars', []) for pattern in add_jars: - pattern = join(self.buildozer.paths.root_path, pattern) + pattern = join(self.buildsupporter.paths.root_path, pattern) matches = glob(expanduser(pattern.strip())) if matches: for jar in matches: @@ -1182,23 +1182,23 @@ def build_package(self): # add presplash, lottie animation or static presplash = config.getdefault('app', 'android.presplash_lottie', '') if presplash: - build_cmd += [("--presplash-lottie", join(self.buildozer.paths.root_path, + build_cmd += [("--presplash-lottie", join(self.buildsupporter.paths.root_path, presplash))] else: presplash = config.getdefault('app', 'presplash.filename', '') if presplash: - build_cmd += [("--presplash", join(self.buildozer.paths.root_path, + build_cmd += [("--presplash", join(self.buildsupporter.paths.root_path, presplash))] # add icon icon = config.getdefault('app', 'icon.filename', '') if icon: - build_cmd += [("--icon", join(self.buildozer.paths.root_path, icon))] + build_cmd += [("--icon", join(self.buildsupporter.paths.root_path, icon))] icon_fg = config.getdefault('app', 'icon.adaptive_foreground.filename', '') icon_bg = config.getdefault('app', 'icon.adaptive_background.filename', '') if icon_fg and icon_bg: - build_cmd += [("--icon-fg", join(self.buildozer.paths.root_path, icon_fg))] - build_cmd += [("--icon-bg", join(self.buildozer.paths.root_path, icon_bg))] + build_cmd += [("--icon-fg", join(self.buildsupporter.paths.root_path, icon_fg))] + build_cmd += [("--icon-bg", join(self.buildsupporter.paths.root_path, icon_bg))] # OUYA Console support ouya_category = config.getdefault('app', 'android.ouya.category', @@ -1212,7 +1212,7 @@ def build_package(self): ouya_icon = config.getdefault('app', 'android.ouya.icon.filename', '') build_cmd += [("--ouya-category", ouya_category)] - build_cmd += [("--ouya-icon", join(self.buildozer.paths.root_path, + build_cmd += [("--ouya-icon", join(self.buildsupporter.paths.root_path, ouya_icon))] if config.getdefault('app', 'p4a.bootstrap', 'sdl2') != 'service_only': @@ -1242,7 +1242,7 @@ def build_package(self): intent_filters = config.getdefault( 'app', 'android.manifest.intent_filters', '') if intent_filters: - build_cmd += [("--intent-filters", join(self.buildozer.paths.root_path, + build_cmd += [("--intent-filters", join(self.buildsupporter.paths.root_path, intent_filters))] # activity launch mode @@ -1270,7 +1270,7 @@ def build_package(self): # android.backup_rules backup_rules = config.getdefault('app', 'android.backup_rules', '') if backup_rules: - build_cmd += [("--backup-rules", join(self.buildozer.paths.root_path, + build_cmd += [("--backup-rules", join(self.buildsupporter.paths.root_path, backup_rules))] # build only in debug right now. @@ -1286,9 +1286,9 @@ def build_package(self): self.execute_build_package(build_cmd) try: - self.buildozer.hook("android_pre_build_apk") + self.buildsupporter.hook("android_pre_build_apk") self.execute_build_package(build_cmd) - self.buildozer.hook("android_post_build_apk") + self.buildsupporter.hook("android_post_build_apk") except: # maybe the hook fail because the apk is not pass @@ -1333,13 +1333,13 @@ def build_package(self): # copy to our place buildops.file_copy( join(artifact_dir, artifact), - join(self.buildozer.paths.bin_path, artifact_dest)) + join(self.buildsupporter.paths.bin_path, artifact_dest)) self.logger.info('Android packaging done!') self.logger.info( u'APK {0} available in the bin directory'.format(artifact_dest)) - self.buildozer.state['android:latestapk'] = artifact_dest - self.buildozer.state['android:latestmode'] = self.build_mode + self.buildsupporter.state['android:latestapk'] = artifact_dest + self.buildsupporter.state['android:latestmode'] = self.build_mode def _update_libraries_references(self, dist_dir): # ensure the project.properties exist @@ -1361,9 +1361,9 @@ def _update_libraries_references(self, dist_dir): content.remove(line) # convert our references to relative path - app_references = self.buildozer.config.getlist( + app_references = self.buildsupporter.config.getlist( 'app', 'android.library_references', []) - source_dir = realpath(expanduser(self.buildozer.config.getdefault( + source_dir = realpath(expanduser(self.buildsupporter.config.getdefault( 'app', 'source.dir', '.'))) for cref in app_references: # get the full path of the current reference @@ -1402,7 +1402,7 @@ def serials(self): lines = buildops.cmd( [self.adb_executable, *self.adb_args, "devices"], get_stdout=True, - env=self.buildozer.environ + env=self.buildsupporter.environ ).stdout.splitlines() serials = [] for serial in lines: @@ -1431,11 +1431,21 @@ def cmd_adb(self, *args): else: buildops.cmd( [self.adb_executable, *self.adb_args, *args], - env=self.buildozer.environ) + env=self.buildsupporter.environ) + + def cmd_debug(self, *args): + self.artifact_format = self.buildsupporter.config.getdefault( + 'app', 'android.debug_artifact', 'apk') + super(self).cmd_debug(*args) + + def cmd_release(self, *args): + self.artifact_format = self.buildsupporter.config.getdefault( + 'app', 'android.release_artifact', 'aab') + super(self).cmd_release(*args) def cmd_deploy(self, *args): super().cmd_deploy(*args) - state = self.buildozer.state + state = self.buildsupporter.state if 'android:latestapk' not in state: self.logger.error('No APK built yet. Run "debug" first.') @@ -1445,21 +1455,21 @@ def cmd_deploy(self, *args): # search the APK in the bin dir apk = state['android:latestapk'] - full_apk = join(self.buildozer.paths.bin_path, apk) + full_apk = join(self.buildsupporter.paths.bin_path, apk) if not buildops.file_exists(full_apk): self.logger.error( 'Unable to found the latest APK. Please run "debug" again.') # push on the device for serial in self.serials: - self.buildozer.environ['ANDROID_SERIAL'] = serial + self.buildsupporter.environ['ANDROID_SERIAL'] = serial self.logger.info('Deploy on {}'.format(serial)) buildops.cmd( [self.adb_executable, *self.adb_args, "install", "-r", full_apk], - cwd=self.buildozer.paths.global_platform_path, - env=self.buildozer.environ + cwd=self.buildsupporter.paths.global_platform_path, + env=self.buildsupporter.environ ) - self.buildozer.environ.pop('ANDROID_SERIAL', None) + self.buildsupporter.environ.pop('ANDROID_SERIAL', None) self.logger.info('Application pushed.') @@ -1476,7 +1486,7 @@ def _get_pid(self): show_output=False, break_on_error=False, quiet=True, - env=self.buildozer.environ + env=self.buildsupporter.environ ).stdout if pid: return pid.strip() @@ -1489,33 +1499,33 @@ def cmd_logcat(self, *args): serial = self.serials[0:] if not serial: return - filters = self.buildozer.config.getlist( + filters = self.buildsupporter.config.getlist( "app", "android.logcat_filters", default="", section_sep=":", strip=False) filters = " ".join(filters) - self.buildozer.environ['ANDROID_SERIAL'] = serial[0] + self.buildsupporter.environ['ANDROID_SERIAL'] = serial[0] extra_args = [] pid = None - if self.buildozer.config.getdefault('app', 'android.logcat_pid_only'): + if self.buildsupporter.config.getdefault('app', 'android.logcat_pid_only'): pid = self._get_pid() if pid: extra_args.extend(('--pid', pid)) buildops.cmd( [self.adb_executable, *self.adb_args, "logcat", filters, *extra_args], - cwd=self.buildozer.paths.global_platform_path, + cwd=self.buildsupporter.paths.global_platform_path, show_output=True, run_condition=self._get_pid if pid else None, break_on_error=False, - env=self.buildozer.environ + env=self.buildsupporter.environ ) self.logger.info(f"{self._get_package()} terminated") - self.buildozer.environ.pop('ANDROID_SERIAL', None) + self.buildsupporter.environ.pop('ANDROID_SERIAL', None) TARGET_CLS = TargetAndroid \ No newline at end of file diff --git a/buildozer/targets/ios.py b/buildozer/targets/ios.py index 35ce0cc4a..cbef4891c 100644 --- a/buildozer/targets/ios.py +++ b/buildozer/targets/ios.py @@ -91,7 +91,7 @@ def check_requirements(self): sdk_list = buildops.cmd( ['xcodebuild', '-showsdks'], get_stdout=True, - env=self.buildozer.environ).stdout + env=self.buildsupporter.environ).stdout iphoneos_lines = [ line for line in sdk_list.split("\n") @@ -112,7 +112,7 @@ def check_requirements(self): xcode = buildops.cmd( ["xcode-select", "-print-path"], get_stdout=True, - env=self.buildozer.environ).stdout + env=self.buildsupporter.environ).stdout if not xcode: raise Exception('Unable to get xcode path') self.logger.debug(' -> found {0}'.format(xcode)) @@ -132,25 +132,25 @@ def toolchain(self, cmd, **kwargs): kwargs.setdefault('cwd', self.ios_dir) return buildops.cmd( [*self._toolchain_cmd, *cmd], - env=self.buildozer.environ, + env=self.buildsupporter.environ, **kwargs) def xcodebuild(self, *args, **kwargs): filtered_args = [arg for arg in args if arg is not None] return buildops.cmd( [*self._xcodebuild_cmd, *filtered_args], - env=self.buildozer.environ, + env=self.buildsupporter.environ, **kwargs) @property def code_signing_allowed(self): - allowed = self.buildozer.config.getboolean("app", "ios.codesign.allowed") + allowed = self.buildsupporter.config.getboolean("app", "ios.codesign.allowed") allowed = "YES" if allowed else "NO" return f"CODE_SIGNING_ALLOWED={allowed}" @property def code_signing_development_team(self): - team = self.buildozer.config.getdefault("app", f"ios.codesign.development_team.{self.build_mode}", None) + team = self.buildsupporter.config.getdefault("app", f"ios.codesign.development_team.{self.build_mode}", None) return f"DEVELOPMENT_TEAM={team}" if team else None def get_available_packages(self): @@ -168,8 +168,8 @@ def dump_plist_to_file(self, plist, plist_rfn): def compile_platform(self): # for ios, the compilation depends really on the app requirements. # compile the distribution only if the requirements changed. - last_requirements = self.buildozer.state.get('ios.requirements', '') - app_requirements = self.buildozer.config.getlist('app', 'requirements', + last_requirements = self.buildsupporter.state.get('ios.requirements', '') + app_requirements = self.buildsupporter.config.getlist('app', 'requirements', '') # we need to extract the requirements that kivy-ios knows about @@ -185,11 +185,11 @@ def compile_platform(self): # len('requirements.source.') == 20, so use name[20:] source_dirs = {'{}_DIR'.format(name[20:].upper()): realpath(expanduser(value)) - for name, value in self.buildozer.config.items('app') + for name, value in self.buildsupporter.config.items('app') if name.startswith('requirements.source.')} if source_dirs: need_compile = 1 - self.buildozer.environ.update(source_dirs) + self.buildsupporter.environ.update(source_dirs) self.logger.info('Using custom source dirs:\n {}'.format( '\n '.join(['{} = {}'.format(k, v) for k, v in source_dirs.items()]))) @@ -204,11 +204,11 @@ def compile_platform(self): join(self.ios_deploy_dir, 'ios-deploy')): self.xcodebuild(cwd=self.ios_deploy_dir) - self.buildozer.state['ios.requirements'] = ios_requirements - self.buildozer.state.sync() + self.buildsupporter.state['ios.requirements'] = ios_requirements + self.buildsupporter.state.sync() def _get_package(self): - config = self.buildozer.config + config = self.buildsupporter.config package_domain = config.getdefault('app', 'package.domain', '') package = config.get('app', 'package.name') if package_domain: @@ -219,17 +219,17 @@ def build_package(self): self._unlock_keychain() # create the project - app_name = self.buildozer.namify(self.buildozer.config.get('app', + app_name = self.buildsupporter.namify(self.buildsupporter.config.get('app', 'package.name')) - ios_frameworks = self.buildozer.config.getlist('app', 'ios.frameworks', '') + ios_frameworks = self.buildsupporter.config.getlist('app', 'ios.frameworks', '') frameworks_cmd = [] for framework in ios_frameworks: frameworks_cmd.append(f"--add-framework={framework}") self.app_project_dir = join(self.ios_dir, '{0}-ios'.format(app_name.lower())) if not buildops.file_exists(self.app_project_dir): - cmd = ["create", *frameworks_cmd, app_name, self.buildozer.app_dir] + cmd = ["create", *frameworks_cmd, app_name, self.buildsupporter.app_dir] else: cmd = ["update", *frameworks_cmd, f"{app_name}-ios"] self.toolchain(cmd) @@ -237,21 +237,21 @@ def build_package(self): # fix the plist plist_fn = '{}-Info.plist'.format(app_name.lower()) plist_rfn = join(self.app_project_dir, plist_fn) - version = self.buildozer.get_version() + version = self.buildsupporter.get_version() self.logger.info('Update Plist {}'.format(plist_fn)) plist = self.load_plist_from_file(plist_rfn) plist['CFBundleIdentifier'] = self._get_package() plist['CFBundleShortVersionString'] = version plist['CFBundleVersion'] = '{}.{}'.format(version, - self.buildozer.build_id) + self.buildsupporter.build_id) # add icons self._create_icons() # Generate OTA distribution manifest if `app_url`, `display_image_url` and `full_size_image_url` are defined. - app_url = self.buildozer.config.getdefault("app", "ios.manifest.app_url", None) - display_image_url = self.buildozer.config.getdefault("app", "ios.manifest.display_image_url", None) - full_size_image_url = self.buildozer.config.getdefault("app", "ios.manifest.full_size_image_url", None) + app_url = self.buildsupporter.config.getdefault("app", "ios.manifest.app_url", None) + display_image_url = self.buildsupporter.config.getdefault("app", "ios.manifest.display_image_url", None) + full_size_image_url = self.buildsupporter.config.getdefault("app", "ios.manifest.full_size_image_url", None) if any((app_url, display_image_url, full_size_image_url)): @@ -282,14 +282,14 @@ def build_package(self): cwd=self.app_project_dir) ios_app_dir = '{app_lower}-ios/build/{mode}-iphoneos/{app_lower}.app'.format( app_lower=app_name.lower(), mode=mode) - self.buildozer.state['ios:latestappdir'] = ios_app_dir + self.buildsupporter.state['ios:latestappdir'] = ios_app_dir intermediate_dir = join(self.ios_dir, '{}-{}.intermediates'.format(app_name, version)) xcarchive = join(intermediate_dir, '{}-{}.xcarchive'.format( app_name, version)) ipa_name = '{}-{}.ipa'.format(app_name, version) ipa_tmp = join(intermediate_dir, ipa_name) - ipa = join(self.buildozer.bin_dir, ipa_name) + ipa = join(self.buildsupporter.bin_dir, ipa_name) build_dir = join(self.ios_dir, '{}-ios'.format(app_name.lower())) buildops.rmdir(intermediate_dir) @@ -312,7 +312,7 @@ def build_package(self): cwd=build_dir) key = 'ios.codesign.{}'.format(self.build_mode) - ioscodesign = self.buildozer.config.getdefault('app', key, '') + ioscodesign = self.buildsupporter.config.getdefault('app', key, '') if not ioscodesign: self.logger.error('Cannot create the IPA package without' ' signature. You must fill the "{}" token.'.format(key)) @@ -336,8 +336,8 @@ def build_package(self): self.logger.info('iOS packaging done!') self.logger.info('IPA {0} available in the bin directory'.format( basename(ipa))) - self.buildozer.state['ios:latestipa'] = ipa - self.buildozer.state['ios:latestmode'] = self.build_mode + self.buildsupporter.state['ios:latestipa'] = ipa + self.buildsupporter.state['ios:latestmode'] = self.build_mode def cmd_deploy(self, *args): super().cmd_deploy(*args) @@ -350,19 +350,19 @@ def cmd_run(self, *args): def cmd_xcode(self, *args): '''Open the xcode project. ''' - app_name = self.buildozer.namify(self.buildozer.config.get('app', + app_name = self.buildsupporter.namify(self.buildsupporter.config.get('app', 'package.name')) app_name = app_name.lower() - ios_dir = join(self.buildozer.platform_dir, 'kivy-ios') + ios_dir = join(self.buildsupporter.platform_dir, 'kivy-ios') buildops.cmd( ["open", f"{app_name}.xcodeproj"], cwd=join(ios_dir, f"{app_name}-ios"), - env=self.buildozer.environ + env=self.buildsupporter.environ ) def _run_ios_deploy(self, lldb=False): - state = self.buildozer.state + state = self.buildsupporter.state if 'ios:latestappdir' not in state: self.logger.error( 'App not built yet. Run "debug" or "release" first.') @@ -380,13 +380,13 @@ def _run_ios_deploy(self, lldb=False): [join(self.ios_deploy_dir, "ios-deploy"), debug_mode, "-b", ios_app_dir], cwd=self.ios_dir, show_output=True, - env=self.buildozer.environ) + env=self.buildsupporter.environ) def _create_icons(self): - icon = self.buildozer.config.getdefault('app', 'icon.filename', '') + icon = self.buildsupporter.config.getdefault('app', 'icon.filename', '') if not icon: return - icon_fn = join(self.buildozer.app_dir, icon) + icon_fn = join(self.buildsupporter.app_dir, icon) if not buildops.file_exists(icon_fn): self.logger.error('Icon {} does not exists'.format(icon_fn)) return @@ -395,7 +395,7 @@ def _create_icons(self): def check_configuration_tokens(self): errors = [] - config = self.buildozer.config + config = self.buildsupporter.config if not config.getboolean('app', 'ios.codesign.allowed'): return identity_debug = config.getdefault('app', 'ios.codesign.debug', '') @@ -431,7 +431,7 @@ def _get_available_identities(self): output = buildops.cmd( ["security", "find-identity", "-v", "-p", "codesigning"], get_stdout=True, - env=self.buildozer.environ + env=self.buildsupporter.environ ).stdout lines = output.splitlines()[:-1] @@ -439,7 +439,7 @@ def _get_available_identities(self): return lines def _unlock_keychain(self): - password_file = join(self.buildozer.buildozer_dir, '.ioscodesign') + password_file = join(self.buildsupporter.buildozer_dir, '.ioscodesign') password = None if buildops.file_exists(password_file): with open(password_file) as fd: @@ -451,7 +451,7 @@ def _unlock_keychain(self): ["security", "unlock-keychain", "-u"], break_on_error=False, quiet=True, # Log doesn't need secure info - env=self.buildozer.environ).return_code + env=self.buildsupporter.environ).return_code if not error: return else: @@ -460,7 +460,7 @@ def _unlock_keychain(self): ["security", "unlock-keychain", "-p", password], break_on_error=False, quiet=True, # Log doesn't need secure info - env=self.buildozer.environ + env=self.buildsupporter.environ ).return_code if not error: return @@ -475,7 +475,7 @@ def _unlock_keychain(self): ["security", "unlock-keychain", "-p", password], quiet=True, # Log doesn't need secure info break_on_error=False, - env=self.buildozer.environ + env=self.buildsupporter.environ ).return_code if not error: correct = True diff --git a/buildozer/targets/osx.py b/buildozer/targets/osx.py index 007726dc7..7c52e7c6c 100644 --- a/buildozer/targets/osx.py +++ b/buildozer/targets/osx.py @@ -21,24 +21,24 @@ class TargetOSX(Target): def ensure_sdk(self): self.logger.info('Check if kivy-sdk-packager exists') if exists( - join(self.buildozer.platform_dir, 'kivy-sdk-packager-master')): + join(self.buildsupporter.platform_dir, 'kivy-sdk-packager-master')): self.logger.info( 'kivy-sdk-packager found at ' - '{}'.format(self.buildozer.platform_dir)) + '{}'.format(self.buildsupporter.platform_dir)) return self.logger.info('kivy-sdk-packager does not exist, clone it') - platdir = self.buildozer.platform_dir + platdir = self.buildsupporter.platform_dir buildops.download( 'https://github.com/kivy/kivy-sdk-packager/archive/master.zip', 'master.zip', cwd=platdir) buildops.file_extract( - 'master.zip', cwd=platdir, env=self.buildozer.environ) + 'master.zip', cwd=platdir, env=self.buildsupporter.environ) buildops.file_remove(join(platdir, 'master.zip')) def download_kivy(self, cwd): - current_kivy_vers = self.buildozer.config.get('app', 'osx.kivy_version') + current_kivy_vers = self.buildsupporter.config.get('app', 'osx.kivy_version') if exists('/Applications/Kivy.app'): self.logger.info('Kivy found in Applications dir...') @@ -68,7 +68,7 @@ def download_kivy(self, cwd): def ensure_kivyapp(self): self.logger.info('check if Kivy.app exists in local dir') - kivy_app_dir = join(self.buildozer.platform_dir, 'kivy-sdk-packager-master', 'osx') + kivy_app_dir = join(self.buildsupporter.platform_dir, 'kivy-sdk-packager-master', 'osx') if exists(join(kivy_app_dir, 'Kivy.app')): self.logger.info('Kivy.app found at ' + kivy_app_dir) @@ -79,32 +79,22 @@ def check_requirements(self): self.ensure_sdk() self.ensure_kivyapp() - def check_configuration_tokens(self, errors=None): - if errors: - self.logger.info('Check target configuration tokens') - self.logger.error( - '{0} error(s) found in the buildozer.spec'.format( - len(errors))) - for error in errors: - print(error) - sys.exit(1) - # check def build_package(self): self.logger.info('Building package') - bc = self.buildozer.config + bc = self.buildsupporter.config bcg = bc.get package_name = bcg('app', 'package.name') domain = bcg('app', 'package.domain') title = bcg('app', 'title') app_deps = open('requirements.txt').read() icon = bc.getdefault('app', 'icon.filename', '') - version = self.buildozer.get_version() + version = self.buildsupporter.get_version() author = bc.getdefault('app', 'author', '') self.logger.info('Create {}.app'.format(package_name)) - cwd = join(self.buildozer.platform_dir, 'kivy-sdk-packager-master', 'osx') + cwd = join(self.buildsupporter.platform_dir, 'kivy-sdk-packager-master', 'osx') # remove kivy from app_deps app_deps = [a for a in app_deps.split('\n') if not a.startswith('#') and a not in ['kivy', '']] @@ -118,7 +108,7 @@ def build_package(self): cmd = [ sys.executable, 'package_app.py', - self.buildozer.app_dir, + self.buildsupporter.app_dir, '--appname={}'.format(package_name), '--bundlename={}'.format(title), '--bundleid={}'.format(domain), @@ -140,97 +130,25 @@ def build_package(self): self.logger.info('{}.dmg created'.format(package_name)) self.logger.info('moving {}.dmg to bin.'.format(package_name)) binpath = join( - self.buildozer.user_build_dir or - dirname(abspath(self.buildozer.specfilename)), 'bin') + self.buildsupporter.user_build_dir or + dirname(abspath(self.buildsupporter.specfilename)), 'bin') buildops.file_copytree( join(cwd, package_name + '.dmg'), binpath) self.logger.info('All Done!') - def compile_platform(self): - pass - def install_platform(self): # ultimate configuration check. # some of our configuration cannot be checked without platform. + # ToDo: This is a no-op. self.check_configuration_tokens() # - self.buildozer.environ.update({ - 'PACKAGES_PATH': self.buildozer.global_packages_dir, + self.buildsupporter.environ.update({ + 'PACKAGES_PATH': self.buildsupporter.global_packages_dir, }) def get_available_packages(self): return ['kivy', 'python3'] - def run_commands(self, args): - if not args: - self.logger.error('Missing target command') - self.buildozer.usage() - sys.exit(1) - - result = [] - last_command = [] - for arg in args: - if not arg.startswith('--'): - if last_command: - result.append(last_command) - last_command = [] - last_command.append(arg) - else: - if not last_command: - self.logger.error('Argument passed without a command') - self.buildozer.usage() - sys.exit(1) - last_command.append(arg) - if last_command: - result.append(last_command) - - config_check = False - - for item in result: - command, args = item[0], item[1:] - if not hasattr(self, 'cmd_{0}'.format(command)): - self.logger.error('Unknown command {0}'.format(command)) - sys.exit(1) - - func = getattr(self, 'cmd_{0}'.format(command)) - - need_config_check = not hasattr(func, '__no_config') - if need_config_check and not config_check: - config_check = True - self.check_configuration_tokens() - - func(args) - - def check_build_prepared(self): - self._build_prepared = False - - def cmd_clean(self, *args): - self.buildozer.clean_platform() - - def cmd_update(self, *args): - self.platform_update = True - self.buildozer.prepare_for_build() - - def cmd_debug(self, *args): - self.buildozer.prepare_for_build() - self.build_mode = 'debug' - self.check_build_prepared() - self.buildozer.build() - - def cmd_release(self, *args): - self.buildozer.prepare_for_build() - self.build_mode = 'release' - self.buildozer.build() - - def cmd_deploy(self, *args): - self.buildozer.prepare_for_build() - - def cmd_run(self, *args): - self.buildozer.prepare_for_build() - - def cmd_serve(self, *args): - self.buildozer.cmd_serve() - TARGET_CLS = TargetOSX \ No newline at end of file diff --git a/tests/targets/test_android.py b/tests/targets/test_android.py index a3db75825..030224c92 100644 --- a/tests/targets/test_android.py +++ b/tests/targets/test_android.py @@ -55,7 +55,7 @@ def call_build_package(target_android): instance so that tests can easily check which command-line arguments would be passed on to python-for-android's toolchain. """ - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter expected_dist_dir = ( '{buildozer_dir}/android/platform/build-arm64-v8a_armeabi-v7a/dists/myapp'.format( buildozer_dir=buildozer.buildozer_dir) @@ -103,7 +103,7 @@ def tear_method(self): def test_init(self): """Tests init defaults.""" target_android = init_target(self.temp_dir) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter assert target_android._archs == ["arm64-v8a", "armeabi-v7a"] assert target_android._build_dir.endswith( ".buildozer/android/platform/build-arm64-v8a_armeabi-v7a" @@ -149,7 +149,7 @@ def test_sdkmanager(self): def test_check_requirements(self): """Basic tests for the check_requirements() method.""" target_android = init_target(self.temp_dir) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter assert not hasattr(target_android, "adb_executable") assert not hasattr(target_android, "adb_args") assert not hasattr(target_android, "javac_cmd") @@ -215,7 +215,7 @@ def test_install_android_sdk(self, platform): def test_build_package(self): """Basic tests for the build_package() method.""" target_android = init_target(self.temp_dir) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter m_execute_build_package = call_build_package(target_android) assert m_execute_build_package.call_args_list == [ mock.call( @@ -239,7 +239,7 @@ def test_build_package(self): def test_execute_build_package__debug__apk(self): """Basic tests for the execute_build_package() method. (in debug mode)""" target_android = init_target(self.temp_dir) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter with patch_target_android("_p4a") as m__p4a: target = TargetAndroid(buildozer) target.execute_build_package([("debug",)]) @@ -261,7 +261,7 @@ def test_execute_build_package__debug__apk(self): def test_execute_build_package__release__apk(self): """Basic tests for the execute_build_package() method. (in apk release mode)""" target_android = init_target(self.temp_dir) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter with patch_target_android("_p4a") as m__p4a: target = TargetAndroid(buildozer) target.execute_build_package([("release",)]) @@ -284,7 +284,7 @@ def test_execute_build_package__release__apk(self): def test_execute_build_package__release__aab(self): """Basic tests for the execute_build_package() method. (in aab release mode)""" target_android = init_target(self.temp_dir) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter with patch_target_android("_p4a") as m__p4a: target = TargetAndroid(buildozer) target.artifact_format = "aab" @@ -310,7 +310,7 @@ def test_numeric_version(self): target_android = init_target(self.temp_dir, { "android.numeric_version": "1234" }) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter m_execute_build_package = call_build_package(target_android) assert m_execute_build_package.call_args_list == [ mock.call( @@ -345,7 +345,7 @@ def test_build_package_intent_filters(self): target_android = init_target(self.temp_dir, { 'android.manifest.intent_filters': 'filters.xml' }) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter m_execute_build_package = call_build_package(target_android) assert m_execute_build_package.call_args_list == [ @@ -373,7 +373,7 @@ def test_allow_backup(self): target_android = init_target(self.temp_dir, { "android.allow_backup": "false" }) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter m_execute_build_package = call_build_package(target_android) assert m_execute_build_package.call_args_list == [ mock.call( @@ -400,7 +400,7 @@ def test_backup_rules(self): target_android = init_target(self.temp_dir, { "android.backup_rules": "backup_rules.xml" }) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter m_execute_build_package = call_build_package(target_android) assert m_execute_build_package.call_args_list == [ mock.call( @@ -470,7 +470,7 @@ def test_orientation(self): target_android = init_target(self.temp_dir, { "orientation": "portrait,portrait-reverse" }) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter m_execute_build_package = call_build_package(target_android) assert m_execute_build_package.call_args_list == [ mock.call( @@ -496,7 +496,7 @@ def test_manifest_orientation(self): target_android = init_target(self.temp_dir, { "android.manifest.orientation": "fullSensor" }) - buildozer = target_android.buildozer + buildozer = target_android.buildsupporter m_execute_build_package = call_build_package(target_android) assert m_execute_build_package.call_args_list == [ mock.call(