diff --git a/git_upstream/commands/__init__.py b/git_upstream/commands/__init__.py index a48cecf..67225cd 100644 --- a/git_upstream/commands/__init__.py +++ b/git_upstream/commands/__init__.py @@ -16,9 +16,9 @@ # limitations under the License. # +import abc import argparse import os -import sys class AppendReplaceAction(argparse._AppendAction): @@ -38,10 +38,37 @@ class AppendReplaceAction(argparse._AppendAction): option_string) -def get_subcommands(subparsers): +class GitUpstreamCommand(object): + """Base command class + + To create commands simply subclass and implement the necessary abstract + methods. + """ + + __metaclass__ = abc.ABCMeta + + def __init__(self, parser): + self.parser = parser + + def validate(self, args): + """Verify the arguments passed for this command""" + return + + @abc.abstractmethod + def run(self, args): + """Execute this command""" + return + + +def get_subcommands(parser): + + subparsers = parser.add_subparsers(title="commands", metavar='', + dest='subcommand') subcommands = _find_actions(subparsers, os.path.dirname(__file__)) + parser.set_defaults(subcommands=subcommands) + return subcommands @@ -51,23 +78,18 @@ def _find_actions(subparsers, module_path): for mod in (p[:-len('.py')] for p in os.listdir(module_path) if p.endswith('.py')): __import__(__name__ + '.' + mod) - module = sys.modules[__name__ + '.' + mod] - for attr in (a for a in dir(module) if a.startswith('do_')): - command = attr[3:].replace('_', '-') - func = getattr(module, attr) - desc = func.__doc__ or '' - help = desc.strip().split('\n')[0] - args = getattr(func, 'arguments', []) - subparser = subparsers.add_parser( - command, - help=help, - description=desc) - subparser.register('action', 'append_replace', AppendReplaceAction) + for cmd_class in GitUpstreamCommand.__subclasses__(): + command = cmd_class.name + desc = cmd_class.__doc__ or None + help = desc.strip().split('\n')[0] - for (args, kwargs) in args: - subparser.add_argument(*args, **kwargs) - subparser.set_defaults(func=func) - subcommands[command] = subparser + subparser = subparsers.add_parser( + command, + help=help, + description=desc) + subparser.register('action', 'append_replace', AppendReplaceAction) + subparser.set_defaults(cmd=cmd_class(subparser)) + subcommands[command] = subparser return subcommands diff --git a/git_upstream/commands/drop.py b/git_upstream/commands/drop.py index a0ecc02..bf59959 100644 --- a/git_upstream/commands/drop.py +++ b/git_upstream/commands/drop.py @@ -15,16 +15,14 @@ # limitations under the License. # -import inspect import re from git import BadObject +from git_upstream.commands import GitUpstreamCommand from git_upstream.errors import GitUpstreamError from git_upstream.lib.utils import GitMixin -from git_upstream import log from git_upstream.log import LogDedentMixin -from git_upstream import subcommand try: from git import BadName @@ -50,6 +48,7 @@ class Drop(LogDedentMixin, GitMixin): Dropped: Walter White """ + DROP_HEADER = 'Dropped:' NOTE_REF = 'refs/notes/upstream-merge' @@ -124,25 +123,31 @@ class Drop(LogDedentMixin, GitMixin): self.commit) -@subcommand.arg('commit', metavar='', nargs=None, - help='Commit to be marked as dropped') -@subcommand.arg('-a', '--author', metavar='', - dest='author', - default=None, - help='Git author for the mark') -def do_drop(args): - """ - Mark a commit as dropped. +class DropCommand(LogDedentMixin, GitUpstreamCommand): + """Mark a commit as dropped. + Marked commits will be skipped during the upstream rebasing process. See also the "git upstream import" command. """ + name = "drop" - logger = log.get_logger('%s.%s' % (__name__, - inspect.stack()[0][0].f_code.co_name)) + def __init__(self, *args, **kwargs): + # make sure to correctly initialize inherited objects before performing + # any computation + super(DropCommand, self).__init__(*args, **kwargs) - drop = Drop(git_object=args.commit, author=args.author) + self.parser.add_argument( + 'commit', metavar='', nargs=None, + help='Commit to be marked as dropped') + self.parser.add_argument( + '-a', '--author', metavar='', dest='author', default=None, + help='Git author for the mark') - if drop.mark(): - logger.notice("Drop mark created successfully") + def run(self, args): + + drop = Drop(git_object=args.commit, author=args.author) + + if drop.mark(): + self.log.notice("Drop mark created successfully") # vim:sw=4:sts=4:ts=4:et: diff --git a/git_upstream/commands/help.py b/git_upstream/commands/help.py new file mode 100644 index 0000000..ad956b7 --- /dev/null +++ b/git_upstream/commands/help.py @@ -0,0 +1,40 @@ +# +# Copyright (c) 2012-2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from git_upstream.commands import GitUpstreamCommand +from git_upstream.log import LogDedentMixin + + +class HelpCommand(LogDedentMixin, GitUpstreamCommand): + """Display help about this program or one of its commands.""" + name = "help" + + def __init__(self, *args, **kwargs): + super(HelpCommand, self).__init__(*args, **kwargs) + + self.parser.add_argument('command', metavar='', nargs='?', + help="command to display help about") + + def run(self, args, parent_parser=None): + if getattr(args, 'command', None): + if args.command in args.subcommands: + args.subcommands[args.command].print_help() + else: + self.parser.error("'%s' is not a valid subcommand" % + args.command) + else: + parent_parser.print_help() diff --git a/git_upstream/commands/import.py b/git_upstream/commands/import.py index 1acf094..626c9e8 100644 --- a/git_upstream/commands/import.py +++ b/git_upstream/commands/import.py @@ -18,10 +18,10 @@ from abc import ABCMeta from abc import abstractmethod from collections import Sequence -import inspect from git import GitCommandError +from git_upstream.commands import GitUpstreamCommand from git_upstream.errors import GitUpstreamError from git_upstream.lib.rebaseeditor import RebaseEditor from git_upstream.lib.searchers import DiscardDuplicateGerritChangeId @@ -31,9 +31,7 @@ from git_upstream.lib.searchers import ReverseCommitFilter from git_upstream.lib.searchers import SupersededCommitFilter from git_upstream.lib.searchers import UpstreamMergeBaseSearcher from git_upstream.lib.utils import GitMixin -from git_upstream import log from git_upstream.log import LogDedentMixin -from git_upstream import subcommand class ImportUpstreamError(GitUpstreamError): @@ -519,45 +517,7 @@ class LocateChangesWalk(LocateChangesStrategy): return super(LocateChangesWalk, self).filtered_iter() -@subcommand.arg('-d', '--dry-run', dest='dry_run', action='store_true', - default=False, - help='Only print out the list of commits that would be ' - 'applied.') -@subcommand.arg('-i', '--interactive', action='store_true', default=False, - help='Let the user edit the list of commits before applying.') -@subcommand.arg('-f', '--force', dest='force', required=False, - action='store_true', default=False, - help='Force overwrite of existing import branch if it exists.') -@subcommand.arg('--merge', dest='merge', required=False, action='store_true', - default=True, - help='Merge the resulting import branch into the target branch' - ' once complete') -@subcommand.arg('--no-merge', dest='merge', required=False, - action='store_false', - help="Disable merge of the resulting import branch") -@subcommand.arg('-s', '--strategy', metavar='', - choices=ImportStrategiesFactory.list_strategies(), - default=LocateChangesWalk.get_strategy_name(), - help='Use the given strategy to re-apply locally carried ' - 'changes to the import branch. (default: %(default)s)') -@subcommand.arg('--search-refs', action='append_replace', metavar='', - default=['upstream/*'], dest='search_refs', - help='Refs to search for previous import commit. May be ' - 'specified multiple times.') -@subcommand.arg('--into', dest='branch', metavar='', default='HEAD', - help='Branch to take changes from, and replace with imported ' - 'branch.') -@subcommand.arg('--import-branch', metavar='', - help='Name of import branch to use', - default='import/{describe}') -@subcommand.arg('upstream_branch', metavar='', nargs='?', - default='upstream/master', - help='Upstream branch to import. Must be specified if ' - 'you wish to provide additional branches.') -@subcommand.arg('branches', metavar='', nargs='*', - help='Branches to additionally merge into the import branch ' - 'using default git merging behaviour') -def do_import(args): +class ImportCommand(LogDedentMixin, GitUpstreamCommand): """Import code from specified upstream branch. Creates an import branch from the specified upstream branch, and optionally @@ -569,81 +529,136 @@ def do_import(args): Once complete it will merge and replace the contents of the target branch with those from the import branch, unless --no-merge is specified. """ + name = "import" - logger = log.get_logger('%s.%s' % (__name__, - inspect.stack()[0][0].f_code.co_name)) + def __init__(self, *args, **kwargs): + super(ImportCommand, self).__init__(*args, **kwargs) - import_upstream = ImportUpstream(branch=args.branch, - upstream=args.upstream_branch, - import_branch=args.import_branch, - extra_branches=args.branches) + self.parser.add_argument( + '-i', '--interactive', action='store_true', default=False, + help='Let the user edit the list of commits before applying.') + self.parser.add_argument( + '-d', '--dry-run', dest='dry_run', action='store_true', + default=False, + help='Only print out the list of commits that would be applied.') + self.parser.add_argument( + '-f', '--force', dest='force', required=False, + action='store_true', default=False, + help='Force overwrite of existing import branch if it exists.') + self.parser.add_argument( + '--merge', dest='merge', required=False, action='store_true', + default=True, + help='Merge the resulting import branch into the target branch ' + 'once complete') + self.parser.add_argument( + '--no-merge', dest='merge', required=False, action='store_false', + help='Disable merge of the resulting import branch') + self.parser.add_argument( + '--search-refs', action='append_replace', metavar='', + default=['upstream/*'], dest='search_refs', + help='Refs to search for previous import commit. May be ' + 'specified multiple times.') + self.parser.add_argument( + '-s', '--strategy', metavar='', + choices=ImportStrategiesFactory.list_strategies(), + default=LocateChangesWalk.get_strategy_name(), + help='Use the given strategy to re-apply locally carried ' + 'changes to the import branch. (default: %(default)s)') + self.parser.add_argument( + '--into', dest='branch', metavar='', default='HEAD', + help='Branch to take changes from, and replace with imported ' + 'branch.') + self.parser.add_argument( + '--import-branch', metavar='', + default='import/{describe}', help='Name of import branch to use') + self.parser.add_argument( + 'upstream_branch', metavar='', nargs='?', + default='upstream/master', + help='Upstream branch to import. Must be specified if you wish to ' + 'provide additional branches.') + self.parser.add_argument( + 'branches', metavar='', nargs='*', + help='Branches to additionally merge into the import branch using ' + 'default git merging behaviour') - logger.notice("Searching for previous import") - strategy = ImportStrategiesFactory.create_strategy( - args.strategy, branch=args.branch, upstream=args.upstream_branch, - search_refs=args.search_refs) + def run(self, args): - if len(strategy) == 0: - raise ImportUpstreamError("Cannot find previous import") + import_upstream = ImportUpstream( + branch=args.branch, + upstream=args.upstream_branch, + import_branch=args.import_branch, + extra_branches=args.branches) - # if last commit in the strategy was a merge, then the additional branches - # that were merged in previously can be extracted based on the commits - # merged. - prev_import_merge = strategy[-1] - if len(prev_import_merge.parents) > 1: - idxs = [idx for idx, commit in enumerate(prev_import_merge.parents) - if commit.hexsha != strategy.searcher.commit.hexsha] + self.log.notice("Searching for previous import") + strategy = ImportStrategiesFactory.create_strategy( + args.strategy, branch=args.branch, upstream=args.upstream_branch, + search_refs=args.search_refs) - if idxs: - additional_commits = [prev_import_merge.parents[i] for i in idxs] - if additional_commits and len(args.branches) == 0: - logger.warning("""\ - **************** WARNING **************** - Previous import merged additional branches but none have - been specified on the command line for this import.\n""") + if len(strategy) == 0: + raise ImportUpstreamError("Cannot find previous import") - if args.dry_run: - commit_list = [c.hexsha[:6] + " - " + c.summary[:60] + - (c.summary[60:] and "...") - for c in list(strategy.filtered_iter())] - logger.notice("""\ - Requested a dry-run: printing the list of commit that should be - rebased + # if last commit in the strategy was a merge, then the additional + # branches that were merged in previously can be extracted based on + # the commits merged. + prev_import_merge = strategy[-1] + if len(prev_import_merge.parents) > 1: + idxs = [idx for idx, commit in enumerate(prev_import_merge.parents) + if commit.hexsha != strategy.searcher.commit.hexsha] - %s - """, "\n ".join(commit_list)) - return True + if idxs: + additional_commits = [prev_import_merge.parents[i] + for i in idxs] + if additional_commits and len(args.branches) == 0: + self.log.warning("""\ + **************** WARNING **************** + Previous import merged additional branches but none + have been specified on the command line for this + import.\n""") - logger.notice("Starting import of upstream") - import_upstream.create_import(force=args.force) - logger.notice("Successfully created import branch") + if args.dry_run: + commit_list = [c.hexsha[:6] + " - " + c.summary[:60] + + (c.summary[60:] and "...") + for c in list(strategy.filtered_iter())] + self.log.notice("""\ + Requested a dry-run: printing the list of commit that should be + rebased - if not import_upstream.apply(strategy, args.interactive): - logger.notice("Import cancelled") - return False + %s + """, "\n ".join(commit_list)) + return True - if not args.merge: - logger.notice( - """\ - Import complete, not merging to target branch '%s' as requested. - """, args.branch) - return True + self.log.notice("Starting import of upstream") + import_upstream.create_import(force=args.force) + self.log.notice("Successfully created import branch") - logger.notice("Merging import to requested branch '%s'", args.branch) - if import_upstream.finish(): - logger.notice( - """\ - Successfully finished import: - target branch: '%s' - upstream branch: '%s' - import branch: '%s'""", args.branch, args.upstream_branch, - import_upstream.import_branch) - if args.branches: - for branch in args.branches: - logger.notice(" extra branch: '%s'", branch, dedent=False) - return True - else: - return False + if not import_upstream.apply(strategy, args.interactive): + self.log.notice("Import cancelled") + return False + + if not args.merge: + self.log.notice( + """\ + Import complete, not merging to target branch '%s' as + requested. + """, args.branch) + return True + + self.log.notice("Merging import to requested branch '%s'", args.branch) + if import_upstream.finish(): + self.log.notice( + """\ + Successfully finished import: + target branch: '%s' + upstream branch: '%s' + import branch: '%s'""", args.branch, args.upstream_branch, + import_upstream.import_branch) + if args.branches: + for branch in args.branches: + self.log.notice(" extra branch: '%s'", branch, + dedent=False) + return True + else: + return False # vim:sw=4:sts=4:ts=4:et: diff --git a/git_upstream/commands/supersede.py b/git_upstream/commands/supersede.py index 2bac71e..1e13698 100644 --- a/git_upstream/commands/supersede.py +++ b/git_upstream/commands/supersede.py @@ -15,19 +15,17 @@ # limitations under the License. # -import inspect import re from git import BadObject from git import Head +from git_upstream.commands import GitUpstreamCommand from git_upstream.errors import GitUpstreamError from git_upstream.lib import note # noqa from git_upstream.lib.searchers import CommitMessageSearcher from git_upstream.lib.utils import GitMixin -from git_upstream import log from git_upstream.log import LogDedentMixin -from git_upstream import subcommand try: from git import BadName @@ -169,40 +167,51 @@ class Supersede(LogDedentMixin, GitMixin): self.log.warning('Note has not been added') -@subcommand.arg('commit', metavar='', nargs=None, - help='Commit to be marked as superseded') -@subcommand.arg('change_ids', metavar='', nargs='+', - help='Change id which makes obsolete. The change id ' - 'must be present in to drop . ' - 'If more than one change id is specified, all must be ' - 'present in to drop ') -@subcommand.arg('-f', '--force', dest='force', required=False, - action='store_true', default=False, - help='Apply the commit mark even if one or more change ids ' - 'could not be found. Use this flag carefully as commits ' - 'will not be dropped during import command execution as ' - 'long as all associated change ids are present in the ' - 'local copy of the upstream branch') -@subcommand.arg('-u', '--upstream-branch', metavar='', - dest='upstream_branch', required=False, - default='upstream/master', - help='Search change ids values in branch ' - '(default: %(default)s)') -def do_supersede(args): - """ - Mark a commit as superseded by a set of change-ids. +class SupersedeCommand(LogDedentMixin, GitUpstreamCommand): + """Mark a commit as superseded by a set of change-ids. + Marked commits will be skipped during the upstream rebasing process. See also the "git upstream import" command. """ + name = "supersede" - logger = log.get_logger('%s.%s' % (__name__, - inspect.stack()[0][0].f_code.co_name)) + def __init__(self, *args, **kwargs): - supersede = Supersede(git_object=args.commit, change_ids=args.change_ids, - upstream_branch=args.upstream_branch, - force=args.force) + # make sure to correctly initialize inherited objects before performing + # any computation + super(SupersedeCommand, self).__init__(*args, **kwargs) - if supersede.mark(): - logger.notice("Supersede mark created successfully") + self.parser.add_argument( + 'commit', metavar='', nargs=None, + help='Commit to be marked as superseded') + self.parser.add_argument( + 'change_ids', metavar='', nargs='+', + help='Change id which makes obsolete. The change id must ' + 'be present in to drop . If more ' + 'than one change id is specified, all must be present in ' + ' to drop ') + self.parser.add_argument( + '-f', '--force', dest='force', required=False, action='store_true', + default=False, + help='Apply the commit mark even if one or more change ids could ' + 'not be found. Use this flag carefully as commits will not ' + 'be dropped during import command execution as long as all ' + 'associated change ids are present in the local copy of the ' + 'upstream branch') + self.parser.add_argument( + '-u', '--upstream-branch', metavar='', + dest='upstream_branch', required=False, default='upstream/master', + help='Search change ids values in branch ' + '(default: %(default)s)') + + def run(self, args): + + supersede = Supersede(git_object=args.commit, + change_ids=args.change_ids, + upstream_branch=args.upstream_branch, + force=args.force) + + if supersede.mark(): + self.logger.notice("Supersede mark created successfully") # vim:sw=4:sts=4:ts=4:et: diff --git a/git_upstream/main.py b/git_upstream/main.py index 0bb06df..c3fd43a 100644 --- a/git_upstream/main.py +++ b/git_upstream/main.py @@ -30,7 +30,6 @@ from git_upstream import __version__ from git_upstream import commands from git_upstream.errors import GitUpstreamError from git_upstream import log -from git_upstream import subcommand try: import argcomplete @@ -39,7 +38,7 @@ except ImportError: argparse_loaded = False -def get_parser(): +def build_parsers(): parser = argparse.ArgumentParser( description=__doc__.strip(), epilog='See "%(prog)s help COMMAND" for help on a specific command.', @@ -62,39 +61,11 @@ def get_parser(): help=argparse.SUPPRESS) parser.add_argument('--log-file', dest='log_file', help=argparse.SUPPRESS) - subparsers = parser.add_subparsers(title="commands", metavar='', - dest='subcommand') - - # it would be nicer if we could hide this help command - desc = help.__doc__ or '' - subparser = subparsers.add_parser( - 'help', - help=desc.strip().split('\n')[0], - description=desc, - ) - for (args, kwargs) in getattr(help, 'arguments', []): - subparser.add_argument(*args, **kwargs) - subparser.set_defaults(func=help) - - subcommand_parsers = commands.get_subcommands(subparsers) + subcommand_parsers = commands.get_subcommands(parser) return subcommand_parsers, parser -@subcommand.arg('command', metavar='', nargs='?', - help='Display help for ') -def help(parser, args, commands=None): - """Display help about this program or one of its commands.""" - if getattr(args, 'command', None): - if args.command in commands: - commands[args.command].print_help() - else: - parser.error("'%s' is not a valid subcommand" % - args.command) - else: - parser.print_help() - - def setup_console_logging(options): options.log_level = getattr(logging, options.log_level.upper(), @@ -147,17 +118,18 @@ def main(argv=None): if not argv: argv = sys.argv[1:] - (cmds, parser) = get_parser() + (cmds, parser) = build_parsers() - if not sys.argv: - help(parser, argv) + if not argv: + parser.print_help() return 0 if argparse_loaded: argcomplete.autocomplete(parser) args = parser.parse_args(argv) - if args.func == help: - help(parser, args, cmds) + + if args.cmd.name == "help": + args.cmd.run(args, parser) return 0 logger = setup_console_logging(args) @@ -167,7 +139,9 @@ def main(argv=None): sys.exit(1) try: - args.func(args) + cmd = args.cmd + cmd.validate(args) + cmd.run(args) except GitUpstreamError as e: logger.fatal("%s", e[0]) logger.debug("Git-Upstream: %s", e[0], exc_info=e) diff --git a/git_upstream/subcommand.py b/git_upstream/subcommand.py deleted file mode 100644 index 57ff0c8..0000000 --- a/git_upstream/subcommand.py +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2012 OpenStack LLC. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# following function taken from python-keystoneclient - keystoneclient/utils.py -# Decorator for cli-args -def arg(*args, **kwargs): - def _decorator(func): - # Because of the sematics of decorator composition if we just append - # to the options list positional options will appear to be backwards. - func.__dict__.setdefault('arguments', []).insert(0, (args, kwargs)) - return func - return _decorator diff --git a/git_upstream/tests/test_commands.py b/git_upstream/tests/test_commands.py index 5bb246a..f3630aa 100644 --- a/git_upstream/tests/test_commands.py +++ b/git_upstream/tests/test_commands.py @@ -24,13 +24,12 @@ from git_upstream import commands as c class TestGetSubcommands(testtools.TestCase): """Test case for get_subcommands function""" - _available_subcommands = ('import', 'supersede', 'drop') + _available_subcommands = ('help', 'import', 'supersede', 'drop') def test_available_subcommands(self): """Test available subcommands""" parser = ArgumentParser() - subparsers = parser.add_subparsers() - subcommands = c.get_subcommands(subparsers) + subcommands = c.get_subcommands(parser) self.assertEqual(len(TestGetSubcommands._available_subcommands), len(subcommands.keys())) for command in subcommands.keys(): diff --git a/git_upstream/tests/test_import_cmd.py b/git_upstream/tests/test_import_cmd.py index 9a3eeae..bb583c4 100644 --- a/git_upstream/tests/test_import_cmd.py +++ b/git_upstream/tests/test_import_cmd.py @@ -44,7 +44,7 @@ class SubstringMatcher(object): class TestImportCommand(BaseTestCase): - commands, parser = main.get_parser() + commands, parser = main.build_parsers() def test_basic(self): """Test that default behaviour and options work @@ -74,7 +74,7 @@ class TestImportCommand(BaseTestCase): self._build_git_tree(tree, branches.values()) self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master') args = self.parser.parse_args(['-q', 'import', 'upstream/master']) - self.assertThat(args.func(args), Equals(True), + self.assertThat(args.cmd.run(args), Equals(True), "import command failed to complete succesfully") def test_basic_additional(self): @@ -111,7 +111,7 @@ class TestImportCommand(BaseTestCase): self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master') args = self.parser.parse_args(['-q', 'import', 'upstream/master', 'packaging/master']) - self.assertThat(args.func(args), Equals(True), + self.assertThat(args.cmd.run(args), Equals(True), "import command failed to complete succesfully") def test_basic_additional_missed(self): @@ -149,15 +149,13 @@ class TestImportCommand(BaseTestCase): self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master') args = self.parser.parse_args(['import', 'upstream/master']) - mock_logger = mock.MagicMock() - with mock.patch('git_upstream.log.get_logger', - return_value=mock_logger): - self.assertThat(args.func(args), Equals(True), + with mock.patch.object(args.cmd.log, 'warning') as mock_logger: + self.assertThat(args.cmd.run(args), Equals(True), "import command failed to complete succesfully") - mock_logger.warning.assert_called_with( - SubstringMatcher( - containing="Previous import merged additional")) + mock_logger.assert_called_with( + SubstringMatcher( + containing="Previous import merged additional")) def test_import_switch_branches_search(self): """Test that the import sub-command can correctly switch branches when @@ -206,7 +204,7 @@ class TestImportCommand(BaseTestCase): self._build_git_tree(tree, branches.values()) self.git.tag(inspect.currentframe().f_code.co_name, 'upstream/master') args = self.parser.parse_args(['-q', 'import']) - self.assertThat(args.func(args), Equals(True), + self.assertThat(args.cmd.run(args), Equals(True), "import command failed to complete succesfully") changes = list(Commit.iter_items( self.repo, 'upstream/master..master^2')) @@ -274,7 +272,7 @@ class TestImportCommand(BaseTestCase): self.git.tag(inspect.currentframe().f_code.co_name, 'custom/master') args = self.parser.parse_args(['-q', 'import', '--into=master', 'custom/master']) - self.assertThat(args.func(args), Equals(True), + self.assertThat(args.cmd.run(args), Equals(True), "import command failed to complete succesfully") changes = list(Commit.iter_items( self.repo, 'custom/master..master^2')) @@ -343,7 +341,7 @@ class TestImportCommand(BaseTestCase): '--search-refs=custom/*', '--search-refs=custom-d/*', '--into=master', 'custom/master']) - self.assertThat(args.func(args), Equals(True), + self.assertThat(args.cmd.run(args), Equals(True), "import command failed to complete succesfully") changes = list(Commit.iter_items( self.repo, 'custom/master..master^2'))