[PATCH 1 of 3] move opener from util to scmutil

Adrian Buehlmann adrian at cadifra.com
Wed Apr 20 16:37:16 CDT 2011


# HG changeset patch
# User Adrian Buehlmann <adrian at cadifra.com>
# Date 1303322097 -7200
# Node ID 6b6e3246f225d54b17f65af757e4e89d00cd5c41
# Parent  ac1c75a7c6b56a1fe5bcb14563d3a8788afeaddb
move opener from util to scmutil

diff --git a/contrib/undumprevlog b/contrib/undumprevlog
--- a/contrib/undumprevlog
+++ b/contrib/undumprevlog
@@ -4,12 +4,12 @@
 # $ undumprevlog < repo.dump
 
 import sys
-from mercurial import revlog, node, util, transaction
+from mercurial import revlog, node, scmutil, util, transaction
 
 for fp in (sys.stdin, sys.stdout, sys.stderr):
     util.set_binary(fp)
 
-opener = util.opener('.', False)
+opener = scmutil.opener('.', False)
 tr = transaction.transaction(sys.stderr.write, opener, "undump.journal")
 while 1:
     l = sys.stdin.readline()
diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -10,7 +10,7 @@
 import urllib
 import urllib2
 
-from mercurial import strutil, util, encoding
+from mercurial import strutil, scmutil, util, encoding
 from mercurial.i18n import _
 
 # Subversion stuff. Works best with very recent Python SVN bindings
@@ -998,8 +998,8 @@
             self.run0('checkout', path, wcpath)
 
             self.wc = wcpath
-        self.opener = util.opener(self.wc)
-        self.wopener = util.opener(self.wc)
+        self.opener = scmutil.opener(self.wc)
+        self.wopener = scmutil.opener(self.wc)
         self.childmap = mapfile(ui, self.join('hg-childmap'))
         self.is_exec = util.checkexec(self.wc) and util.is_exec or None
 
diff --git a/hgext/extdiff.py b/hgext/extdiff.py
--- a/hgext/extdiff.py
+++ b/hgext/extdiff.py
@@ -61,7 +61,7 @@
 
 from mercurial.i18n import _
 from mercurial.node import short, nullid
-from mercurial import cmdutil, util, commands, encoding
+from mercurial import cmdutil, scmutil, util, commands, encoding
 import os, shlex, shutil, tempfile, re
 
 def snapshot(ui, repo, files, node, tmproot):
@@ -81,7 +81,7 @@
     else:
         ui.note(_('making snapshot of %d files from working directory\n') %
             (len(files)))
-    wopener = util.opener(base)
+    wopener = scmutil.opener(base)
     fns_and_mtime = []
     ctx = repo[node]
     for fn in files:
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -45,7 +45,7 @@
 from mercurial.i18n import _
 from mercurial.node import bin, hex, short, nullid, nullrev
 from mercurial.lock import release
-from mercurial import commands, cmdutil, hg, patch, util
+from mercurial import commands, cmdutil, hg, patch, scmutil, util
 from mercurial import repair, extensions, url, error
 import os, sys, re, errno, shutil
 
@@ -259,7 +259,7 @@
         except IOError:
             curpath = os.path.join(path, 'patches')
         self.path = patchdir or curpath
-        self.opener = util.opener(self.path)
+        self.opener = scmutil.opener(self.path)
         self.ui = ui
         self.applied_dirty = 0
         self.series_dirty = 0
diff --git a/hgext/transplant.py b/hgext/transplant.py
--- a/hgext/transplant.py
+++ b/hgext/transplant.py
@@ -16,7 +16,7 @@
 from mercurial.i18n import _
 import os, tempfile
 from mercurial import bundlerepo, cmdutil, hg, merge, match
-from mercurial import patch, revlog, util, error
+from mercurial import patch, revlog, scmutil, util, error
 from mercurial import revset, templatekw
 
 class transplantentry(object):
@@ -31,7 +31,7 @@
         self.opener = opener
 
         if not opener:
-            self.opener = util.opener(self.path)
+            self.opener = scmutil.opener(self.path)
         self.transplants = {}
         self.dirty = False
         self.read()
