コード例 #1
0
 def callback_dump_only(self, option, opt_str, value, parser):
   parser.values.dump_only = True
   logger.error(
       warning_prefix +
       ': The --dump-only option is deprecated (it is implied '
       'by --dumpfile).\n'
       )
コード例 #2
0
 def callback_create(self, option, opt_str, value, parser):
   logger.error(
       warning_prefix +
       ': The behaviour produced by the --create option is now the '
       'default;\n'
       'passing the option is deprecated.\n'
       )
コード例 #3
0
    def process_options(self):
        # Consistency check for options and arguments.
        if len(self.args) == 0:
            # Default to using '.' as the source repository path
            self.args.append(os.getcwd())

        if len(self.args) > 1:
            logger.error(error_prefix +
                         ": must pass only one CVS repository.\n")
            self.usage()
            sys.exit(1)

        cvsroot = self.args[0]

        self.process_extraction_options()
        self.process_output_options()
        self.process_symbol_strategy_options()
        self.process_property_setter_options()

        # Create the project:
        self.set_project(
            cvsroot,
            symbol_transforms=self.options.symbol_transforms,
            symbol_strategy_rules=self.options.symbol_strategy_rules,
        )
コード例 #4
0
  def _check_blocked_excludes(self, symbol_map):
    """Check for any excluded LODs that are blocked by non-excluded symbols.

    If any are found, describe the problem to logger.error() and raise
    a FatalException."""

    # A list of (lod,[blocker,...]) tuples for excludes that are
    # blocked by the specified non-excluded blockers:
    problems = []

    for lod in symbol_map.itervalues():
      if isinstance(lod, ExcludedSymbol):
        # Symbol is excluded; make sure that its blockers are also
        # excluded:
        lod_blockers = []
        for blocker in self.get_stats(lod).branch_blockers:
          if isinstance(symbol_map.get(blocker, None), IncludedSymbol):
            lod_blockers.append(blocker)
        if lod_blockers:
          problems.append((lod, lod_blockers))

    if problems:
      s = []
      for (lod, lod_blockers) in problems:
        s.append(
            '%s: %s cannot be excluded because the following symbols '
                'depend on it:\n'
            % (error_prefix, lod,)
            )
        for blocker in lod_blockers:
          s.append('    %s\n' % (blocker,))
      s.append('\n')
      logger.error(''.join(s))

      raise FatalException()
コード例 #5
0
    def process_options(self):
        # Consistency check for options and arguments.
        if len(self.args) == 0:
            self.usage()
            sys.exit(1)

        if len(self.args) > 1:
            logger.error(error_prefix +
                         ": must pass only one CVS repository.\n")
            self.usage()
            sys.exit(1)

        cvsroot = self.args[0]

        self.process_extraction_options()
        self.process_output_options()
        self.process_symbol_strategy_options()
        self.process_property_setter_options()

        # Create the default project (using ctx.trunk, ctx.branches, and
        # ctx.tags):
        self.add_project(
            cvsroot,
            trunk_path=self.options.trunk_base,
            branches_path=self.options.branches_base,
            tags_path=self.options.tags_base,
            symbol_transforms=self.options.symbol_transforms,
            symbol_strategy_rules=self.options.symbol_strategy_rules,
        )
コード例 #6
0
ファイル: symbol_statistics.py プロジェクト: robinst/cvs2svn
  def _check_blocked_excludes(self, symbol_map):
    """Check for any excluded LODs that are blocked by non-excluded symbols.

    If any are found, describe the problem to logger.error() and raise
    a FatalException."""

    # A list of (lod,[blocker,...]) tuples for excludes that are
    # blocked by the specified non-excluded blockers:
    problems = []

    for lod in symbol_map.itervalues():
      if isinstance(lod, ExcludedSymbol):
        # Symbol is excluded; make sure that its blockers are also
        # excluded:
        lod_blockers = []
        for blocker in self.get_stats(lod).branch_blockers:
          if isinstance(symbol_map.get(blocker, None), IncludedSymbol):
            lod_blockers.append(blocker)
        if lod_blockers:
          problems.append((lod, lod_blockers))

    if problems:
      s = []
      for (lod, lod_blockers) in problems:
        s.append(
            '%s: %s cannot be excluded because the following symbols '
                'depend on it:\n'
            % (error_prefix, lod,)
            )
        for blocker in lod_blockers:
          s.append('    %s\n' % (blocker,))
      s.append('\n')
      logger.error(''.join(s))

      raise FatalException()
