def __init__( self, all_parts: Dict[str, Any], *, work_dir: pathlib.Path, project_dir: pathlib.Path, project_name: str, ignore_local_sources: List[str], ): self._all_parts = all_parts.copy() self._project_dir = project_dir # set the cache dir for parts package management cache_dir = BaseDirectory.save_cache_path("charmcraft") try: self._lcm = LifecycleManager( {"parts": all_parts}, application_name="charmcraft", work_dir=work_dir, cache_dir=cache_dir, ignore_local_sources=ignore_local_sources, project_name=project_name, ) except PartsError as err: raise CraftError(f"Error bootstrapping lifecycle manager: {err}") from err
def _do_clean(lf: craft_parts.LifecycleManager, options: argparse.Namespace) -> None: if options.plan_only: raise ValueError("Clean operations cannot be planned.") if not options.parts: print("Clean all parts.") lf.clean(None, options.parts) if _LAYER_DIR.is_dir(): shutil.rmtree(_LAYER_DIR)
def __init__( self, all_parts: Dict[str, Any], *, work_dir: pathlib.Path, ignore_local_sources: List[str], ): self._all_parts = all_parts.copy() # set the cache dir for parts package management cache_dir = BaseDirectory.save_cache_path("charmcraft") try: self._lcm = LifecycleManager( {"parts": all_parts}, application_name="charmcraft", work_dir=work_dir, cache_dir=cache_dir, ignore_local_sources=ignore_local_sources, ) self._lcm.refresh_packages_list() except PartsError as err: raise CommandError(err)
def _do_step(lf: craft_parts.LifecycleManager, options: argparse.Namespace) -> None: target_step = _parse_step(options.command) if options.command else Step.PRIME part_names = vars(options).get("parts", []) if options.update: lf.update() actions = lf.plan(target_step, part_names) if options.plan_only: printed = False for a in actions: if a.type != ActionType.SKIP: print(_action_message(a)) printed = True if not printed: print("No actions to execute.") sys.exit() with lf.execution_context() as ctx: for a in actions: if a.type != ActionType.SKIP: print(f"Execute: {_action_message(a)}") ctx.execute(a)
class PartsLifecycle: """Create and manage the parts lifecycle.""" def __init__( self, all_parts: Dict[str, Any], *, work_dir: pathlib.Path, ignore_local_sources: List[str], ): self._all_parts = all_parts.copy() # set the cache dir for parts package management cache_dir = BaseDirectory.save_cache_path("charmcraft") try: self._lcm = LifecycleManager( {"parts": all_parts}, application_name="charmcraft", work_dir=work_dir, cache_dir=cache_dir, ignore_local_sources=ignore_local_sources, ) self._lcm.refresh_packages_list() except PartsError as err: raise CommandError(err) @property def prime_dir(self) -> pathlib.Path: """Return the parts prime directory path.""" return self._lcm.project_info.prime_dir def run(self, target_step: Step) -> None: """Run the parts lifecycle. :param target_step: The final step to execute. """ try: # invalidate build if packing a charm and entrypoint changed if "charm" in self._all_parts: charm_part = self._all_parts["charm"] entrypoint = os.path.normpath(charm_part["charm-entrypoint"]) dis_entrypoint = os.path.normpath( _get_dispatch_entrypoint(self.prime_dir)) if entrypoint != dis_entrypoint: self._lcm.clean(Step.BUILD, part_names=["charm"]) self._lcm.reload_state() actions = self._lcm.plan(target_step) logger.debug("Parts actions: %s", actions) with self._lcm.action_executor() as aex: aex.execute(actions) except RuntimeError as err: raise RuntimeError( f"Parts processing internal error: {err}") from err except OSError as err: msg = err.strerror if err.filename: msg = f"{err.filename}: {msg}" raise CommandError(f"Parts processing error: {msg}") from err except Exception as err: raise CommandError(f"Parts processing error: {err}") from err
class PartsLifecycle: """Create and manage the parts lifecycle. :param all_parts: A dictionary containing the parts defined in the project. :param work_dir: The working directory for parts processing. :param project_dir: The directory containing the charm project. :param ignore_local_sources: A list of local source patterns to be ignored. :param name: Charm name as defined in ``metadata.yaml``. """ def __init__( self, all_parts: Dict[str, Any], *, work_dir: pathlib.Path, project_dir: pathlib.Path, project_name: str, ignore_local_sources: List[str], ): self._all_parts = all_parts.copy() self._project_dir = project_dir # set the cache dir for parts package management cache_dir = BaseDirectory.save_cache_path("charmcraft") try: self._lcm = LifecycleManager( {"parts": all_parts}, application_name="charmcraft", work_dir=work_dir, cache_dir=cache_dir, ignore_local_sources=ignore_local_sources, project_name=project_name, ) except PartsError as err: raise CraftError(f"Error bootstrapping lifecycle manager: {err}") from err @property def prime_dir(self) -> pathlib.Path: """Return the parts prime directory path.""" return self._lcm.project_info.prime_dir def run(self, target_step: Step) -> None: """Run the parts lifecycle. :param target_step: The final step to execute. :raises CraftError: On error during lifecycle ops. :raises RuntimeError: On unexpected error. """ previous_dir = os.getcwd() try: os.chdir(self._project_dir) # invalidate build if packing a charm and entrypoint changed if "charm" in self._all_parts: charm_part = self._all_parts["charm"] if charm_part.get("plugin") == "charm": entrypoint = os.path.normpath(charm_part["charm-entrypoint"]) dis_entrypoint = os.path.normpath(_get_dispatch_entrypoint(self.prime_dir)) if entrypoint != dis_entrypoint: self._lcm.clean(Step.BUILD, part_names=["charm"]) self._lcm.reload_state() emit.trace(f"Executing parts lifecycle in {str(self._project_dir)!r}") actions = self._lcm.plan(target_step) emit.trace(f"Parts actions: {actions}") with self._lcm.action_executor() as aex: for action in actions: emit.progress(f"Running step {action.step.name} for part {action.part_name!r}") with emit.open_stream("Execute action") as stream: aex.execute([action], stdout=stream, stderr=stream) except RuntimeError as err: raise RuntimeError(f"Parts processing internal error: {err}") from err except OSError as err: msg = err.strerror if err.filename: msg = f"{err.filename}: {msg}" raise CraftError(f"Parts processing error: {msg}") from err except Exception as err: raise CraftError(f"Parts processing error: {err}") from err finally: os.chdir(previous_dir)