def should_step_run(self, part: pluginhandler.PluginHandler, step: steps.Step) -> bool: """Determine if a given step of a given part should run. :param pluginhandler.PluginHandler part: Part in question. :param steps.Step step: Step in question. :return: Whether or not step should run. :rtype: bool A given step should run if it: 1. Hasn't yet run 2. Is dirty 3. Is outdated 4. Either (1), (2), or (3) apply to any earlier steps in the part's lifecycle """ if (not self.has_step_run(part, step) or self.get_outdated_report(part, step) is not None or self.get_dirty_report(part, step) is not None): return True previous_step = step.previous_step() if previous_step: return self.should_step_run(part, previous_step) return False
def should_step_run( self, part: pluginhandler.PluginHandler, step: steps.Step ) -> bool: """Determine if a given step of a given part should run. :param pluginhandler.PluginHandler part: Part in question. :param steps.Step step: Step in question. :return: Whether or not step should run. :rtype: bool A given step should run if it: 1. Hasn't yet run 2. Is dirty 3. Is outdated 4. Either (1), (2), or (3) apply to any earlier steps in the part's lifecycle """ if ( not self.has_step_run(part, step) or self.get_outdated_report(part, step) is not None or self.get_dirty_report(part, step) is not None ): return True previous_step = step.previous_step() if previous_step: return self.should_step_run(part, previous_step) return False
def _execute( # noqa: C901 step: steps.Step, parts: str, pack_project: bool = False, output: str = None, shell: bool = False, shell_after: bool = False, destructive_mode: bool = False, **kwargs) -> "Project": # fmt: on provider = "host" if destructive_mode else None build_environment = env.BuilderEnvironmentConfig(force_provider=provider) project = get_project(is_managed_host=build_environment.is_managed_host, **kwargs) conduct_project_sanity_check(project) if build_environment.is_managed_host or build_environment.is_host: project_config = project_loader.load_config(project) lifecycle.execute(step, project_config, parts) if pack_project: _pack(project.prime_dir, output=output) else: build_provider_class = build_providers.get_provider_for( build_environment.provider) echo.info("Launching a VM.") with build_provider_class(project=project, echoer=echo) as instance: instance.mount_project() try: if shell: # shell means we want to do everything right up to the previous # step and then go into a shell instead of the requested step. # the "snap" target is a special snowflake that has not made its # way to be a proper step. previous_step = None if pack_project: previous_step = steps.PRIME elif step > steps.PULL: previous_step = step.previous_step() # steps.PULL is the first step, so we would directly shell into it. if previous_step: instance.execute_step(previous_step) elif pack_project: instance.pack_project(output=output) else: instance.execute_step(step) except Exception: if project.debug: instance.shell() else: echo.warning( "Run the same command again with --debug to shell into the environment " "if you wish to introspect this failure.") raise else: if shell or shell_after: instance.shell() return project
def _execute( # noqa: C901 step: steps.Step, parts: str, pack_project: bool = False, output: str = None, shell: bool = False, shell_after: bool = False, destructive_mode: bool = False, **kwargs) -> "Project": _clean_provider_error() provider = "host" if destructive_mode else None build_environment = env.BuilderEnvironmentConfig(force_provider=provider) project = get_project(is_managed_host=build_environment.is_managed_host, **kwargs) echo.wrapped("Using {!r}: Project assets will be " "searched for from the {!r} directory.".format( project.info.snapcraft_yaml_file_path, os.path.relpath(project._get_snapcraft_assets_dir(), project._project_dir), )) conduct_project_sanity_check(project) if build_environment.is_managed_host or build_environment.is_host: project_config = project_loader.load_config(project) lifecycle.execute(step, project_config, parts) if pack_project: _pack(project.prime_dir, output=output) else: build_provider_class = build_providers.get_provider_for( build_environment.provider) try: build_provider_class.ensure_provider() except build_providers.errors.ProviderNotFound as provider_error: if provider_error.prompt_installable: click.echo(str(provider_error)) if click.confirm("Would you like to install it now?"): build_provider_class.setup_provider(echoer=echo) else: raise provider_error else: raise provider_error echo.info("Launching a VM.") with build_provider_class(project=project, echoer=echo) as instance: instance.mount_project() try: if shell: # shell means we want to do everything right up to the previous # step and then go into a shell instead of the requested step. # the "snap" target is a special snowflake that has not made its # way to be a proper step. previous_step = None if pack_project: previous_step = steps.PRIME elif step > steps.PULL: previous_step = step.previous_step() # steps.PULL is the first step, so we would directly shell into it. if previous_step: instance.execute_step(previous_step) elif pack_project: instance.pack_project(output=output) else: instance.execute_step(step) except Exception: _retrieve_provider_error(instance) if project.debug: instance.shell() else: echo.warning( "Run the same command again with --debug to shell into the environment " "if you wish to introspect this failure.") raise else: if shell or shell_after: instance.shell() return project
def _execute( # noqa: C901 step: steps.Step, parts: str, pack_project: bool = False, output: Optional[str] = None, shell: bool = False, shell_after: bool = False, setup_prime_try: bool = False, **kwargs, ) -> "Project": # Cleanup any previous errors. _clean_provider_error() build_provider = get_build_provider(**kwargs) build_provider_flags = get_build_provider_flags(build_provider, **kwargs) apply_host_provider_flags(build_provider_flags) is_managed_host = build_provider == "managed-host" # Temporary fix to ignore target_arch. if kwargs.get("target_arch") is not None and build_provider in ["multipass", "lxd"]: echo.warning( "Ignoring '--target-arch' flag. This flag requires --destructive-mode and is unsupported with Multipass and LXD build providers." ) kwargs.pop("target_arch") project = get_project(is_managed_host=is_managed_host, **kwargs) conduct_project_sanity_check(project, **kwargs) project_path = pathlib.Path(project._project_dir) if project_path.name in ["build-aux", "snap"]: echo.warning( f"Snapcraft is running in directory {project_path.name!r}. If this is the snap assets directory, please run snapcraft from {project_path.parent}." ) if build_provider in ["host", "managed-host"]: project_config = project_loader.load_config(project) lifecycle.execute(step, project_config, parts) if pack_project: _pack( project.prime_dir, compression=project._snap_meta.compression, output=output, ) else: build_provider_class = build_providers.get_provider_for(build_provider) try: build_provider_class.ensure_provider() except build_providers.errors.ProviderNotFound as provider_error: if provider_error.prompt_installable: if echo.is_tty_connected() and echo.confirm( "Support for {!r} needs to be set up. " "Would you like to do it now?".format(provider_error.provider) ): build_provider_class.setup_provider(echoer=echo) else: raise provider_error else: raise provider_error with build_provider_class( project=project, echoer=echo, build_provider_flags=build_provider_flags ) as instance: try: if shell: # shell means we want to do everything right up to the previous # step and then go into a shell instead of the requested step. # the "snap" target is a special snowflake that has not made its # way to be a proper step. previous_step = None if pack_project: previous_step = steps.PRIME elif step > steps.PULL: previous_step = step.previous_step() # steps.PULL is the first step, so we would directly shell into it. if previous_step: instance.execute_step(previous_step) elif pack_project: instance.pack_project(output=output) elif setup_prime_try: instance.expose_prime() instance.execute_step(step) else: instance.execute_step(step) except Exception: _retrieve_provider_error(instance) if project.debug: instance.shell() else: echo.warning( "Run the same command again with --debug to shell into the environment " "if you wish to introspect this failure." ) raise else: if shell or shell_after: instance.shell() return project
def _execute( # noqa: C901 step: steps.Step, parts: str, pack_project: bool = False, output: Optional[str] = None, shell: bool = False, shell_after: bool = False, setup_prime_try: bool = False, **kwargs, ) -> "Project": # Cleanup any previous errors. _clean_provider_error() build_provider = get_build_provider(**kwargs) build_provider_flags = get_build_provider_flags(build_provider, **kwargs) apply_host_provider_flags(build_provider_flags) is_managed_host = build_provider == "managed-host" project = get_project(is_managed_host=is_managed_host, **kwargs) conduct_project_sanity_check(project, **kwargs) if build_provider in ["host", "managed-host"]: project_config = project_loader.load_config(project) lifecycle.execute(step, project_config, parts) if pack_project: _pack(project.prime_dir, output=output) else: build_provider_class = build_providers.get_provider_for(build_provider) try: build_provider_class.ensure_provider() except build_providers.errors.ProviderNotFound as provider_error: if provider_error.prompt_installable: if echo.is_tty_connected() and echo.confirm( "Support for {!r} needs to be set up. " "Would you like to do that it now?".format( provider_error.provider)): build_provider_class.setup_provider(echoer=echo) else: raise provider_error else: raise provider_error with build_provider_class( project=project, echoer=echo, build_provider_flags=build_provider_flags) as instance: instance.mount_project() try: if shell: # shell means we want to do everything right up to the previous # step and then go into a shell instead of the requested step. # the "snap" target is a special snowflake that has not made its # way to be a proper step. previous_step = None if pack_project: previous_step = steps.PRIME elif step > steps.PULL: previous_step = step.previous_step() # steps.PULL is the first step, so we would directly shell into it. if previous_step: instance.execute_step(previous_step) elif pack_project: instance.pack_project(output=output) elif setup_prime_try: instance.expose_prime() instance.execute_step(step) else: instance.execute_step(step) except Exception: _retrieve_provider_error(instance) if project.debug: instance.shell() else: echo.warning( "Run the same command again with --debug to shell into the environment " "if you wish to introspect this failure.") raise else: if shell or shell_after: instance.shell() return project
def _execute( # noqa: C901 step: steps.Step, parts: str, pack_project: bool = False, output: str = None, shell: bool = False, shell_after: bool = False, **kwargs ) -> "Project": # fmt: on if sys.platform == "darwin": default_provider = "multipass" else: default_provider = "host" build_environment = env.BuilderEnvironmentConfig(default=default_provider) project = get_project(is_managed_host=build_environment.is_managed_host, **kwargs) conduct_project_sanity_check(project) # When we are ready to pull the trigger we will trigger this when # project.info.base is set if build_environment.is_multipass: build_provider_class = build_providers.get_provider_for( build_environment.provider ) echo.info("Launching a VM.") with build_provider_class(project=project, echoer=echo) as instance: instance.mount_project() try: if shell: # shell means we want to do everything right up to the previous # step and then go into a shell instead of the requested step. # the "snap" target is a special snowflake that has not made its # way to be a proper step. previous_step = None if pack_project: previous_step = steps.PRIME elif step > steps.PULL: previous_step = step.previous_step() # steps.PULL is the first step, so we would directly shell into it. if previous_step: instance.execute_step(previous_step) elif pack_project: instance.pack_project(output=output) else: instance.execute_step(step) except Exception: if project.debug: instance.shell() else: echo.warning("Run the same command again with --debug to shell into the environment " "if you wish to introspect this failure.") raise else: if shell or shell_after: instance.shell() elif build_environment.is_managed_host or build_environment.is_host: project_config = project_loader.load_config(project) lifecycle.execute(step, project_config, parts) if pack_project: _pack(project.prime_dir, output=output) else: # containerbuild takes a snapcraft command name, not a step lifecycle.containerbuild(command=step.name, project=project, args=parts) if pack_project: _pack(project.prime_dir, output=output) return project
def _execute( # noqa: C901 step: steps.Step, parts: str, pack_project: bool = False, output: str = None, shell: bool = False, shell_after: bool = False, destructive_mode: bool = False, **kwargs) -> "Project": # fmt: on _clean_provider_error() provider = "host" if destructive_mode else None build_environment = env.BuilderEnvironmentConfig(force_provider=provider) try: conduct_build_environment_sanity_check(build_environment.provider) except MultipassMissingInstallableError as e: click.echo("You need multipass installed to build snaps " "(https://github.com/CanonicalLtd/multipass).") if click.confirm("Would you like to install it now?"): _install_multipass() else: raise errors.SnapcraftEnvironmentError( "multipass is required to continue.") from e project = get_project(is_managed_host=build_environment.is_managed_host, **kwargs) conduct_project_sanity_check(project) if build_environment.is_managed_host or build_environment.is_host: project_config = project_loader.load_config(project) lifecycle.execute(step, project_config, parts) if pack_project: _pack(project.prime_dir, output=output) else: build_provider_class = build_providers.get_provider_for( build_environment.provider) echo.info("Launching a VM.") with build_provider_class(project=project, echoer=echo) as instance: instance.mount_project() try: if shell: # shell means we want to do everything right up to the previous # step and then go into a shell instead of the requested step. # the "snap" target is a special snowflake that has not made its # way to be a proper step. previous_step = None if pack_project: previous_step = steps.PRIME elif step > steps.PULL: previous_step = step.previous_step() # steps.PULL is the first step, so we would directly shell into it. if previous_step: instance.execute_step(previous_step) elif pack_project: instance.pack_project(output=output) else: instance.execute_step(step) except Exception: _retrieve_provider_error(instance) if project.debug: instance.shell() else: echo.warning( "Run the same command again with --debug to shell into the environment " "if you wish to introspect this failure.") raise else: if shell or shell_after: instance.shell() return project