コード例 #7
0
ファイル: symbol_statistics.py プロジェクト: robinst/cvs2svn
  def _check_invalid_tags(self, symbol_map):
    """Check for commits on any symbols that are to be converted as tags.

    SYMBOL_MAP is a map {AbstractSymbol : (Trunk|TypedSymbol)}
    indicating how each AbstractSymbol is to be converted.  If there
    is a commit on a symbol, then it cannot be converted as a tag.  If
    any tags with commits are found, output error messages describing
    the problems then raise a FatalException."""

    logger.quiet("Checking for forced tags with commits...")

    invalid_tags = [ ]
    for symbol in symbol_map.itervalues():
      if isinstance(symbol, Tag):
        stats = self.get_stats(symbol)
        if stats.branch_commit_count > 0:
          invalid_tags.append(symbol)

    if not invalid_tags:
      # No problems found:
      return

    s = []
    s.append(
        '%s: The following branches cannot be forced to be tags '
        'because they have commits:\n'
        % (error_prefix,)
        )
    for tag in invalid_tags:
      s.append('    %s\n' % (tag.name))
    s.append('\n')
    logger.error(''.join(s))

    raise FatalException()
コード例 #8
0
  def process_options(self):
    # Consistency check for options and arguments.
    if len(self.args) == 0:
      self.usage()
      sys.exit(1)

    if len(self.args) > 1:
      logger.error(error_prefix + ": must pass only one CVS repository.\n")
      self.usage()
      sys.exit(1)

    cvsroot = self.args[0]

    self.process_extraction_options()
    self.process_output_options()
    self.process_symbol_strategy_options()
    self.process_property_setter_options()

    # Create the default project (using ctx.trunk, ctx.branches, and
    # ctx.tags):
    self.add_project(
        cvsroot,
        trunk_path=self.options.trunk_base,
        branches_path=self.options.branches_base,
        tags_path=self.options.tags_base,
        symbol_transforms=self.options.symbol_transforms,
        symbol_strategy_rules=self.options.symbol_strategy_rules,
        )
コード例 #9
0
ファイル: symbol_statistics.py プロジェクト: robinst/cvs2svn
    def _check_invalid_tags(self, symbol_map):
        """Check for commits on any symbols that are to be converted as tags.

    SYMBOL_MAP is a map {AbstractSymbol : (Trunk|TypedSymbol)}
    indicating how each AbstractSymbol is to be converted.  If there
    is a commit on a symbol, then it cannot be converted as a tag.  If
    any tags with commits are found, output error messages describing
    the problems then raise a FatalException."""

        logger.quiet("Checking for forced tags with commits...")

        invalid_tags = []
        for symbol in symbol_map.itervalues():
            if isinstance(symbol, Tag):
                stats = self.get_stats(symbol)
                if stats.branch_commit_count > 0:
                    invalid_tags.append(symbol)

        if not invalid_tags:
            # No problems found:
            return

        s = []
        s.append('%s: The following branches cannot be forced to be tags '
                 'because they have commits:\n' % (error_prefix, ))
        for tag in invalid_tags:
            s.append('    %s\n' % (tag.name))
        s.append('\n')
        logger.error(''.join(s))

        raise FatalException()
