Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(multipass): parse dev multipass versions #662

Merged
merged 10 commits into from
Sep 26, 2024
7 changes: 4 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: "v4.6.0"
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -13,16 +13,17 @@ repos:
- id: fix-byte-order-marker
- id: mixed-line-ending
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.6.3"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/psf/black
# renovate: datasource=pypi;depName=black
rev: "23.3.0"
rev: "24.8.0"
hooks:
- id: black
- repo: https://github.com/adrienverge/yamllint.git
# renovate: datasource=pypi;depName=yamllint
rev: "v1.31.0"
rev: "v1.35.1"
hooks:
- id: yamllint
12 changes: 11 additions & 1 deletion craft_providers/multipass/multipass.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,17 @@ def is_supported_version(self) -> bool:
minimum_version = packaging.version.parse(self.minimum_required_version)
version, _ = self.version()

return packaging.version.parse(version) >= minimum_version
parsed_version = None
while parsed_version is None:
try:
parsed_version = packaging.version.parse(version)
except packaging.version.InvalidVersion:
# This catches versions such as: 1.15.0-dev.2929.pr661, which are
# compliant, but not pep440 compliant. We can lob off sections until
# we get a pep440 cempliant version.
version = version.rpartition(".")[0]
lengau marked this conversation as resolved.
Show resolved Hide resolved

return parsed_version >= minimum_version

def launch(
self,
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Changelog
See the `Releases page`_ on GitHub for a complete list of commits that are
included in each version.

2.0.2 (2024-09-26)
------------------
- Improve multipass version parsing

2.0.1 (2024-08-28)
------------------
- Require Multipass>=1.14.1 when launching Ubuntu 24.04 (Noble) VMs, which
Expand Down
14 changes: 7 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,32 @@ dev = [
"freezegun==1.5.1",
"logassert==7",
"pyfakefs==5.4.1",
"pytest==8.3.2",
"pytest==8.3.3",
"pytest-cov==5.0.0",
"pytest-mock==3.14.0",
"pytest-rerunfailures==14.0",
"pytest-subprocess==1.5.2",
"pytest-xdist==3.6.1",
"pytest-time==0.3.1",
"pytest-time==0.3.2",
"responses==0.25.3",
# types-requests>=2.31.0.7 requires urllib3>=2
"types-requests==2.31.0.6",
"types-setuptools==73.0.0.20240822",
"types-pyyaml==6.0.12.20240808",
"types-pyyaml==6.0.12.20240917",
]
lint = [
"black==24.8.0",
"codespell[toml]==2.3.0",
"yamllint==1.35.1",
]
types = [
"mypy[reports]==1.11.1",
"pyright==1.1.377",
"mypy[reports]==1.11.2",
"pyright==1.1.381",
]
docs = [
"pyspelling==2.10",
"sphinx-autobuild==2024.4.16",
"sphinx-lint==0.9.1",
"sphinx-autobuild==2024.9.19",
"sphinx-lint==1.0.0",
"sphinx-tabs==3.4.5",
"canonical-sphinx~=0.1"
]
Expand Down
37 changes: 29 additions & 8 deletions tests/unit/multipass/test_multipass.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,20 +201,31 @@ def test_info_error(fake_process, mock_details_from_process_error):
)


def test_is_supported_version(fake_process):
fake_process.register_subprocess(
["multipass", "version"], stdout=b"multipass 1.7.0\nmultipassd 1.7.0\n"
)
@pytest.mark.parametrize(
"version_output",
[
b"multipass 1.7.0\nmultipassd 1.7.0\n",
b"multipass 1.15.0-dev.354+g533e02ffc\nmultipassd 1.15.0-dev.354+g533e02ffc\n", # Snap multipass, edge channel
b"multipass 1.15.0-dev.2929.pr661+gc67ef6641.mac\nmultipassd 1.15.0-dev.2929.pr661+gc67ef6641.mac", # Dev build on a mac
],
)
def test_is_supported_version(fake_process, version_output):
fake_process.register_subprocess(["multipass", "version"], stdout=version_output)

assert Multipass().is_supported_version() is True

assert len(fake_process.calls) == 1


def test_is_supported_version_false(fake_process):
fake_process.register_subprocess(
["multipass", "version"], stdout=b"multipass 1.4.0\nmultipassd 1.4.0\n"
)
@pytest.mark.parametrize(
"version_output",
[
b"multipass 1.4.0\nmultipassd 1.4.0\n",
b"multipass 1.invalid.15.999\nmultipassd 999\n",
],
)
def test_is_supported_version_false(fake_process, version_output):
fake_process.register_subprocess(["multipass", "version"], stdout=version_output)

assert Multipass().is_supported_version() is False

Expand Down Expand Up @@ -718,6 +729,16 @@ def test_wait_until_ready_timeout_error(
),
("1.6.2", "1.6.3"),
),
pytest.param(
b"multipass 1.15.0-dev.354+g533e02ffc\nmultipassd 1.15.0-dev.354+g533e02ffc\n",
("1.15.0-dev.354", "1.15.0-dev.354"),
id="snap-edge-channel",
),
pytest.param(
b"multipass 1.15.0-dev.2929.pr661+gc67ef6641.mac\nmultipassd 1.15.0-dev.2929.pr661+gc67ef6641.mac",
("1.15.0-dev.2929.pr661", "1.15.0-dev.2929.pr661"),
id="macos-dev-build",
),
],
)
def test_version(fake_process, output, expected):
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ requires =
# renovate: datasource=pypi
tox-ignore-env-name-mismatch>=0.2.0.post2
# renovate: datasource=pypi
tox-gh==1.3.2
tox-gh==1.4.1
# Allow tox to access the user's $TMPDIR environment variable if set.
# This workaround is required to avoid circular dependencies for TMPDIR,
# since tox will otherwise attempt to use the environment's TMPDIR variable.
Expand Down
Loading