aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'cvs2svn_lib/svn_output_option.py')
-rw-r--r--cvs2svn_lib/svn_output_option.py753
1 files changed, 0 insertions, 753 deletions
diff --git a/cvs2svn_lib/svn_output_option.py b/cvs2svn_lib/svn_output_option.py
deleted file mode 100644
index 86d1ba4..0000000
--- a/cvs2svn_lib/svn_output_option.py
+++ /dev/null
@@ -1,753 +0,0 @@
-# (Be in -*- python -*- mode.)
-#
-# ====================================================================
-# Copyright (c) 2000-2009 CollabNet. All rights reserved.
-#
-# This software is licensed as described in the file COPYING, which
-# you should have received as part of this distribution. The terms
-# are also available at http://subversion.tigris.org/license-1.html.
-# If newer versions of this license are posted there, you may use a
-# newer version instead, at your option.
-#
-# This software consists of voluntary contributions made by many
-# individuals. For exact contribution history, see the revision
-# history and logs, available at http://cvs2svn.tigris.org/.
-# ====================================================================
-
-"""Classes for outputting the converted repository to SVN."""
-
-
-import os
-
-from cvs2svn_lib import config
-from cvs2svn_lib.common import InternalError
-from cvs2svn_lib.common import FatalError
-from cvs2svn_lib.common import FatalException
-from cvs2svn_lib.common import error_prefix
-from cvs2svn_lib.common import format_date
-from cvs2svn_lib.common import PathsNotDisjointException
-from cvs2svn_lib.common import verify_paths_disjoint
-from cvs2svn_lib.log import Log
-from cvs2svn_lib.context import Ctx
-from cvs2svn_lib.artifact_manager import artifact_manager
-from cvs2svn_lib.process import CommandFailedException
-from cvs2svn_lib.process import check_command_runs
-from cvs2svn_lib.process import call_command
-from cvs2svn_lib.cvs_file import CVSDirectory
-from cvs2svn_lib.symbol import Trunk
-from cvs2svn_lib.symbol import LineOfDevelopment
-from cvs2svn_lib.cvs_item import CVSRevisionAdd
-from cvs2svn_lib.cvs_item import CVSRevisionChange
-from cvs2svn_lib.cvs_item import CVSRevisionDelete
-from cvs2svn_lib.cvs_item import CVSRevisionNoop
-from cvs2svn_lib.repository_mirror import RepositoryMirror
-from cvs2svn_lib.repository_mirror import PathExistsError
-from cvs2svn_lib.svn_commit_item import SVNCommitItem
-from cvs2svn_lib.openings_closings import SymbolingsReader
-from cvs2svn_lib.fill_source import get_source_set
-from cvs2svn_lib.stdout_delegate import StdoutDelegate
-from cvs2svn_lib.dumpfile_delegate import DumpfileDelegate
-from cvs2svn_lib.repository_delegate import RepositoryDelegate
-from cvs2svn_lib.output_option import OutputOption
-
-
-class SVNOutputOption(OutputOption):
- """An OutputOption appropriate for output to Subversion."""
-
- class ParentMissingError(Exception):
- """The parent of a path is missing.
-
- Exception raised if an attempt is made to add a path to the
- repository mirror but the parent's path doesn't exist in the
- youngest revision of the repository."""
-
- pass
-
- class ExpectedDirectoryError(Exception):
- """A file was found where a directory was expected."""
-
- pass
-
- def __init__(self, author_transforms=None):
- self._mirror = RepositoryMirror()
-
- def to_utf8(s):
- if isinstance(s, unicode):
- return s.encode('utf8')
- else:
- return s
-
- self.author_transforms = {}
- if author_transforms is not None:
- for (cvsauthor, name) in author_transforms.iteritems():
- cvsauthor = to_utf8(cvsauthor)
- name = to_utf8(name)
- self.author_transforms[cvsauthor] = name
-
- def register_artifacts(self, which_pass):
- # These artifacts are needed for SymbolingsReader:
- artifact_manager.register_temp_file_needed(
- config.SYMBOL_OPENINGS_CLOSINGS_SORTED, which_pass
- )
- artifact_manager.register_temp_file_needed(
- config.SYMBOL_OFFSETS_DB, which_pass
- )
-
- self._mirror.register_artifacts(which_pass)
- Ctx().revision_reader.register_artifacts(which_pass)
-
- def check_symbols(self, symbol_map):
- """Check that the paths of all included LODs are set and disjoint."""
-
- error_found = False
-
- # Check that all included LODs have their base paths set, and
- # collect the paths into a list:
- paths = []
- for lod in symbol_map.itervalues():
- if isinstance(lod, LineOfDevelopment):
- if lod.base_path is None:
- Log().error('%s: No path was set for %r\n' % (error_prefix, lod,))
- error_found = True
- else:
- paths.append(lod.base_path)
-
- # Check that the SVN paths of all LODS are disjoint:
- try:
- verify_paths_disjoint(*paths)
- except PathsNotDisjointException, e:
- Log().error(str(e))
- error_found = True
-
- if error_found:
- raise FatalException(
- 'Please fix the above errors and restart CollateSymbolsPass'
- )
-
- def setup(self, svn_rev_count):
- self._symbolings_reader = SymbolingsReader()
- self._mirror.open()
- self._delegates = []
- Ctx().revision_reader.start()
- self.add_delegate(StdoutDelegate(svn_rev_count))
-
- def _get_author(self, svn_commit):
- author = svn_commit.get_author()
- name = self.author_transforms.get(author, author)
- return name
-
- def _get_revprops(self, svn_commit):
- """Return the Subversion revprops for this SVNCommit."""
-
- return {
- 'svn:author' : self._get_author(svn_commit),
- 'svn:log' : svn_commit.get_log_msg(),
- 'svn:date' : format_date(svn_commit.date),
- }
-
- def start_commit(self, revnum, revprops):
- """Start a new commit."""
-
- self._mirror.start_commit(revnum)
- self._invoke_delegates('start_commit', revnum, revprops)
-
- def end_commit(self):
- """Called at the end of each commit.
-
- This method copies the newly created nodes to the on-disk nodes
- db."""
-
- self._mirror.end_commit()
- self._invoke_delegates('end_commit')
-
- def delete_lod(self, lod):
- """Delete the main path for LOD from the tree.
-
- The path must currently exist. Silently refuse to delete trunk
- paths."""
-
- if isinstance(lod, Trunk):
- # Never delete a Trunk path.
- return
-
- self._mirror.get_current_lod_directory(lod).delete()
- self._invoke_delegates('delete_lod', lod)
-
- def delete_path(self, cvs_path, lod, should_prune=False):
- """Delete CVS_PATH from LOD."""
-
- if cvs_path.parent_directory is None:
- self.delete_lod(lod)
- return
-
- parent_node = self._mirror.get_current_path(
- cvs_path.parent_directory, lod
- )
- del parent_node[cvs_path]
- self._invoke_delegates('delete_path', lod, cvs_path)
-
- if should_prune:
- while parent_node is not None and len(parent_node) == 0:
- # A drawback of this code is that we issue a delete for each
- # path and not just a single delete for the topmost directory
- # pruned.
- node = parent_node
- cvs_path = node.cvs_path
- if cvs_path.parent_directory is None:
- parent_node = None
- self.delete_lod(lod)
- else:
- parent_node = node.parent_mirror_dir
- node.delete()
- self._invoke_delegates('delete_path', lod, cvs_path)
-
- def initialize_project(self, project):
- """Create the basic structure for PROJECT."""
-
- self._invoke_delegates('initialize_project', project)
-
- # Don't invoke delegates.
- self._mirror.add_lod(project.get_trunk())
-
- def change_path(self, cvs_rev):
- """Register a change in self._youngest for the CVS_REV's svn_path."""
-
- # We do not have to update the nodes because our mirror is only
- # concerned with the presence or absence of paths, and a file
- # content change does not cause any path changes.
- self._invoke_delegates('change_path', SVNCommitItem(cvs_rev, False))
-
- def _mkdir_p(self, cvs_directory, lod):
- """Make sure that CVS_DIRECTORY exists in LOD.
-
- If not, create it, calling delegates. Return the node for
- CVS_DIRECTORY."""
-
- try:
- node = self._mirror.get_current_lod_directory(lod)
- except KeyError:
- node = self._mirror.add_lod(lod)
- self._invoke_delegates('initialize_lod', lod)
-
- for sub_path in cvs_directory.get_ancestry()[1:]:
- try:
- node = node[sub_path]
- except KeyError:
- node = node.mkdir(sub_path)
- self._invoke_delegates('mkdir', lod, sub_path)
- if node is None:
- raise self.ExpectedDirectoryError(
- 'File found at \'%s\' where directory was expected.' % (sub_path,)
- )
-
- return node
-
- def add_path(self, cvs_rev):
- """Add the CVS_REV's svn_path to the repository mirror.
-
- Create any missing intermediate paths."""
-
- cvs_file = cvs_rev.cvs_file
- parent_path = cvs_file.parent_directory
- lod = cvs_rev.lod
- parent_node = self._mkdir_p(parent_path, lod)
- parent_node.add_file(cvs_file)
- self._invoke_delegates('add_path', SVNCommitItem(cvs_rev, True))
-
- def copy_lod(self, src_lod, dest_lod, src_revnum):
- """Copy all of SRC_LOD at SRC_REVNUM to DST_LOD.
-
- In the youngest revision of the repository, the destination LOD
- *must not* already exist.
-
- Return the new node at DEST_LOD. Note that this node is not
- necessarily writable, though its parent node necessarily is."""
-
- node = self._mirror.copy_lod(src_lod, dest_lod, src_revnum)
- self._invoke_delegates('copy_lod', src_lod, dest_lod, src_revnum)
- return node
-
- def copy_path(
- self, cvs_path, src_lod, dest_lod, src_revnum, create_parent=False
- ):
- """Copy CVS_PATH from SRC_LOD at SRC_REVNUM to DST_LOD.
-
- In the youngest revision of the repository, the destination's
- parent *must* exist unless CREATE_PARENT is specified. But the
- destination itself *must not* exist.
-
- Return the new node at (CVS_PATH, DEST_LOD), as a
- CurrentMirrorDirectory."""
-
- if cvs_path.parent_directory is None:
- return self.copy_lod(src_lod, dest_lod, src_revnum)
-
- # Get the node of our source, or None if it is a file:
- src_node = self._mirror.get_old_path(cvs_path, src_lod, src_revnum)
-
- # Get the parent path of the destination:
- if create_parent:
- dest_parent_node = self._mkdir_p(cvs_path.parent_directory, dest_lod)
- else:
- try:
- dest_parent_node = self._mirror.get_current_path(
- cvs_path.parent_directory, dest_lod
- )
- except KeyError:
- raise self.ParentMissingError(
- 'Attempt to add path \'%s\' to repository mirror, '
- 'but its parent directory doesn\'t exist in the mirror.'
- % (dest_lod.get_path(cvs_path.cvs_path),)
- )
-
- if cvs_path in dest_parent_node:
- raise PathExistsError(
- 'Attempt to add path \'%s\' to repository mirror '
- 'when it already exists in the mirror.'
- % (dest_lod.get_path(cvs_path.cvs_path),)
- )
-
- dest_parent_node[cvs_path] = src_node
- self._invoke_delegates(
- 'copy_path',
- cvs_path, src_lod, dest_lod, src_revnum
- )
-
- return dest_parent_node[cvs_path]
-
- def fill_symbol(self, svn_symbol_commit, fill_source):
- """Perform all copies for the CVSSymbols in SVN_SYMBOL_COMMIT.
-
- The symbolic name is guaranteed to exist in the Subversion
- repository by the end of this call, even if there are no paths
- under it."""
-
- symbol = svn_symbol_commit.symbol
-
- try:
- dest_node = self._mirror.get_current_lod_directory(symbol)
- except KeyError:
- self._fill_directory(symbol, None, fill_source, None)
- else:
- self._fill_directory(symbol, dest_node, fill_source, None)
-
- def _fill_directory(self, symbol, dest_node, fill_source, parent_source):
- """Fill the tag or branch SYMBOL at the path indicated by FILL_SOURCE.
-
- Use items from FILL_SOURCE, and recurse into the child items.
-
- Fill SYMBOL starting at the path FILL_SOURCE.cvs_path. DEST_NODE
- is the node of this destination path, or None if the destination
- does not yet exist. All directories above this path have already
- been filled. FILL_SOURCE is a FillSource instance describing the
- items within a subtree of the repository that still need to be
- copied to the destination.
-
- PARENT_SOURCE is the SVNRevisionRange that was used to copy the
- parent directory, if it was copied in this commit. We prefer to
- copy from the same source as was used for the parent, since it
- typically requires less touching-up. If PARENT_SOURCE is None,
- then the parent directory was not copied in this commit, so no
- revision is preferable to any other."""
-
- copy_source = fill_source.compute_best_source(parent_source)
-
- # Figure out if we shall copy to this destination and delete any
- # destination path that is in the way.
- if dest_node is None:
- # The destination does not exist at all, so it definitely has to
- # be copied:
- dest_node = self.copy_path(
- fill_source.cvs_path, copy_source.source_lod,
- symbol, copy_source.opening_revnum
- )
- elif (parent_source is not None) and (
- copy_source.source_lod != parent_source.source_lod
- or copy_source.opening_revnum != parent_source.opening_revnum
- ):
- # The parent path was copied from a different source than we
- # need to use, so we have to delete the version that was copied
- # with the parent then re-copy from the correct source:
- self.delete_path(fill_source.cvs_path, symbol)
- dest_node = self.copy_path(
- fill_source.cvs_path, copy_source.source_lod,
- symbol, copy_source.opening_revnum
- )
- else:
- copy_source = parent_source
-
- # The map {CVSPath : FillSource} of entries within this directory
- # that need filling:
- src_entries = fill_source.get_subsource_map()
-
- if copy_source is not None:
- self._prune_extra_entries(
- fill_source.cvs_path, symbol, dest_node, src_entries
- )
-
- return self._cleanup_filled_directory(
- symbol, dest_node, src_entries, copy_source
- )
-
- def _cleanup_filled_directory(
- self, symbol, dest_node, src_entries, copy_source
- ):
- """The directory at DEST_NODE has been filled and pruned; recurse.
-
- Recurse into the SRC_ENTRIES, in alphabetical order. If DEST_NODE
- was copied in this revision, COPY_SOURCE should indicate where it
- was copied from; otherwise, COPY_SOURCE should be None."""
-
- cvs_paths = src_entries.keys()
- cvs_paths.sort()
- for cvs_path in cvs_paths:
- if isinstance(cvs_path, CVSDirectory):
- # Path is a CVSDirectory:
- try:
- dest_subnode = dest_node[cvs_path]
- except KeyError:
- # Path doesn't exist yet; it has to be created:
- dest_node = self._fill_directory(
- symbol, None, src_entries[cvs_path], None
- ).parent_mirror_dir
- else:
- # Path already exists, but might have to be cleaned up:
- dest_node = self._fill_directory(
- symbol, dest_subnode, src_entries[cvs_path], copy_source
- ).parent_mirror_dir
- else:
- # Path is a CVSFile:
- self._fill_file(
- symbol, cvs_path in dest_node, src_entries[cvs_path], copy_source
- )
- # Reread dest_node since the call to _fill_file() might have
- # made it writable:
- dest_node = self._mirror.get_current_path(
- dest_node.cvs_path, dest_node.lod
- )
-
- return dest_node
-
- def _fill_file(self, symbol, dest_existed, fill_source, parent_source):
- """Fill the tag or branch SYMBOL at the path indicated by FILL_SOURCE.
-
- Use items from FILL_SOURCE.
-
- Fill SYMBOL at path FILL_SOURCE.cvs_path. DEST_NODE is the node
- of this destination path, or None if the destination does not yet
- exist. All directories above this path have already been filled
- as needed. FILL_SOURCE is a FillSource instance describing the
- item that needs to be copied to the destination.
-
- PARENT_SOURCE is the source from which the parent directory was
- copied, or None if the parent directory was not copied during this
- commit. We prefer to copy from PARENT_SOURCE, since it typically
- requires less touching-up. If PARENT_SOURCE is None, then the
- parent directory was not copied in this commit, so no revision is
- preferable to any other."""
-
- copy_source = fill_source.compute_best_source(parent_source)
-
- # Figure out if we shall copy to this destination and delete any
- # destination path that is in the way.
- if not dest_existed:
- # The destination does not exist at all, so it definitely has to
- # be copied:
- self.copy_path(
- fill_source.cvs_path, copy_source.source_lod,
- symbol, copy_source.opening_revnum
- )
- elif (parent_source is not None) and (
- copy_source.source_lod != parent_source.source_lod
- or copy_source.opening_revnum != parent_source.opening_revnum
- ):
- # The parent path was copied from a different source than we
- # need to use, so we have to delete the version that was copied
- # with the parent and then re-copy from the correct source:
- self.delete_path(fill_source.cvs_path, symbol)
- self.copy_path(
- fill_source.cvs_path, copy_source.source_lod,
- symbol, copy_source.opening_revnum
- )
-
- def _prune_extra_entries(
- self, dest_cvs_path, symbol, dest_node, src_entries
- ):
- """Delete any entries in DEST_NODE that are not in SRC_ENTRIES."""
-
- delete_list = [
- cvs_path
- for cvs_path in dest_node
- if cvs_path not in src_entries
- ]
-
- # Sort the delete list so that the output is in a consistent
- # order:
- delete_list.sort()
- for cvs_path in delete_list:
- del dest_node[cvs_path]
- self._invoke_delegates('delete_path', symbol, cvs_path)
-
- def add_delegate(self, delegate):
- """Adds DELEGATE to self._delegates.
-
- For every delegate you add, whenever a repository action method is
- performed, delegate's corresponding repository action method is
- called. Multiple delegates will be called in the order that they
- are added. See SVNRepositoryDelegate for more information."""
-
- self._delegates.append(delegate)
-
- def _invoke_delegates(self, method, *args):
- """Invoke a method on each delegate.
-
- Iterate through each of our delegates, in the order that they were
- added, and call the delegate's method named METHOD with the
- arguments in ARGS."""
-
- for delegate in self._delegates:
- getattr(delegate, method)(*args)
-
- def process_initial_project_commit(self, svn_commit):
- self.start_commit(svn_commit.revnum, self._get_revprops(svn_commit))
-
- for project in svn_commit.projects:
- self.initialize_project(project)
-
- self.end_commit()
-
- def process_primary_commit(self, svn_commit):
- self.start_commit(svn_commit.revnum, self._get_revprops(svn_commit))
-
- # This actually commits CVSRevisions
- if len(svn_commit.cvs_revs) > 1:
- plural = "s"
- else:
- plural = ""
- Log().verbose("Committing %d CVSRevision%s"
- % (len(svn_commit.cvs_revs), plural))
- for cvs_rev in svn_commit.cvs_revs:
- if isinstance(cvs_rev, CVSRevisionNoop):
- pass
-
- elif isinstance(cvs_rev, CVSRevisionDelete):
- self.delete_path(cvs_rev.cvs_file, cvs_rev.lod, Ctx().prune)
-
- elif isinstance(cvs_rev, CVSRevisionAdd):
- self.add_path(cvs_rev)
-
- elif isinstance(cvs_rev, CVSRevisionChange):
- self.change_path(cvs_rev)
-
- self.end_commit()
-
- def process_post_commit(self, svn_commit):
- self.start_commit(svn_commit.revnum, self._get_revprops(svn_commit))
-
- Log().verbose(
- 'Synchronizing default branch motivated by %d'
- % (svn_commit.motivating_revnum,)
- )
-
- for cvs_rev in svn_commit.cvs_revs:
- trunk = cvs_rev.cvs_file.project.get_trunk()
- if isinstance(cvs_rev, CVSRevisionAdd):
- # Copy from branch to trunk:
- self.copy_path(
- cvs_rev.cvs_file, cvs_rev.lod, trunk,
- svn_commit.motivating_revnum, True
- )
- elif isinstance(cvs_rev, CVSRevisionChange):
- # Delete old version of the path on trunk...
- self.delete_path(cvs_rev.cvs_file, trunk)
- # ...and copy the new version over from branch:
- self.copy_path(
- cvs_rev.cvs_file, cvs_rev.lod, trunk,
- svn_commit.motivating_revnum, True
- )
- elif isinstance(cvs_rev, CVSRevisionDelete):
- # Delete trunk path:
- self.delete_path(cvs_rev.cvs_file, trunk)
- elif isinstance(cvs_rev, CVSRevisionNoop):
- # Do nothing
- pass
- else:
- raise InternalError('Unexpected CVSRevision type: %s' % (cvs_rev,))
-
- self.end_commit()
-
- def process_branch_commit(self, svn_commit):
- self.start_commit(svn_commit.revnum, self._get_revprops(svn_commit))
- Log().verbose('Filling branch:', svn_commit.symbol.name)
-
- # Get the set of sources for the symbolic name:
- source_set = get_source_set(
- svn_commit.symbol,
- self._symbolings_reader.get_range_map(svn_commit),
- )
-
- self.fill_symbol(svn_commit, source_set)
-
- self.end_commit()
-
- def process_tag_commit(self, svn_commit):
- self.start_commit(svn_commit.revnum, self._get_revprops(svn_commit))
- Log().verbose('Filling tag:', svn_commit.symbol.name)
-
- # Get the set of sources for the symbolic name:
- source_set = get_source_set(
- svn_commit.symbol,
- self._symbolings_reader.get_range_map(svn_commit),
- )
-
- self.fill_symbol(svn_commit, source_set)
-
- self.end_commit()
-
- def cleanup(self):
- self._invoke_delegates('finish')
- self._mirror.close()
- self._mirror = None
- Ctx().revision_reader.finish()
- self._symbolings_reader.close()
- del self._symbolings_reader
-
-
-class DumpfileOutputOption(SVNOutputOption):
- """Output the result of the conversion into a dumpfile."""
-
- def __init__(self, dumpfile_path, author_transforms=None):
- SVNOutputOption.__init__(self, author_transforms)
- self.dumpfile_path = dumpfile_path
-
- def check(self):
- pass
-
- def setup(self, svn_rev_count):
- Log().quiet("Starting Subversion Dumpfile.")
- SVNOutputOption.setup(self, svn_rev_count)
- if not Ctx().dry_run:
- self.add_delegate(
- DumpfileDelegate(Ctx().revision_reader, self.dumpfile_path)
- )
-
-
-class RepositoryOutputOption(SVNOutputOption):
- """Output the result of the conversion into an SVN repository."""
-
- def __init__(self, target, author_transforms=None):
- SVNOutputOption.__init__(self, author_transforms)
- self.target = target
-
- def check(self):
- if not Ctx().dry_run:
- # Verify that svnadmin can be executed. The 'help' subcommand
- # should be harmless.
- try:
- check_command_runs([Ctx().svnadmin_executable, 'help'], 'svnadmin')
- except CommandFailedException, e:
- raise FatalError(
- '%s\n'
- 'svnadmin could not be executed. Please ensure that it is\n'
- 'installed and/or use the --svnadmin option.' % (e,))
-
- def setup(self, svn_rev_count):
- Log().quiet("Starting Subversion Repository.")
- SVNOutputOption.setup(self, svn_rev_count)
- if not Ctx().dry_run:
- self.add_delegate(
- RepositoryDelegate(Ctx().revision_reader, self.target)
- )
-
-
-class NewRepositoryOutputOption(RepositoryOutputOption):
- """Output the result of the conversion into a new SVN repository."""
-
- def __init__(
- self, target, fs_type=None, bdb_txn_nosync=None, author_transforms=None, create_options=[]
- ):
- RepositoryOutputOption.__init__(self, target, author_transforms)
- self.bdb_txn_nosync = bdb_txn_nosync
-
- # Determine the options to be passed to "svnadmin create":
- if not fs_type:
- # User didn't say what kind repository (bdb, fsfs, etc). We
- # still pass --bdb-txn-nosync. It's a no-op if the default
- # repository type doesn't support it, but we definitely want it
- # if BDB is the default.
- self.create_options = ['--bdb-txn-nosync']
- elif fs_type == 'bdb':
- # User explicitly specified bdb.
- #
- # Since this is a BDB repository, pass --bdb-txn-nosync, because
- # it gives us a 4-5x speed boost (if cvs2svn is creating the
- # repository, cvs2svn should be the only program accessing the
- # svn repository until cvs2svn is done). But we'll turn no-sync
- # off in self.finish(), unless instructed otherwise.
- self.create_options = ['--fs-type=bdb', '--bdb-txn-nosync']
- else:
- # User specified something other than bdb.
- self.create_options = ['--fs-type=%s' % fs_type]
-
- # Now append the user's explicitly-set create options:
- self.create_options += create_options
-
- def check(self):
- RepositoryOutputOption.check(self)
- if not Ctx().dry_run and os.path.exists(self.target):
- raise FatalError("the svn-repos-path '%s' exists.\n"
- "Remove it, or pass '--existing-svnrepos'."
- % self.target)
-
- def setup(self, svn_rev_count):
- Log().normal("Creating new repository '%s'" % (self.target))
- if Ctx().dry_run:
- # Do not actually create repository:
- pass
- else:
- call_command([
- Ctx().svnadmin_executable, 'create',
- ] + self.create_options + [
- self.target
- ])
-
- RepositoryOutputOption.setup(self, svn_rev_count)
-
- def cleanup(self):
- RepositoryOutputOption.cleanup(self)
-
- # If this is a BDB repository, and we created the repository, and
- # --bdb-no-sync wasn't passed, then comment out the DB_TXN_NOSYNC
- # line in the DB_CONFIG file, because txn syncing should be on by
- # default in BDB repositories.
- #
- # We determine if this is a BDB repository by looking for the
- # DB_CONFIG file, which doesn't exist in FSFS, rather than by
- # checking self.fs_type. That way this code will Do The Right
- # Thing in all circumstances.
- db_config = os.path.join(self.target, "db/DB_CONFIG")
- if Ctx().dry_run:
- # Do not change repository:
- pass
- elif not self.bdb_txn_nosync and os.path.exists(db_config):
- no_sync = 'set_flags DB_TXN_NOSYNC\n'
-
- contents = open(db_config, 'r').readlines()
- index = contents.index(no_sync)
- contents[index] = '# ' + no_sync
- open(db_config, 'w').writelines(contents)
-
-
-class ExistingRepositoryOutputOption(RepositoryOutputOption):
- """Output the result of the conversion into an existing SVN repository."""
-
- def __init__(self, target, author_transforms=None):
- RepositoryOutputOption.__init__(self, target, author_transforms)
-
- def check(self):
- RepositoryOutputOption.check(self)
- if not os.path.isdir(self.target):
- raise FatalError("the svn-repos-path '%s' is not an "
- "existing directory." % self.target)
-
-