aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'cvs2svn_lib/pass_manager.py')
-rw-r--r--cvs2svn_lib/pass_manager.py215
1 files changed, 0 insertions, 215 deletions
diff --git a/cvs2svn_lib/pass_manager.py b/cvs2svn_lib/pass_manager.py
deleted file mode 100644
index 90fa2dc..0000000
--- a/cvs2svn_lib/pass_manager.py
+++ /dev/null
@@ -1,215 +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/.
-# ====================================================================
-
-"""This module contains tools to manage the passes of a conversion."""
-
-
-import time
-import gc
-
-from cvs2svn_lib import config
-from cvs2svn_lib.common import FatalError
-from cvs2svn_lib.context import Ctx
-from cvs2svn_lib.log import Log
-from cvs2svn_lib.stats_keeper import StatsKeeper
-from cvs2svn_lib.stats_keeper import read_stats_keeper
-from cvs2svn_lib.artifact_manager import artifact_manager
-
-
-class InvalidPassError(FatalError):
- def __init__(self, msg):
- FatalError.__init__(
- self, msg + '\nUse --help-passes for more information.')
-
-
-def check_for_garbage():
- # We've turned off the garbage collector because we shouldn't
- # need it (we don't create circular dependencies) and because it
- # is therefore a waste of time. So here we check for any
- # unreachable objects and generate a debug-level warning if any
- # occur:
- gc.set_debug(gc.DEBUG_SAVEALL)
- gc_count = gc.collect()
- if gc_count:
- if Log().is_on(Log.DEBUG):
- Log().debug(
- 'INTERNAL: %d unreachable object(s) were garbage collected:'
- % (gc_count,)
- )
- for g in gc.garbage:
- Log().debug(' %s' % (g,))
- del gc.garbage[:]
-
-
-class Pass(object):
- """Base class for one step of the conversion."""
-
- def __init__(self):
- # By default, use the pass object's class name as the pass name:
- self.name = self.__class__.__name__
-
- def register_artifacts(self):
- """Register artifacts (created and needed) in artifact_manager."""
-
- raise NotImplementedError
-
- def _register_temp_file(self, basename):
- """Helper method; for brevity only."""
-
- artifact_manager.register_temp_file(basename, self)
-
- def _register_temp_file_needed(self, basename):
- """Helper method; for brevity only."""
-
- artifact_manager.register_temp_file_needed(basename, self)
-
- def run(self, run_options, stats_keeper):
- """Carry out this step of the conversion.
-
- RUN_OPTIONS is an instance of RunOptions. STATS_KEEPER is an
- instance of StatsKeeper."""
-
- raise NotImplementedError
-
-
-class PassManager:
- """Manage a list of passes that can be executed separately or all at once.
-
- Passes are numbered starting with 1."""
-
- def __init__(self, passes):
- """Construct a PassManager with the specified PASSES.
-
- Internally, passes are numbered starting with 1. So PASSES[0] is
- considered to be pass number 1."""
-
- self.passes = passes
- self.num_passes = len(self.passes)
-
- def get_pass_number(self, pass_name, default=None):
- """Return the number of the pass indicated by PASS_NAME.
-
- PASS_NAME should be a string containing the name or number of a
- pass. If a number, it should be in the range 1 <= value <=
- self.num_passes. Return an integer in the same range. If
- PASS_NAME is the empty string and DEFAULT is specified, return
- DEFAULT. Raise InvalidPassError if PASS_NAME cannot be converted
- into a valid pass number."""
-
- if not pass_name and default is not None:
- assert 1 <= default <= self.num_passes
- return default
-
- try:
- # Does pass_name look like an integer?
- pass_number = int(pass_name)
- if not 1 <= pass_number <= self.num_passes:
- raise InvalidPassError(
- 'illegal value (%d) for pass number. Must be 1 through %d or\n'
- 'the name of a known pass.'
- % (pass_number,self.num_passes,))
- return pass_number
- except ValueError:
- # Is pass_name the name of one of the passes?
- for (i, the_pass) in enumerate(self.passes):
- if the_pass.name == pass_name:
- return i + 1
- raise InvalidPassError('Unknown pass name (%r).' % (pass_name,))
-
- def run(self, run_options):
- """Run the specified passes, one after another.
-
- RUN_OPTIONS will be passed to the Passes' run() methods.
- RUN_OPTIONS.start_pass is the number of the first pass that should
- be run. RUN_OPTIONS.end_pass is the number of the last pass that
- should be run. It must be that 1 <= RUN_OPTIONS.start_pass <=
- RUN_OPTIONS.end_pass <= self.num_passes."""
-
- # Convert start_pass and end_pass into the indices of the passes
- # to execute, using the Python index range convention (i.e., first
- # pass executed and first pass *after* the ones that should be
- # executed).
- index_start = run_options.start_pass - 1
- index_end = run_options.end_pass
-
- # Inform the artifact manager when artifacts are created and used:
- for (i, the_pass) in enumerate(self.passes):
- the_pass.register_artifacts()
- # Each pass creates a new version of the statistics file:
- artifact_manager.register_temp_file(
- config.STATISTICS_FILE % (i + 1,), the_pass
- )
- if i != 0:
- # Each pass subsequent to the first reads the statistics file
- # from the preceding pass:
- artifact_manager.register_temp_file_needed(
- config.STATISTICS_FILE % (i + 1 - 1,), the_pass
- )
-
- # Tell the artifact manager about passes that are being skipped this run:
- for the_pass in self.passes[0:index_start]:
- artifact_manager.pass_skipped(the_pass)
-
- start_time = time.time()
- for i in range(index_start, index_end):
- the_pass = self.passes[i]
- Log().quiet('----- pass %d (%s) -----' % (i + 1, the_pass.name,))
- artifact_manager.pass_started(the_pass)
-
- if i == 0:
- stats_keeper = StatsKeeper()
- else:
- stats_keeper = read_stats_keeper(
- artifact_manager.get_temp_file(
- config.STATISTICS_FILE % (i + 1 - 1,)
- )
- )
-
- the_pass.run(run_options, stats_keeper)
- end_time = time.time()
- stats_keeper.log_duration_for_pass(
- end_time - start_time, i + 1, the_pass.name
- )
- Log().normal(stats_keeper.single_pass_timing(i + 1))
- stats_keeper.archive(
- artifact_manager.get_temp_file(config.STATISTICS_FILE % (i + 1,))
- )
- start_time = end_time
- Ctx().clean()
- # Allow the artifact manager to clean up artifacts that are no
- # longer needed:
- artifact_manager.pass_done(the_pass, Ctx().skip_cleanup)
-
- check_for_garbage()
-
- # Tell the artifact manager about passes that are being deferred:
- for the_pass in self.passes[index_end:]:
- artifact_manager.pass_deferred(the_pass)
-
- Log().quiet(stats_keeper)
- Log().normal(stats_keeper.timings())
-
- # Consistency check:
- artifact_manager.check_clean()
-
- def help_passes(self):
- """Output (to sys.stdout) the indices and names of available passes."""
-
- print 'PASSES:'
- for (i, the_pass) in enumerate(self.passes):
- print '%5d : %s' % (i + 1, the_pass.name,)
-
-