-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Redesigning
protostar.toml
6 — Version checker (#858)
Currently, `protostar_version` is not properly handled by Protostar. It shouldn't be used to detect the version of the configuration file (v1, v2), but help a development team that uses Protostar to use compatible versions. ### Use case Let's say we introduce a new cheatcode in Protostar v0.5. Alice upgraded Protostar and uses Protostar v0.5. Bob uses Protostar v0.4. Alice uses the new cheatcode and integrates her code with the mainline. Bob pulls the mainline and runs the code that uses the new cheatcode. #### Note: We should bump the minor (not micro) if forward compatibility is no preserved (e.g. new cheatcode). ### Current behavior Protostar crashes for Bob. ### Expected behavior 1. Protostar tells Alice to update the declared version in the configuration file. 2. Protostar tells Bob to upgrade Protostar.
- Loading branch information
1 parent
bf20a7b
commit d835da0
Showing
8 changed files
with
154 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from .protostar_compatibility_with_project_checker import ( | ||
DeclaredProtostarVersionProviderProtocol, | ||
ProtostarVersion, | ||
parse_protostar_version, | ||
) |
56 changes: 56 additions & 0 deletions
56
protostar/self/protostar_compatibility_with_project_checker.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from enum import Enum, auto | ||
from typing import Optional, Protocol | ||
|
||
from packaging import version | ||
|
||
ProtostarVersion = version.Version | ||
|
||
|
||
class DeclaredProtostarVersionProviderProtocol(Protocol): | ||
def get_declared_protostar_version(self) -> Optional[ProtostarVersion]: | ||
... | ||
|
||
|
||
class ProtostarVersionProviderProtocol(Protocol): | ||
def get_protostar_version(self) -> ProtostarVersion: | ||
... | ||
|
||
|
||
class CompatibilityCheckResult(Enum): | ||
COMPATIBLE = auto() | ||
OUTDATED_PROTOSTAR = auto() | ||
OUTDATED_DECLARED_VERSION = auto() | ||
FAILURE = auto() | ||
|
||
|
||
class ProtostarCompatibilityWithProjectChecker: | ||
def __init__( | ||
self, | ||
protostar_version_provider: ProtostarVersionProviderProtocol, | ||
declared_protostar_version_provider: DeclaredProtostarVersionProviderProtocol, | ||
) -> None: | ||
self._protostar_version_provider = protostar_version_provider | ||
self._declared_protostar_version_provider = declared_protostar_version_provider | ||
|
||
def check_compatibility(self) -> CompatibilityCheckResult: | ||
protostar_version = self._protostar_version_provider.get_protostar_version() | ||
declared_protostar_version = ( | ||
self._declared_protostar_version_provider.get_declared_protostar_version() | ||
) | ||
if declared_protostar_version is None: | ||
return CompatibilityCheckResult.FAILURE | ||
if ( | ||
declared_protostar_version.major == protostar_version.major | ||
and declared_protostar_version.minor == protostar_version.minor | ||
and declared_protostar_version.micro <= protostar_version.micro | ||
): | ||
return CompatibilityCheckResult.COMPATIBLE | ||
if declared_protostar_version < protostar_version: | ||
return CompatibilityCheckResult.OUTDATED_DECLARED_VERSION | ||
return CompatibilityCheckResult.OUTDATED_PROTOSTAR | ||
|
||
|
||
def parse_protostar_version(value: str) -> ProtostarVersion: | ||
result = version.parse(value) | ||
assert isinstance(result, ProtostarVersion) | ||
return result |
62 changes: 62 additions & 0 deletions
62
protostar/self/protostar_compatibility_with_project_checker_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import pytest | ||
|
||
from .protostar_compatibility_with_project_checker import ( | ||
CompatibilityCheckResult, | ||
DeclaredProtostarVersionProviderProtocol, | ||
ProtostarCompatibilityWithProjectChecker, | ||
ProtostarVersionProviderProtocol, | ||
parse_protostar_version, | ||
) | ||
|
||
|
||
class DeclaredProtostarVersionProviderDouble(DeclaredProtostarVersionProviderProtocol): | ||
def __init__(self, declared_protostar_version_str: str): | ||
self._declared_protostar_version_str = declared_protostar_version_str | ||
|
||
def get_declared_protostar_version(self): | ||
return parse_protostar_version(self._declared_protostar_version_str) | ||
|
||
|
||
class ProtostarVersionProviderDouble(ProtostarVersionProviderProtocol): | ||
def __init__(self, protostar_version_str: str): | ||
self._protostar_version_str = protostar_version_str | ||
|
||
def get_protostar_version(self): | ||
return parse_protostar_version(self._protostar_version_str) | ||
|
||
|
||
@pytest.fixture(name="declared_protostar_version_provider") | ||
def declared_protostar_version_provider_fixture(declared_protostar_version: str): | ||
return DeclaredProtostarVersionProviderDouble(declared_protostar_version) | ||
|
||
|
||
@pytest.fixture(name="protostar_version_provider") | ||
def protostar_version_provider_fixture(protostar_version: str): | ||
return ProtostarVersionProviderDouble(protostar_version) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"protostar_version, declared_protostar_version, is_compatible", | ||
( | ||
("0.1.2", "0.1.2", CompatibilityCheckResult.COMPATIBLE), | ||
("0.1.2", "0.1.1", CompatibilityCheckResult.COMPATIBLE), | ||
("1.0.0", "1.0.0", CompatibilityCheckResult.COMPATIBLE), | ||
("0.1.1", "0.1.2", CompatibilityCheckResult.OUTDATED_PROTOSTAR), | ||
("1.0.0", "1.1.0", CompatibilityCheckResult.OUTDATED_PROTOSTAR), | ||
("0.2.0", "0.1.2", CompatibilityCheckResult.OUTDATED_DECLARED_VERSION), | ||
("1.0.0", "0.9.0", CompatibilityCheckResult.OUTDATED_DECLARED_VERSION), | ||
), | ||
) | ||
def test_compatibility( | ||
declared_protostar_version_provider: DeclaredProtostarVersionProviderProtocol, | ||
protostar_version_provider: ProtostarVersionProviderProtocol, | ||
is_compatible: bool, | ||
): | ||
compatibility_checker = ProtostarCompatibilityWithProjectChecker( | ||
protostar_version_provider, | ||
declared_protostar_version_provider, | ||
) | ||
|
||
result = compatibility_checker.check_compatibility() | ||
|
||
assert result == is_compatible |