From eb318ffa63d64691be0b28d8eff070c8c130421f Mon Sep 17 00:00:00 2001 From: Mark Thomas Date: Wed, 21 Mar 2018 13:41:26 -0700 Subject: [PATCH] convert: use new-style progress bars Reviewed By: quark-zju Differential Revision: D7329501 fbshipit-source-id: 5312f905b513200904c79acbdb1c7b17968a8aba --- hgext/convert/convcmd.py | 88 +++++++++-------- hgext/convert/subversion.py | 175 +++++++++++++++++----------------- tests/test-convert-git.t | 2 + tests/test-convert-svn-move.t | 1 + 4 files changed, 135 insertions(+), 131 deletions(-) diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py index 9d270c8a9f..126d269dc4 100644 --- a/hgext/convert/convcmd.py +++ b/hgext/convert/convcmd.py @@ -15,6 +15,7 @@ from mercurial import ( encoding, error, hg, + progress, scmutil, util, ) @@ -53,7 +54,7 @@ svn_source = subversion.svn_source orig_encoding = 'ascii' def recode(s): - if isinstance(s, unicode): + if isinstance(s, unicode): # noqa return s.encode(orig_encoding, 'replace') else: return s.decode('utf-8').encode(orig_encoding, 'replace') @@ -137,16 +138,14 @@ def convertsink(ui, path, type): raise error.Abort(_('%s: unknown repository type') % path) class progresssource(object): - def __init__(self, ui, source, filecount): - self.ui = ui + def __init__(self, source, prog): self.source = source - self.filecount = filecount + self.prog = prog self.retrieved = 0 def getfile(self, file, rev): self.retrieved += 1 - self.ui.progress(_('getting files'), self.retrieved, - item=file, total=self.filecount, unit=_('files')) + self.prog.value = (self.retrieved, file) return self.source.getfile(file, rev) def targetfilebelongstosource(self, targetfilename): @@ -155,9 +154,6 @@ class progresssource(object): def lookuprev(self, rev): return self.source.lookuprev(rev) - def close(self): - self.ui.progress(_('getting files'), None) - class converter(object): def __init__(self, ui, source, dest, revmapfile, opts): @@ -236,23 +232,23 @@ class converter(object): known = set() parents = {} numcommits = self.source.numcommits() - while visit: - n = visit.pop(0) - if n in known: - continue - if n in self.map: - m = self.map[n] - if m == SKIPREV or self.dest.hascommitfrommap(m): + with progress.bar(self.ui, _('scanning'), _('revisions'), + numcommits) as prog: + while visit: + n = visit.pop(0) + if n in known: continue - known.add(n) - self.ui.progress(_('scanning'), len(known), unit=_('revisions'), - total=numcommits) - commit = self.cachecommit(n) - parents[n] = [] - for p in commit.parents: - parents[n].append(p) - visit.append(p) - self.ui.progress(_('scanning'), None) + if n in self.map: + m = self.map[n] + if m == SKIPREV or self.dest.hascommitfrommap(m): + continue + known.add(n) + prog.value = len(known) + commit = self.cachecommit(n) + parents[n] = [] + for p in commit.parents: + parents[n].append(p) + visit.append(p) return parents @@ -478,17 +474,19 @@ class converter(object): if len(pbranches) != 2: cleanp2 = set() if len(parents) < 3: - source = progresssource(self.ui, self.source, len(files)) + sourcelength = len(files) else: # For an octopus merge, we end up traversing the list of # changed files N-1 times. This tweak to the number of # files makes it so the progress bar doesn't overflow # itself. - source = progresssource(self.ui, self.source, - len(files) * (len(parents) - 1)) - newnode = self.dest.putcommit(files, copies, parents, commit, - source, self.map, full, cleanp2) - source.close() + sourcelength = len(files) * (len(parents) - 1) + + with progress.bar(self.ui, _('getting files'), _('files'), + sourcelength) as prog: + source = progresssource(self.source, prog) + newnode = self.dest.putcommit(files, copies, parents, commit, + source, self.map, full, cleanp2) self.source.converted(rev, newnode) self.map[rev] = newnode @@ -507,20 +505,20 @@ class converter(object): c = None self.ui.status(_("converting...\n")) - for i, c in enumerate(t): - num -= 1 - desc = self.commitcache[c].desc - if "\n" in desc: - desc = desc.splitlines()[0] - # convert log message to local encoding without using - # tolocal() because the encoding.encoding convert() - # uses is 'utf-8' - self.ui.status("%d %s\n" % (num, recode(desc))) - self.ui.note(_("source: %s\n") % recode(c)) - self.ui.progress(_('converting'), i, unit=_('revisions'), - total=len(t)) - self.copy(c) - self.ui.progress(_('converting'), None) + with progress.bar(self.ui, _('converting'), _('revisions'), + len(t)) as prog: + for i, c in enumerate(t): + num -= 1 + desc = self.commitcache[c].desc + if "\n" in desc: + desc = desc.splitlines()[0] + # convert log message to local encoding without using + # tolocal() because the encoding.encoding convert() + # uses is 'utf-8' + self.ui.status("%d %s\n" % (num, recode(desc))) + self.ui.note(_("source: %s\n") % recode(c)) + prog.value = i + self.copy(c) if not self.ui.configbool('convert', 'skiptags'): tags = self.source.gettags() diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py index b87e93b1aa..d2a90c64b0 100644 --- a/hgext/convert/subversion.py +++ b/hgext/convert/subversion.py @@ -12,6 +12,7 @@ from mercurial.i18n import _ from mercurial import ( encoding, error, + progress, pycompat, util, vfs as vfsmod, @@ -745,95 +746,97 @@ class svn_source(converter_source): self.module = new_module self.reparent(self.module) - for i, (path, ent) in enumerate(paths): - self.ui.progress(_('scanning paths'), i, item=path, - total=len(paths), unit=_('paths')) - entrypath = self.getrelpath(path) + with progress.bar(self.ui, _('scanning paths'), _('paths'), + len(paths)) as prog: + for i, (path, ent) in enumerate(paths): + prog.value = (i, path) + entrypath = self.getrelpath(path) - kind = self._checkpath(entrypath, revnum) - if kind == svn.core.svn_node_file: - changed.add(self.recode(entrypath)) - if not ent.copyfrom_path or not parents: - continue - # Copy sources not in parent revisions cannot be - # represented, ignore their origin for now - pmodule, prevnum = revsplit(parents[0])[1:] - if ent.copyfrom_rev < prevnum: - continue - copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule) - if not copyfrom_path: - continue - self.ui.debug("copied to %s from %s@%s\n" % - (entrypath, copyfrom_path, ent.copyfrom_rev)) - copies[self.recode(entrypath)] = self.recode(copyfrom_path) - elif kind == 0: # gone, but had better be a deleted *file* - self.ui.debug("gone from %s\n" % ent.copyfrom_rev) - pmodule, prevnum = revsplit(parents[0])[1:] - parentpath = pmodule + "/" + entrypath - fromkind = self._checkpath(entrypath, prevnum, pmodule) - - if fromkind == svn.core.svn_node_file: - removed.add(self.recode(entrypath)) - elif fromkind == svn.core.svn_node_dir: - oroot = parentpath.strip('/') - nroot = path.strip('/') - children = self._iterfiles(oroot, prevnum) - for childpath in children: - childpath = childpath.replace(oroot, nroot) - childpath = self.getrelpath("/" + childpath, pmodule) - if childpath: - removed.add(self.recode(childpath)) - else: - self.ui.debug('unknown path in revision %d: %s\n' % \ - (revnum, path)) - elif kind == svn.core.svn_node_dir: - if ent.action == 'M': - # If the directory just had a prop change, - # then we shouldn't need to look for its children. - continue - if ent.action == 'R' and parents: - # If a directory is replacing a file, mark the previous - # file as deleted - pmodule, prevnum = revsplit(parents[0])[1:] - pkind = self._checkpath(entrypath, prevnum, pmodule) - if pkind == svn.core.svn_node_file: - removed.add(self.recode(entrypath)) - elif pkind == svn.core.svn_node_dir: - # We do not know what files were kept or removed, - # mark them all as changed. - for childpath in self._iterfiles(pmodule, prevnum): - childpath = self.getrelpath("/" + childpath) - if childpath: - changed.add(self.recode(childpath)) - - for childpath in self._iterfiles(path, revnum): - childpath = self.getrelpath("/" + childpath) - if childpath: - changed.add(self.recode(childpath)) - - # Handle directory copies - if not ent.copyfrom_path or not parents: - continue - # Copy sources not in parent revisions cannot be - # represented, ignore their origin for now - pmodule, prevnum = revsplit(parents[0])[1:] - if ent.copyfrom_rev < prevnum: - continue - copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule) - if not copyfrompath: - continue - self.ui.debug("mark %s came from %s:%d\n" - % (path, copyfrompath, ent.copyfrom_rev)) - children = self._iterfiles(ent.copyfrom_path, ent.copyfrom_rev) - for childpath in children: - childpath = self.getrelpath("/" + childpath, pmodule) - if not childpath: + kind = self._checkpath(entrypath, revnum) + if kind == svn.core.svn_node_file: + changed.add(self.recode(entrypath)) + if not ent.copyfrom_path or not parents: continue - copytopath = path + childpath[len(copyfrompath):] - copytopath = self.getrelpath(copytopath) - copies[self.recode(copytopath)] = self.recode(childpath) + # Copy sources not in parent revisions cannot be + # represented, ignore their origin for now + pmodule, prevnum = revsplit(parents[0])[1:] + if ent.copyfrom_rev < prevnum: + continue + copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule) + if not copyfrom_path: + continue + self.ui.debug("copied to %s from %s@%s\n" % + (entrypath, copyfrom_path, ent.copyfrom_rev)) + copies[self.recode(entrypath)] = self.recode(copyfrom_path) + elif kind == 0: # gone, but had better be a deleted *file* + self.ui.debug("gone from %s\n" % ent.copyfrom_rev) + pmodule, prevnum = revsplit(parents[0])[1:] + parentpath = pmodule + "/" + entrypath + fromkind = self._checkpath(entrypath, prevnum, pmodule) + + if fromkind == svn.core.svn_node_file: + removed.add(self.recode(entrypath)) + elif fromkind == svn.core.svn_node_dir: + oroot = parentpath.strip('/') + nroot = path.strip('/') + children = self._iterfiles(oroot, prevnum) + for childpath in children: + childpath = childpath.replace(oroot, nroot) + childpath = self.getrelpath("/" + childpath, + pmodule) + if childpath: + removed.add(self.recode(childpath)) + else: + self.ui.debug('unknown path in revision %d: %s\n' % \ + (revnum, path)) + elif kind == svn.core.svn_node_dir: + if ent.action == 'M': + # If the directory just had a prop change, + # then we shouldn't need to look for its children. + continue + if ent.action == 'R' and parents: + # If a directory is replacing a file, mark the previous + # file as deleted + pmodule, prevnum = revsplit(parents[0])[1:] + pkind = self._checkpath(entrypath, prevnum, pmodule) + if pkind == svn.core.svn_node_file: + removed.add(self.recode(entrypath)) + elif pkind == svn.core.svn_node_dir: + # We do not know what files were kept or removed, + # mark them all as changed. + for childpath in self._iterfiles(pmodule, prevnum): + childpath = self.getrelpath("/" + childpath) + if childpath: + changed.add(self.recode(childpath)) + + for childpath in self._iterfiles(path, revnum): + childpath = self.getrelpath("/" + childpath) + if childpath: + changed.add(self.recode(childpath)) + + # Handle directory copies + if not ent.copyfrom_path or not parents: + continue + # Copy sources not in parent revisions cannot be + # represented, ignore their origin for now + pmodule, prevnum = revsplit(parents[0])[1:] + if ent.copyfrom_rev < prevnum: + continue + copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule) + if not copyfrompath: + continue + self.ui.debug("mark %s came from %s:%d\n" + % (path, copyfrompath, ent.copyfrom_rev)) + children = self._iterfiles(ent.copyfrom_path, + ent.copyfrom_rev) + for childpath in children: + childpath = self.getrelpath("/" + childpath, pmodule) + if not childpath: + continue + copytopath = path + childpath[len(copyfrompath):] + copytopath = self.getrelpath(copytopath) + copies[self.recode(copytopath)] = self.recode(childpath) - self.ui.progress(_('scanning paths'), None) changed.update(removed) return (list(changed), removed, copies) diff --git a/tests/test-convert-git.t b/tests/test-convert-git.t index 95c472c06d..111e05953a 100644 --- a/tests/test-convert-git.t +++ b/tests/test-convert-git.t @@ -58,6 +58,7 @@ Remove the directory, then try to replace it with a file (issue754) $ hg convert --config extensions.progress= --config progress.assume-tty=1 \ > --config progress.delay=0 --config progress.changedelay=0 \ > --config progress.refresh=0 --config progress.width=60 \ + > --config progress.debug=1 \ > --config progress.format='topic, bar, number' --datesort git-repo \r (no-eol) (esc) scanning [======> ] 1/6\r (no-eol) (esc) @@ -178,6 +179,7 @@ full conversion > --config extensions.progress= --config progress.assume-tty=1 \ > --config progress.delay=0 --config progress.changedelay=0 \ > --config progress.refresh=0 --config progress.width=60 \ + > --config progress.debug=1 \ > --config progress.format='topic, bar, number' \r (no-eol) (esc) scanning [===> ] 1/9\r (no-eol) (esc) diff --git a/tests/test-convert-svn-move.t b/tests/test-convert-svn-move.t index 93de03f979..74e26196a9 100644 --- a/tests/test-convert-svn-move.t +++ b/tests/test-convert-svn-move.t @@ -161,6 +161,7 @@ Test convert progress bar > format = topic bar number > refresh = 0 > width = 60 + > debug = true > EOF $ hg convert svn-repo hg-progress