Mercurial > public > mercurial-scm > hg-stable
diff hgext/extdiff.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | a4cd77a425a3 |
children | 687b865b95ad |
line wrap: on
line diff
--- a/hgext/extdiff.py Sat Oct 05 10:29:34 2019 -0400 +++ b/hgext/extdiff.py Sun Oct 06 09:45:02 2019 -0400 @@ -117,22 +117,20 @@ configtable = {} configitem = registrar.configitem(configtable) -configitem('extdiff', br'opts\..*', - default='', - generic=True, +configitem( + 'extdiff', br'opts\..*', default='', generic=True, ) -configitem('extdiff', br'gui\..*', - generic=True, +configitem( + 'extdiff', br'gui\..*', generic=True, ) -configitem('diff-tools', br'.*\.diffargs$', - default=None, - generic=True, +configitem( + 'diff-tools', br'.*\.diffargs$', default=None, generic=True, ) -configitem('diff-tools', br'.*\.gui$', - generic=True, +configitem( + 'diff-tools', br'.*\.gui$', generic=True, ) # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for @@ -141,6 +139,7 @@ # leave the attribute unspecified. testedwith = 'ships-with-hg-core' + def snapshot(ui, repo, files, node, tmproot, listsubrepos): '''snapshot files as of some revision if not using snapshot, -I/-X does not work and recursive diff @@ -155,18 +154,27 @@ fnsandstat = [] if node is not None: - ui.note(_('making snapshot of %d files from rev %s\n') % - (len(files), short(node))) + ui.note( + _('making snapshot of %d files from rev %s\n') + % (len(files), short(node)) + ) else: - ui.note(_('making snapshot of %d files from working directory\n') % - (len(files))) + ui.note( + _('making snapshot of %d files from working directory\n') + % (len(files)) + ) if files: repo.ui.setconfig("ui", "archivemeta", False) - archival.archive(repo, base, node, 'files', - match=scmutil.matchfiles(repo, files), - subrepos=listsubrepos) + archival.archive( + repo, + base, + node, + 'files', + match=scmutil.matchfiles(repo, files), + subrepos=listsubrepos, + ) for fn in sorted(files): wfn = util.pconvert(fn) @@ -178,15 +186,32 @@ fnsandstat.append((dest, repo.wjoin(fn), os.lstat(dest))) return dirname, fnsandstat -def formatcmdline(cmdline, repo_root, do3way, - parent1, plabel1, parent2, plabel2, child, clabel): + +def formatcmdline( + cmdline, + repo_root, + do3way, + parent1, + plabel1, + parent2, + plabel2, + child, + clabel, +): # Function to quote file/dir names in the argument string. # When not operating in 3-way mode, an empty string is # returned for parent2 - replace = {'parent': parent1, 'parent1': parent1, 'parent2': parent2, - 'plabel1': plabel1, 'plabel2': plabel2, - 'child': child, 'clabel': clabel, - 'root': repo_root} + replace = { + 'parent': parent1, + 'parent1': parent1, + 'parent2': parent2, + 'plabel1': plabel1, + 'plabel2': plabel2, + 'child': child, + 'clabel': clabel, + 'root': repo_root, + } + def quote(match): pre = match.group(2) key = match.group(3) @@ -195,28 +220,48 @@ return pre + procutil.shellquote(replace[key]) # Match parent2 first, so 'parent1?' will match both parent1 and parent - regex = (br'''(['"]?)([^\s'"$]*)''' - br'\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)\1') + regex = ( + br'''(['"]?)([^\s'"$]*)''' + br'\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)\1' + ) if not do3way and not re.search(regex, cmdline): cmdline += ' $parent1 $child' return re.sub(regex, quote, cmdline) + def _systembackground(cmd, environ=None, cwd=None): ''' like 'procutil.system', but returns the Popen object directly so we don't have to wait on it. ''' cmd = procutil.quotecommand(cmd) env = procutil.shellenviron(environ) - proc = subprocess.Popen(procutil.tonativestr(cmd), - shell=True, close_fds=procutil.closefds, - env=procutil.tonativeenv(env), - cwd=pycompat.rapply(procutil.tonativestr, cwd)) + proc = subprocess.Popen( + procutil.tonativestr(cmd), + shell=True, + close_fds=procutil.closefds, + env=procutil.tonativeenv(env), + cwd=pycompat.rapply(procutil.tonativestr, cwd), + ) return proc -def _runperfilediff(cmdline, repo_root, ui, guitool, do3way, confirm, - commonfiles, tmproot, dir1a, dir1b, - dir2root, dir2, - rev1a, rev1b, rev2): + +def _runperfilediff( + cmdline, + repo_root, + ui, + guitool, + do3way, + confirm, + commonfiles, + tmproot, + dir1a, + dir1b, + dir2root, + dir2, + rev1a, + rev1b, + rev2, +): # Note that we need to sort the list of files because it was # built in an "unstable" way and it's annoying to get files in a # random order, especially when "confirm" mode is enabled. @@ -241,31 +286,42 @@ if confirm: # Prompt before showing this diff - difffiles = _('diff %s (%d of %d)') % (commonfile, idx + 1, - totalfiles) - responses = _('[Yns?]' - '$$ &Yes, show diff' - '$$ &No, skip this diff' - '$$ &Skip remaining diffs' - '$$ &? (display help)') + difffiles = _('diff %s (%d of %d)') % ( + commonfile, + idx + 1, + totalfiles, + ) + responses = _( + '[Yns?]' + '$$ &Yes, show diff' + '$$ &No, skip this diff' + '$$ &Skip remaining diffs' + '$$ &? (display help)' + ) r = ui.promptchoice('%s %s' % (difffiles, responses)) - if r == 3: # ? + if r == 3: # ? while r == 3: for c, t in ui.extractchoices(responses)[1]: ui.write('%s - %s\n' % (c, encoding.lower(t))) r = ui.promptchoice('%s %s' % (difffiles, responses)) - if r == 0: # yes + if r == 0: # yes pass - elif r == 1: # no + elif r == 1: # no continue - elif r == 2: # skip + elif r == 2: # skip break curcmdline = formatcmdline( - cmdline, repo_root, do3way=do3way, - parent1=path1a, plabel1=label1a, - parent2=path1b, plabel2=label1b, - child=path2, clabel=label2) + cmdline, + repo_root, + do3way=do3way, + parent1=path1a, + plabel1=label1a, + parent2=path1b, + plabel2=label1b, + child=path2, + clabel=label2, + ) if confirm or not guitool: # Run the comparison program and wait for it to exit @@ -274,15 +330,18 @@ # from the user between each invocation, or because, as far # as we know, the tool doesn't have a GUI, in which case # we can't run multiple CLI programs at the same time. - ui.debug('running %r in %s\n' % - (pycompat.bytestr(curcmdline), tmproot)) + ui.debug( + 'running %r in %s\n' % (pycompat.bytestr(curcmdline), tmproot) + ) ui.system(curcmdline, cwd=tmproot, blockedtag='extdiff') else: # Run the comparison program but don't wait, as we're # going to rapid-fire each file diff and then wait on # the whole group. - ui.debug('running %r in %s (backgrounded)\n' % - (pycompat.bytestr(curcmdline), tmproot)) + ui.debug( + 'running %r in %s (backgrounded)\n' + % (pycompat.bytestr(curcmdline), tmproot) + ) proc = _systembackground(curcmdline, cwd=tmproot) waitprocs.append(proc) @@ -291,6 +350,7 @@ for proc in waitprocs: proc.wait() + def dodiff(ui, repo, cmdline, pats, opts, guitool=False): '''Do the actual diff: @@ -329,7 +389,7 @@ if node1b == nullid: do3way = False - subrepos=opts.get('subrepos') + subrepos = opts.get('subrepos') matcher = scmutil.match(repo[node2], pats, opts) @@ -341,12 +401,14 @@ if node2 is None: raise error.Abort(_('--patch requires two revisions')) else: - mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher, - listsubrepos=subrepos)[:3]) + mod_a, add_a, rem_a = map( + set, repo.status(node1a, node2, matcher, listsubrepos=subrepos)[:3] + ) if do3way: - mod_b, add_b, rem_b = map(set, - repo.status(node1b, node2, matcher, - listsubrepos=subrepos)[:3]) + mod_b, add_b, rem_b = map( + set, + repo.status(node1b, node2, matcher, listsubrepos=subrepos)[:3], + ) else: mod_b, add_b, rem_b = set(), set(), set() modadd = mod_a | add_a | mod_b | add_b @@ -359,13 +421,15 @@ if not opts.get('patch'): # Always make a copy of node1a (and node1b, if applicable) dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a) - dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, - subrepos)[0] + dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, subrepos)[ + 0 + ] rev1a = '@%d' % repo[node1a].rev() if do3way: dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b) - dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot, - subrepos)[0] + dir1b = snapshot( + ui, repo, dir1b_files, node1b, tmproot, subrepos + )[0] rev1b = '@%d' % repo[node1b].rev() else: dir1b = None @@ -380,12 +444,13 @@ dir2 = snapshot(ui, repo, modadd, node2, tmproot, subrepos)[0] rev2 = '@%d' % repo[node2].rev() elif len(common) > 1: - #we only actually need to get the files to copy back to - #the working dir in this case (because the other cases - #are: diffing 2 revisions or single file -- in which case - #the file is already directly passed to the diff tool). - dir2, fnsandstat = snapshot(ui, repo, modadd, None, tmproot, - subrepos) + # we only actually need to get the files to copy back to + # the working dir in this case (because the other cases + # are: diffing 2 revisions or single file -- in which case + # the file is already directly passed to the diff tool). + dir2, fnsandstat = snapshot( + ui, repo, modadd, None, tmproot, subrepos + ) else: # This lets the diff tool open the changed file directly dir2 = '' @@ -413,10 +478,13 @@ else: template = 'hg-%h.patch' with formatter.nullformatter(ui, 'extdiff', {}) as fm: - cmdutil.export(repo, [repo[node1a].rev(), repo[node2].rev()], - fm, - fntemplate=repo.vfs.reljoin(tmproot, template), - match=matcher) + cmdutil.export( + repo, + [repo[node1a].rev(), repo[node2].rev()], + fm, + fntemplate=repo.vfs.reljoin(tmproot, template), + match=matcher, + ) label1a = cmdutil.makefilename(repo[node1a], template) label2 = cmdutil.makefilename(repo[node2], template) dir1a = repo.vfs.reljoin(tmproot, label1a) @@ -428,21 +496,39 @@ if not perfile: # Run the external tool on the 2 temp directories or the patches cmdline = formatcmdline( - cmdline, repo.root, do3way=do3way, - parent1=dir1a, plabel1=label1a, - parent2=dir1b, plabel2=label1b, - child=dir2, clabel=label2) - ui.debug('running %r in %s\n' % (pycompat.bytestr(cmdline), - tmproot)) + cmdline, + repo.root, + do3way=do3way, + parent1=dir1a, + plabel1=label1a, + parent2=dir1b, + plabel2=label1b, + child=dir2, + clabel=label2, + ) + ui.debug( + 'running %r in %s\n' % (pycompat.bytestr(cmdline), tmproot) + ) ui.system(cmdline, cwd=tmproot, blockedtag='extdiff') else: # Run the external tool once for each pair of files _runperfilediff( - cmdline, repo.root, ui, guitool=guitool, - do3way=do3way, confirm=confirm, - commonfiles=common, tmproot=tmproot, dir1a=dir1a, dir1b=dir1b, - dir2root=dir2root, dir2=dir2, - rev1a=rev1a, rev1b=rev1b, rev2=rev2) + cmdline, + repo.root, + ui, + guitool=guitool, + do3way=do3way, + confirm=confirm, + commonfiles=common, + tmproot=tmproot, + dir1a=dir1a, + dir1b=dir1b, + dir2root=dir2root, + dir2=dir2, + rev1a=rev1a, + rev1b=rev1b, + rev2=rev2, + ) for copy_fn, working_fn, st in fnsandstat: cpstat = os.lstat(copy_fn) @@ -453,11 +539,15 @@ # copyfile() carries over the permission, so the mode check could # be in an 'elif' branch, but for the case where the file has # changed without affecting mtime or size. - if (cpstat[stat.ST_MTIME] != st[stat.ST_MTIME] + if ( + cpstat[stat.ST_MTIME] != st[stat.ST_MTIME] or cpstat.st_size != st.st_size - or (cpstat.st_mode & 0o100) != (st.st_mode & 0o100)): - ui.debug('file changed while diffing. ' - 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn)) + or (cpstat.st_mode & 0o100) != (st.st_mode & 0o100) + ): + ui.debug( + 'file changed while diffing. ' + 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn) + ) util.copyfile(copy_fn, working_fn) return 1 @@ -465,24 +555,39 @@ ui.note(_('cleaning up temp directory\n')) shutil.rmtree(tmproot) -extdiffopts = [ - ('o', 'option', [], - _('pass option to comparison program'), _('OPT')), - ('r', 'rev', [], _('revision'), _('REV')), - ('c', 'change', '', _('change made by revision'), _('REV')), - ('', 'per-file', False, - _('compare each file instead of revision snapshots')), - ('', 'confirm', False, - _('prompt user before each external program invocation')), - ('', 'patch', None, _('compare patches for two revisions')) - ] + cmdutil.walkopts + cmdutil.subrepoopts -@command('extdiff', - [('p', 'program', '', _('comparison program to run'), _('CMD')), - ] + extdiffopts, +extdiffopts = ( + [ + ('o', 'option', [], _('pass option to comparison program'), _('OPT')), + ('r', 'rev', [], _('revision'), _('REV')), + ('c', 'change', '', _('change made by revision'), _('REV')), + ( + '', + 'per-file', + False, + _('compare each file instead of revision snapshots'), + ), + ( + '', + 'confirm', + False, + _('prompt user before each external program invocation'), + ), + ('', 'patch', None, _('compare patches for two revisions')), + ] + + cmdutil.walkopts + + cmdutil.subrepoopts +) + + +@command( + 'extdiff', + [('p', 'program', '', _('comparison program to run'), _('CMD')),] + + extdiffopts, _('hg extdiff [OPT]... [FILE]...'), helpcategory=command.CATEGORY_FILE_CONTENTS, - inferrepo=True) + inferrepo=True, +) def extdiff(ui, repo, *pats, **opts): '''use external program to diff repository (or selected files) @@ -523,6 +628,7 @@ cmdline = ' '.join(map(procutil.shellquote, [program] + option)) return dodiff(ui, repo, cmdline, pats, opts) + class savedcmd(object): """use external program to diff repository (or selected files) @@ -552,8 +658,10 @@ options = ' '.join(map(procutil.shellquote, opts['option'])) if options: options = ' ' + options - return dodiff(ui, repo, self._cmdline + options, pats, opts, - guitool=self._isgui) + return dodiff( + ui, repo, self._cmdline + options, pats, opts, guitool=self._isgui + ) + def uisetup(ui): for cmd, path in ui.configitems('extdiff'): @@ -594,9 +702,14 @@ if isgui is None: isgui = ui.configbool(section, cmd + '.gui') or False break - command(cmd, extdiffopts[:], _('hg %s [OPTION]... [FILE]...') % cmd, - helpcategory=command.CATEGORY_FILE_CONTENTS, - inferrepo=True)(savedcmd(path, cmdline, isgui)) + command( + cmd, + extdiffopts[:], + _('hg %s [OPTION]... [FILE]...') % cmd, + helpcategory=command.CATEGORY_FILE_CONTENTS, + inferrepo=True, + )(savedcmd(path, cmdline, isgui)) + # tell hggettext to extract docstrings from these functions: i18nfunctions = [savedcmd]