def _call_diff(branch=None, check_structure=None): config = Config(repos=['test_diff_command_git_repo_dir'], git=git) params = Params(config, ['dd'] + [branch] if branch else [], config_file=None) called = [] def Call(cmd, *args, **kwargs): try: if check_structure: check_structure() except: NotifyErrorListeners() called.append(cmd[0].lower()) errors = [] def OnError(error): errors.append(error) # Mock things original_call = subprocess.call subprocess.call = Call action_diff.on_errors_listeners.add(OnError) try: action_diff.Run(params) finally: action_diff.on_errors_listeners.remove(OnError) subprocess.call = original_call if errors: raise AssertionError('\n\n'.join(errors)) return called
def testActionDiff(self): temp_dir = 'test_diff_command_git_repo_dir' git = r'C:\D\bin\git\bin\git.exe' if not os.path.exists(git): git = 'git' self.git = git # Test diffing with new folder structure subprocess.call([git] + 'init test_diff_command_git_repo_dir'.split(), cwd='.') os.mkdir(os.path.join(temp_dir, 'folder1')) with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f: f.write('out') called = self.CallDiff() self.assertEqual(['winmergeu.exe'], called) # Test diffing with previous version of HEAD without changes subprocess.call([git] + 'add -A'.split(), cwd=temp_dir) subprocess.call([git] + 'commit -m "Second'.split(), cwd=temp_dir) called = self.CallDiff() self.assertEqual([], called) #Not called as we don't have any changes. # Test diffing with previous version of HEAD^ def CheckStructure(): prev = os.path.join('.mu.diff.git.tmp', 'REPO', 'test_diff_command_git_repo_dir', 'folder1', 'out.txt') curr = os.path.join('.mu.diff.git.tmp', 'WORKING', 'test_diff_command_git_repo_dir', 'folder1', 'out.txt') self.assert_(os.path.exists(prev)) self.assert_(os.path.exists(curr)) Print('prev', open(prev, 'r').read()) Print('curr', open(curr, 'r').read()) with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f: f.write('new out') subprocess.call([git] + 'add -A'.split(), cwd=temp_dir) subprocess.call([git] + 'commit -m "Second'.split(), cwd=temp_dir) called = self.CallDiff('HEAD^', check_structure=CheckStructure) self.assertEqual(['winmergeu.exe'], called) # Test diffing dir structure in git changed for file in working dir subprocess.call([git] + 'add -A'.split(), cwd=temp_dir) subprocess.call([git] + 'commit -m "Third'.split(), cwd=temp_dir) RmTree(os.path.join(temp_dir, 'folder1')) with open(os.path.join(temp_dir, 'folder1'), 'w') as f: f.write('folder1 is now file.') called = self.CallDiff() self.assertEqual(['winmergeu.exe'], called) # Do mu st/mu up just to check if it works. from mu_repo.action_default import Run config = Config(repos=[temp_dir], git=git) Run(Params(config, ['st'], config_file=None)) import mu_repo mu_repo.main(config_file=None, args=['up'])
def CreateConfig(config_file='.mu_repo'): if config_file is None: # Mostly for testing. contents = '' else: exists = os.path.exists(config_file) if not exists: contents = '' else: with open(config_file, 'r') as f: contents = f.read() return Config.Create(contents)
def test_mu_repo(): contents = ''' repo=pydev repo=studio3 repo=python-devel repo=django current_group=pydev-devel group=pydev-devel, pydev, studio3 ''' config = Config.Create(contents) expected_config = mu_repo.Config( repos=['pydev', 'studio3', 'python-devel', 'django'], current_group='pydev-devel', groups={'pydev-devel': ['pydev', 'studio3']}, ) assert config == expected_config
def test_action_diff(): temp_dir = 'test_diff_command_git_repo_dir' # Test diffing with new folder structure subprocess.call([git, 'init', temp_dir], cwd='.') configure_git_user(cwd=temp_dir) os.mkdir(os.path.join(temp_dir, 'folder1')) with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f: f.write('out') called = _call_diff() if sys.platform.startswith('win'): merge_command = 'winmergeu.exe' else: merge_command = 'meld' assert [merge_command] == called # Test diffing with previous version of HEAD without changes subprocess.check_call([git] + 'add -A'.split(), cwd=temp_dir) subprocess.check_call([git] + 'commit -m "Second'.split(), cwd=temp_dir) called = _call_diff() assert [] == called # Not called as we don't have any changes. # Test diffing with previous version of HEAD~1 def check_structure(): prev = os.path.join('.mu.diff.git.tmp', 'REPO', 'test_diff_command_git_repo_dir', 'folder1', 'out.txt') curr = os.path.join('.mu.diff.git.tmp', 'WORKING', 'test_diff_command_git_repo_dir', 'folder1', 'out.txt') assert os.path.exists(prev) assert os.path.exists(curr) Print('prev', open(prev, 'r').read()) Print('curr', open(curr, 'r').read()) with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f: f.write('new out') subprocess.check_call([git] + 'add -A'.split(), cwd=temp_dir) subprocess.check_call([git] + 'commit -m "Second'.split(), cwd=temp_dir) called = _call_diff('HEAD~1', check_structure=check_structure) assert [merge_command] == called # Test diffing dir structure in git changed for file in working dir # Nothing changed at this point: newest git now gives a non-zero value in # such a case if we try to commit. # subprocess.check_call([git] + 'add -A'.split(), cwd=temp_dir) # subprocess.check_call([git] + 'commit -m "Third'.split(), cwd=temp_dir) RmTree(os.path.join(temp_dir, 'folder1')) with open(os.path.join(temp_dir, 'folder1'), 'w') as f: f.write('folder1 is now file.') called = _call_diff() assert [merge_command] == called # Do mu st/mu up just to check if it works. from mu_repo.action_default import Run config = Config(repos=[temp_dir], git=git) Run(Params(config, ['st'], config_file=None)) import mu_repo mu_repo.main(config_file=None, args=['up'])
def main(config_file='.mu_repo', args=None): ''' Entry point. ''' if args is None: args = sys.argv[1:] if len(args) == 0 or (len(args) == 1 and args[0] in ('help', '--help')): from string import Template from . import __docs__ msg = __docs__.__doc__ # @UndefinedVariable Print(msg) return Status(msg, False) config = Config.CreateConfig(config_file) for arg in args: if arg.startswith('repo:'): args.remove(arg) config.repos = arg[len('repo:'):].replace(';', ',').split(',') if not args: Print('"repo" specified, but no additional args given.') return elif arg.startswith('repos:'): args.remove(arg) config.repos = arg[len('repos:'):].replace(';', ',').split(',') if not args: Print('"repos" specified, but no additional args given.') return elif arg == '--help': # On a help command, don't execute in multiple repos. config.repos = ['.'] break else: if not config.repos: if '.' == args[0]: del args[0] config.repos.append('.') elif os.path.exists('.git'): # Allow it to be used on single git repos too. config.repos.append('.') arg0 = args[0] change_to_serial_if_possible = True update_repos_from_groups = True Run = None # actions related to repos or mu itself -------------------------------------------------------- # This should be executed first, because some of them expect to see config as it was loaded if arg0 == 'set-var': from .action_set_var import Run # @Reimport change_to_serial_if_possible = False update_repos_from_groups = False elif arg0 == 'get-vars': from .action_get_vars import Run # @Reimport change_to_serial_if_possible = False elif arg0 == 'auto-update': from .action_auto_update import Run # @Reimport elif arg0 == 'list': from .action_list import Run # @Reimport elif arg0 == 'register': from .action_register import Run # @Reimport update_repos_from_groups = False elif arg0 == 'unregister': from .action_unregister import Run #@Reimport update_repos_from_groups = False elif arg0 == 'group': from .action_group import Run # @Reimport update_repos_from_groups = False # change global repos list to the current group, if any if update_repos_from_groups: group_repos = config.groups.get(config.current_group, None) if group_repos is not None: config.repos = group_repos # acp variants --------------------------------------------------------------------------------- if arg0 == 'acp': # Add, commit, push def Run(params): from .action_add_commit_push import Run # @Reimport Run(params, add=True, commit=True, push=True) elif arg0 == 'ac': # Add, commit def Run(params): from .action_add_commit_push import Run # @Reimport Run(params, add=True, commit=True, push=False) elif arg0 == 'a': # Add def Run(params): from .action_add_commit_push import Run # @Reimport Run(params, add=True, commit=False, push=False) elif arg0 == 'c': # Commit def Run(params): from .action_add_commit_push import Run # @Reimport Run(params, add=False, commit=True, push=False) elif arg0 == 'p': # Push def Run(params): from .action_add_commit_push import Run # @Reimport Run(params, add=False, commit=False, push=True) # related to git actions ----------------------------------------------------------------------- elif arg0 == 'dd': from .action_diff import Run # @Reimport elif arg0 == 'up': from .action_up import Run # @Reimport elif arg0 in ('sync', 'upd'): from .action_sync import Run # @Reimport elif arg0 == 'st': # Concise status message (branch, changes) from .action_st import Run # @Reimport elif arg0 == 'rb': # Rebase current_branch origin/current_branch from .action_rebase import Run # @Reimport # assorted ------------------------------------------------------------------------------------- elif arg0 == 'install': from .action_install import Run # @Reimport elif arg0 == 'mu-patch': from .action_mu_patch import Run # @Reimport elif arg0 == 'post-review': from .action_post_review import Run # @Reimport elif arg0 == 'fix-eol': from .action_fix_eol import Run # @Reimport elif arg0 == 'github-request': from .action_github_pull_request import Run # @Reimport elif arg0 == 'howto': from .howto import Run # @Reimport elif arg0 == 'shell': import subprocess try: subprocess.call(['sh', '--login', '-i']) except: # Ignore any error here (if the user pressed Ctrl+C before exit, we'd have an exception). import traceback traceback.print_exc() return # default action ------------------------------------------------------------------------------- if Run is None: if arg0 == 'stash' and len(args) == 1: # Fixing stash: if git stash is provided without arguments, append a '-u' so that it # also stashes untracked files. args.append('-u') from .action_default import Run # @Reimport if change_to_serial_if_possible: if len(config.repos) == 1: config.serial = True return Run(Params(config, args, config_file))