Skip to content

Commit

Permalink
fix(application): handle clean command project loading
Browse files Browse the repository at this point in the history
Support for outer commands that need project to be loaded.

Signed-off-by: Claudio Matsuoka <[email protected]>
  • Loading branch information
cmatsuoka committed Sep 10, 2023
1 parent 6fc22e8 commit 8bd11bd
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 6 deletions.
3 changes: 3 additions & 0 deletions craft_application/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ def _configure_services(self, build_for: str | None) -> None:
def project(self) -> models.Project:
"""Get this application's Project metadata."""
project_file = (self._work_dir / f"{self.app.name}.yaml").resolve()
craft_cli.emit.debug(f"Loading project file '{project_file!s}'")
return self.app.ProjectClass.from_yaml_file(project_file)

def run_managed(self, build_for: str | None) -> None:
Expand Down Expand Up @@ -268,6 +269,8 @@ def run(self) -> int:
if not command.run_managed:
# command runs in the outer instance
craft_cli.emit.debug(f"Running {self.app.name} {command.name} on host")
if command.always_load_project:
self.services.project = self.project
return_code = dispatcher.run() or 0
elif not self.services.ProviderClass.is_managed():
# command runs in inner instance, but this is the outer instance
Expand Down
3 changes: 3 additions & 0 deletions craft_application/commands/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class AppCommand(BaseCommand):
run_managed: bool = False
"""Whether this command should run in managed mode."""

always_load_project: bool = False
"""The project is also loaded in non-managed mode."""

def __init__(self, config: dict[str, Any]) -> None:
super().__init__(config)
self._app: application.AppMetadata = config["app"]
Expand Down
5 changes: 1 addition & 4 deletions craft_application/commands/lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,7 @@ def run(
) -> None:
"""Run a lifecycle step command."""
super().run(parsed_args)

step_name = step_name or self.name

# resolve build matrix, depending on the environment (managed/manager)

self._services.lifecycle.run(
step_name=step_name,
part_names=parsed_args.parts,
Expand Down Expand Up @@ -272,6 +268,7 @@ class CleanCommand(_LifecyclePartsCommand):
remove the packing environment.
"""
)
always_load_project = True

@override
def run(self, parsed_args: argparse.Namespace) -> None:
Expand Down
4 changes: 3 additions & 1 deletion craft_application/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,6 @@ def effective_base(self) -> Any: # noqa: ANN401 app specific classes can improv

def get_build_plan(self) -> List[BuildInfo]:
"""Obtain the list of architectures and bases from the project file."""
raise NotImplementedError(f"{self.__class__.__name__!s} must implement get_build_plan")
raise NotImplementedError(
f"{self.__class__.__name__!s} must implement get_build_plan"
)
11 changes: 11 additions & 0 deletions tests/integration/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,14 @@ def run(self, parsed_args: argparse.Namespace) -> None:

app.add_command_group("Nothing", [NothingCommand])
app.run()


def test_run_always_load_project(monkeypatch, app):
"""Run a command without having a project instance shall not fail."""
monkeypatch.setenv("CRAFT_DEBUG", "1")
monkeypatch.setattr("sys.argv", ["testcraft", "clean"])

with pytest.raises(FileNotFoundError) as raised:
app.run()

assert str(raised.value).endswith("/testcraft.yaml'") is True
1 change: 0 additions & 1 deletion tests/unit/services/test_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,6 @@ def test_repr(fake_parts_lifecycle, app_metadata, fake_project):
start = f"FakePartsLifecycle({app_metadata!r}, {fake_project!r}, "

actual = repr(fake_parts_lifecycle)
print("=====", actual)

pytest_check.is_true(actual.startswith(start))
pytest_check.is_true(
Expand Down

0 comments on commit 8bd11bd

Please sign in to comment.