From 830522c293a479636d7bfc0fff125ec57f06e9a3 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 31 Aug 2009 12:32:05 -0400 Subject: Added libbe/upgrade.py to handle upgrading on-disk bugdirs. --- libbe/upgrade.py | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 libbe/upgrade.py (limited to 'libbe/upgrade.py') diff --git a/libbe/upgrade.py b/libbe/upgrade.py new file mode 100644 index 0000000..a31d6df --- /dev/null +++ b/libbe/upgrade.py @@ -0,0 +1,135 @@ +# Copyright (C) 2009 W. Trevor King +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +""" +Handle conversion between the various on-disk images. +""" + +import os, os.path +import sys +import doctest + +import encoding +import mapfile +import rcs + +# a list of all past versions +BUGDIR_DISK_VERSIONS = ["Bugs Everywhere Tree 1 0", + "Bugs Everywhere Directory v2"] + +# the current version +BUGDIR_DISK_VERSION = BUGDIR_DISK_VERSIONS[-1] + +class Upgrader (object): + "Class for converting " + initial_version = None + final_version = None + def __init__(self, root): + self.root = root + # use the "None" RCS to ensure proper encoding/decoding and + # simplify path construction. + self.rcs = rcs.rcs_by_name("None") + self.rcs.root(self.root) + self.rcs.encoding = encoding.get_encoding() + + def get_path(self, *args): + """ + Return a path relative to .root. + """ + dir = os.path.join(self.root, ".be") + if len(args) == 0: + return dir + assert args[0] in ["version", "settings", "bugs"], str(args) + return os.path.join(dir, *args) + + def check_initial_version(self): + path = self.get_path("version") + version = self.rcs.get_file_contents(path).rstrip("\n") + assert version == self.initial_version, version + + def set_version(self): + path = self.get_path("version") + self.rcs.set_file_contents(path, self.final_version+"\n") + + def upgrade(self): + print >> sys.stderr, "upgrading bugdir from '%s' to '%s'" \ + % (self.initial_version, self.final_version) + self.check_initial_version() + self.set_version() + self._upgrade() + + def _upgrade(self): + raise NotImplementedError + +class Upgrade_1_0_to_2 (Upgrader): + initial_version = "Bugs Everywhere Tree 1 0" + final_version = "Bugs Everywhere Directory v2" + def _upgrade(self): + for bug_uuid in os.listdir(self.get_path("bugs")): + c_path = ["bugs", bug_uuid, "comments"] + if not os.path.exists(self.get_path(*c_path)): + continue # no comments for this bug + for comment_uuid in os.listdir(self.get_path(*c_path)): + path_list = c_path + [comment_uuid, "values"] + path = self.get_path(*path_list) + settings = mapfile.map_load(self.rcs, path) + if "From" in settings: + settings["Author"] = settings.pop("From") + mapfile.map_save(self.rcs, path, settings) + +upgraders = [Upgrade_1_0_to_2] +upgrade_classes = {} +for upgrader in upgraders: + upgrade_classes[(upgrader.initial_version,upgrader.final_version)]=upgrader + +def upgrade(path, current_version, + target_version=BUGDIR_DISK_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: + raise NotImplementedError, \ + "Cannot handle version '%s' yet." % version + if target_version not in BUGDIR_DISK_VERSIONS: + raise NotImplementedError, \ + "Cannot handle version '%s' yet." % version + + if (current_version, target_version) in upgrade_classes: + # direct conversion + upgrade_class = upgrade_classes[(current_version, target_version)] + u = upgrade_class(path) + u.upgrade() + else: + # consecutive single-step conversion + i = BUGDIR_DISK_VERSIONS.index(current_version) + while True: + version_a = BUGDIR_DISK_VERSIONS[i] + version_b = BUGDIR_DISK_VERSIONS[i+1] + try: + upgrade_class = upgrade_classes[(version_a, version_b)] + except KeyError: + raise NotImplementedError, \ + "Cannot convert version '%s' to '%s' yet." \ + % (version_a, version_b) + u = upgrade_class(path) + u.upgrade() + if version_b == target_version: + break + i += 1 + +suite = doctest.DocTestSuite() -- cgit From 5e8576a48fae6e9f7a9699d57571e926d7e6e236 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 31 Aug 2009 13:16:48 -0400 Subject: Upgrade duplicate bugdirs if necessary (e.g. for `be diff'). Also moved pre-YAML mapfile handling in mapfile.parse() into upgrade.Upgrade_1_0_to_2._upgrade_mapfile(). --- libbe/upgrade.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'libbe/upgrade.py') diff --git a/libbe/upgrade.py b/libbe/upgrade.py index a31d6df..215dbce 100644 --- a/libbe/upgrade.py +++ b/libbe/upgrade.py @@ -74,22 +74,58 @@ class Upgrader (object): def _upgrade(self): raise NotImplementedError + class Upgrade_1_0_to_2 (Upgrader): initial_version = "Bugs Everywhere Tree 1 0" final_version = "Bugs Everywhere Directory v2" + def _upgrade_mapfile(self, path): + contents = self.rcs.get_file_contents(path) + old_format = False + for line in contents.splitlines(): + if len(line.split("=")) == 2: + old_format = True + break + if old_format == True: + # translate to YAML. + newlines = [] + for line in contents.splitlines(): + line = line.rstrip('\n') + if len(line) == 0: + continue + fields = line.split("=") + if len(fields) == 2: + key,value = fields + newlines.append('%s: "%s"' % (key, value.replace('"','\\"'))) + else: + newlines.append(line) + contents = '\n'.join(newlines) + # load the YAML and save + map = mapfile.parse(contents) + mapfile.map_save(self.rcs, path, map) + def _upgrade(self): + """ + Comment value field "From" -> "Author". + Homegrown mapfile -> YAML. + """ + path = self.get_path("settings") + self._upgrade_mapfile(path) for bug_uuid in os.listdir(self.get_path("bugs")): + path = self.get_path("bugs", bug_uuid, "values") + self._upgrade_mapfile(path) c_path = ["bugs", bug_uuid, "comments"] if not os.path.exists(self.get_path(*c_path)): continue # no comments for this bug for comment_uuid in os.listdir(self.get_path(*c_path)): path_list = c_path + [comment_uuid, "values"] path = self.get_path(*path_list) + self._upgrade_mapfile(path) settings = mapfile.map_load(self.rcs, path) if "From" in settings: settings["Author"] = settings.pop("From") mapfile.map_save(self.rcs, path, settings) + upgraders = [Upgrade_1_0_to_2] upgrade_classes = {} for upgrader in upgraders: -- cgit From 61445df504c4267c774d572521a63136c595f007 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 31 Aug 2009 13:18:36 -0400 Subject: Use 'v#.#' for major/minor version in upgrade.BUGDIR_DISK_VERSIONS --- libbe/upgrade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbe/upgrade.py') diff --git a/libbe/upgrade.py b/libbe/upgrade.py index 215dbce..6f14cd8 100644 --- a/libbe/upgrade.py +++ b/libbe/upgrade.py @@ -28,7 +28,7 @@ import rcs # a list of all past versions BUGDIR_DISK_VERSIONS = ["Bugs Everywhere Tree 1 0", - "Bugs Everywhere Directory v2"] + "Bugs Everywhere Directory v1.1"] # the current version BUGDIR_DISK_VERSION = BUGDIR_DISK_VERSIONS[-1] -- cgit From 6d3fc831cdbba47a90b03706f25af1682abe862b Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 31 Aug 2009 13:43:32 -0400 Subject: RCS -> VCS, BUGDIR_DISK_VERSION -> v1.2 --- libbe/upgrade.py | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) (limited to 'libbe/upgrade.py') diff --git a/libbe/upgrade.py b/libbe/upgrade.py index 6f14cd8..4123c72 100644 --- a/libbe/upgrade.py +++ b/libbe/upgrade.py @@ -24,11 +24,12 @@ import doctest import encoding import mapfile -import rcs +import vcs # a list of all past versions BUGDIR_DISK_VERSIONS = ["Bugs Everywhere Tree 1 0", - "Bugs Everywhere Directory v1.1"] + "Bugs Everywhere Directory v1.1", + "Bugs Everywhere Directory v1.2"] # the current version BUGDIR_DISK_VERSION = BUGDIR_DISK_VERSIONS[-1] @@ -39,11 +40,11 @@ class Upgrader (object): final_version = None def __init__(self, root): self.root = root - # use the "None" RCS to ensure proper encoding/decoding and + # use the "None" VCS to ensure proper encoding/decoding and # simplify path construction. - self.rcs = rcs.rcs_by_name("None") - self.rcs.root(self.root) - self.rcs.encoding = encoding.get_encoding() + self.vcs = vcs.vcs_by_name("None") + self.vcs.root(self.root) + self.vcs.encoding = encoding.get_encoding() def get_path(self, *args): """ @@ -57,12 +58,12 @@ class Upgrader (object): def check_initial_version(self): path = self.get_path("version") - version = self.rcs.get_file_contents(path).rstrip("\n") + version = self.vcs.get_file_contents(path).rstrip("\n") assert version == self.initial_version, version def set_version(self): path = self.get_path("version") - self.rcs.set_file_contents(path, self.final_version+"\n") + self.vcs.set_file_contents(path, self.final_version+"\n") def upgrade(self): print >> sys.stderr, "upgrading bugdir from '%s' to '%s'" \ @@ -75,11 +76,11 @@ class Upgrader (object): raise NotImplementedError -class Upgrade_1_0_to_2 (Upgrader): +class Upgrade_1_0_to_1_1 (Upgrader): initial_version = "Bugs Everywhere Tree 1 0" - final_version = "Bugs Everywhere Directory v2" + final_version = "Bugs Everywhere Directory v1.1" def _upgrade_mapfile(self, path): - contents = self.rcs.get_file_contents(path) + contents = self.vcs.get_file_contents(path) old_format = False for line in contents.splitlines(): if len(line.split("=")) == 2: @@ -101,7 +102,7 @@ class Upgrade_1_0_to_2 (Upgrader): contents = '\n'.join(newlines) # load the YAML and save map = mapfile.parse(contents) - mapfile.map_save(self.rcs, path, map) + mapfile.map_save(self.vcs, path, map) def _upgrade(self): """ @@ -120,13 +121,28 @@ class Upgrade_1_0_to_2 (Upgrader): path_list = c_path + [comment_uuid, "values"] path = self.get_path(*path_list) self._upgrade_mapfile(path) - settings = mapfile.map_load(self.rcs, path) + settings = mapfile.map_load(self.vcs, path) if "From" in settings: settings["Author"] = settings.pop("From") - mapfile.map_save(self.rcs, path, settings) + mapfile.map_save(self.vcs, path, settings) -upgraders = [Upgrade_1_0_to_2] +class Upgrade_1_1_to_1_2 (Upgrader): + initial_version = "Bugs Everywhere Directory v1.1" + final_version = "Bugs Everywhere Directory v1.2" + def _upgrade(self): + """ + BugDir settings field "rcs_name" -> "vcs_name". + """ + path = self.get_path("settings") + settings = mapfile.map_load(self.vcs, path) + if "rcs_name" in settings: + settings["vcs_name"] = settings.pop("rcs_name") + mapfile.map_save(self.vcs, path, settings) + + +upgraders = [Upgrade_1_0_to_1_1, + Upgrade_1_1_to_1_2] upgrade_classes = {} for upgrader in upgraders: upgrade_classes[(upgrader.initial_version,upgrader.final_version)]=upgrader -- cgit