コード例 #10
0
    def set_revision_info(self, revision, log, text):
        if revision in self.revisions_seen:
            # One common form of CVS repository corruption is that the
            # Deltatext block for revision 1.1 appears twice.  CollectData
            # has already warned about this problem; here we can just ignore
            # it.
            return
        else:
            self.revisions_seen.add(revision)

        cvs_rev_id = self.cvs_file_items.original_ids[revision]
        if is_trunk_revision(revision):
            # On trunk, revisions are encountered in reverse order (1.<N>
            # ... 1.1) and deltas are inverted.  The first text that we see
            # is the fulltext for the HEAD revision.  After that, the text
            # corresponding to revision 1.N is the delta (1.<N+1> ->
            # 1.<N>)).  We have to invert the deltas here so that we can
            # read the revisions out in dependency order; that is, for
            # revision 1.1 we want the fulltext, and for revision 1.<N> we
            # want the delta (1.<N-1> -> 1.<N>).  This means that we can't
            # compute the delta for a revision until we see its logical
            # parent.  When we finally see revision 1.1 (which is recognized
            # because it doesn't have a parent), we can record the diff (1.1
            # -> 1.2) for revision 1.2, and also the fulltext for 1.1.

            if revision == self.head_revision:
                # This is HEAD, as fulltext.  Initialize the RCSStream so
                # that we can compute deltas backwards in time.
                self._rcs_stream = RCSStream(text)
                self._rcs_stream_revision = revision
            else:
                # Any other trunk revision is a backward delta.  Apply the
                # delta to the RCSStream to mutate it to the contents of this
                # revision, and also to get the reverse delta, which we store
                # as the forward delta of our child revision.
                try:
                    text = self._rcs_stream.invert_diff(text)
                except MalformedDeltaException, e:
                    logger.error(
                        'Malformed RCS delta in %s, revision %s: %s' %
                        (self.cvs_file_items.cvs_file.rcs_path, revision, e))
                    raise RuntimeError()
                text_record = DeltaTextRecord(
                    self.cvs_file_items.original_ids[
                        self._rcs_stream_revision], cvs_rev_id)
                self.revision_collector._writeout(text_record, text)
                self._rcs_stream_revision = revision

            if revision == self.revision_1_1:
                # This is revision 1.1.  Write its fulltext:
                text_record = FullTextRecord(cvs_rev_id)
                self.revision_collector._writeout(text_record,
                                                  self._rcs_stream.get_text())

                # There will be no more trunk revisions delivered, so free the
                # RCSStream.
                del self._rcs_stream
                del self._rcs_stream_revision
コード例 #11
0
    def define_revision(self, revision, timestamp, author, state, branches,
                        next):
        """This is a callback method declared in Sink."""

        for branch in branches:
            try:
                branch_data = self.sdc.rev_to_branch_data(branch)
            except KeyError:
                # Normally we learn about the branches from the branch names
                # and numbers parsed from the symbolic name header.  But this
                # must have been an unlabeled branch that slipped through the
                # net.  Generate a name for it and create a _BranchData record
                # for it now.
                branch_data = self.sdc._add_unlabeled_branch(
                    self.sdc.rev_to_branch_number(branch))

            assert branch_data.child is None
            branch_data.child = branch

        if revision in self._rev_data:
            # This revision has already been seen.
            logger.error(
                'File %r contains duplicate definitions of revision %s.' % (
                    self.cvs_file.rcs_path,
                    revision,
                ))
            raise RuntimeError()

        # Record basic information about the revision:
        rev_data = _RevisionData(self.collect_data.item_key_generator.gen_id(),
                                 revision, int(timestamp), author, state)
        self._rev_data[revision] = rev_data

        # When on trunk, the RCS 'next' revision number points to what
        # humans might consider to be the 'previous' revision number.  For
        # example, 1.3's RCS 'next' is 1.2.
        #
        # However, on a branch, the RCS 'next' revision number really does
        # point to what humans would consider to be the 'next' revision
        # number.  For example, 1.1.2.1's RCS 'next' would be 1.1.2.2.
        #
        # In other words, in RCS, 'next' always means "where to find the next
        # deltatext that you need this revision to retrieve.
        #
        # That said, we don't *want* RCS's behavior here, so we determine
        # whether we're on trunk or a branch and set the dependencies
        # accordingly.
        if next:
            if is_trunk_revision(revision):
                self._primary_dependencies.append((
                    next,
                    revision,
                ))
            else:
                self._primary_dependencies.append((
                    revision,
                    next,
                ))
コード例 #12
0
ファイル: collect_data.py プロジェクト: robinst/cvs2svn
  def record_fatal_error(self, err):
    """Record that fatal error ERR was found.

    ERR is a string (without trailing newline) describing the error.
    Output the error to stderr immediately, and record a copy to be
    output again in a summary at the end of CollectRevsPass."""

    err = '%s: %s' % (error_prefix, err,)
    logger.error(err + '\n')
    self.fatal_errors.append(err)
コード例 #13
0
    def record_fatal_error(self, err):
        """Record that fatal error ERR was found.

    ERR is a string (without trailing newline) describing the error.
    Output the error to stderr immediately, and record a copy to be
    output again in a summary at the end of CollectRevsPass."""

        err = '%s: %s' % (
            error_prefix,
            err,
        )
        logger.error(err + '\n')
        self.fatal_errors.append(err)