@@ -74,7 +74,7 @@
     def __init__(self, ui, repo):
         self.ui = ui
         self.path = repo.join('transplant')
-        self.opener = util.opener(self.path)
+        self.opener = scmutil.opener(self.path)
         self.transplants = transplants(self.path, 'transplants',
                                        opener=self.opener)
 
diff --git a/mercurial/archival.py b/mercurial/archival.py
--- a/mercurial/archival.py
+++ b/mercurial/archival.py
@@ -8,7 +8,7 @@
 from i18n import _
 from node import hex
 import cmdutil
-import util, encoding
+import scmutil, util, encoding
 import cStringIO, os, tarfile, time, zipfile
 import zlib, gzip
 
@@ -187,7 +187,7 @@
 
     def __init__(self, name, mtime):
         self.basedir = name
-        self.opener = util.opener(self.basedir)
+        self.opener = scmutil.opener(self.basedir)
 
     def addfile(self, name, mode, islink, data):
         if islink:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -9,7 +9,7 @@
 from lock import release
 from i18n import _, gettext
 import os, re, sys, difflib, time, tempfile
-import hg, util, revlog, extensions, copies, error, bookmarks
+import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
 import patch, help, mdiff, url, encoding, templatekw, discovery
 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
 import merge as mergemod
@@ -975,7 +975,7 @@
     """find the ancestor revision of two revisions in a given index"""
     if len(args) == 3:
         index, rev1, rev2 = args
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
+        r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
         lookup = r.lookup
     elif len(args) == 2:
         if not repo:
@@ -1393,7 +1393,7 @@
     spaces = opts.get('spaces')
     dots = opts.get('dots')
     if file_:
-        rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+        rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
         revs = set((int(r) for r in revs))
         def events():
             for r in rlog:
@@ -1443,7 +1443,8 @@
         if len(filelog):
             r = filelog
     if not r:
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
+        r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
+                          file_[:-2] + ".i")
     try:
         ui.write(r.revision(r.lookup(rev)))
     except KeyError:
