Skip to content

Commit

Permalink
Use integer schema version numbers (#688)
Browse files Browse the repository at this point in the history
* Change schema versioning to use integer strings.

* Switch from int strings to pure ints.

* Update signac/contrib/migration/__init__.py

Co-authored-by: Bradley Dice <[email protected]>

Co-authored-by: Bradley Dice <[email protected]>
  • Loading branch information
vyasr and bdice committed Jun 14, 2022
1 parent 955a19a commit 700ca4a
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 34 deletions.
36 changes: 13 additions & 23 deletions signac/contrib/migration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import sys

from filelock import FileLock
from packaging import version

from ...version import SCHEMA_VERSION, __version__
from .v0_to_v1 import _load_config_v1, _migrate_v0_to_v1
Expand All @@ -25,20 +24,17 @@
# writeable, i.e. it must be possible to persist in-memory changes from these
# objects to the underlying config files.
_CONFIG_LOADERS = {
"1": _load_config_v1,
"2": _load_config_v2,
1: _load_config_v1,
2: _load_config_v2,
}


_MIGRATIONS = {
("0", "1"): _migrate_v0_to_v1,
("1", "2"): _migrate_v1_to_v2,
(0, 1): _migrate_v0_to_v1,
(1, 2): _migrate_v1_to_v2,
}

_PARSED_SCHEMA_VERSION = version.parse(SCHEMA_VERSION)


_VERSION_LIST = list(reversed(sorted(version.parse(v) for v in _CONFIG_LOADERS.keys())))
_VERSION_LIST = list(reversed(sorted(_CONFIG_LOADERS.keys())))


def _get_config_schema_version(root_directory, version_guess):
Expand All @@ -52,26 +48,24 @@ def _get_config_schema_version(root_directory, version_guess):
# Note: We could consider using a different component as the key
# for _CONFIG_LOADERS, but since this is an internal detail it's
# not terribly consequential.
config = _CONFIG_LOADERS[guess.public](root_directory)
config = _CONFIG_LOADERS[guess](root_directory)
break
except Exception:
# The load failed, go to the next
pass
else:
raise RuntimeError("Unable to load config file.")
try:
return version.parse(config["schema_version"])
return int(config["schema_version"])
except KeyError:
# The default schema version is version 0.
return version.parse("0")
return 0


def _collect_migrations(root_directory):
schema_version = _PARSED_SCHEMA_VERSION
schema_version = int(SCHEMA_VERSION)

current_schema_version = _get_config_schema_version(
root_directory, _PARSED_SCHEMA_VERSION
)
current_schema_version = _get_config_schema_version(root_directory, schema_version)
if current_schema_version > schema_version:
# Project config schema version is newer and therefore not supported.
raise RuntimeError(
Expand All @@ -84,11 +78,9 @@ def _collect_migrations(root_directory):
guess = current_schema_version
while _get_config_schema_version(root_directory, guess) < schema_version:
for (origin, destination), migration in _MIGRATIONS.items():
if version.parse(origin) == _get_config_schema_version(
root_directory, guess
):
if origin == _get_config_schema_version(root_directory, guess):
yield (origin, destination), migration
guess = version.parse(destination)
guess = destination
break
else:
raise RuntimeError(
Expand Down Expand Up @@ -129,9 +121,7 @@ def apply_migrations(root_directory):
f"Failed to apply migration {destination}."
) from e
else:
config = _CONFIG_LOADERS[version.parse(destination).public](
root_directory
)
config = _CONFIG_LOADERS[destination](root_directory)
config["schema_version"] = destination
config.write()

Expand Down
4 changes: 2 additions & 2 deletions signac/contrib/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,8 @@ def _check_schema_compatibility(self):
If the schema version is incompatible.
"""
schema_version = version.parse(SCHEMA_VERSION)
config_schema_version = version.parse(self.config["schema_version"])
schema_version = SCHEMA_VERSION
config_schema_version = int(self.config["schema_version"])
if config_schema_version > schema_version:
# Project config schema version is newer and therefore not supported.
raise IncompatibleSchemaVersion(
Expand Down
2 changes: 1 addition & 1 deletion signac/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

__version__ = "1.7.0"

SCHEMA_VERSION = "2"
SCHEMA_VERSION = 2


__all__ = [
Expand Down
8 changes: 0 additions & 8 deletions tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -2460,14 +2460,6 @@ def test_project_schema_versions(self):
with pytest.raises(RuntimeError):
apply_migrations(self.project.root_directory())

# Ensure that migration fails on an invalid version.
invalid_schema_version = "0.5"
config = read_config_file(_get_project_config_fn(self.project.root_directory()))
config["schema_version"] = invalid_schema_version
config.write()
with pytest.raises(RuntimeError):
apply_migrations(self.project.root_directory())

def test_no_migration(self):
# This unit test should fail as long as there are no schema migrations
# implemented within the signac.contrib.migration package.
Expand Down

0 comments on commit 700ca4a

Please sign in to comment.