コード例 #14
0
ファイル: cvs_file_items.py プロジェクト: zhuchag/cvs2svn
    def check_link_consistency(self):
        """Check that the CVSItems are linked correctly with each other."""

        for cvs_item in self.values():
            try:
                cvs_item.check_links(self)
            except AssertionError:
                logger.error(
                    'Link consistency error in %s\n'
                    'This is probably a bug internal to cvs2svn.  Please file a bug\n'
                    'report including the following stack trace (see FAQ for more '
                    'info).' % (cvs_item, ))
                raise
コード例 #15
0
ファイル: collect_data.py プロジェクト: robinst/cvs2svn
  def define_revision(self, revision, timestamp, author, state,
                      branches, next):
    """This is a callback method declared in Sink."""

    for branch in branches:
      try:
        branch_data = self.sdc.rev_to_branch_data(branch)
      except KeyError:
        # Normally we learn about the branches from the branch names
        # and numbers parsed from the symbolic name header.  But this
        # must have been an unlabeled branch that slipped through the
        # net.  Generate a name for it and create a _BranchData record
        # for it now.
        branch_data = self.sdc._add_unlabeled_branch(
            self.sdc.rev_to_branch_number(branch))

      assert branch_data.child is None
      branch_data.child = branch

    if revision in self._rev_data:
      # This revision has already been seen.
      logger.error('File %r contains duplicate definitions of revision %s.'
                  % (self.cvs_file.rcs_path, revision,))
      raise RuntimeError()

    # Record basic information about the revision:
    rev_data = _RevisionData(
        self.collect_data.item_key_generator.gen_id(),
        revision, int(timestamp), author, state)
    self._rev_data[revision] = rev_data

    # When on trunk, the RCS 'next' revision number points to what
    # humans might consider to be the 'previous' revision number.  For
    # example, 1.3's RCS 'next' is 1.2.
    #
    # However, on a branch, the RCS 'next' revision number really does
    # point to what humans would consider to be the 'next' revision
    # number.  For example, 1.1.2.1's RCS 'next' would be 1.1.2.2.
    #
    # In other words, in RCS, 'next' always means "where to find the next
    # deltatext that you need this revision to retrieve.
    #
    # That said, we don't *want* RCS's behavior here, so we determine
    # whether we're on trunk or a branch and set the dependencies
    # accordingly.
    if next:
      if is_trunk_revision(revision):
        self._primary_dependencies.append( (next, revision,) )
      else:
        self._primary_dependencies.append( (revision, next,) )
コード例 #16
0
ファイル: cvs_file_items.py プロジェクト: mhagger/cvs2svn
  def check_link_consistency(self):
    """Check that the CVSItems are linked correctly with each other."""

    for cvs_item in self.values():
      try:
        cvs_item.check_links(self)
      except AssertionError:
        logger.error(
            'Link consistency error in %s\n'
            'This is probably a bug internal to cvs2svn.  Please file a bug\n'
            'report including the following stack trace (see FAQ for more '
            'info).'
            % (cvs_item,))
        raise
コード例 #17
0
    def verify_option_compatibility(self):
        """Verify that no options incompatible with --options were used.

    The --options option was specified.  Verify that no incompatible
    options or arguments were specified."""

        if self.options.options_incompatible_options or self.args:
            if self.options.options_incompatible_options:
                oio = self.options.options_incompatible_options
                logger.error(
                    '%s: The following options cannot be used in combination with '
                    'the --options\n'
                    'option:\n'
                    '    %s\n' % (error_prefix, '\n    '.join(oio)))
            if self.args:
                logger.error(
                    '%s: No cvs-repos-path arguments are allowed with the --options '
                    'option.\n' % (error_prefix, ))
            sys.exit(1)
コード例 #18
0
ファイル: run_options.py プロジェクト: termim/cvs2svn
    def verify_option_compatibility(self):
        """Verify that no options incompatible with --options were used.

    The --options option was specified.  Verify that no incompatible
    options or arguments were specified."""

        if self.options.options_incompatible_options or self.args:
            if self.options.options_incompatible_options:
                oio = self.options.options_incompatible_options
                logger.error(
                    "%s: The following options cannot be used in combination with "
                    "the --options\n"
                    "option:\n"
                    "    %s\n" % (error_prefix, "\n    ".join(oio))
                )
            if self.args:
                logger.error(
                    "%s: No cvs-repos-path arguments are allowed with the --options " "option.\n" % (error_prefix,)
                )
            sys.exit(1)
