Skip to content

Commit

Permalink
fix: parse release-candidate hathor-core versions (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
luislhl committed Dec 11, 2023
1 parent 98b09e9 commit 355d3c4
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
with:
python-version: ${{ matrix.python }}
- name: Install Poetry
run: pipx install poetry
run: pip install poetry
- name: Install Poetry dependencies
run: poetry install -n --no-root -E client
- name: Run linters
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ check: flake8 isort-check mypy

# formatting:

.PHONY: fmt
fmt: isort

.PHONY: isort
isort: $(py_sources) $(py_tests)
isort -ac $^
Expand Down
32 changes: 29 additions & 3 deletions hathorlib/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
import re
from typing import Any, Dict, List, NamedTuple, Optional, cast
from urllib.parse import urljoin

Expand All @@ -21,6 +22,15 @@
logger = get_logger()


# This regex was copied from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
semver_pattern = (
r"(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)"
r"(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
r"(?:\+(?P<metadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?"
)
semver_re = re.compile(semver_pattern)


class BlockTemplate(NamedTuple):
"""Block template."""

Expand All @@ -41,6 +51,8 @@ class HathorVersion(NamedTuple):
major: int
minor: int
patch: int
prerelease: Optional[str] = None
metadata: Optional[str] = None


class HathorClient:
Expand Down Expand Up @@ -73,11 +85,25 @@ def _get_url(self, url: str) -> str:
async def version(self) -> HathorVersion:
"""Return the version of the backend."""
assert self._session is not None

async with self._session.get(self._get_url('version')) as resp:
data = await resp.json()
ver = data['version']
major, minor, patch = ver.split('.')
return HathorVersion(int(major), int(minor), int(patch))
version = data['version']

match = semver_re.match(version)

if match:
result = match.groupdict()

return HathorVersion(
major=int(result['major']),
minor=int(result['minor']),
patch=int(result['patch']),
prerelease=result.get('prerelease'),
metadata=result.get('metadata'),
)
else:
raise RuntimeError(f'Cannot parse version {version}')

async def get_block_template(self, address: Optional[str] = None) -> BlockTemplate:
"""Return a block template."""
Expand Down
48 changes: 48 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
LICENSE file in the root directory of this source tree.
"""

from contextlib import asynccontextmanager
from typing import AsyncIterator
from unittest import IsolatedAsyncioTestCase
from unittest.mock import Mock

Expand Down Expand Up @@ -133,3 +135,49 @@ async def json(self):
'v1a/get_block_template',
params=dict(address='my_address')
)

async def test_version(self) -> None:
# Preparation
versions = [
"1.2.3",
"1.2.3-rc.2",
"1.2.3-rc.2+build.2",
"1.2.3+build.2",
]

class MockResponse:
def __init__(self):
self.status = 200
self.version = None

async def json(self):
return {"version": self.version}

mock_response = MockResponse()
self.client._session = Mock()

@asynccontextmanager
async def get_mock(url: str) -> AsyncIterator[MockResponse]:
yield mock_response

self.client._session.get = get_mock

# Execution
for version in versions:
mock_response.version = version
result = await self.client.version()

# Assertion
self.assertEqual(result.major, 1)
self.assertEqual(result.minor, 2)
self.assertEqual(result.patch, 3)

if version.endswith('-rc.2+build.2'):
self.assertEqual(result.metadata, 'build.2')
self.assertEqual(result.prerelease, 'rc.2')
elif version.endswith('+build.2'):
self.assertEqual(result.metadata, 'build.2')
self.assertIsNone(result.prerelease)
elif version.endswith('-rc.2'):
self.assertIsNone(result.metadata)
self.assertEqual(result.prerelease, 'rc.2')

0 comments on commit 355d3c4

Please sign in to comment.