@@ -1482,7 +1483,7 @@
         raise util.Abort(_("unknown format %d") % format)
 
     if not r:
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+        r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
 
     if format == 0:
         ui.write("   rev    offset  length   base linkrev"
@@ -1515,7 +1516,7 @@
         if len(filelog):
             r = filelog
     if not r:
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+        r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
     ui.write("digraph G {\n")
     for i in r:
         node = r.node(i)
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -10,7 +10,7 @@
 import repo, changegroup, subrepo, discovery, pushkey
 import changelog, dirstate, filelog, manifest, context, bookmarks
 import lock, transaction, store, encoding
-import util, extensions, hook, error
+import scmutil, util, extensions, hook, error
 import match as matchmod
 import merge as mergemod
 import tags as tagsmod
@@ -32,8 +32,8 @@
         self.path = os.path.join(self.root, ".hg")
         self.origroot = path
         self.auditor = util.path_auditor(self.root, self._checknested)
-        self.opener = util.opener(self.path)
-        self.wopener = util.opener(self.root)
+        self.opener = scmutil.opener(self.path)
+        self.wopener = scmutil.opener(self.root)
         self.baseui = baseui
         self.ui = baseui.copy()
 
@@ -90,7 +90,7 @@
             if inst.errno != errno.ENOENT:
                 raise
 
-        self.store = store.store(requirements, self.sharedpath, util.opener)
+        self.store = store.store(requirements, self.sharedpath, scmutil.opener)
         self.spath = self.store.path
         self.sopener = self.store.opener
         self.sjoin = self.store.join
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -11,7 +11,7 @@
 
 from i18n import _
 from node import hex, nullid, short
-import base85, mdiff, util, diffhelpers, copies, encoding
+import base85, mdiff, scmutil, util, diffhelpers, copies, encoding
 
 gitre = re.compile('diff --git a/(.*) b/(.*)')
 
@@ -1111,7 +1111,7 @@
     err = 0
     current_file = None
     cwd = os.getcwd()
-    opener = util.opener(cwd)
+    opener = scmutil.opener(cwd)
 
     for state, values in iterhunks(ui, fp):
         if state == 'hunk':
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -7,7 +7,7 @@
 
 from i18n import _
 import util, error
-import os
+import os, errno
 
 def checkportable(ui, f):
     '''Check if filename f is portable and warn or abort depending on config'''
@@ -25,3 +25,98 @@
     elif bval is None and lval != 'ignore':
         raise error.ConfigError(
             _("ui.portablefilenames value is invalid ('%s')") % val)
+
+class opener(object):
+    '''Open files relative to a base directory
+
+    This class is used to hide the details of COW semantics and
+    remote file access from higher level code.
+    '''
+    def __init__(self, base, audit=True):
+        self.base = base
+        if audit:
+            self.auditor = util.path_auditor(base)
+        else:
+            self.auditor = util.always
+        self.createmode = None
+        self._trustnlink = None
+
+    @util.propertycache
+    def _can_symlink(self):
+        return util.checklink(self.base)
+
+    def _fixfilemode(self, name):
+        if self.createmode is None:
+            return
+        os.chmod(name, self.createmode & 0666)
+
+    def __call__(self, path, mode="r", text=False, atomictemp=False):
+        r = util.checkosfilename(path)
+        if r:
+            raise Abort("%s: %r" % (r, path))
+        self.auditor(path)
+        f = os.path.join(self.base, path)
+
+        if not text and "b" not in mode:
+            mode += "b" # for that other OS
+
+        nlink = -1
+        dirname, basename = os.path.split(f)
+        # If basename is empty, then the path is malformed because it points
+        # to a directory. Let the posixfile() call below raise IOError.
+        if basename and mode not in ('r', 'rb'):
+            if atomictemp:
+                if not os.path.isdir(dirname):
+                    util.makedirs(dirname, self.createmode)
+                return util.atomictempfile(f, mode, self.createmode)
+            try:
+                if 'w' in mode:
+                    util.unlink(f)
+                    nlink = 0
+                else:
+                    # nlinks() may behave differently for files on Windows
+                    # shares if the file is open.
+                    fd = util.posixfile(f)
+                    nlink = util.nlinks(f)
+                    if nlink < 1:
+                        nlink = 2 # force mktempcopy (issue1922)
+                    fd.close()
+            except (OSError, IOError), e:
+                if e.errno != errno.ENOENT:
+                    raise
+                nlink = 0
+                if not os.path.isdir(dirname):
+                    util.makedirs(dirname, self.createmode)
+            if nlink > 0:
+                if self._trustnlink is None:
+                    self._trustnlink = nlink > 1 or util.checknlink(f)
+                if nlink > 1 or not self._trustnlink:
+                    util.rename(util.mktempcopy(f), f)
+        fp = util.posixfile(f, mode)
+        if nlink == 0:
+            self._fixfilemode(f)
+        return fp
+
+    def symlink(self, src, dst):
+        self.auditor(dst)
+        linkname = os.path.join(self.base, dst)
+        try:
+            os.unlink(linkname)
+        except OSError:
+            pass
+
+        dirname = os.path.dirname(linkname)
+        if not os.path.exists(dirname):
+            util.makedirs(dirname, self.createmode)
+
+        if self._can_symlink:
+            try:
+                os.symlink(src, linkname)
+            except OSError, err:
+                raise OSError(err.errno, _('could not symlink to %r: %s') %
+                              (src, err.strerror), linkname)
+        else:
+            f = self(dst, "w")
+            f.write(src)
+            f.close()
+            self._fixfilemode(dst)
diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -18,7 +18,7 @@
 # s: "i hate that."
 
 from i18n import _
-import util, mdiff
+import scmutil, util, mdiff
 import sys, os
 
 class CantReprocessAndShowBase(Exception):
@@ -429,7 +429,7 @@
 
     local = os.path.realpath(local)
     if not opts.get('print'):
-        opener = util.opener(os.path.dirname(local))
+        opener = scmutil.opener(os.path.dirname(local))
         out = opener(os.path.basename(local), "w", atomictemp=True)
     else:
         out = sys.stdout
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -895,101 +895,6 @@
     makedirs(parent, mode)
     makedirs(name, mode)
 
-class opener(object):
-    """Open files relative to a base directory
-
-    This class is used to hide the details of COW semantics and
-    remote file access from higher level code.
-    """
-    def __init__(self, base, audit=True):
-        self.base = base
-        if audit:
-            self.auditor = path_auditor(base)
-        else:
-            self.auditor = always
-        self.createmode = None
-        self._trustnlink = None
-
-    @propertycache
-    def _can_symlink(self):
-        return checklink(self.base)
-
-    def _fixfilemode(self, name):
-        if self.createmode is None:
-            return
-        os.chmod(name, self.createmode & 0666)
-
-    def __call__(self, path, mode="r", text=False, atomictemp=False):
-        r = checkosfilename(path)
-        if r:
-            raise Abort("%s: %r" % (r, path))
-        self.auditor(path)
-        f = os.path.join(self.base, path)
-
-        if not text and "b" not in mode:
-            mode += "b" # for that other OS
-
-        nlink = -1
-        dirname, basename = os.path.split(f)
-        # If basename is empty, then the path is malformed because it points
-        # to a directory. Let the posixfile() call below raise IOError.
-        if basename and mode not in ('r', 'rb'):
-            if atomictemp:
-                if not os.path.isdir(dirname):
-                    makedirs(dirname, self.createmode)
-                return atomictempfile(f, mode, self.createmode)
-            try:
-                if 'w' in mode:
-                    unlink(f)
-                    nlink = 0
-                else:
-                    # nlinks() may behave differently for files on Windows
-                    # shares if the file is open.
-                    fd = posixfile(f)
-                    nlink = nlinks(f)
-                    if nlink < 1:
-                        nlink = 2 # force mktempcopy (issue1922)
-                    fd.close()
-            except (OSError, IOError), e:
-                if e.errno != errno.ENOENT:
-                    raise
-                nlink = 0
-                if not os.path.isdir(dirname):
-                    makedirs(dirname, self.createmode)
-            if nlink > 0:
-                if self._trustnlink is None:
-                    self._trustnlink = nlink > 1 or checknlink(f)
-                if nlink > 1 or not self._trustnlink:
-                    rename(mktempcopy(f), f)
-        fp = posixfile(f, mode)
-        if nlink == 0:
-            self._fixfilemode(f)
-        return fp
-
-    def symlink(self, src, dst):
-        self.auditor(dst)
-        linkname = os.path.join(self.base, dst)
-        try:
-            os.unlink(linkname)
-        except OSError:
-            pass
-
-        dirname = os.path.dirname(linkname)
-        if not os.path.exists(dirname):
-            makedirs(dirname, self.createmode)
-
-        if self._can_symlink:
-            try:
-                os.symlink(src, linkname)
-            except OSError, err:
-                raise OSError(err.errno, _('could not symlink to %r: %s') %
-                              (src, err.strerror), linkname)
-        else:
-            f = self(dst, "w")
-            f.write(src)
-            f.close()
-            self._fixfilemode(dst)
-
 class chunkbuffer(object):
     """Allow arbitrary sized chunks of data to be efficiently read from an
     iterator over chunks of arbitrary size."""
diff --git a/tests/test-parseindex.t b/tests/test-parseindex.t
--- a/tests/test-parseindex.t
+++ b/tests/test-parseindex.t
@@ -26,7 +26,7 @@
   summary:     change foo
   
   $ cat >> test.py << EOF
-  > from mercurial import changelog, util
+  > from mercurial import changelog, scmutil
   > from mercurial.node import *
   > 
   > class singlebyteread(object):
@@ -42,7 +42,7 @@
   >         return getattr(self.real, key)
   > 
   > def opener(*args):
-  >     o = util.opener(*args)
+  >     o = scmutil.opener(*args)
   >     def wrapper(*a):
   >         f = o(*a)
   >         return singlebyteread(f)


More information about the Mercurial-devel mailing list