예제 #1
0
def main(usage):
    if getattr(sys.stdout, "encoding", None) != "UTF-8":
        usage = usage.replace(u"\xaf", u"-")
    parser = OptionParser(usage=usage)
    parser.add_option(
        "--username",
        help="specify SVN username to use when modifying groups or mappings")
    options, args = parser.parse_args()
    if not args or args[0] == "help":
        parser.print_help()
        return 0
    command = args[0]
    command_args = args[1:]

    username_provider = UsernameProvider(options.username)
    server = ServerApi(CODEMAPPING_API_URL, username_provider)
    svn = SvnApi(SVN_BASE_URL)
    command_executor = CommandExecutor(server, svn, sys.stdout)
    command_handler = getattr(command_executor,
                              "cmd_" + command.replace("-", "_"), None)
    try:
        if command_handler is None:
            usage_error("unknown subcommand: {0}".format(command))
        command_handler(*command_args)
        return 0
    except (ExecutionError, UsageError, IOError) as e:
        if isinstance(e, IOError) and e.errno == EPIPE:
            return 1
        if isinstance(e, UsageError):
            parser.print_help()
            sys.stderr.write("\n")
        sys.stderr.write("codemapper: error: {0}\n".format(e))
        return 1
예제 #2
0
 def cmd_add(self, pattern, group_name, triggers_katt2):
     triggers_katt2 = triggers_katt2.strip().lower()
     if triggers_katt2 not in ["true", "false"]:
         usage_error("TRIGGERS_KATT2 argument should be true or false.")
     pattern = self._guess_and_verify_pattern(pattern)
     group = self._get_group_by_name(group_name)
     self._add_mapping(pattern, group, triggers_katt2)
예제 #3
0
def _execute_new():
    config_path = _get_config_path()
    if isfile(config_path):
        if options.config is None:
            usage_error('''\
Found an existing review configuration at %(config_path)s.

Do you want to create a new review using this configuration?
If so, run "review new -c %(config_path)s".

Or did you want to update an existing review using this configuration?
If so, run "review update" instead.\
''' % {"config_path": config_path})
        else:
            review_file_set = ReviewFileSet(config_path)
            if any([
                    review.review_id is not None
                    for review in review_file_set.review_config
            ]):
                usage_error('''\
Expected no reviews with IDs listed in "%s" when running a "new" command.

Did you mean to run an "update" command?
If yes, run "review update -c %s ...".\
''' % (options.config, config_path))

            review_file_set.review_state.reset()
    else:
        review_file_set = \
            _init_default_review_config_file(config_path, None, False)

    if options.uncommitted:
        review_file_set.review_state.set_uncommitted(options.uncommitted)

    _post_reviews_in_config(review_file_set)
예제 #4
0
def _get_config_path():
    branch_url = "." if options.branch_url is None else options.branch_url
    if branch_url == "." and options.config is None:
        return _get_default_config_path()
    elif options.config is not None:
        return options.config
    else:
        usage_error('Please specify a review configuration file'
                    ' with "-c REVIEWCONFIG".')
예제 #5
0
 def cmd_map_diff(self, path):
     if path is None:
         if stdin.isatty():
             usage_error("please pipe a diff into \"codemapper map-diff\","
                         " or provide a path to a .diff/.patch file")
         diff_fp = stdin
     else:
         diff_fp = open(path)
     patternish_paths = self._get_patternish_paths_from_diff(diff_fp)
     self._map_paths(patternish_paths)
예제 #6
0
def _execute_with_interaction():
    unexpected_options = ['config', 'diff', 'unpushed']

    if len(args) != 0 or any(
        [getattr(options, name) for name in unexpected_options]):
        usage_error('Expected a "new" or "update" command when using one of'
                    ' the following options: {0}'.format(
                        ', '.join(unexpected_options)))

    review_file_set = _user_choose_review_config()
    if review_file_set is not None:
        _post_reviews_in_config(review_file_set)
예제 #7
0
 def inner(self, *args):
     lower = min_num
     upper = lower if max_num is None else max_num
     if not (lower <= len(args) <= upper):
         message = "subcommand expects "
         if upper == lower:
             message += "{0} argument{1}".format(
                 lower, "" if lower == 1 else "s")
         else:
             message += "between {0} and {1} arguments".format(
                 lower, upper)
         usage_error(message)
     # Set missing arguments to None
     args = list(args) + [None] * (upper - len(args))
     return func(self, *args)
