From dff704764d77bffbf6cc94c5ba4bb03309da45f8 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sun, 27 Dec 2009 16:30:54 -0500 Subject: [PATCH] Added storage.Storage.storage_version() and command.InvalidStorageVersion. Now commands automatically check for storage version compatibility. --- libbe/command/__init__.py | 4 +++- libbe/command/base.py | 13 +++++++++++++ libbe/storage/__init__.py | 14 +++++++++++++- libbe/storage/base.py | 5 +++++ libbe/storage/util/upgrade.py | 24 +++++++----------------- libbe/storage/vcs/base.py | 14 ++++++++------ libbe/version.py | 4 ++-- 7 files changed, 51 insertions(+), 27 deletions(-) diff --git a/libbe/command/__init__.py b/libbe/command/__init__.py index 916b5ce..ab9d2db 100644 --- a/libbe/command/__init__.py +++ b/libbe/command/__init__.py @@ -19,6 +19,7 @@ import base UserError = base.UserError UnknownCommand = base.UnknownCommand +InvalidStorageVersion = base.InvalidStorageVersion get_command = base.get_command get_command_class = base.get_command_class commands = base.commands @@ -26,5 +27,6 @@ Option = base.Option Argument = base.Argument Command = base.Command -__all__ = [UserError, UnknownCommand, get_command, get_command_class, +__all__ = [UserError, UnknownCommand, InvalidStorageVersion, + get_command, get_command_class, commands, Option, Argument, Command] diff --git a/libbe/command/base.py b/libbe/command/base.py index 6a49413..1409c74 100644 --- a/libbe/command/base.py +++ b/libbe/command/base.py @@ -6,6 +6,7 @@ import os.path import sys import libbe +import libbe.storage import libbe.ui.util.user import libbe.util.encoding import libbe.util.plugin @@ -18,6 +19,15 @@ class UnknownCommand(UserError): Exception.__init__(self, "Unknown command '%s'" % cmd) self.cmd = cmd +class InvalidStorageVersion(UserError): + def __init__(self, active_version, expected_version=None): + if expected_version == None: + expected_version = libbe.storage.STORAGE_VERSION + msg = 'Storage in "%s" not the expected "%s"' \ + % (active_version, expected_version) + UserError.__init__(self, msg) + self.active_version = active_version + self.expected_version = expected_version def get_command(command_name): """Retrieves the module for a user command @@ -354,6 +364,9 @@ class Command (object): if not hasattr(self, '_storage'): self._storage = self._get_unconnected_storage() self._storage.connect() + version = self._storage.storage_version() + if version != libbe.storage.STORAGE_VERSION: + raise InvalidStorageVersion(version) return self._storage def _get_bugdir(self): diff --git a/libbe/storage/__init__.py b/libbe/storage/__init__.py index c58ec34..104b1e1 100644 --- a/libbe/storage/__init__.py +++ b/libbe/storage/__init__.py @@ -10,6 +10,17 @@ NotWriteable = base.NotWriteable NotReadable = base.NotReadable EmptyCommit = base.EmptyCommit +# a list of all past versions +STORAGE_VERSIONS = ['Bugs Everywhere Tree 1 0', + 'Bugs Everywhere Directory v1.1', + 'Bugs Everywhere Directory v1.2', + 'Bugs Everywhere Directory v1.3', + 'Bugs Everywhere Directory v1.4', + ] + +# the current version +STORAGE_VERSION = STORAGE_VERSIONS[-1] + def get_storage(location): """ Return a Storage instance from a repo location string. @@ -21,4 +32,5 @@ def get_storage(location): __all__ = [ConnectionError, InvalidID, InvalidRevision, InvalidDirectory, NotWriteable, NotReadable, - EmptyCommit, get_storage] + EmptyCommit, STORAGE_VERSIONS, STORAGE_VERSION, + get_storage] diff --git a/libbe/storage/base.py b/libbe/storage/base.py index 97c8b29..f32353f 100644 --- a/libbe/storage/base.py +++ b/libbe/storage/base.py @@ -10,6 +10,7 @@ import pickle import types from libbe.error import NotSupported +import libbe.storage from libbe.util.tree import Tree from libbe.util import InvalidObject from libbe import TESTING @@ -133,6 +134,10 @@ class Storage (object): """Return a version string for this backend.""" return '0' + def storage_version(self): + """Return the storage format for this backend.""" + return libbe.storage.STORAGE_VERSION + def is_readable(self): return self.readable and self._readable diff --git a/libbe/storage/util/upgrade.py b/libbe/storage/util/upgrade.py index ce6831d..20ef1e4 100644 --- a/libbe/storage/util/upgrade.py +++ b/libbe/storage/util/upgrade.py @@ -25,6 +25,7 @@ import sys import libbe import libbe.bug import libbe.storage.util.mapfile as mapfile +from libbe.storage import STORAGE_VERSIONS, STORAGE_VERSION #import libbe.storage.vcs # delay import to avoid cyclic dependency import libbe.ui.util.editor import libbe.util @@ -32,17 +33,6 @@ import libbe.util.encoding as encoding import libbe.util.id -# a list of all past versions -BUGDIR_DISK_VERSIONS = ['Bugs Everywhere Tree 1 0', - 'Bugs Everywhere Directory v1.1', - 'Bugs Everywhere Directory v1.2', - 'Bugs Everywhere Directory v1.3', - 'Bugs Everywhere Directory v1.4', - ] - -# the current version -BUGDIR_DISK_VERSION = BUGDIR_DISK_VERSIONS[-1] - class Upgrader (object): "Class for converting between different on-disk BE storage formats." initial_version = None @@ -304,16 +294,16 @@ for upgrader in upgraders: upgrade_classes[(upgrader.initial_version,upgrader.final_version)]=upgrader def upgrade(path, current_version, - target_version=BUGDIR_DISK_VERSION): + target_version=STORAGE_VERSION): """ Call the appropriate upgrade function to convert current_version to target_version. If a direct conversion function does not exist, use consecutive conversion functions. """ - if current_version not in BUGDIR_DISK_VERSIONS: + if current_version not in STORAGE_VERSIONS: raise NotImplementedError, \ "Cannot handle version '%s' yet." % current_version - if target_version not in BUGDIR_DISK_VERSIONS: + if target_version not in STORAGE_VERSIONS: raise NotImplementedError, \ "Cannot handle version '%s' yet." % current_version @@ -324,10 +314,10 @@ def upgrade(path, current_version, u.upgrade() else: # consecutive single-step conversion - i = BUGDIR_DISK_VERSIONS.index(current_version) + i = STORAGE_VERSIONS.index(current_version) while True: - version_a = BUGDIR_DISK_VERSIONS[i] - version_b = BUGDIR_DISK_VERSIONS[i+1] + version_a = STORAGE_VERSIONS[i] + version_b = STORAGE_VERSIONS[i+1] try: upgrade_class = upgrade_classes[(version_a, version_b)] except KeyError: diff --git a/libbe/storage/vcs/base.py b/libbe/storage/vcs/base.py index a45f1fe..1df08cf 100644 --- a/libbe/storage/vcs/base.py +++ b/libbe/storage/vcs/base.py @@ -34,6 +34,7 @@ import sys import tempfile import libbe +import libbe.storage import libbe.storage.base import libbe.util.encoding from libbe.storage.base import EmptyCommit, InvalidRevision @@ -652,7 +653,7 @@ os.listdir(self.get_path("bugs")): if not os.path.isdir(self.be_dir): raise libbe.storage.base.ConnectionError(self) self._cached_path_id.connect() - self.check_disk_version() + self.check_storage_version() def disconnect(self): self._cached_path_id.disconnect() @@ -879,18 +880,19 @@ os.listdir(self.get_path("bugs")): f.close() return (summary, body) - def check_disk_version(self): - version = self.disk_version() - if version != upgrade.BUGDIR_DISK_VERSION: + def check_storage_version(self): + version = self.storage_version() + if version != libbe.storage.STORAGE_VERSION: upgrade.upgrade(self.repo, version) - def disk_version(self, path=None): + def storage_version(self, path=None): """ Requires disk access. """ if path == None: path = os.path.join(self.repo, '.be', 'version') - return libbe.util.encoding.get_file_contents(path).rstrip('\n') + return libbe.util.encoding.get_file_contents( + path, decode=True).rstrip('\n') diff --git a/libbe/version.py b/libbe/version.py index 1214b3e..ddff5a5 100644 --- a/libbe/version.py +++ b/libbe/version.py @@ -26,7 +26,7 @@ over the version strings" workflows. import copy import libbe._version as _version -import libbe.storage.util.upgrade as upgrade +import libbe.storage # Manually set a version string (optional, defaults to bzr revision id) #_VERSION = "1.2.3" @@ -43,7 +43,7 @@ def version(verbose=False): string = _version.version_info["revision_id"] if verbose == True: info = copy.copy(_version.version_info) - info['storage'] = upgrade.BUGDIR_DISK_VERSION + info['storage'] = libbe.storage.STORAGE_VERSION string += ("\n" "revision: %(revno)d\n" "nick: %(branch_nick)s\n" -- 2.26.2