[PATCH] upgrade casecollisionauditor to portabilityauditor

Adrian Buehlmann adrian at cadifra.com
Mon May 2 12:55:26 CDT 2011


# HG changeset patch
# User Adrian Buehlmann <adrian at cadifra.com>
# Date 1304343849 -7200
# Node ID 663767d08c5193686b9672d0e5954526f335f572
# Parent  d8ba6fb2ce15add4937ce9c3710e8dbd99648818
upgrade casecollisionauditor to portabilityauditor

- include calls to checkfilename and checkwinfilename in auditor
- check filenames on rename/copy/addremove
- scmutil.checkportable and checkportabilityalert are no longer needed

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -287,6 +287,8 @@
     # we'd use status here, except handling of symlinks and ignore is tricky
     added, unknown, deleted, removed = [], [], [], []
     audit_path = scmutil.path_auditor(repo.root)
+    wctx = repo[None]
+    pa = scmutil.portabilityauditor(repo.ui, wctx)
     m = match(repo, pats, opts)
     for abs in repo.walk(m):
         target = repo.wjoin(abs)
@@ -298,6 +300,7 @@
         rel = m.rel(abs)
         exact = m.exact(abs)
         if good and abs not in repo.dirstate:
+            pa(abs)
             unknown.append(abs)
             if repo.ui.verbose or not exact:
                 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
@@ -319,10 +322,10 @@
                 repo.ui.status(_('recording removal of %s as rename to %s '
                                  '(%d%% similar)\n') %
                                (m.rel(old), m.rel(new), score * 100))
+            pa(new)
             copies[new] = old
 
     if not dry_run:
-        wctx = repo[None]
         wlock = repo.wlock()
         try:
             wctx.remove(deleted)
@@ -428,14 +431,14 @@
     # abssrc: hgsep
     # relsrc: ossep
     # otarget: ossep
-    def copyfile(abssrc, relsrc, otarget, exact):
+    def copyfile(abssrc, relsrc, otarget, exact, auditor):
         abstarget = scmutil.canonpath(repo.root, cwd, otarget)
         reltarget = repo.pathto(abstarget, cwd)
         target = repo.wjoin(abstarget)
         src = repo.wjoin(abssrc)
         state = repo.dirstate[abstarget]
 
-        scmutil.checkportable(ui, abstarget)
+        auditor(abstarget)
 
         # check for collisions
         prevsrc = targets.get(abstarget)
@@ -584,10 +587,11 @@
     if not copylist:
         raise util.Abort(_('no files to copy'))
 
+    pa = scmutil.portabilityauditor(ui, wctx)
     errors = 0
     for targetpath, srcs in copylist:
         for abssrc, relsrc, exact in srcs:
-            if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
+            if copyfile(abssrc, relsrc, targetpath(abssrc), exact, pa):
                 errors += 1
 
     if errors:
@@ -1314,15 +1318,11 @@
     match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
     names = []
     wctx = repo[None]
-    cca = None
-    abort, warn = scmutil.checkportabilityalert(ui)
-    if abort or warn:
-        cca = scmutil.casecollisionauditor(ui, abort, wctx)
+    pa = scmutil.portabilityauditor(ui, wctx)
     for f in repo.walk(match):
         exact = match.exact(f)
         if exact or f not in repo.dirstate:
-            if cca:
-                cca(f)
+            pa(f)
             names.append(f)
             if ui.verbose or not exact:
                 ui.status(_('adding %s\n') % match.rel(join(f)))
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -7,7 +7,7 @@
 
 from node import nullid, nullrev, short, hex
 from i18n import _
-import ancestor, bdiff, error, util, scmutil, subrepo, patch, encoding
+import ancestor, bdiff, error, util, subrepo, patch, encoding
 import os, errno, stat
 
 propertycache = util.propertycache
@@ -807,7 +807,6 @@
         try:
             rejected = []
             for f in list:
-                scmutil.checkportable(ui, join(f))
                 p = self._repo.wjoin(f)
                 try:
                     st = os.lstat(p)
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -14,48 +14,40 @@
     if '\r' in f or '\n' in f:
         raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r") % f)
 
-def checkportable(ui, f):
-    '''Check if filename f is portable and warn or abort depending on config'''
-    checkfilename(f)
-    abort, warn = checkportabilityalert(ui)
-    if abort or warn:
+class portabilityauditor(object):
+    def __init__(self, ui, existingiter):
+        self._ui = ui
+        val = ui.config('ui', 'portablefilenames', 'warn')
+        lval = val.lower()
+        bval = util.parsebool(val)
+        abort = os.name == 'nt' or lval == 'abort'
+        warn = bval or lval == 'warn'
+        if bval is None and not (warn or abort or lval == 'ignore'):
+            raise error.ConfigError(
+                _("ui.portablefilenames value is invalid ('%s')") % val)
+        self._abort = abort
+        self._map = None
+        if abort or warn:
+            self._map = {}
+            for f in existingiter:
+                self._map[f.lower()] = f
+
+    def __call__(self, f):
+        checkfilename(f)
+        if self._map is None:
+            return
         msg = util.checkwinfilename(f)
