def Run(params): ''' This is the first action that should be run in a new mu installation. It'll ask for common things to configure git properly. Things not done here but which the user should still do: Set: GIT_SSH to point to plink.exe (and have pageant with the key already loaded). ''' git = params.config.git or 'git' from mu_repo.execute_command import ExecuteCommand #--- Name user_name = raw_input('User name:').strip() if user_name: ExecuteCommand([git] + 'config --global user.name'.split() + [user_name], '.') else: Print('Skipping user.name configuration.') #--- E-mail user_email = raw_input('\nUser e-mail:').strip() if user_email: ExecuteCommand([git] + 'config --global user.email'.split() + [user_email], '.') else: Print('Skipping user.email configuration.') #--- Auto-crlf auto_crlf = raw_input('\nAuto-crlf handling (default false, options: false, true, input):').strip().lower() if not auto_crlf: auto_crlf = 'false' if auto_crlf in ('false', 'true', 'input'): ExecuteCommand([git] + 'config --global core.autocrlf'.split() + [auto_crlf], '.') else: Print('Skipping core.autocrlf configuration (input: "%s" not recognized).' % (auto_crlf,)) config_date = raw_input('\nConfig format.pretty for one line and set default to short? (default: y, options: y, n)').strip().lower() if not config_date: config_date = 'y' if config_date == 'y': ExecuteCommand([git] + ['config', '--global', 'format.pretty', '%h %ad %Cgreen%aN%Creset %s'], '.') ExecuteCommand([git] + 'config --global log.date short'.split(), '.') wrap = raw_input('\nShow logs wrapped? (i.e.: set less -r): (default: y, options: y, n)').strip().lower() if not wrap: wrap = 'y' if wrap == 'y': ExecuteCommand([git, 'config', '--global', 'core.pager', 'less -r'], '.') wrap = raw_input('\nCreate "git st" and "git create-branch" aliases? (default: y, options: y, n)').strip().lower() if not wrap: wrap = 'y' if wrap == 'y': ExecuteCommand([git, 'config', '--global', 'alias.st', 'status -s'], '.') ExecuteCommand([git, 'config', '--global', 'alias.create-branch', 'checkout -b '], '.')
def Run(params): #Update them from .action_up import Run repos_and_curr_branch = Run(params) if not repos_and_curr_branch: Print('No tracked repos!') return branch_to_repos = {} #Check if all on the same branch for repo, branch in repos_and_curr_branch: curr = branch_to_repos.setdefault(branch, []) curr.append(repo) if len(branch_to_repos) > 1: msg = '\n${START_COLOR}Warning: found repos in different branches${RESET_COLOR}:\n %s\nProceed?(y/n)' % ( '\n '.join([ str('Branch: ${START_COLOR}%s${RESET_COLOR} (%s)' % (key, ', '.join(val))) for (key, val) in branch_to_repos.items() ])) ret = '' while ret not in ('y', 'n'): Print(msg) ret = raw_input().strip().lower() if ret != 'y': return #Diff it from .action_diff import Run #@Reimport initial_args = params.args[:] initial_repos = params.config.repos[:] for branch, repos in iteritems(branch_to_repos): params.args = initial_args + ['origin/' + branch] params.config.repos = repos if len(branch_to_repos) > 1: Print('\nOutput for branch: ${START_COLOR}%s${RESET_COLOR} (%s)' % (branch, ', '.join(repos))) Run(params) params.args = initial_args params.config.repos = initial_repos
def Run(params): #Update them from .action_up import Run repos_and_curr_branch = Run(params) if not repos_and_curr_branch: Print('No tracked repos!') return branch_to_repos = {} #Check if all on the same branch for repo, branch in repos_and_curr_branch: curr = branch_to_repos.setdefault(branch, []) curr.append(repo) if len(branch_to_repos) > 1: msg = '\n${START_COLOR}Warning: found repos in different branches${RESET_COLOR}:\n %s\nProceed?(y/n)' % ('\n '.join([str('Branch: ${START_COLOR}%s${RESET_COLOR} (%s)' % (key, ', '.join(val))) for (key, val) in branch_to_repos.items()])) ret = '' while ret not in ('y', 'n'): Print(msg) ret = raw_input().strip().lower() if ret != 'y': return #Diff it from .action_diff import Run #@Reimport initial_args = params.args[:] initial_repos = params.config.repos[:] for branch, repos in iteritems(branch_to_repos): params.args = initial_args + ['origin/' + branch] params.config.repos = repos if len(branch_to_repos) > 1: Print('\nOutput for branch: ${START_COLOR}%s${RESET_COLOR} (%s)' % (branch, ', '.join(repos))) Run(params) params.args = initial_args params.config.repos = initial_repos
def Run(params): config = params.config join = os.path.join temp_dir_name = '.mu.diff.git.tmp' if os.path.exists(temp_dir_name): n = '' while n not in ('y', 'n'): n = raw_input( 'Temporary dir for diff: %s already exists. Delete and continue (y) or cancel (n)? ' % (temp_dir_name,) ).strip().lower() if n == 'y': RmTree(temp_dir_name) break if n == 'n': Print('Canceling diff action.') return temp_working = join(temp_dir_name, 'WORKING') temp_repo = join(temp_dir_name, 'REPO') os.mkdir(temp_dir_name) os.mkdir(temp_working) os.mkdir(temp_repo) from mu_repo import keep_files_synched def symlink(src, target): if os.path.isdir(src): if os.path.exists(target): os.rmdir(target) shutil.copytree(src, target) keep_files_synched.KeepInSync(src, target) else: if os.path.exists(target): if os.path.isdir(target): RmTree(target) else: os.remove(target) shutil.copyfile(src, target) keep_files_synched.KeepInSync(src, target) try: #Note: we could use diff status --porcelain instead if we wanted to check untracked files. #cmd = [git] + 'diff --name-only -z'.split() args = params.args branch = '' repos_and_curr_branch = None if len(args) > 1: #Ok, the user is comparing current branch with a previous branch or commit. #i.e.: mu dd HEAD^^ branch = args[1] if branch == '--prev': repos_and_curr_branch = dict(GetReposAndCurrBranch(params, verbose=False)) threads = [] for repo in config.repos: if repos_and_curr_branch is not None: #Note: if --prev is given, it means current_branch@{1} #But note that users could also do things as: mu dd master@{10.minutes.ago} #References: #http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html #http://stackoverflow.com/questions/1362952/detail-change-after-git-pull branch = repos_and_curr_branch[repo] + '@{1}' #Get the version before the last update. thread = DoDiffOnRepoThread(config, repo, symlink, temp_working, temp_repo, branch) else: thread = DoDiffOnRepoThread(config, repo, symlink, temp_working, temp_repo, branch) threads.append(thread) thread.start() for thread in threads: thread.join() thread_pool.Join() for thread in threads: if thread.entry_count != 0: break else: Print('No changes found.') return if sys.platform == 'win32': write_left = ['/wl'] #Cannot write on left if not branch: write_left = [] #Can write on left when not working with branch (i.e.: working dir). winmerge_cmd = 'WinMergeU.exe /r /u /wr /dl WORKINGCOPY /dr HEAD'.split() cmd = winmerge_cmd + write_left + [temp_working, temp_repo] try: subprocess.call(cmd) except: Print('Error calling: %s' % (' '.join(cmd),)) else: # Winmerge is not available on Linux, so, let's use another option (meld) cmd = ['meld', temp_working, temp_repo] try: subprocess.call(cmd) except: Print('Error calling: %s' % (' '.join(cmd),)) finally: #If we've gone to the synching mode, make sure we had a last synchronization before #getting out of the diff. if keep_files_synched is not None: keep_files_synched.StopSyncs() def onerror(*args): Print('Error removing temporary directory structure: %s' % (args,)) RmTree(temp_dir_name, onerror=onerror)
def Run(params): ''' Actions for mu group. ''' args = params.args config_file = params.config_file config = params.config msgs = [] command = args[1] if len(args) > 1 else None group_name = args[2] if len(args) > 2 else None clean_new_group = '--clean' in args or '--empty' in args if command != 'add' and clean_new_group: msg = '--clean and --empty only for "add" command' Print(msg) return Status(msg, False) if not command: if not config.groups: msg = 'No groups registered. Use "add" to add a new one.' Print(msg) msgs.append(msg) else: for group_name in config.groups: if group_name == config.current_group: msg = '* %s' % group_name else: msg = ' %s' % group_name Print(msg) msgs.append(msg) elif command == 'add': if group_name is None: msg = 'Group name not given.' Print(msg) return Status(msg, False) if group_name in config.groups: msg = 'Group ${START_COLOR}%s${RESET_COLOR} already exists.' % group_name Print(msg) return Status(msg, False) if clean_new_group: config.groups[group_name] = [] else: config.groups[group_name] = config.repos config.current_group = group_name elif command in ('rm', 'del', 'switch', 'sw'): if group_name is None: header_msg = 'Please choose which group you want to switch to:' while True: Print(header_msg) groups = set() i_to_group = {} lines = [] for i, (group, group_contents) in enumerate(sorted(backwards.iteritems(config.groups))): groups_desc = ', '.join(group_contents) lines.append(('[${START_COLOR}%s${RESET_COLOR}]: %s' % (i, group), groups_desc)) i_to_group[str(i)] = group groups.add(group) discount_len = len('${START_COLOR}') + len('${RESET_COLOR}') max_part_0 = 0 for line in lines: max_part_0 = max(max_part_0, len(line[0])-discount_len) max_part_0+= 1 max_cols = 80 remainder = max_cols - max_part_0 if remainder < 20: remainder = 20 part0_size = max_cols - remainder for part0, part1 in lines: if (len(part0) - discount_len) < part0_size: part0 += ' ' * (part0_size - (len(part0) - discount_len)) if len(part1) > remainder: part1 = part1[:remainder-3] + '...' Print(part0+part1) Print('\n[${START_COLOR}C${RESET_COLOR}]: Cancel') try: user_entered = raw_input('\nSelect: ').strip() except KeyboardInterrupt: return Status('Cancelled', False) if user_entered in i_to_group: group_name = i_to_group[user_entered] break if user_entered in groups: group_name = user_entered break if user_entered in ('C', 'c'): return Status('Cancelled', False) header_msg = 'Did not match. Please choose again:' if group_name not in config.groups: msg = 'Group "%s" does not exist.' % group_name Print(msg) return Status(msg, False) if command in ('switch', 'sw'): msg = 'Switched to group ${START_COLOR}%s${RESET_COLOR}' % group_name config.current_group = group_name else: msg = 'Group ${START_COLOR}%s${RESET_COLOR} removed' % group_name if config.current_group == group_name: config.current_group = None msg += ' (no current group)' msg += '.' del config.groups[group_name] Print(msg) msgs.append(msg) elif command == 'reset': config.current_group = None msg = 'Group reset. No current group.' Print(msg) msgs.append(msg) else: msg = 'Unknown group command: %s' % command Print(msg) return Status(msg, False) with open(config_file, 'w') as f: f.write(str(config)) return Status('\n'.join(msgs), True, config)
def Run(params): config = params.config join = os.path.join temp_dir_name = '.mu.diff.git.tmp' if os.path.exists(temp_dir_name): n = '' while n not in ('y', 'n'): n = raw_input( 'Temporary dir for diff: %s already exists. Delete and continue (y) or cancel (n)? ' % (temp_dir_name, )).strip().lower() if n == 'y': RmTree(temp_dir_name) break if n == 'n': Print('Canceling diff action.') return temp_working = join(temp_dir_name, 'WORKING') temp_repo = join(temp_dir_name, 'REPO') os.mkdir(temp_dir_name) os.mkdir(temp_working) os.mkdir(temp_repo) from mu_repo import keep_files_synched def symlink(src, target): if os.path.isdir(src): if os.path.exists(target): os.rmdir(target) shutil.copytree(src, target) keep_files_synched.KeepInSync(src, target) else: if os.path.exists(target): if os.path.isdir(target): RmTree(target) else: os.remove(target) shutil.copyfile(src, target) keep_files_synched.KeepInSync(src, target) try: #Note: we could use diff status --porcelain instead if we wanted to check untracked files. #cmd = [git] + 'diff --name-only -z'.split() args = params.args branch = '' repos_and_curr_branch = None if len(args) > 1: #Ok, the user is comparing current branch with a previous branch or commit. #i.e.: mu dd HEAD^^ branch = args[1] if branch == '--prev': repos_and_curr_branch = dict( GetReposAndCurrBranch(params, verbose=False)) threads = [] for repo in config.repos: if repos_and_curr_branch is not None: #Note: if --prev is given, it means current_branch@{1} #But note that users could also do things as: mu dd master@{10.minutes.ago} #References: #http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html #http://stackoverflow.com/questions/1362952/detail-change-after-git-pull branch = repos_and_curr_branch[ repo] + '@{1}' #Get the version before the last update. thread = DoDiffOnRepoThread(config, repo, symlink, temp_working, temp_repo, branch) else: thread = DoDiffOnRepoThread(config, repo, symlink, temp_working, temp_repo, branch) threads.append(thread) thread.start() for thread in threads: thread.join() thread_pool.Join() for thread in threads: if thread.entry_count != 0: break else: Print('No changes found.') return if sys.platform == 'win32': write_left = ['/wl'] #Cannot write on left if not branch: write_left = [ ] #Can write on left when not working with branch (i.e.: working dir). winmerge_cmd = 'WinMergeU.exe /r /u /wr /dl WORKINGCOPY /dr HEAD'.split( ) cmd = winmerge_cmd + write_left + [temp_working, temp_repo] try: subprocess.call(cmd) except: Print('Error calling: %s' % (' '.join(cmd), )) else: # Winmerge is not available on Linux, so, let's use another option (meld) cmd = ['meld', temp_working, temp_repo] try: subprocess.call(cmd) except: Print('Error calling: %s' % (' '.join(cmd), )) finally: #If we've gone to the synching mode, make sure we had a last synchronization before #getting out of the diff. if keep_files_synched is not None: keep_files_synched.StopSyncs() def onerror(*args): Print('Error removing temporary directory structure: %s' % (args, )) RmTree(temp_dir_name, onerror=onerror)
def Run(params): ''' This is the first action that should be run in a new mu installation. It'll ask for common things to configure git properly. Things not done here but which the user should still do: Set: GIT_SSH to point to plink.exe (and have pageant with the key already loaded). ''' git = params.config.git or 'git' from mu_repo.execute_command import ExecuteCommand #--- Name user_name = raw_input('User name:').strip() if user_name: ExecuteCommand([git] + 'config --global user.name'.split() + [user_name], '.') else: Print('Skipping user.name configuration.') #--- E-mail user_email = raw_input('\nUser e-mail:').strip() if user_email: ExecuteCommand([git] + 'config --global user.email'.split() + [user_email], '.') else: Print('Skipping user.email configuration.') #--- Auto-crlf auto_crlf = raw_input( '\nAuto-crlf handling (default false, options: false, true, input):' ).strip().lower() if not auto_crlf: auto_crlf = 'false' if auto_crlf in ('false', 'true', 'input'): ExecuteCommand([git] + 'config --global core.autocrlf'.split() + [auto_crlf], '.') else: Print( 'Skipping core.autocrlf configuration (input: "%s" not recognized).' % (auto_crlf, )) config_date = raw_input( '\nConfig format.pretty for one line and set default to short? (default: y, options: y, n)' ).strip().lower() if not config_date: config_date = 'y' if config_date == 'y': ExecuteCommand([git] + [ 'config', '--global', 'format.pretty', '%h %ad %Cgreen%aN%Creset %s' ], '.') ExecuteCommand([git] + 'config --global log.date short'.split(), '.') wrap = raw_input( '\nShow logs wrapped? (i.e.: set less -r): (default: y, options: y, n)' ).strip().lower() if not wrap: wrap = 'y' if wrap == 'y': ExecuteCommand([git, 'config', '--global', 'core.pager', 'less -r'], '.') wrap = raw_input( '\nCreate "git st" and "git create-branch" aliases? (default: y, options: y, n)' ).strip().lower() if not wrap: wrap = 'y' if wrap == 'y': ExecuteCommand([git, 'config', '--global', 'alias.st', 'status -s'], '.') ExecuteCommand([ git, 'config', '--global', 'alias.create-branch', 'checkout -b ' ], '.')