예제 #8
0
def _check_for_mutually_exclusive_options():
    if options.unpushed:
        if options.parent is not None:
            usage_error(
                'options --unpushed and --parent are mutually exclusive')
        elif options.pushed:
            usage_error(
                'options --unpushed and --pushed are mutually exclusive')

    if options.diff is not None:
        if options.parent is not None:
            usage_error('options --diff and --parent are mutually exclusive')
        elif options.unpushed:
            usage_error('options --diff and --unpushed are mutually exclusive')
        elif options.pushed:
            usage_error('options --diff and --pushed are mutually exclusive')
예제 #9
0
def main(usage):
    global options

    parser, options, args = _get_options(usage)

    try:
        if len(args) == 0:
            parser.print_help()
            sys.exit(0)

        if len(args) > 1:
            usage_error("Too many arguments.")

        # validate option --line
        if options.line and not options.line.isdigit():
            usage_error("Invalid line number specified with option \"-l\"")

        # validate option --revision
        if options.revision and not options.revision.isdigit():
            usage_error("Invalid revision specified with option \"-r\"")

        # set svn authentication
        svn_common.SVN_AUTH = svn_common.SvnAuth(options.svn_username,
                                                 options.svn_password)

        # verify input path
        path_or_url = args[0]
        path_info = svn_common.SvnPathInfo(path_or_url, svn_common.SVN_AUTH)
        if options.line and path_info.node_kind != "file":
            usage_error(
                "The --line option requires the path/URL to refer to a file")

        svn_path = SvnPath(path_info.repository_root, path_info.url,
                           path_info.revision)

        # decide if remotesvn shall be used
        svn_common.REMOTESVN_ENABLED = \
            svn_common.should_enable_remotesvn_if_ping_is_slow()

        if options.line:
            _execute_line_trace(svn_path, options.revision, int(options.line))
        else:
            _execute_file_trace(svn_path, options.revision)
    except ExecutionError as ex:
        print >> sys.stderr, "Error: %s" % ex
        sys.exit(1)
    except UsageError as ex:
        print >> sys.stderr, '''\

%s

Run "tracecommit --help" for usage information.''' % ex
        sys.exit(2)
    except KeyboardInterrupt:
        print
        sys.exit(3)
예제 #10
0
def _init_default_review_config_file(config_path, review_id, unpushed, parent):
    if (not unpushed and not options.pushed and options.diff is None
            and _do_unpushed_commits_exist()):
        usage_error(WORKING_COPY_HAS_UNPUSHED_COMMITS)

    review_file_set = ReviewFileSet(config_path)
    review_config = review_file_set.review_config
    review_state = review_file_set.review_state

    review_state.set_unpushed(unpushed)
    review_state.set_branch_parent(parent)
    review_config.add_review(review_id, '-i *')
    if not options.dry_run:
        print('Creating review configuration file {0}.'.format(config_path))
        review_config.save()

    return review_file_set
예제 #11
0
def _get_diff(parent, unpushed):
    if options.diff is not None:
        if not isfile(options.diff):
            error('diff file {0} does not exist.'.format(options.diff))

        return options.diff

    if (not unpushed and not options.pushed and _do_unpushed_commits_exist()):
        usage_error(WORKING_COPY_HAS_UNPUSHED_COMMITS)

    if unpushed:
        branch = ''
    else:
        branch = 'origin/{0}'.format(repo.branch_name)

    cmd = [
        'git', 'diff', '{0}...{1}'.format(parent, branch), '--full-index',
        '--no-color'
    ]

    return _generate_diff(cmd)
예제 #12
0
def _execute_new():
    config_path = _get_config_path()
    if isfile(config_path):
        if options.config is None:
            usage_error(USAGE_ERROR_CONFIG_FOUND.format(config_path))
        else:
            review_file_set = ReviewFileSet(config_path)
            if any([
                    review.review_id is not None
                    for review in review_file_set.review_config
            ]):
                usage_error(
                    USAGE_ERROR_ID_FOUND_WITH_NEW.format(
                        options.config, config_path))
            review_file_set.review_state.reset()
    else:
        review_file_set = _init_default_review_config_file(
            config_path, None, options.unpushed, None)

    review_file_set.review_state.set_branch_parent(
        _get_branch_parent(options.unpushed))

    _post_reviews_in_config(review_file_set)