diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c499eeda..2304c166 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 @@ -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 diff --git a/craft_providers/multipass/multipass.py b/craft_providers/multipass/multipass.py index fc2b5b60..aa25825a 100644 --- a/craft_providers/multipass/multipass.py +++ b/craft_providers/multipass/multipass.py @@ -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] + + return parsed_version >= minimum_version def launch( self, diff --git a/docs/reference/changelog.rst b/docs/reference/changelog.rst index 41df5f3e..3f5ff63d 100644 --- a/docs/reference/changelog.rst +++ b/docs/reference/changelog.rst @@ -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 diff --git a/pyproject.toml b/pyproject.toml index 8abbf562..8e464181 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,18 +35,18 @@ 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", @@ -54,13 +54,13 @@ lint = [ "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" ] diff --git a/tests/unit/multipass/test_multipass.py b/tests/unit/multipass/test_multipass.py index 2c3722d8..a4014502 100644 --- a/tests/unit/multipass/test_multipass.py +++ b/tests/unit/multipass/test_multipass.py @@ -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 @@ -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): diff --git a/tox.ini b/tox.ini index 72190f87..99fa0f64 100644 --- a/tox.ini +++ b/tox.ini @@ -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.