+        if not msg:
+            fl = f.lower()
+            map = self._map
+            if fl in map and map[fl] != f:
+                msg = _('possible case-folding collision')
+            map[fl] = f
         if msg:
             msg = "%s: %r" % (msg, f)
-            if abort:
-                raise util.Abort(msg)
-            ui.warn(_("warning: %s\n") % msg)
-
-def checkportabilityalert(ui):
-    '''check if the user's config requests nothing, a warning, or abort for
-    non-portable filenames'''
-    val = ui.config('ui', 'portablefilenames', 'warn')
-    lval = val.lower()
-    bval = util.parsebool(val)
-    abort = os.name == 'nt' or lval == 'abort'
-    warn = bval or lval == 'warn'
-    if bval is None and not (warn or abort or lval == 'ignore'):
-        raise error.ConfigError(
-            _("ui.portablefilenames value is invalid ('%s')") % val)
-    return abort, warn
-
-class casecollisionauditor(object):
-    def __init__(self, ui, abort, existingiter):
-        self._ui = ui
-        self._abort = abort
-        self._map = {}
-        for f in existingiter:
-            self._map[f.lower()] = f
-
-    def __call__(self, f):
-        fl = f.lower()
-        map = self._map
-        if fl in map and map[fl] != f:
-            msg = _('possible case-folding collision for %s') % f
             if self._abort:
                 raise util.Abort(msg)
             self._ui.warn(_("warning: %s\n") % msg)
-        map[fl] = f
 
 class path_auditor(object):
     '''ensure that a filesystem path contains no banned components.
diff --git a/tests/test-add.t b/tests/test-add.t
--- a/tests/test-add.t
+++ b/tests/test-add.t
@@ -52,7 +52,6 @@
   A con.xml
   $ echo bla > 'hello:world'
   $ hg --config ui.portablefilenames=abort add
-  adding hello:world
   abort: filename contains ':', which is reserved on Windows: 'hello:world'
   [255]
   $ hg st
diff --git a/tests/test-addremove.t b/tests/test-addremove.t
--- a/tests/test-addremove.t
+++ b/tests/test-addremove.t
@@ -13,9 +13,9 @@
   $ touch ../foo_2 bar_2 con.xml
   $ hg -v addremove
   adding dir/bar_2
+  warning: filename contains 'con', which is reserved on Windows: 'dir/con.xml'
   adding dir/con.xml
   adding foo_2
-  warning: filename contains 'con', which is reserved on Windows: 'dir/con.xml'
   $ hg -v commit -m "add 2"
   dir/bar_2
   dir/con.xml
diff --git a/tests/test-casecollision.t b/tests/test-casecollision.t
--- a/tests/test-casecollision.t
+++ b/tests/test-casecollision.t
@@ -7,19 +7,28 @@
   $ hg init repo1
   $ cd repo1
   $ echo a > a
+  $ hg add a
+  $ hg copy --config ui.portablefilenames=abort a A
+  abort: possible case-folding collision: 'A'
+  [255]
+  $ hg rename --config ui.portablefilenames=abort a A
+  abort: possible case-folding collision: 'A'
+  [255]
   $ echo A > A
-  $ hg add a
   $ hg st
   A a
   ? A
+  $ hg addremove --config ui.portablefilenames=abort
+  abort: possible case-folding collision: 'A'
+  [255]
   $ hg add --config ui.portablefilenames=abort A
-  abort: possible case-folding collision for A
+  abort: possible case-folding collision: 'A'
   [255]
   $ hg st
   A a
   ? A
   $ hg add A
-  warning: possible case-folding collision for A
+  warning: possible case-folding collision: 'A'
   $ hg st
   A A
   A a
diff --git a/tests/test-eolfilename.t b/tests/test-eolfilename.t
--- a/tests/test-eolfilename.t
+++ b/tests/test-eolfilename.t
@@ -9,24 +9,18 @@
   $ A=`printf 'he\rllo'`
   $ echo foo > "$A"
   $ hg add
-  adding he\rllo (esc)
   abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
   [255]
   $ hg ci -A -m m
-  adding he\rllo (esc)
   abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
   [255]
   $ rm "$A"
   $ echo foo > "hell
   > o"
   $ hg add
-  adding hell
-  o
   abort: '\n' and '\r' disallowed in filenames: 'hell\no'
   [255]
   $ hg ci -A -m m
-  adding hell
-  o
   abort: '\n' and '\r' disallowed in filenames: 'hell\no'
   [255]
   $ echo foo > "$A"
diff --git a/tests/test-walk.t b/tests/test-walk.t
--- a/tests/test-walk.t
+++ b/tests/test-walk.t
@@ -23,12 +23,12 @@
   adding fennel
   adding fenugreek
   adding fiddlehead
+  warning: filename contains ':', which is reserved on Windows: 'glob:glob'
   adding glob:glob
   adding mammals/Procyonidae/cacomistle
   adding mammals/Procyonidae/coatimundi
   adding mammals/Procyonidae/raccoon
   adding mammals/skunk
-  warning: filename contains ':', which is reserved on Windows: 'glob:glob'
   $ hg commit -m "commit #0"
 
   $ hg debugwalk


More information about the Mercurial-devel mailing list