Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion craft_application/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,6 @@ def run_managed(self, platform: str | None, build_for: str | None) -> None:

with self.services.provider.instance(
build_info,
work_dir=self._work_dir,
clean_existing=self._enable_fetch_service,
) as instance:
if self._enable_fetch_service:
Expand Down
14 changes: 12 additions & 2 deletions craft_application/services/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import sys
import urllib.request
from collections.abc import Generator, Iterable, Sequence
import warnings
from collections.abc import Generator, Iterable
from pathlib import Path
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -136,7 +138,7 @@ def instance(
self,
build_info: craft_platforms.BuildInfo,
*,
work_dir: pathlib.Path,
work_dir: pathlib.Path | None = None,
allow_unstable: bool = True,
clean_existing: bool = False,
project_name: str | None = None,
Expand All @@ -145,12 +147,20 @@ def instance(
"""Context manager for getting a provider instance.

:param build_info: Build information for the instance.
:param work_dir: Local path to mount inside the provider instance.
:param work_dir: (DEPRECATED) Local path to mount inside the provider instance.
:param allow_unstable: Whether to allow the use of unstable images.
:param clean_existing: Whether pre-existing instances should be wiped
and re-created.
:returns: a context manager of the provider instance.
"""
if work_dir is not None:
warnings.warn(
"work_dir is deprecated. Use the service's work dir instead.",
DeprecationWarning,
stacklevel=3,
)
else:
work_dir = self._work_dir
if not project_name:
project_name = self._services.get("project").get().name
instance_name = self._get_instance_name(work_dir, build_info, project_name)
Expand Down
12 changes: 7 additions & 5 deletions docs/reference/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ Changelog
5.4.0 (2025-MM-DD)
------------------

Services
========

- Deprecate the ``work_dir`` parameter on :meth:`ProviderService.instance`. The
parameter is still used if provided, but is now optional. It will be removed in
a future release.

Models
======

Expand Down Expand Up @@ -63,15 +70,10 @@ Commands

- The ``test`` command now accepts paths to specific tests as well as the
``--debug``, ``--shell`` and ``--shell-after`` parameters.
=======
4.x.x (YYYY-MMM-DD)
-------------------
>>>>>>> 7e225ac (feat(models): expose Part type)

Models
======

<<<<<<< HEAD
- A new :doc:`how-to guide </howto/platforms>` describes how to implement
application-specific ``platforms`` keys.

Expand Down
24 changes: 19 additions & 5 deletions tests/unit/services/test_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ def test_instance(
mock_capture_pack_state,
):
with provider_service.instance(
fake_build_info, work_dir=tmp_path, allow_unstable=allow_unstable
fake_build_info, allow_unstable=allow_unstable
) as instance:
pass

Expand All @@ -645,6 +645,22 @@ def test_instance(
emitter.assert_progress("Launching managed .+ instance...", regex=True)


def test_instance_work_dir_deprecated(provider_service, mock_provider):
arch = util.get_host_architecture()
build_info = models.BuildInfo("foo", arch, arch, bases.BaseName("ubuntu", "24.04"))
with pytest.warns(DeprecationWarning, match="work_dir is deprecated"):
with provider_service.instance(build_info, work_dir=pathlib.Path("/")):
pass

mock_provider.launched_environment.assert_called_once_with(
project_name=mock.ANY,
project_path=pathlib.Path("/"),
instance_name=mock.ANY,
base_configuration=mock.ANY,
allow_unstable=True,
)


@pytest.mark.parametrize("clean_existing", [True, False])
def test_instance_clean_existing(
tmp_path,
Expand All @@ -658,7 +674,7 @@ def test_instance_clean_existing(
build_info = craft_platforms.BuildInfo("foo", arch, arch, base_name)

with provider_service.instance(
build_info, work_dir=tmp_path, clean_existing=clean_existing
build_info, clean_existing=clean_existing
) as _instance:
pass

Expand Down Expand Up @@ -705,7 +721,7 @@ def test_load_bashrc_missing(

mocker.patch.object(pkgutil, "get_data", return_value=None)
with provider_service.instance(
fake_build_info, work_dir=tmp_path, allow_unstable=allow_unstable
fake_build_info, allow_unstable=allow_unstable
) as instance:
instance._setup_instance_bashrc(instance)
emitter.assert_debug(
Expand Down Expand Up @@ -771,7 +787,6 @@ def test_instance_fetch_logs(
with (
provider_service.instance(
build_info=fake_build_info,
work_dir=pathlib.Path(),
) as mock_instance,
):
pass
Expand Down Expand Up @@ -832,7 +847,6 @@ def test_instance_fetch_logs_missing_file(
provider_service = setup_fetch_logs_provider(should_have_logfile=False)
with provider_service.instance(
build_info=fake_build_info,
work_dir=pathlib.Path(),
) as mock_instance:
pass

Expand Down
Loading