changeset 6797:8909070fd05e

merge another backout
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Wed, 02 Jul 2008 12:27:57 +0200
parents c228ae4bc89c (diff) 943f066c0d58 (current diff)
children ceb28b67204e
files mercurial/hgweb/hgweb_mod.py mercurial/hgweb/hgwebdir_mod.py
diffstat 16 files changed, 109 insertions(+), 136 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/win32/mercurial.iss	Wed Jul 02 12:02:33 2008 +0200
+++ b/contrib/win32/mercurial.iss	Wed Jul 02 12:27:57 2008 +0200
@@ -2,7 +2,7 @@
 ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
 
 [Setup]
-AppCopyright=Copyright 2005-2007 Matt Mackall and others
+AppCopyright=Copyright 2005-2008 Matt Mackall and others
 AppName=Mercurial
 AppVerName=Mercurial snapshot
 InfoAfterFile=contrib/win32/postinstall.txt
@@ -18,7 +18,7 @@
 DefaultDirName={pf}\Mercurial
 SourceDir=..\..
 VersionInfoDescription=Mercurial distributed SCM
-VersionInfoCopyright=Copyright 2005-2007 Matt Mackall and others
+VersionInfoCopyright=Copyright 2005-2008 Matt Mackall and others
 VersionInfoCompany=Matt Mackall and others
 InternalCompressLevel=max
 SolidCompression=true
--- a/hgext/acl.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/hgext/acl.py	Wed Jul 02 12:27:57 2008 +0200
@@ -46,77 +46,45 @@
 #   ** = user6
 
 from mercurial.i18n import _
-from mercurial.node import bin, short
 from mercurial import util
 import getpass
 
-class checker(object):
-    '''acl checker.'''
-
-    def buildmatch(self, key):
-        '''return tuple of (match function, list enabled).'''
-        if not self.ui.has_section(key):
-            self.ui.debug(_('acl: %s not enabled\n') % key)
-            return None, False
-
-        thisuser = self.getuser()
-        pats = [pat for pat, users in self.ui.configitems(key)
-                if thisuser in users.replace(',', ' ').split()]
-        self.ui.debug(_('acl: %s enabled, %d entries for user %s\n') %
-                      (key, len(pats), thisuser))
-        if pats:
-            match = util.matcher(self.repo.root, names=pats)[1]
-        else:
-            match = util.never
-        return match, True
-
-    def getuser(self):
-        '''return name of authenticated user.'''
-        return self.user
+def buildmatch(ui, repo, user, key):
+    '''return tuple of (match function, list enabled).'''
+    if not ui.has_section(key):
+        ui.debug(_('acl: %s not enabled\n') % key)
+        return None
 
-    def __init__(self, ui, repo):
-        self.ui = ui
-        self.repo = repo
-        self.user = getpass.getuser()
-        cfg = self.ui.config('acl', 'config')
-        if cfg:
-            self.ui.readsections(cfg, 'acl.allow', 'acl.deny')
-        self.allow, self.allowable = self.buildmatch('acl.allow')
-        self.deny, self.deniable = self.buildmatch('acl.deny')
-
-    def skipsource(self, source):
-        '''true if incoming changes from this source should be skipped.'''
-        ok_sources = self.ui.config('acl', 'sources', 'serve').split()
-        return source not in ok_sources
-
-    def check(self, node):
-        '''return if access allowed, raise exception if not.'''
-        files = self.repo[node].files()
-        if self.deniable:
-            for f in files:
-                if self.deny(f):
-                    self.ui.debug(_('acl: user %s denied on %s\n') %
-                                  (self.getuser(), f))
-                    raise util.Abort(_('acl: access denied for changeset %s') %
-                                     short(node))
-        if self.allowable:
-            for f in files:
-                if not self.allow(f):
-                    self.ui.debug(_('acl: user %s not allowed on %s\n') %
-                                  (self.getuser(), f))
-                    raise util.Abort(_('acl: access denied for changeset %s') %
-                                     short(node))
-        self.ui.debug(_('acl: allowing changeset %s\n') % short(node))
+    pats = [pat for pat, users in ui.configitems(key)
+            if user in users.replace(',', ' ').split()]
+    ui.debug(_('acl: %s enabled, %d entries for user %s\n') %
+             (key, len(pats), user))
+    if pats:
+        return util.matcher(repo.root, names=pats)[1]
+    return util.never
 
 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
     if hooktype != 'pretxnchangegroup':
         raise util.Abort(_('config error - hook type "%s" cannot stop '
                            'incoming changesets') % hooktype)