コード例 #19
0
ファイル: property_setters.py プロジェクト: termim/cvs2svn
  def __init__(
          self, mime_types_file=None, mime_mappings=None,
          ignore_case=False
          ):
    """Constructor.

    Arguments:

      mime_types_file -- a path to a MIME types file on disk.  Each
          line of the file should contain the MIME type, then a
          whitespace-separated list of file extensions; e.g., one line
          might be 'text/plain txt c h cpp hpp'.

      mime_mappings -- a dictionary mapping a file extension to a MIME
          type; e.g., {'txt': 'text/plain', 'cpp': 'text/plain'}.

      ignore_case -- True iff case should be ignored in filename
          extensions.  Setting this option to True can be useful if
          your CVS repository was used on systems with
          case-insensitive filenames, in which case you might have a
          mix of uppercase and lowercase filenames."""

    self.mappings = { }
    if ignore_case:
      self.transform_case = _squash_case
    else:
      self.transform_case = _preserve_case

    if mime_types_file is None and mime_mappings is None:
      logger.error('Should specify MIME types file or dict.\n')

    if mime_types_file is not None:
      for line in file(mime_types_file):
        if line.startswith("#"):
          continue

        # format of a line is something like
        # text/plain c h cpp
        extensions = line.split()
        if len(extensions) < 2:
          continue
        type = extensions.pop(0)
        for ext in extensions:
          ext = self.transform_case(ext)
          if ext in self.mappings and self.mappings[ext] != type:
            logger.error(
                "%s: ambiguous MIME mapping for *.%s (%s or %s)\n"
                % (warning_prefix, ext, self.mappings[ext], type)
                )
          self.mappings[ext] = type

    if mime_mappings is not None:
      for ext, type in mime_mappings.iteritems():
        ext = self.transform_case(ext)
        if ext in self.mappings and self.mappings[ext] != type:
          logger.error(
              "%s: ambiguous MIME mapping for *.%s (%s or %s)\n"
              % (warning_prefix, ext, self.mappings[ext], type)
              )
        self.mappings[ext] = type
コード例 #20
0
    def __init__(self,
                 mime_types_file=None,
                 mime_mappings=None,
                 ignore_case=False):
        """Constructor.

    Arguments:

      mime_types_file -- a path to a MIME types file on disk.  Each
          line of the file should contain the MIME type, then a
          whitespace-separated list of file extensions; e.g., one line
          might be 'text/plain txt c h cpp hpp'.  (See
          http://en.wikipedia.org/wiki/Mime.types for information
          about mime.types files):

      mime_mappings -- a dictionary mapping a file extension to a MIME
          type; e.g., {'txt': 'text/plain', 'cpp': 'text/plain'}.

      ignore_case -- True iff case should be ignored in filename
          extensions.  Setting this option to True can be useful if
          your CVS repository was used on systems with
          case-insensitive filenames, in which case you might have a
          mix of uppercase and lowercase filenames."""

        self.mappings = {}
        if ignore_case:
            self.transform_case = _squash_case
        else:
            self.transform_case = _preserve_case

        if mime_types_file is None and mime_mappings is None:
            logger.error('Should specify MIME types file or dict.\n')

        if mime_types_file is not None:
            for line in file(mime_types_file):
                if line.startswith("#"):
                    continue

                # format of a line is something like
                # text/plain c h cpp
                extensions = line.split()
                if len(extensions) < 2:
                    continue
                type = extensions.pop(0)
                for ext in extensions:
                    ext = self.transform_case(ext)
                    if ext in self.mappings and self.mappings[ext] != type:
                        logger.error(
                            "%s: ambiguous MIME mapping for *.%s (%s or %s)\n"
                            % (warning_prefix, ext, self.mappings[ext], type))
                    self.mappings[ext] = type

        if mime_mappings is not None:
            for ext, type in mime_mappings.iteritems():
                ext = self.transform_case(ext)
                if ext in self.mappings and self.mappings[ext] != type:
                    logger.error(
                        "%s: ambiguous MIME mapping for *.%s (%s or %s)\n" %
                        (warning_prefix, ext, self.mappings[ext], type))
                self.mappings[ext] = type
