diff options
Diffstat (limited to 'cvs2svn_lib/run_options.py')
-rw-r--r-- | cvs2svn_lib/run_options.py | 1035 |
1 files changed, 0 insertions, 1035 deletions
diff --git a/cvs2svn_lib/run_options.py b/cvs2svn_lib/run_options.py deleted file mode 100644 index 27d2ea6..0000000 --- a/cvs2svn_lib/run_options.py +++ /dev/null @@ -1,1035 +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 classes to set common cvs2xxx run options.""" - -import sys -import re -import optparse -from optparse import OptionGroup -import time - -from cvs2svn_lib.version import VERSION -from cvs2svn_lib import config -from cvs2svn_lib.common import warning_prefix -from cvs2svn_lib.common import error_prefix -from cvs2svn_lib.common import FatalError -from cvs2svn_lib.common import CVSTextDecoder -from cvs2svn_lib.log import Log -from cvs2svn_lib.context import Ctx -from cvs2svn_lib.man_writer import ManOption -from cvs2svn_lib.pass_manager import InvalidPassError -from cvs2svn_lib.symbol_strategy import AllBranchRule -from cvs2svn_lib.symbol_strategy import AllTagRule -from cvs2svn_lib.symbol_strategy import BranchIfCommitsRule -from cvs2svn_lib.symbol_strategy import ExcludeRegexpStrategyRule -from cvs2svn_lib.symbol_strategy import ForceBranchRegexpStrategyRule -from cvs2svn_lib.symbol_strategy import ForceTagRegexpStrategyRule -from cvs2svn_lib.symbol_strategy import ExcludeTrivialImportBranchRule -from cvs2svn_lib.symbol_strategy import HeuristicStrategyRule -from cvs2svn_lib.symbol_strategy import UnambiguousUsageRule -from cvs2svn_lib.symbol_strategy import HeuristicPreferredParentRule -from cvs2svn_lib.symbol_strategy import SymbolHintsFileRule -from cvs2svn_lib.symbol_transform import ReplaceSubstringsSymbolTransform -from cvs2svn_lib.symbol_transform import RegexpSymbolTransform -from cvs2svn_lib.symbol_transform import NormalizePathsSymbolTransform -from cvs2svn_lib.property_setters import AutoPropsPropertySetter -from cvs2svn_lib.property_setters import CVSBinaryFileDefaultMimeTypeSetter -from cvs2svn_lib.property_setters import CVSBinaryFileEOLStyleSetter -from cvs2svn_lib.property_setters import CVSRevisionNumberSetter -from cvs2svn_lib.property_setters import DefaultEOLStyleSetter -from cvs2svn_lib.property_setters import EOLStyleFromMimeTypeSetter -from cvs2svn_lib.property_setters import ExecutablePropertySetter -from cvs2svn_lib.property_setters import KeywordsPropertySetter -from cvs2svn_lib.property_setters import MimeMapper -from cvs2svn_lib.property_setters import SVNBinaryFileKeywordsPropertySetter - - -usage = """\ -Usage: %prog --options OPTIONFILE - %prog [OPTION...] OUTPUT-OPTION CVS-REPOS-PATH""" - -description="""\ -Convert a CVS repository into a Subversion repository, including history. -""" - -authors = u"""\ -Main authors are: -.br -C. Michael Pilato <cmpilato@collab.net> -.br -Greg Stein <gstein@lyra.org> -.br -Branko \u010cibej <brane@xbc.nu> -.br -Blair Zajac <blair@orcaware.com> -.br -Max Bowsher <maxb@ukf.net> -.br -Brian Fitzpatrick <fitz@red-bean.com> -.br -Tobias Ringstr\u00f6m <tobias@ringstrom.mine.nu> -.br -Karl Fogel <kfogel@collab.net> -.br -Erik H\u00fclsmann <e.huelsmann@gmx.net> -.br -David Summers <david@summersoft.fay.ar.us> -.br -Michael Haggerty <mhagger@alum.mit.edu> -.PP -Manpage was written for the Debian GNU/Linux system by -Laszlo 'GCS' Boszormenyi <gcs@lsc.hu> (but may be used by others). -""" - - -class IncompatibleOption(ManOption): - """A ManOption that is incompatible with the --options option. - - Record that the option was used so that error checking can later be - done.""" - - def __init__(self, *args, **kw): - ManOption.__init__(self, *args, **kw) - - def take_action(self, action, dest, opt, value, values, parser): - oio = parser.values.options_incompatible_options - if opt not in oio: - oio.append(opt) - return ManOption.take_action( - self, action, dest, opt, value, values, parser - ) - - -class ContextOption(ManOption): - """A ManOption that stores its value to Ctx.""" - - def __init__(self, *args, **kw): - if kw.get('action') not in self.STORE_ACTIONS: - raise ValueError('Invalid action: %s' % (kw['action'],)) - - self.__compatible_with_option = kw.pop('compatible_with_option', False) - self.__action = kw.pop('action') - try: - self.__dest = kw.pop('dest') - except KeyError: - opt = args[0] - if not opt.startswith('--'): - raise ValueError - self.__dest = opt[2:].replace('-', '_') - if 'const' in kw: - self.__const = kw.pop('const') - - kw['action'] = 'callback' - kw['callback'] = self.__callback - - ManOption.__init__(self, *args, **kw) - - def __callback(self, option, opt_str, value, parser): - if not self.__compatible_with_option: - oio = parser.values.options_incompatible_options - if opt_str not in oio: - oio.append(opt_str) - - action = self.__action - dest = self.__dest - - if action == "store": - setattr(Ctx(), dest, value) - elif action == "store_const": - setattr(Ctx(), dest, self.__const) - elif action == "store_true": - setattr(Ctx(), dest, True) - elif action == "store_false": - setattr(Ctx(), dest, False) - elif action == "append": - getattr(Ctx(), dest).append(value) - elif action == "count": - setattr(Ctx(), dest, getattr(Ctx(), dest, 0) + 1) - else: - raise RuntimeError("unknown action %r" % self.__action) - - return 1 - - -class IncompatibleOptionsException(FatalError): - pass - - -# Options that are not allowed to be used with --trunk-only: -SYMBOL_OPTIONS = [ - '--symbol-transform', - '--symbol-hints', - '--force-branch', - '--force-tag', - '--exclude', - '--keep-trivial-imports', - '--symbol-default', - '--no-cross-branch-commits', - ] - -class SymbolOptionsWithTrunkOnlyException(IncompatibleOptionsException): - def __init__(self): - IncompatibleOptionsException.__init__( - self, - 'The following symbol-related options cannot be used together\n' - 'with --trunk-only:\n' - ' %s' - % ('\n '.join(SYMBOL_OPTIONS),) - ) - - -def not_both(opt1val, opt1name, opt2val, opt2name): - """Raise an exception if both opt1val and opt2val are set.""" - if opt1val and opt2val: - raise IncompatibleOptionsException( - "cannot pass both '%s' and '%s'." % (opt1name, opt2name,) - ) - - -class RunOptions(object): - """A place to store meta-options that are used to start the conversion.""" - - def __init__(self, progname, cmd_args, pass_manager): - """Process the command-line options, storing run options to SELF. - - PROGNAME is the name of the program, used in the usage string. - CMD_ARGS is the list of command-line arguments passed to the - program. PASS_MANAGER is an instance of PassManager, needed to - help process the -p and --help-passes options.""" - - self.progname = progname - self.cmd_args = cmd_args - self.pass_manager = pass_manager - self.start_pass = 1 - self.end_pass = self.pass_manager.num_passes - self.profiling = False - - self.projects = [] - - # A list of one list of SymbolStrategyRules for each project: - self.project_symbol_strategy_rules = [] - - parser = self.parser = optparse.OptionParser( - usage=usage, - description=self.get_description(), - add_help_option=False, - ) - # A place to record any options used that are incompatible with - # --options: - parser.set_default('options_incompatible_options', []) - - # Populate the options parser with the options, one group at a - # time: - parser.add_option_group(self._get_options_file_options_group()) - parser.add_option_group(self._get_output_options_group()) - parser.add_option_group(self._get_conversion_options_group()) - parser.add_option_group(self._get_symbol_handling_options_group()) - parser.add_option_group(self._get_subversion_properties_options_group()) - parser.add_option_group(self._get_extraction_options_group()) - parser.add_option_group(self._get_environment_options_group()) - parser.add_option_group(self._get_partial_conversion_options_group()) - parser.add_option_group(self._get_information_options_group()) - - (self.options, self.args) = parser.parse_args(args=self.cmd_args) - - # Now the log level has been set; log the time when the run started: - Log().verbose( - time.strftime( - 'Conversion start time: %Y-%m-%d %I:%M:%S %Z', - time.localtime(Log().start_time) - ) - ) - - if self.options.options_file_found: - # Check that no options that are incompatible with --options - # were used: - self.verify_option_compatibility() - else: - # --options was not specified. So do the main initialization - # based on other command-line options: - self.process_options() - - # Check for problems with the options: - self.check_options() - - def get_description(self): - return description - - def _get_options_file_options_group(self): - group = OptionGroup( - self.parser, 'Configuration via options file' - ) - self.parser.set_default('options_file_found', False) - group.add_option(ManOption( - '--options', type='string', - action='callback', callback=self.callback_options, - help=( - 'read the conversion options from PATH. This ' - 'method allows more flexibility than using ' - 'command-line options. See documentation for info' - ), - man_help=( - 'Read the conversion options from \\fIpath\\fR instead of from ' - 'the command line. This option allows far more conversion ' - 'flexibility than can be achieved using the command-line alone. ' - 'See the documentation for more information. Only the following ' - 'command-line options are allowed in combination with ' - '\\fB--options\\fR: \\fB-h\\fR/\\fB--help\\fR, ' - '\\fB--help-passes\\fR, \\fB--version\\fR, ' - '\\fB-v\\fR/\\fB--verbose\\fR, \\fB-q\\fR/\\fB--quiet\\fR, ' - '\\fB-p\\fR/\\fB--pass\\fR/\\fB--passes\\fR, \\fB--dry-run\\fR, ' - '\\fB--profile\\fR, \\fB--sort\\fR, \\fB--trunk-only\\fR, ' - '\\fB--encoding\\fR, and \\fB--fallback-encoding\\fR. ' - 'Options are processed in the order specified on the command ' - 'line.' - ), - metavar='PATH', - )) - return group - - def _get_output_options_group(self): - group = OptionGroup(self.parser, 'Output options') - return group - - def _get_conversion_options_group(self): - group = OptionGroup(self.parser, 'Conversion options') - group.add_option(ContextOption( - '--trunk-only', - action='store_true', - compatible_with_option=True, - help='convert only trunk commits, not tags nor branches', - man_help=( - 'Convert only trunk commits, not tags nor branches.' - ), - )) - group.add_option(ManOption( - '--encoding', type='string', - action='callback', callback=self.callback_encoding, - help=( - 'encoding for paths and log messages in CVS repos. ' - 'If option is specified multiple times, encoders ' - 'are tried in order until one succeeds. See ' - 'http://docs.python.org/lib/standard-encodings.html ' - 'for a list of standard Python encodings.' - ), - man_help=( - 'Use \\fIencoding\\fR as the encoding for filenames, log ' - 'messages, and author names in the CVS repos. This option ' - 'may be specified multiple times, in which case the encodings ' - 'are tried in order until one succeeds. Default: ascii. See ' - 'http://docs.python.org/lib/standard-encodings.html for a list ' - 'of other standard encodings.' - ), - metavar='ENC', - )) - group.add_option(ManOption( - '--fallback-encoding', type='string', - action='callback', callback=self.callback_fallback_encoding, - help='If all --encodings fail, use lossy encoding with ENC', - man_help=( - 'If none of the encodings specified with \\fB--encoding\\fR ' - 'succeed in decoding an author name or log message, then fall ' - 'back to using \\fIencoding\\fR in lossy \'replace\' mode. ' - 'Use of this option may cause information to be lost, but at ' - 'least it allows the conversion to run to completion. This ' - 'option only affects the encoding of log messages and author ' - 'names; there is no fallback encoding for filenames. (By ' - 'using an \\fB--options\\fR file, it is possible to specify ' - 'a fallback encoding for filenames.) Default: disabled.' - ), - metavar='ENC', - )) - group.add_option(ContextOption( - '--retain-conflicting-attic-files', - action='store_true', - help=( - 'if a file appears both in and out of ' - 'the CVS Attic, then leave the attic version in a ' - 'SVN directory called "Attic"' - ), - man_help=( - 'If a file appears both inside an outside of the CVS attic, ' - 'retain the attic version in an SVN subdirectory called ' - '\'Attic\'. (Normally this situation is treated as a fatal ' - 'error.)' - ), - )) - - return group - - def _get_symbol_handling_options_group(self): - group = OptionGroup(self.parser, 'Symbol handling') - self.parser.set_default('symbol_transforms', []) - group.add_option(IncompatibleOption( - '--symbol-transform', type='string', - action='callback', callback=self.callback_symbol_transform, - help=( - 'transform symbol names from P to S, where P and S ' - 'use Python regexp and reference syntax ' - 'respectively. P must match the whole symbol name' - ), - man_help=( - 'Transform RCS/CVS symbol names before entering them into ' - 'Subversion. \\fIpattern\\fR is a Python regexp pattern that ' - 'is matches against the entire symbol name; \\fIreplacement\\fR ' - 'is a replacement using Python\'s regexp reference syntax. ' - 'You may specify any number of these options; they will be ' - 'applied in the order given on the command line.' - ), - metavar='P:S', - )) - self.parser.set_default('symbol_strategy_rules', []) - group.add_option(IncompatibleOption( - '--symbol-hints', type='string', - action='callback', callback=self.callback_symbol_hints, - help='read symbol conversion hints from PATH', - man_help=( - 'Read symbol conversion hints from \\fIpath\\fR. The format of ' - '\\fIpath\\fR is the same as the format output by ' - '\\fB--write-symbol-info\\fR, namely a text file with four ' - 'whitespace-separated columns: \\fIproject-id\\fR, ' - '\\fIsymbol\\fR, \\fIconversion\\fR, and ' - '\\fIparent-lod-name\\fR. \\fIproject-id\\fR is the numerical ' - 'ID of the project to which the symbol belongs, counting from ' - '0. \\fIproject-id\\fR can be set to \'.\' if ' - 'project-specificity is not needed. \\fIsymbol-name\\fR is the ' - 'name of the symbol being specified. \\fIconversion\\fR ' - 'specifies how the symbol should be converted, and can be one ' - 'of the values \'branch\', \'tag\', or \'exclude\'. If ' - '\\fIconversion\\fR is \'.\', then this rule does not affect ' - 'how the symbol is converted. \\fIparent-lod-name\\fR is the ' - 'name of the symbol from which this symbol should sprout, or ' - '\'.trunk.\' if the symbol should sprout from trunk. If ' - '\\fIparent-lod-name\\fR is omitted or \'.\', then this rule ' - 'does not affect the preferred parent of this symbol. The file ' - 'may contain blank lines or comment lines (lines whose first ' - 'non-whitespace character is \'#\').' - ), - metavar='PATH', - )) - self.parser.set_default('symbol_default', 'heuristic') - group.add_option(IncompatibleOption( - '--symbol-default', type='choice', - choices=['heuristic', 'strict', 'branch', 'tag'], - action='store', - help=( - 'specify how ambiguous symbols are converted. ' - 'OPT is "heuristic" (default), "strict", "branch", ' - 'or "tag"' - ), - man_help=( - 'Specify how to convert ambiguous symbols (those that appear in ' - 'the CVS archive as both branches and tags). \\fIopt\\fR must ' - 'be \'heuristic\' (decide how to treat each ambiguous symbol ' - 'based on whether it was used more often as a branch/tag in ' - 'CVS), \'strict\' (no default; every ambiguous symbol has to be ' - 'resolved manually using \\fB--force-branch\\fR, ' - '\\fB--force-tag\\fR, or \\fB--exclude\\fR), \'branch\' (treat ' - 'every ambiguous symbol as a branch), or \'tag\' (treat every ' - 'ambiguous symbol as a tag). The default is \'heuristic\'.' - ), - metavar='OPT', - )) - group.add_option(IncompatibleOption( - '--force-branch', type='string', - action='callback', callback=self.callback_force_branch, - help='force symbols matching REGEXP to be branches', - man_help=( - 'Force symbols whose names match \\fIregexp\\fR to be branches. ' - '\\fIregexp\\fR must match the whole symbol name.' - ), - metavar='REGEXP', - )) - group.add_option(IncompatibleOption( - '--force-tag', type='string', - action='callback', callback=self.callback_force_tag, - help='force symbols matching REGEXP to be tags', - man_help=( - 'Force symbols whose names match \\fIregexp\\fR to be tags. ' - '\\fIregexp\\fR must match the whole symbol name.' - ), - metavar='REGEXP', - )) - group.add_option(IncompatibleOption( - '--exclude', type='string', - action='callback', callback=self.callback_exclude, - help='exclude branches and tags matching REGEXP', - man_help=( - 'Exclude branches and tags whose names match \\fIregexp\\fR ' - 'from the conversion. \\fIregexp\\fR must match the whole ' - 'symbol name.' - ), - metavar='REGEXP', - )) - self.parser.set_default('keep_trivial_imports', False) - group.add_option(IncompatibleOption( - '--keep-trivial-imports', - action='store_true', - help=( - 'do not exclude branches that were only used for ' - 'a single import (usually these are unneeded)' - ), - man_help=( - 'Do not exclude branches that were only used for a single ' - 'import. (By default such branches are excluded because they ' - 'are usually created by the inappropriate use of \\fBcvs ' - 'import\\fR.)' - ), - )) - - return group - - def _get_subversion_properties_options_group(self): - group = OptionGroup(self.parser, 'Subversion properties') - group.add_option(ContextOption( - '--username', type='string', - action='store', - help='username for cvs2svn-synthesized commits', - man_help=( - 'Set the default username to \\fIname\\fR when cvs2svn needs ' - 'to generate a commit for which CVS does not record the ' - 'original username. This happens when a branch or tag is ' - 'created. The default is to use no author at all for such ' - 'commits.' - ), - metavar='NAME', - )) - self.parser.set_default('auto_props_files', []) - group.add_option(IncompatibleOption( - '--auto-props', type='string', - action='append', dest='auto_props_files', - help=( - 'set file properties from the auto-props section ' - 'of a file in svn config format' - ), - man_help=( - 'Specify a file in the format of Subversion\'s config file, ' - 'whose [auto-props] section can be used to set arbitrary ' - 'properties on files in the Subversion repository based on ' - 'their filenames. (The [auto-props] section header must be ' - 'present; other sections of the config file, including the ' - 'enable-auto-props setting, are ignored.) Filenames are matched ' - 'to the filename patterns case-insensitively.' - - ), - metavar='FILE', - )) - self.parser.set_default('mime_types_files', []) - group.add_option(IncompatibleOption( - '--mime-types', type='string', - action='append', dest='mime_types_files', - help=( - 'specify an apache-style mime.types file for setting ' - 'svn:mime-type' - ), - man_help=( - 'Specify an apache-style mime.types \\fIfile\\fR for setting ' - 'svn:mime-type.' - ), - metavar='FILE', - )) - self.parser.set_default('eol_from_mime_type', False) - group.add_option(IncompatibleOption( - '--eol-from-mime-type', - action='store_true', - help='set svn:eol-style from mime type if known', - man_help=( - 'For files that don\'t have the kb expansion mode but have a ' - 'known mime type, set the eol-style based on the mime type. ' - 'For such files, set svn:eol-style to "native" if the mime type ' - 'begins with "text/", and leave it unset (i.e., no EOL ' - 'translation) otherwise. Files with unknown mime types are ' - 'not affected by this option. This option has no effect ' - 'unless the \\fB--mime-types\\fR option is also specified.' - ), - )) - group.add_option(IncompatibleOption( - '--default-eol', type='choice', - choices=['binary', 'native', 'CRLF', 'LF', 'CR'], - action='store', - help=( - 'default svn:eol-style for non-binary files with ' - 'undetermined mime types. STYLE is "binary" ' - '(default), "native", "CRLF", "LF", or "CR"' - ), - man_help=( - 'Set svn:eol-style to \\fIstyle\\fR for files that don\'t have ' - 'the CVS \'kb\' expansion mode and whose end-of-line ' - 'translation mode hasn\'t been determined by one of the other ' - 'options. \\fIstyle\\fR must be \'binary\' (default), ' - '\'native\', \'CRLF\', \'LF\', or \'CR\'.' - ), - metavar='STYLE', - )) - self.parser.set_default('keywords_off', False) - group.add_option(IncompatibleOption( - '--keywords-off', - action='store_true', - help=( - 'don\'t set svn:keywords on any files (by default, ' - 'cvs2svn sets svn:keywords on non-binary files to "%s")' - % (config.SVN_KEYWORDS_VALUE,) - ), - man_help=( - 'By default, cvs2svn sets svn:keywords on CVS files to "author ' - 'id date" if the mode of the RCS file in question is either kv, ' - 'kvl or unset. If you use the --keywords-off switch, cvs2svn ' - 'will not set svn:keywords for any file. While this will not ' - 'touch the keywords in the contents of your files, Subversion ' - 'will not expand them.' - ), - )) - group.add_option(ContextOption( - '--keep-cvsignore', - action='store_true', - help=( - 'keep .cvsignore files (in addition to creating ' - 'the analogous svn:ignore properties)' - ), - man_help=( - 'Include \\fI.cvsignore\\fR files in the output. (Normally ' - 'they are unneeded because cvs2svn sets the corresponding ' - '\\fIsvn:ignore\\fR properties.)' - ), - )) - group.add_option(IncompatibleOption( - '--cvs-revnums', - action='callback', callback=self.callback_cvs_revnums, - help='record CVS revision numbers as file properties', - man_help=( - 'Record CVS revision numbers as file properties in the ' - 'Subversion repository. (Note that unless it is removed ' - 'explicitly, the last CVS revision number will remain ' - 'associated with the file even after the file is changed ' - 'within Subversion.)' - ), - )) - - # Deprecated options: - group.add_option(IncompatibleOption( - '--no-default-eol', - action='store_const', dest='default_eol', const=None, - help=optparse.SUPPRESS_HELP, - man_help=optparse.SUPPRESS_HELP, - )) - self.parser.set_default('auto_props_ignore_case', True) - # True is the default now, so this option has no effect: - group.add_option(IncompatibleOption( - '--auto-props-ignore-case', - action='store_true', - help=optparse.SUPPRESS_HELP, - man_help=optparse.SUPPRESS_HELP, - )) - - return group - - def _get_extraction_options_group(self): - group = OptionGroup(self.parser, 'Extraction options') - - return group - - def _get_environment_options_group(self): - group = OptionGroup(self.parser, 'Environment options') - group.add_option(ContextOption( - '--tmpdir', type='string', - action='store', - help=( - 'directory to use for temporary data files ' - '(default "cvs2svn-tmp")' - ), - man_help=( - 'Set the \\fIpath\\fR to use for temporary data. Default ' - 'is a directory called \\fIcvs2svn-tmp\\fR under the current ' - 'directory.' - ), - metavar='PATH', - )) - self.parser.set_default('co_executable', config.CO_EXECUTABLE) - group.add_option(IncompatibleOption( - '--co', type='string', - action='store', dest='co_executable', - help='path to the "co" program (required if --use-rcs)', - man_help=( - 'Path to the \\fIco\\fR program. (\\fIco\\fR is needed if the ' - '\\fB--use-rcs\\fR option is used.)' - ), - metavar='PATH', - )) - self.parser.set_default('cvs_executable', config.CVS_EXECUTABLE) - group.add_option(IncompatibleOption( - '--cvs', type='string', - action='store', dest='cvs_executable', - help='path to the "cvs" program (required if --use-cvs)', - man_help=( - 'Path to the \\fIcvs\\fR program. (\\fIcvs\\fR is needed if the ' - '\\fB--use-cvs\\fR option is used.)' - ), - metavar='PATH', - )) - group.add_option(ContextOption( - '--sort', type='string', - action='store', dest='sort_executable', - compatible_with_option=True, - help='path to the GNU "sort" program', - man_help=( - 'Path to the GNU \\fIsort\\fR program. (cvs2svn requires GNU ' - 'sort.)' - ), - metavar='PATH', - )) - - return group - - def _get_partial_conversion_options_group(self): - group = OptionGroup(self.parser, 'Partial conversions') - group.add_option(ManOption( - '--pass', type='string', - action='callback', callback=self.callback_passes, - help='execute only specified PASS of conversion', - man_help=( - 'Execute only pass \\fIpass\\fR of the conversion. ' - '\\fIpass\\fR can be specified by name or by number (see ' - '\\fB--help-passes\\fR).' - ), - metavar='PASS', - )) - group.add_option(ManOption( - '--passes', '-p', type='string', - action='callback', callback=self.callback_passes, - help=( - 'execute passes START through END, inclusive (PASS, ' - 'START, and END can be pass names or numbers)' - ), - man_help=( - 'Execute passes \\fIstart\\fR through \\fIend\\fR of the ' - 'conversion (inclusive). \\fIstart\\fR and \\fIend\\fR can be ' - 'specified by name or by number (see \\fB--help-passes\\fR). ' - 'If \\fIstart\\fR or \\fIend\\fR is missing, it defaults to ' - 'the first or last pass, respectively. For this to work the ' - 'earlier passes must have been completed before on the ' - 'same CVS repository, and the generated data files must be ' - 'in the temporary directory (see \\fB--tmpdir\\fR).' - ), - metavar='[START]:[END]', - )) - - return group - - def _get_information_options_group(self): - group = OptionGroup(self.parser, 'Information options') - group.add_option(ManOption( - '--version', - action='callback', callback=self.callback_version, - help='print the version number', - man_help='Print the version number.', - )) - group.add_option(ManOption( - '--help', '-h', - action="help", - help='print this usage message and exit with success', - man_help='Print the usage message and exit with success.', - )) - group.add_option(ManOption( - '--help-passes', - action='callback', callback=self.callback_help_passes, - help='list the available passes and their numbers', - man_help=( - 'Print the numbers and names of the conversion passes and ' - 'exit with success.' - ), - )) - group.add_option(ManOption( - '--man', - action='callback', callback=self.callback_manpage, - help='write the manpage for this program to standard output', - man_help=( - 'Output the unix-style manpage for this program to standard ' - 'output.' - ), - )) - group.add_option(ManOption( - '--verbose', '-v', - action='callback', callback=self.callback_verbose, - help='verbose (may be specified twice for debug output)', - man_help=( - 'Print more information while running. This option may be ' - 'specified twice to output voluminous debugging information.' - ), - )) - group.add_option(ManOption( - '--quiet', '-q', - action='callback', callback=self.callback_quiet, - help='quiet (may be specified twice for very quiet)', - man_help=( - 'Print less information while running. This option may be ' - 'specified twice to suppress all non-error output.' - ), - )) - group.add_option(ContextOption( - '--write-symbol-info', type='string', - action='store', dest='symbol_info_filename', - help='write information and statistics about CVS symbols to PATH.', - man_help=( - 'Write to \\fIpath\\fR symbol statistics and information about ' - 'how symbols were converted during CollateSymbolsPass.' - ), - metavar='PATH', - )) - group.add_option(ContextOption( - '--skip-cleanup', - action='store_true', - help='prevent the deletion of intermediate files', - man_help='Prevent the deletion of temporary files.', - )) - group.add_option(ManOption( - '--profile', - action='callback', callback=self.callback_profile, - help='profile with \'hotshot\' (into file cvs2svn.hotshot)', - man_help=( - 'Profile with \'hotshot\' (into file \\fIcvs2svn.hotshot\\fR).' - ), - )) - - return group - - def callback_options(self, option, opt_str, value, parser): - parser.values.options_file_found = True - self.process_options_file(value) - - def callback_encoding(self, option, opt_str, value, parser): - ctx = Ctx() - - try: - ctx.cvs_author_decoder.add_encoding(value) - ctx.cvs_log_decoder.add_encoding(value) - ctx.cvs_filename_decoder.add_encoding(value) - except LookupError, e: - raise FatalError(str(e)) - - def callback_fallback_encoding(self, option, opt_str, value, parser): - ctx = Ctx() - - try: - ctx.cvs_author_decoder.set_fallback_encoding(value) - ctx.cvs_log_decoder.set_fallback_encoding(value) - # Don't use fallback_encoding for filenames. - except LookupError, e: - raise FatalError(str(e)) - - def callback_help_passes(self, option, opt_str, value, parser): - self.pass_manager.help_passes() - sys.exit(0) - - def callback_manpage(self, option, opt_str, value, parser): - raise NotImplementedError() - - def callback_version(self, option, opt_str, value, parser): - sys.stdout.write( - '%s version %s\n' % (self.progname, VERSION) - ) - sys.exit(0) - - def callback_verbose(self, option, opt_str, value, parser): - Log().increase_verbosity() - - def callback_quiet(self, option, opt_str, value, parser): - Log().decrease_verbosity() - - def callback_passes(self, option, opt_str, value, parser): - if value.find(':') >= 0: - start_pass, end_pass = value.split(':') - self.start_pass = self.pass_manager.get_pass_number(start_pass, 1) - self.end_pass = self.pass_manager.get_pass_number( - end_pass, self.pass_manager.num_passes - ) - else: - self.end_pass = \ - self.start_pass = \ - self.pass_manager.get_pass_number(value) - - def callback_profile(self, option, opt_str, value, parser): - self.profiling = True - - def callback_symbol_hints(self, option, opt_str, value, parser): - parser.values.symbol_strategy_rules.append(SymbolHintsFileRule(value)) - - def callback_force_branch(self, option, opt_str, value, parser): - parser.values.symbol_strategy_rules.append( - ForceBranchRegexpStrategyRule(value) - ) - - def callback_force_tag(self, option, opt_str, value, parser): - parser.values.symbol_strategy_rules.append( - ForceTagRegexpStrategyRule(value) - ) - - def callback_exclude(self, option, opt_str, value, parser): - parser.values.symbol_strategy_rules.append( - ExcludeRegexpStrategyRule(value) - ) - - def callback_cvs_revnums(self, option, opt_str, value, parser): - Ctx().svn_property_setters.append(CVSRevisionNumberSetter()) - - def callback_symbol_transform(self, option, opt_str, value, parser): - [pattern, replacement] = value.split(":") - try: - parser.values.symbol_transforms.append( - RegexpSymbolTransform(pattern, replacement) - ) - except re.error: - raise FatalError("'%s' is not a valid regexp." % (pattern,)) - - def process_symbol_strategy_options(self): - """Process symbol strategy-related options.""" - - ctx = Ctx() - options = self.options - - # Add the standard symbol name cleanup rules: - self.options.symbol_transforms.extend([ - ReplaceSubstringsSymbolTransform('\\','/'), - # Remove leading, trailing, and repeated slashes: - NormalizePathsSymbolTransform(), - ]) - - if ctx.trunk_only: - if options.symbol_strategy_rules or options.keep_trivial_imports: - raise SymbolOptionsWithTrunkOnlyException() - - else: - if not options.keep_trivial_imports: - options.symbol_strategy_rules.append(ExcludeTrivialImportBranchRule()) - - options.symbol_strategy_rules.append(UnambiguousUsageRule()) - if options.symbol_default == 'strict': - pass - elif options.symbol_default == 'branch': - options.symbol_strategy_rules.append(AllBranchRule()) - elif options.symbol_default == 'tag': - options.symbol_strategy_rules.append(AllTagRule()) - elif options.symbol_default == 'heuristic': - options.symbol_strategy_rules.append(BranchIfCommitsRule()) - options.symbol_strategy_rules.append(HeuristicStrategyRule()) - else: - assert False - - # Now add a rule whose job it is to pick the preferred parents of - # branches and tags: - options.symbol_strategy_rules.append(HeuristicPreferredParentRule()) - - def process_property_setter_options(self): - """Process the options that set SVN properties.""" - - ctx = Ctx() - options = self.options - - for value in options.auto_props_files: - ctx.svn_property_setters.append( - AutoPropsPropertySetter(value, options.auto_props_ignore_case) - ) - - for value in options.mime_types_files: - ctx.svn_property_setters.append(MimeMapper(value)) - - ctx.svn_property_setters.append(CVSBinaryFileEOLStyleSetter()) - - ctx.svn_property_setters.append(CVSBinaryFileDefaultMimeTypeSetter()) - - if options.eol_from_mime_type: - ctx.svn_property_setters.append(EOLStyleFromMimeTypeSetter()) - - ctx.svn_property_setters.append( - DefaultEOLStyleSetter(options.default_eol) - ) - - ctx.svn_property_setters.append(SVNBinaryFileKeywordsPropertySetter()) - - if not options.keywords_off: - ctx.svn_property_setters.append( - KeywordsPropertySetter(config.SVN_KEYWORDS_VALUE)) - - ctx.svn_property_setters.append(ExecutablePropertySetter()) - - def process_options(self): - """Do the main configuration based on command-line options. - - This method is only called if the --options option was not - specified.""" - - raise NotImplementedError() - - def check_options(self): - """Check the the run options are OK. - - This should only be called after all options have been processed.""" - - # Convenience var, so we don't have to keep instantiating this Borg. - ctx = Ctx() - - if not self.start_pass <= self.end_pass: - raise InvalidPassError( - 'Ending pass must not come before starting pass.') - - if not ctx.dry_run and ctx.output_option is None: - raise FatalError('No output option specified.') - - if ctx.output_option is not None: - ctx.output_option.check() - - if not self.projects: - raise FatalError('No project specified.') - - 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 - Log().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: - Log().error( - '%s: No cvs-repos-path arguments are allowed with the --options ' - 'option.\n' - % (error_prefix,) - ) - sys.exit(1) - - def process_options_file(self, options_filename): - """Read options from the file named OPTIONS_FILENAME. - - Store the run options to SELF.""" - - g = { - 'ctx' : Ctx(), - 'run_options' : self, - } - execfile(options_filename, g) - - def usage(self): - self.parser.print_help() - - |