-
-    c = checker(ui, repo)
-    if c.skipsource(source):
+    if source not in ui.config('acl', 'sources', 'serve').split():
         ui.debug(_('acl: changes have source "%s" - skipping\n') % source)
         return
 
-    for rev in xrange(repo[node].rev(), len(repo)):
-        c.check(repo.changelog.node(rev))
+    user = getpass.getuser()
+    cfg = ui.config('acl', 'config')
+    if cfg:
+        ui.readsections(cfg, 'acl.allow', 'acl.deny')
+    allow = buildmatch(ui, repo, user, 'acl.allow')
+    deny = buildmatch(ui, repo, user, 'acl.deny')
+
+    for rev in xrange(repo[node], len(repo)):
+        ctx = repo[rev]
+        for f in ctx.files():
+            if deny and deny(f):
+                ui.debug(_('acl: user %s denied on %s\n') % (user, f))
+                raise util.Abort(_('acl: access denied for changeset %s') % ctx)
+            if allow and not allow(f):
+                ui.debug(_('acl: user %s not allowed on %s\n') % (user, f))
+                raise util.Abort(_('acl: access denied for changeset %s') % ctx)
+        ui.debug(_('acl: allowing changeset %s\n') % ctx)
--- a/mercurial/commands.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/commands.py	Wed Jul 02 12:27:57 2008 +0200
@@ -110,8 +110,8 @@
     ctx = repo[opts['rev']]
 
     m = cmdutil.match(repo, pats, opts)
-    for abs in repo.walk(m, ctx.node()):
-        fctx = ctx.filectx(abs)
+    for abs in ctx.walk(m):
+        fctx = ctx[abs]
         if not opts['text'] and util.binary(fctx.data()):
             ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
             continue
@@ -485,9 +485,9 @@
     ctx = repo[opts['rev']]
     err = 1
     m = cmdutil.match(repo, (file1,) + pats, opts)
-    for abs in repo.walk(m, ctx.node()):
+    for abs in ctx.walk(m):
         fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
-        data = ctx.filectx(abs).data()
+        data = ctx[abs].data()
         if opts.get('decode'):
             data = repo.wwritedata(abs, data)
         fp.write(data)
@@ -907,8 +907,8 @@
 
     ctx = repo[opts.get('rev')]
     m = cmdutil.match(repo, (file1,) + pats, opts)
-    for abs in repo.walk(m, ctx.node()):
-        fctx = ctx.filectx(abs)
+    for abs in ctx.walk(m):
+        fctx = ctx[abs]
         o = fctx.filelog().renamed(fctx.filenode())
         rel = m.rel(abs)
         if o:
@@ -1693,17 +1693,13 @@
     that contain white space as multiple filenames.
     """
     end = opts['print0'] and '\0' or '\n'
-    rev = opts['rev']
-    if rev:
-        node = repo.lookup(rev)
-    else:
-        node = None
+    rev = opts.get('rev') or None
 
     ret = 1
     m = cmdutil.match(repo, pats, opts, default='relglob')
     m.bad = lambda x,y: False
-    for abs in repo.walk(m, node):
-        if not node and abs not in repo.dirstate:
+    for abs in repo[rev].walk(m):
+        if not rev and abs not in repo.dirstate:
             continue
         if opts['fullpath']:
             ui.write(os.path.join(repo.root, abs), end)
@@ -2350,7 +2346,7 @@
 
         m = cmdutil.match(repo, pats, opts)
         m.bad = badfn
-        for abs in repo.walk(m, node=node):
+        for abs in repo[node].walk(m):
             if abs not in names:
                 names[abs] = m.rel(abs), m.exact(abs)
 
--- a/mercurial/context.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/context.py	Wed Jul 02 12:27:57 2008 +0200
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
 
-from node import nullid, nullrev, short
+from node import nullid, nullrev, short, hex
 from i18n import _
 import ancestor, bdiff, revlog, util, os, errno
 
@@ -23,6 +23,9 @@
     def __str__(self):
         return short(self.node())
 
+    def __int__(self):
+        return self.rev()
+
     def __repr__(self):
         return "<changectx %s>" % str(self)
 
@@ -79,6 +82,7 @@
 
     def rev(self): return self._rev
     def node(self): return self._node
+    def hex(self): return hex(self._node)
     def user(self): return self._changeset[1]
     def date(self): return self._changeset[2]
     def files(self): return self._changeset[3]
@@ -142,6 +146,23 @@
         n = self._repo.changelog.ancestor(self._node, c2._node)
         return changectx(self._repo, n)
 
+    def walk(self, match):
+        fdict = dict.fromkeys(match.files())
+        # for dirstate.walk, files=['.'] means "walk the whole tree".
+        # follow that here, too
+        fdict.pop('.', None)
+        for fn in self:
+            for ffn in fdict:
+                # match if the file is the exact name or a directory
+                if ffn == fn or fn.startswith("%s/" % ffn):
+                    del fdict[ffn]
+                    break
+            if match(fn):
+                yield fn
+        for fn in util.sort(fdict):
+            if match.bad(fn, 'No such file in rev ' + str(self)) and match(fn):
+                yield fn
+
 class filectx(object):
     """A filecontext object makes access to data related to a particular
        filerevision convenient."""
@@ -572,6 +593,10 @@
         """return the ancestor context of self and c2"""
         return self._parents[0].ancestor(c2) # punt on two parents for now
 
+    def walk(self, match):
+        for src, fn, st in self._repo.dirstate.walk(match, True, False):
+            yield fn
+
 class workingfilectx(filectx):
     """A workingfilectx object makes access to data related to a particular
        file in the working directory convenient."""
@@ -693,6 +718,9 @@
     def __str__(self):
         return str(self._parents[0]) + "+"
 
+    def __int__(self):
+        return self._rev
+
     def __nonzero__(self):
         return True
 
--- a/mercurial/hgweb/hgweb_mod.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/hgweb/hgweb_mod.py	Wed Jul 02 12:27:57 2008 +0200
@@ -169,7 +169,7 @@
 
             req.write(content)
             del tmpl
-            return req
+            return []
 
         except revlog.LookupError, err:
             req.respond(HTTP_NOT_FOUND, ctype)
@@ -177,12 +177,15 @@
             if 'manifest' not in msg:
                 msg = 'revision not found: %s' % err.name
             req.write(tmpl('error', error=msg))
+            return []
         except (RepoError, revlog.RevlogError), inst:
             req.respond(HTTP_SERVER_ERROR, ctype)
             req.write(tmpl('error', error=str(inst)))
+            return []
         except ErrorResponse, inst:
             req.respond(inst.code, ctype)
             req.write(tmpl('error', error=inst.message))
+            return []
 
     def templater(self, req):
 
--- a/mercurial/hgweb/hgwebdir_mod.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/hgweb/hgwebdir_mod.py	Wed Jul 02 12:27:57 2008 +0200
@@ -70,8 +70,7 @@
 
     def __call__(self, env, respond):
         req = wsgirequest(env, respond)
-        self.run_wsgi(req)
-        return req
+        return self.run_wsgi(req)
 
     def run_wsgi(self, req):
 
@@ -91,13 +90,13 @@
                     else:
                         fname = req.form['static'][0]
                     req.write(staticfile(static, fname, req))
-                    return
+                    return []
 
                 # top-level index
                 elif not virtual:
                     req.respond(HTTP_OK, ctype)
                     req.write(self.makeindex(req, tmpl))
-                    return
+                    return []
 
                 # nested indexes and hgwebs
 
@@ -108,8 +107,7 @@
                         req.env['REPO_NAME'] = virtual
                         try:
                             repo = hg.repository(self.parentui, real)
-                            hgweb(repo).run_wsgi(req)
-                            return
+                            return hgweb(repo).run_wsgi(req)
                         except IOError, inst:
                             msg = inst.strerror
                             raise ErrorResponse(HTTP_SERVER_ERROR, msg)
@@ -121,7 +119,7 @@
                     if [r for r in repos if r.startswith(subdir)]:
                         req.respond(HTTP_OK, ctype)
                         req.write(self.makeindex(req, tmpl, subdir))
-                        return
+                        return []
 
                     up = virtual.rfind('/')
                     if up < 0:
@@ -131,10 +129,12 @@
                 # prefixes not found
                 req.respond(HTTP_NOT_FOUND, ctype)
                 req.write(tmpl("notfound", repo=virtual))
+                return []
 
             except ErrorResponse, err:
                 req.respond(err.code, ctype)
                 req.write(tmpl('error', error=err.message or ''))
+                return []
         finally:
             tmpl = None
 
--- a/mercurial/hgweb/protocol.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/hgweb/protocol.py	Wed Jul 02 12:27:57 2008 +0200
@@ -124,8 +124,7 @@
             # response when run outside cgi script
             pass
         req.respond(HTTP_OK, HGTYPE)
-        yield errorfmt % 'unsynced changes'
-        return
+        return errorfmt % 'unsynced changes',
 
     req.respond(HTTP_OK, HGTYPE)
 
@@ -143,8 +142,7 @@
             lock = repo.lock()
             try:
                 if not check_heads():
-                    yield errorfmt % 'unsynced changes'
-                    return
+                    return errorfmt % 'unsynced changes',
 
                 fp.seek(0)
                 header = fp.read(6)
@@ -170,11 +168,11 @@
                 finally:
                     val = sys.stdout.getvalue()
                     sys.stdout, sys.stderr = oldio
-                yield '%d\n%s' % (ret, val)
+                return '%d\n%s' % (ret, val),
             finally:
                 del lock
         except ValueError, inst:
-            yield errorfmt % inst
+            return errorfmt % inst,
         except (OSError, IOError), inst:
             filename = getattr(inst, 'filename', '')
             # Don't send our filesystem layout to the client
@@ -188,11 +186,12 @@
             else:
                 code = HTTP_SERVER_ERROR
             req.respond(code)
-            yield '0\n%s: %s\n' % (error, filename)
+            return '0\n%s: %s\n' % (error, filename),
     finally:
         fp.close()
         os.unlink(tempname)
 
 def stream_out(repo, req):
     req.respond(HTTP_OK, HGTYPE)
-    return streamclone.stream_out(repo, untrusted=True)
+    streamclone.stream_out(repo, req, untrusted=True)
+    return []
--- a/mercurial/httprepo.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/httprepo.py	Wed Jul 02 12:27:57 2008 +0200
@@ -268,6 +268,7 @@
 
         # 1.0 here is the _protocol_ version
         opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
+        opener.addheaders.append(('Accept', 'application/mercurial-0.1'))
         urllib2.install_opener(opener)
 
     def url(self):
--- a/mercurial/localrepo.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/localrepo.py	Wed Jul 02 12:27:57 2008 +0200
@@ -941,27 +941,7 @@
         changeset, finding all files matched by the match
         function
         '''
-
-        if node:
-            fdict = dict.fromkeys(match.files())
-            # for dirstate.walk, files=['.'] means "walk the whole tree".
-            # follow that here, too
-            fdict.pop('.', None)
-            for fn in self[node]:
-                for ffn in fdict:
-                    # match if the file is the exact name or a directory
-                    if ffn == fn or fn.startswith("%s/" % ffn):
-                        del fdict[ffn]
-                        break
-                if match(fn):
-                    yield fn
-            for fn in util.sort(fdict):
-                if match.bad(fn, 'No such file in rev ' + short(node)) \
-                        and match(fn):
-                    yield fn
-        else:
-            for src, fn, st in self.dirstate.walk(match, True, False):
-                yield fn
+        return self[node].walk(match)
 
     def status(self, node1=None, node2=None, match=None,
                ignored=False, clean=False, unknown=False):
--- a/mercurial/manifest.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/manifest.py	Wed Jul 02 12:27:57 2008 +0200
@@ -119,16 +119,16 @@
             return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2]
                             for d in x ])
 
-        def checkforbidden(f):
-            if '\n' in f or '\r' in f:
-                raise RevlogError(_("'\\n' and '\\r' disallowed in filenames"))
+        def checkforbidden(l):
+            for f in l:
+                if '\n' in f or '\r' in f:
+                    raise RevlogError(_("'\\n' and '\\r' disallowed in filenames"))
 
         # if we're using the listcache, make sure it is valid and
         # parented by the same node we're diffing against
         if not (changed and self.listcache and p1 and self.mapcache[0] == p1):
             files = util.sort(map)
-            for f in files:
-                checkforbidden(f)
+            checkforbidden(files)
 
             # if this is changed to support newlines in filenames,
             # be sure to check the templates/ dir again (especially *-raw.tmpl)
@@ -139,8 +139,7 @@
         else:
             addlist = self.listcache
 
-            for f in changed[0]:
-                checkforbidden(f)
+            checkforbidden(changed[0])
             # combine the changed lists into one list for sorting
             work = [[x, 0] for x in changed[0]]
             work[len(work):] = [[x, 1] for x in changed[1]]
--- a/mercurial/sshserver.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/sshserver.py	Wed Jul 02 12:27:57 2008 +0200
@@ -204,6 +204,4 @@
                 os.unlink(tempname)
 
     def do_stream_out(self):
-        for chunk in streamclone.stream_out(self.repo):
-            self.fout.write(chunk)
-        self.fout.flush()
+        streamclone.stream_out(self.repo, self.fout)
--- a/mercurial/streamclone.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/mercurial/streamclone.py	Wed Jul 02 12:27:57 2008 +0200
@@ -51,12 +51,12 @@
 #
 #   server writes out raw file data.
 
-def stream_out(repo, untrusted=False):
+def stream_out(repo, fileobj, untrusted=False):
     '''stream out all metadata files in repository.
     writes to file-like object, must support write() and optional flush().'''
 
     if not repo.ui.configbool('server', 'uncompressed', untrusted=untrusted):
-        yield '1\n'
+        fileobj.write('1\n')
         return
 
     # get consistent snapshot of repo. lock during scan so lock not
@@ -67,10 +67,10 @@
             repolock = repo.lock()
         except (lock.LockHeld, lock.LockUnavailable), inst:
             repo.ui.warn('locking the repository failed: %s\n' % (inst,))
-            yield '2\n'
+            fileobj.write('2\n')
             return
 
-        yield '0\n'
+        fileobj.write('0\n')
         repo.ui.debug('scanning\n')
         entries = []
         total_bytes = 0
@@ -83,9 +83,11 @@
 
     repo.ui.debug('%d files, %d bytes to transfer\n' %
                   (len(entries), total_bytes))
-    yield '%d %d\n' % (len(entries), total_bytes)
+    fileobj.write('%d %d\n' % (len(entries), total_bytes))
     for name, size in entries:
         repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
-        yield '%s\0%d\n' % (name, size)
+        fileobj.write('%s\0%d\n' % (name, size))
         for chunk in util.filechunkiter(repo.sopener(name), limit=size):
-            yield chunk
+            fileobj.write(chunk)
+    flush = getattr(fileobj, 'flush', None)
+    if flush: flush()
--- a/setup.py	Wed Jul 02 12:02:33 2008 +0200
+++ b/setup.py	Wed Jul 02 12:27:57 2008 +0200
@@ -129,7 +129,7 @@
                    [os.path.join(root, file_) for file_ in files])
                   for root, dirs, files in os.walk('templates')],
       cmdclass=cmdclass,
-      options=dict(py2exe=dict(packages=['hgext']),
+      options=dict(py2exe=dict(packages=['hgext', 'email']),
                    bdist_mpkg=dict(zipdist=True,
                                    license='COPYING',
                                    readme='contrib/macosx/Readme.html',
--- a/tests/test-acl.out	Wed Jul 02 12:02:33 2008 +0200
+++ b/tests/test-acl.out	Wed Jul 02 12:27:57 2008 +0200
@@ -58,8 +58,6 @@
 adding quux/file.py revisions
 added 3 changesets with 3 changes to 3 files
 calling hook pretxnchangegroup.acl: hgext.acl.hook
-acl: acl.allow not enabled
-acl: acl.deny not enabled
 acl: changes have source "push" - skipping
 updating the branch cache
 rolling back last transaction
--- a/tests/test-hgweb-commands	Wed Jul 02 12:02:33 2008 +0200
+++ b/tests/test-hgweb-commands	Wed Jul 02 12:27:57 2008 +0200
@@ -34,6 +34,7 @@
 echo % Overviews
 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/tags/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//"
 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb' | sed "s/[0-9]* years ago/long ago/g"
+"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb' | sed "s/[0-9]* years/long/g"
 
 echo % capabilities
 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'
Binary file tests/test-hgweb-commands.out has changed