コード例 #21
0
ファイル: symbol_statistics.py プロジェクト: robinst/cvs2svn
    def check_consistency(self, symbol_map):
        """Check the plan for how to convert symbols for consistency.

    SYMBOL_MAP is a map {AbstractSymbol : (Trunk|TypedSymbol)}
    indicating how each AbstractSymbol is to be converted.  If any
    problems are detected, describe the problem to logger.error() and
    raise a FatalException."""

        # We want to do all of the consistency checks even if one of them
        # fails, so that the user gets as much feedback as possible.  Set
        # this variable to True if any errors are found.
        error_found = False

        # Check that the planned preferred parents are OK for all
        # IncludedSymbols:
        for lod in symbol_map.itervalues():
            if isinstance(lod, IncludedSymbol):
                stats = self.get_stats(lod)
                try:
                    stats.check_preferred_parent_allowed(lod)
                except SymbolPlanException, e:
                    logger.error('%s\n' % (e, ))
                    error_found = True
コード例 #22
0
ファイル: symbol_statistics.py プロジェクト: robinst/cvs2svn
  def check_consistency(self, symbol_map):
    """Check the plan for how to convert symbols for consistency.

    SYMBOL_MAP is a map {AbstractSymbol : (Trunk|TypedSymbol)}
    indicating how each AbstractSymbol is to be converted.  If any
    problems are detected, describe the problem to logger.error() and
    raise a FatalException."""

    # We want to do all of the consistency checks even if one of them
    # fails, so that the user gets as much feedback as possible.  Set
    # this variable to True if any errors are found.
    error_found = False

    # Check that the planned preferred parents are OK for all
    # IncludedSymbols:
    for lod in symbol_map.itervalues():
      if isinstance(lod, IncludedSymbol):
        stats = self.get_stats(lod)
        try:
          stats.check_preferred_parent_allowed(lod)
        except SymbolPlanException, e:
          logger.error('%s\n' % (e,))
          error_found = True
コード例 #23
0
ファイル: dvcs_common.py プロジェクト: mddtrifecta/cvs2svn
  def process_options(self):
    # Consistency check for options and arguments.
    if len(self.args) == 0:
      # Default to using '.' as the source repository path
      self.args.append(os.getcwd())

    if len(self.args) > 1:
      logger.error(error_prefix + ": must pass only one CVS repository.\n")
      self.usage()
      sys.exit(1)

    cvsroot = self.args[0]

    self.process_extraction_options()
    self.process_output_options()
    self.process_symbol_strategy_options()
    self.process_property_setter_options()

    # Create the project:
    self.set_project(
        cvsroot,
        symbol_transforms=self.options.symbol_transforms,
        symbol_strategy_rules=self.options.symbol_strategy_rules,
        )
コード例 #24
0
ファイル: database.py プロジェクト: robinst/cvs2svn
#    so that the dbhash module used by anydbm will use bsddb3.
try:
  import bsddb3
  sys.modules['bsddb'] = sys.modules['bsddb3']
except ImportError:
  pass

# 2. These DBM modules are not good for cvs2svn.
import anydbm
if anydbm._defaultmod.__name__ in ['dumbdbm', 'dbm']:
  logger.error(
      '%s: cvs2svn uses the anydbm package, which depends on lower level '
          'dbm\n'
      'libraries.  Your system has %s, with which cvs2svn is known to have\n'
      'problems.  To use cvs2svn, you must install a Python dbm library '
          'other than\n'
      'dumbdbm or dbm.  See '
          'http://python.org/doc/current/lib/module-anydbm.html\n'
      'for more information.\n'
      % (error_prefix, anydbm._defaultmod.__name__,)
      )
  sys.exit(1)

# 3. If we are using the old bsddb185 module, then try prefer gdbm instead.
#    Unfortunately, gdbm appears not to be trouble free, either.
if hasattr(anydbm._defaultmod, 'bsddb') \
    and not hasattr(anydbm._defaultmod.bsddb, '__version__'):
  try:
    gdbm = __import__('gdbm')
  except ImportError:
    logger.warn(
コード例 #25
0
  def set_revision_info(self, revision, log, text):
    if revision in self.revisions_seen:
      # One common form of CVS repository corruption is that the
      # Deltatext block for revision 1.1 appears twice.  CollectData
      # has already warned about this problem; here we can just ignore
      # it.
      return
    else:
      self.revisions_seen.add(revision)

    cvs_rev_id = self.cvs_file_items.original_ids[revision]
    if is_trunk_revision(revision):
      # On trunk, revisions are encountered in reverse order (1.<N>
      # ... 1.1) and deltas are inverted.  The first text that we see
      # is the fulltext for the HEAD revision.  After that, the text
      # corresponding to revision 1.N is the delta (1.<N+1> ->
      # 1.<N>)).  We have to invert the deltas here so that we can
      # read the revisions out in dependency order; that is, for
      # revision 1.1 we want the fulltext, and for revision 1.<N> we
      # want the delta (1.<N-1> -> 1.<N>).  This means that we can't
      # compute the delta for a revision until we see its logical
      # parent.  When we finally see revision 1.1 (which is recognized
      # because it doesn't have a parent), we can record the diff (1.1
      # -> 1.2) for revision 1.2, and also the fulltext for 1.1.

      if revision == self.head_revision:
        # This is HEAD, as fulltext.  Initialize the RCSStream so
        # that we can compute deltas backwards in time.
        self._rcs_stream = RCSStream(text)
        self._rcs_stream_revision = revision
      else:
        # Any other trunk revision is a backward delta.  Apply the
        # delta to the RCSStream to mutate it to the contents of this
        # revision, and also to get the reverse delta, which we store
        # as the forward delta of our child revision.
        try:
          text = self._rcs_stream.invert_diff(text)
        except MalformedDeltaException, e:
          logger.error(
              'Malformed RCS delta in %s, revision %s: %s'
              % (self.cvs_file_items.cvs_file.rcs_path, revision, e)
              )
          raise RuntimeError()
        text_record = DeltaTextRecord(
            self.cvs_file_items.original_ids[self._rcs_stream_revision],
            cvs_rev_id
            )
        self.revision_collector._writeout(text_record, text)
        self._rcs_stream_revision = revision

      if revision == self.revision_1_1:
        # This is revision 1.1.  Write its fulltext:
        text_record = FullTextRecord(cvs_rev_id)
        self.revision_collector._writeout(
            text_record, self._rcs_stream.get_text()
            )

        # There will be no more trunk revisions delivered, so free the
        # RCSStream.
        del self._rcs_stream
        del self._rcs_stream_revision
コード例 #26
0
 def callback_create(self, option, opt_str, value, parser):
     logger.error(
         warning_prefix +
         ': The behaviour produced by the --create option is now the '
         'default;\n'
         'passing the option is deprecated.\n')
コード例 #27
0
#    so that the dbhash module used by anydbm will use bsddb3.
try:
    import bsddb3
    sys.modules['bsddb'] = sys.modules['bsddb3']
except ImportError:
    pass

# 2. These DBM modules are not good for cvs2svn.
import anydbm
if anydbm._defaultmod.__name__ in ['dumbdbm', 'dbm']:
    logger.error(
        '%s: cvs2svn uses the anydbm package, which depends on lower level '
        'dbm\n'
        'libraries.  Your system has %s, with which cvs2svn is known to have\n'
        'problems.  To use cvs2svn, you must install a Python dbm library '
        'other than\n'
        'dumbdbm or dbm.  See '
        'http://python.org/doc/current/lib/module-anydbm.html\n'
        'for more information.\n' % (
            error_prefix,
            anydbm._defaultmod.__name__,
        ))
    sys.exit(1)

# 3. If we are using the old bsddb185 module, then try prefer gdbm instead.
#    Unfortunately, gdbm appears not to be trouble free, either.
if hasattr(anydbm._defaultmod, 'bsddb') \
    and not hasattr(anydbm._defaultmod.bsddb, '__version__'):
    try:
        gdbm = __import__('gdbm')
    except ImportError:
        logger.warn(
コード例 #28
0
 def callback_dump_only(self, option, opt_str, value, parser):
     parser.values.dump_only = True
     logger.error(warning_prefix +
                  ': The --dump-only option is deprecated (it is implied '
                  'by --dumpfile).\n')