[PATCH 1 of 2] serve: add support for Mercurial subrepositories

2017-02-12 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1486875517 18000
#  Sat Feb 11 23:58:37 2017 -0500
# Node ID eb928f06946008029568abd1ef8491ded316fc31
# Parent  a95fc01aaffe805bcc4c02a822b82a1162fa35b9
serve: add support for Mercurial subrepositories

I've been using `hg serve --web-conf ...` with a simple '/=projects/**' [paths]
configuration for awhile without issue.  Let's ditch the need for the manual
configuration in this case, and limit the repos served to the actual subrepos.

This doesn't attempt to handle the case where a new subrepo appears while the
server is running.  That could probably be handled with a hook if somebody wants
it.  But it's such a rare case, it probably doesn't matter for the temporary
serves.

Unfortunately, the root of the webserver when serving multiple repos is the html
index file.  This makes the URL different for `hg serve` vs `hg serve -S`,
because the top level repo then needs to be part of the path.  That will be
fixed next.

The web.staticurl config is set, because the icons served up are already visible
by default when -S isn't given.  I assume this is a difference between hgweb and
hgwebdir, but there's no reason for the user to be exposed to this.  As an
aside, the help for web.staticurl seems to wrongly describe the value of this
setting.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2294,6 +2294,15 @@
 bad.extend(f for f in rejected if f in match.files())
 return bad
 
+def addwebdirpath(repo, serverpath, webconf):
+webconf[serverpath] = repo.root
+repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
+
+for r in repo.revs('filelog("path:.hgsub")'):
+ctx = repo[r]
+for subpath in ctx.substate:
+ctx.sub(subpath).addwebdirpath(serverpath, webconf)
+
 def forget(ui, repo, match, prefix, explicitonly):
 join = lambda f: os.path.join(prefix, f)
 bad = []
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5787,7 +5787,8 @@
 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
 ('', 'style', '', _('template style to use'), _('STYLE')),
 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
-('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
+('', 'certificate', '', _('SSL certificate file'), _('FILE'))]
+ + subrepoopts,
 _('[OPTION]...'),
 optionalrepo=True)
 def serve(ui, repo, **opts):
diff --git a/mercurial/help/subrepos.txt b/mercurial/help/subrepos.txt
--- a/mercurial/help/subrepos.txt
+++ b/mercurial/help/subrepos.txt
@@ -136,6 +136,11 @@
 subrepository changes are available when referenced by top-level
 repositories.  Push is a no-op for Subversion subrepositories.
 
+:serve: serve does not recurse into subrepositories unless
+-S/--subrepos is specified.  Git and Subversion subrepositories
+are currently silently ignored.  Mercurial subrepositories with a
+URL source are also silently ignored.
+
 :status: status does not recurse into subrepositories unless
 -S/--subrepos is specified. Subrepository changes are displayed as
 regular Mercurial changes on the subrepository
diff --git a/mercurial/server.py b/mercurial/server.py
--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -16,6 +16,7 @@
 
 from . import (
 chgserver,
+cmdutil,
 commandserver,
 error,
 hgweb,
@@ -135,11 +136,31 @@
 baseui = ui
 webconf = opts.get('web_conf') or opts.get('webdir_conf')
 if webconf:
+if opts.get('subrepos'):
+raise error.Abort(_('--web-conf cannot be used with --subrepos'))
+
 # load server settings (e.g. web.port) to "copied" ui, which allows
 # hgwebdir to reload webconf cleanly
 servui = ui.copy()
 servui.readconfig(webconf, sections=['web'])
 alluis.add(servui)
+elif opts.get('subrepos'):
+servui = ui.copy()
+alluis.add(servui)
+
+# If repo is None, hgweb.createapp() already raises a proper abort
+# message as long as webconf is None.
+if repo:
+webconf = dict()
+cmdutil.addwebdirpath(repo, repo.wvfs.basename(repo.root) + '/',
+  webconf)
+
+# The icons aren't rendered in a web browser without this.
+# Unfortunately, the pages generated aren't sensitive to this
+# config, so it can't be set to something else if there's a repo
+

[PATCH 2 of 2] serve: make the URL the same for `hg serve` and `hg serve -S`

2017-02-12 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1486877030 18000
#  Sun Feb 12 00:23:50 2017 -0500
# Node ID d91a0fe8016deaca3134f119bd07f99cd96cf43d
# Parent  eb928f06946008029568abd1ef8491ded316fc31
serve: make the URL the same for `hg serve` and `hg serve -S`

It's perfectly workable to serve up the parent repo without the -S for push and
pull, as long as there are no subrepo changes are in play.  Therefore, having a
different URL for the main repo based on the presence of this option seems like
it would get annoying.

diff --git a/mercurial/hgweb/__init__.py b/mercurial/hgweb/__init__.py
--- a/mercurial/hgweb/__init__.py
+++ b/mercurial/hgweb/__init__.py
@@ -85,9 +85,9 @@
 def run(self):
 self.httpd.serve_forever()
 
-def createapp(baseui, repo, webconf):
+def createapp(baseui, repo, webconf, subrepos=False):
 if webconf:
-return hgwebdir_mod.hgwebdir(webconf, baseui=baseui)
+return hgwebdir_mod.hgwebdir(webconf, baseui=baseui, subrepos=subrepos)
 else:
 if not repo:
 raise error.RepoError(_("there is no Mercurial repository"
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -115,12 +115,13 @@
 
 Instances are typically used as WSGI applications.
 """
-def __init__(self, conf, baseui=None):
+def __init__(self, conf, baseui=None, subrepos=False):
 self.conf = conf
 self.baseui = baseui
 self.ui = None
 self.lastrefresh = 0
 self.motd = None
+self._subrepos = subrepos
 self.refresh()
 
 def refresh(self):
@@ -254,7 +255,7 @@
 return []
 
 # top-level index
-elif not virtual:
+elif not virtual and not self._subrepos:
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl)
 
@@ -262,8 +263,9 @@
 
 repos = dict(self.repos)
 virtualrepo = virtual
-while virtualrepo:
-real = repos.get(virtualrepo)
+real = repos.get(virtualrepo)
+
+while virtualrepo or self._subrepos:
 if real:
 req.env['REPO_NAME'] = virtualrepo
 try:
@@ -280,6 +282,7 @@
 if up < 0:
 break
 virtualrepo = virtualrepo[:up]
+real = repos.get(virtualrepo)
 
 # browse subdirectories
 subdir = virtual + '/'
diff --git a/mercurial/server.py b/mercurial/server.py
--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -152,12 +152,11 @@
 # message as long as webconf is None.
 if repo:
 webconf = dict()
-cmdutil.addwebdirpath(repo, repo.wvfs.basename(repo.root) + '/',
-  webconf)
+cmdutil.addwebdirpath(repo, "", webconf)
 
 # The icons aren't rendered in a web browser without this.
 # Unfortunately, the pages generated aren't sensitive to this
-# config, so it can't be set to something else if there's a repo
+# config, so it can't be set to something else if there's a subrepo
 # named 'static'.
 if 'static' not in webconf:
 baseui.setconfig('web', 'staticurl', 'static', source='serve')
@@ -173,7 +172,7 @@
 for u in alluis:
 u.setconfig("web", o, val, 'serve')
 
-app = hgweb.createapp(baseui, repo, webconf)
+app = hgweb.createapp(baseui, repo, webconf, opts.get('subrepos'))
 return hgweb.httpservice(servui, app, opts)
 
 def createservice(ui, repo, opts):
diff --git a/tests/test-subrepo-deep-nested-change.t 
b/tests/test-subrepo-deep-nested-change.t
--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -75,29 +75,29 @@
 
 #if serve
   $ hg serve -R main --debug -S -p $HGPORT -d --pid-file=hg1.pid -E error.log 
-A access.log
-  adding main/ = $TESTTMP/main (glob)
-  adding sub1/ = $TESTTMP/main/sub1 (glob)
-  adding sub2/ = $TESTTMP/main/sub1/sub2 (glob)
+  adding  = $TESTTMP/main (glob)
+  adding ../sub1/ = $TESTTMP/main/sub1 (glob)
+  adding ../sub2/ = $TESTTMP/main/sub1/sub2 (glob)
   listening at http://*:$HGPORT/ (bound to *:$HGPORT) (glob)
-  adding main/ = $TESTTMP/main (glob)
-  adding sub1/ = $TESTTMP/main/sub1 (glob)
-  adding sub2/ = $TESTTMP/main/sub1/sub2 (glob)
+  adding  = $TESTTMP/main (glob)
+  adding ../sub1/ = $TESTTMP/main/sub1 (glob)
+  adding ../sub2/ = $TESTTMP/main/sub1/sub2 (glob)
   $ cat hg1.pid >> $DAEMON_PIDS
 
-  $ hg clone http://localhost:$HGPORT/main httpclone --config 
progress.disable=True
+  $ hg clone http://localhost:$HGPORT h

[PATCH 2 of 4 V2] clone: use the HTTP 301 location to record the default path

2017-02-16 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1487087965 18000
#  Tue Feb 14 10:59:25 2017 -0500
# Node ID 27a4bc77e8b8e50abc76c387f117082e5853c47e
# Parent  4f2862487d789edc1f36b5687d828a2914e1dc32
clone: use the HTTP 301 location to record the default path

This is needed to simplify making `hg serve -S` paths the same as `hg serve`.
Since 301 is permanent and cachable, this is arguably the proper behavior
anyway.  For example, once Firefox sees a 301, it automatically forwards,
without querying the original URL again.

Code hosting software may make use of redirects.  I only have access to SCM
Manager.  It uses 302 to access subrepos, so it isn't affected by this.  My
understanding of the python libraries being used is minimal, and this was
inspired by http://www.diveintopython.net/http_web_services/redirects.html.

Since `hg serve` doesn't issue redirects, the added tests aren't showing the new
redirect functionality yet.  But they set a baseline that won't change when
redirects are issued.  Check-commit complains about the methods with '_', but
those names are defined by python.

diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -621,6 +621,15 @@
 
 destrepo = destpeer.local()
 if destrepo:
+# Update for 301 redirects
+endsrc = srcpeer.url()
+if not islocal(endsrc):
+abspath = endsrc
+
+# statichttprepository never sees the 'static-' prefix, so that
+# need to be accounted for here.
+if origsource.startswith('static-http'):
+abspath = 'static-' + abspath
 template = uimod.samplehgrcs['cloned']
 fp = destrepo.vfs("hgrc", "w", text=True)
 u = util.url(abspath)
diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
--- a/mercurial/httppeer.py
+++ b/mercurial/httppeer.py
@@ -88,12 +88,12 @@
  (u.query or u.fragment))
 
 # urllib cannot handle URLs with embedded user or passwd
-self._url, authinfo = u.authinfo()
+self._url, self._authinfo = u.authinfo()
 
 self.ui = ui
 self.ui.debug('using %s\n' % self._url)
 
-self.urlopener = url.opener(ui, authinfo)
+self.urlopener = url.opener(ui, self._authinfo)
 self.requestbuilder = urlreq.request
 
 def __del__(self):
@@ -230,6 +230,16 @@
 if self._url.rstrip('/') != resp_url.rstrip('/'):
 if not self.ui.quiet:
 self.ui.warn(_('real URL is %s\n') % resp_url)
+if resp.status == httplib.MOVED_PERMANENTLY:
+u = util.url(resp_url.rstrip('/'))
+
+# The path has auth info on creation.  Restore that here.
+creds = self._authinfo
+if creds:
+u.user = creds[2]
+u.passwd = creds[3] or None
+self.path = str(u)
+
 self._url = resp_url
 try:
 proto = resp.getheader('content-type')
diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -227,6 +227,7 @@
 "HTTPDigestAuthHandler",
 "HTTPHandler",
 "HTTPPasswordMgrWithDefaultRealm",
+"HTTPRedirectHandler",
 "HTTPSHandler",
 "install_opener",
 "ProxyHandler",
diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -272,6 +272,30 @@
 
 return False
 
+class httpredirecthandler(urlreq.httpredirecthandler):
+def __init__(self):
+self._permmoved = True
+
+def redirect_request(self, req, fp, code, msg, hdrs, newurl):
+'''Called by all http_error_3xx() to monitor redirect types seen'''
+# Avoid treating 302 -> 301 -> 200 or 301 -> 302 -> 200 as permanent
+# redirects.
+self._permmoved = self._permmoved and code == httplib.MOVED_PERMANENTLY
+
+impl = urlreq.httpredirecthandler.redirect_request
+return impl(self, req, fp, code, msg, hdrs, newurl)
+
+def http_error_301(self, req, fp, code, msg, headers):
+'''Capture the permanent redirect status for later access'''
+impl = urlreq.httpredirecthandler.http_error_301
+result = impl(self, req, fp, code, msg, headers)
+
+# For an unbroken chain of 301, indicate 301 in the status.  Otherwise,
+# keep the 200 status.
+if self._permmoved:
+result.status = code
+return result
+
 class httphandler(keepalive.HTTPHandler):
 def http_open(self, req):
 return self.do_open(httpconnection, req)
@@ -43

[PATCH 4 of 4 V2] serve: restore the index file for `hg serve -S`

2017-02-16 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1487129917 18000
#  Tue Feb 14 22:38:37 2017 -0500
# Node ID 3a0c0f139204e6fa86af22c1d54d8c1dd7a4aa2b
# Parent  38babd487181374325f3d27c5bc081dadf31b9b9
serve: restore the index file for `hg serve -S`

There's currently no integration of subrepos into the browsable directory
listing for the parent repo, so this is a nice to have.  The redirect is only
necessary for a Mercurial client.  The comment in mercurial.url.opener() seems
to indicate that the 'Accept' header will always be around for BC.  Another
option to detect a Mercurial client is to check the Request URI for the
capabilities command.

diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -255,10 +255,11 @@
 staticfile(static, fname, req)
 return []
 
-# top-level index
+# top-level index, or HTTP_MOVED_PERMANENTLY for a Mercurial client
+# when the server is invoked with --subrepos.
 elif not virtual:
-if self._rootrepo:
-# Redirect '/' to the main repo when -S is given.
+accept = req.env.get('HTTP_ACCEPT', "")
+if self._rootrepo and accept == 'application/mercurial-0.1':
 path = '/' + self._rootrepo
 if self.prefix:
 path = '/' + self.prefix + path
diff --git a/tests/test-subrepo-recursion.t b/tests/test-subrepo-recursion.t
--- a/tests/test-subrepo-recursion.t
+++ b/tests/test-subrepo-recursion.t
@@ -295,6 +295,10 @@
   z2
   z3
 
+  $ wget -q http://localhost:$HGPORT
+  $ cat index.html | grep ''
+  Mercurial repositories index
+
   $ cat access.log
   * "GET /?cmd=capabilities HTTP/1.1" 301 - (glob)
   * "GET /repo HTTP/1.1" 200 - (glob)
@@ -308,9 +312,10 @@
   * "GET /repo/foo/bar?cmd=capabilities HTTP/1.1" 200 - (glob)
   * "GET /repo/foo/bar?cmd=batch HTTP/1.1" 200 - * (glob)
   * "GET /repo/foo/bar?cmd=getbundle HTTP/1.1" 200 - * (glob)
+  * "GET / HTTP/1.0" 200 - (glob)
 
   $ killdaemons.py
-  $ rm hg1.pid error.log access.log
+  $ rm hg1.pid error.log access.log index.html
   $ cd repo
 #endif
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4 V2] serve: add support for Mercurial subrepositories

2017-02-16 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1486875517 18000
#  Sat Feb 11 23:58:37 2017 -0500
# Node ID 4f2862487d789edc1f36b5687d828a2914e1dc32
# Parent  afaf3c2b129c8940387fd9928ae4fdc28259d13c
serve: add support for Mercurial subrepositories

I've been using `hg serve --web-conf ...` with a simple '/=projects/**' [paths]
configuration for awhile without issue.  Let's ditch the need for the manual
configuration in this case, and limit the repos served to the actual subrepos.

This doesn't attempt to handle the case where a new subrepo appears while the
server is running.  That could probably be handled with a hook if somebody wants
it.  But it's such a rare case, it probably doesn't matter for the temporary
serves.

Unfortunately, the root of the webserver when serving multiple repos is the html
index file.  This makes the URL different for `hg serve` vs `hg serve -S`,
because the top level repo then needs to be part of the path.  That can be
fixed later.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2294,6 +2294,15 @@
 bad.extend(f for f in rejected if f in match.files())
 return bad
 
+def addwebdirpath(repo, serverpath, webconf):
+webconf[serverpath] = repo.root
+repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
+
+for r in repo.revs('filelog("path:.hgsub")'):
+ctx = repo[r]
+for subpath in ctx.substate:
+ctx.sub(subpath).addwebdirpath(serverpath, webconf)
+
 def forget(ui, repo, match, prefix, explicitonly):
 join = lambda f: os.path.join(prefix, f)
 bad = []
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4607,7 +4607,8 @@
 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
 ('', 'style', '', _('template style to use'), _('STYLE')),
 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
-('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
+('', 'certificate', '', _('SSL certificate file'), _('FILE'))]
+ + subrepoopts,
 _('[OPTION]...'),
 optionalrepo=True)
 def serve(ui, repo, **opts):
diff --git a/mercurial/help/subrepos.txt b/mercurial/help/subrepos.txt
--- a/mercurial/help/subrepos.txt
+++ b/mercurial/help/subrepos.txt
@@ -136,6 +136,11 @@
 subrepository changes are available when referenced by top-level
 repositories.  Push is a no-op for Subversion subrepositories.
 
+:serve: serve does not recurse into subrepositories unless
+-S/--subrepos is specified.  Git and Subversion subrepositories
+are currently silently ignored.  Mercurial subrepositories with a
+URL source are also silently ignored.
+
 :status: status does not recurse into subrepositories unless
 -S/--subrepos is specified. Subrepository changes are displayed as
 regular Mercurial changes on the subrepository
diff --git a/mercurial/server.py b/mercurial/server.py
--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -16,6 +16,7 @@
 
 from . import (
 chgserver,
+cmdutil,
 commandserver,
 error,
 hgweb,
@@ -135,11 +136,24 @@
 baseui = ui
 webconf = opts.get('web_conf') or opts.get('webdir_conf')
 if webconf:
+if opts.get('subrepos'):
+raise error.Abort(_('--web-conf cannot be used with --subrepos'))
+
 # load server settings (e.g. web.port) to "copied" ui, which allows
 # hgwebdir to reload webconf cleanly
 servui = ui.copy()
 servui.readconfig(webconf, sections=['web'])
 alluis.add(servui)
+elif opts.get('subrepos'):
+servui = ui.copy()
+alluis.add(servui)
+
+# If repo is None, hgweb.createapp() already raises a proper abort
+# message as long as webconf is None.
+if repo:
+webconf = dict()
+cmdutil.addwebdirpath(repo, repo.wvfs.basename(repo.root) + '/',
+  webconf)
 else:
 servui = ui
 
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -438,6 +438,15 @@
 self._ctx = ctx
 self._path = path
 
+def addwebdirpath(self, serverpath, webconf):
+"""Add the hgwebdir entries for this subrepo, and any of its subrepos.
+
+``serverpath`` is the path component of the URL for this repo.
+
+``webconf`` is the dictionary of hgwebdir entries.
+"""
+pass
+
 def storeclean(self, path):
 ""

[PATCH 3 of 4 V2] serve: make the URL the same for `hg serve` and `hg serve -S`

2017-02-16 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1486877030 18000
#  Sun Feb 12 00:23:50 2017 -0500
# Node ID 38babd487181374325f3d27c5bc081dadf31b9b9
# Parent  27a4bc77e8b8e50abc76c387f117082e5853c47e
serve: make the URL the same for `hg serve` and `hg serve -S`

It's perfectly workable to serve up the parent repo without the -S for push and
pull, as long as there are no subrepo changes are in play.  Therefore, having a
different URL for the main repo based on the presence of this option seems like
it would get annoying.

The first attempt at this was simply to trim the outer repo name from the paths
when populating 'webconf', so that the root repository was actually hosted at
'/'.  That worked fine for `hg` operations, but had bad effects on the html,
such as making the 'changeset' link on the left side simply 'rev/tip'.  (The
source html shows the link was '//rev/tip', since {repo} was subbed in as an
empty string.)  There were also issues rendering the subrepo pages that ended
with 'tip', including missing icons.

By forwarding the `hg` request for the outer repo, all of the actual
repositories can remain in their normal places.  The forward needs to be
permanent, so that the actual address is stored in the hgrc file.  This is
crucial, because the .hgsub source paths are evaluated relative to the parent
repo's source.  This avoids having to figure out how to put in forwarding logic
for each subrepository as well.

diff --git a/mercurial/hgweb/__init__.py b/mercurial/hgweb/__init__.py
--- a/mercurial/hgweb/__init__.py
+++ b/mercurial/hgweb/__init__.py
@@ -85,9 +85,13 @@
 def run(self):
 self.httpd.serve_forever()
 
-def createapp(baseui, repo, webconf):
+def createapp(baseui, repo, webconf, subrepos=False):
 if webconf:
-return hgwebdir_mod.hgwebdir(webconf, baseui=baseui)
+rootrepo = None
+if subrepos:
+rootrepo = repo.wvfs.basename(repo.root)
+
+return hgwebdir_mod.hgwebdir(webconf, baseui=baseui, rootrepo=rootrepo)
 else:
 if not repo:
 raise error.RepoError(_("there is no Mercurial repository"
diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -23,6 +23,7 @@
 httpserver = util.httpserver
 
 HTTP_OK = 200
+HTTP_MOVED_PERMANENTLY = 301
 HTTP_NOT_MODIFIED = 304
 HTTP_BAD_REQUEST = 400
 HTTP_UNAUTHORIZED = 401
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -16,6 +16,7 @@
 
 from .common import (
 ErrorResponse,
+HTTP_MOVED_PERMANENTLY,
 HTTP_NOT_FOUND,
 HTTP_OK,
 HTTP_SERVER_ERROR,
@@ -115,12 +116,13 @@
 
 Instances are typically used as WSGI applications.
 """
-def __init__(self, conf, baseui=None):
+def __init__(self, conf, baseui=None, rootrepo=None):
 self.conf = conf
 self.baseui = baseui
 self.ui = None
 self.lastrefresh = 0
 self.motd = None
+self._rootrepo = rootrepo
 self.refresh()
 
 def refresh(self):
@@ -255,6 +257,15 @@
 
 # top-level index
 elif not virtual:
+if self._rootrepo:
+# Redirect '/' to the main repo when -S is given.
+path = '/' + self._rootrepo
+if self.prefix:
+path = '/' + self.prefix + path
+req.headers.append(('Location', path))
+html = 'Moved here.'
+req.respond(HTTP_MOVED_PERMANENTLY, "text/html", body=html)
+return []
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl)
 
diff --git a/mercurial/server.py b/mercurial/server.py
--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -166,7 +166,7 @@
 for u in alluis:
 u.setconfig("web", o, val, 'serve')
 
-app = hgweb.createapp(baseui, repo, webconf)
+app = hgweb.createapp(baseui, repo, webconf, opts.get('subrepos'))
 return hgweb.httpservice(servui, app, opts)
 
 def createservice(ui, repo, opts):
diff --git a/tests/test-subrepo-deep-nested-change.t 
b/tests/test-subrepo-deep-nested-change.t
--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -84,7 +84,8 @@
   adding sub2/ = $TESTTMP/main/sub1/sub2 (glob)
   $ cat hg1.pid >> $DAEMON_PIDS
 
-  $ hg clone http://user@localhost:$HGPORT/main httpclone --config 
progress.disable=True
+  $ hg clone http://user@localhost:$HGPORT httpclone --config 
progress.disable=True
+  real URL is http://localhost:$HGPORT/main
   requesting all changes
   adding changesets
   adding manifests
@@ -111,7 +112,10 @@
 

Re: [PATCH 2 of 4 V2] clone: use the HTTP 301 location to record the default path

2017-02-20 Thread Matt Harbison

On Mon, 20 Feb 2017 09:33:05 -0500, Yuya Nishihara  wrote:


On Thu, 16 Feb 2017 16:41:09 -0500, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1487087965 18000
#  Tue Feb 14 10:59:25 2017 -0500
# Node ID 27a4bc77e8b8e50abc76c387f117082e5853c47e
# Parent  4f2862487d789edc1f36b5687d828a2914e1dc32
clone: use the HTTP 301 location to record the default path



@@ -230,6 +230,16 @@
 if self._url.rstrip('/') != resp_url.rstrip('/'):
 if not self.ui.quiet:
 self.ui.warn(_('real URL is %s\n') % resp_url)
+if resp.status == httplib.MOVED_PERMANENTLY:
+u = util.url(resp_url.rstrip('/'))
+
+# The path has auth info on creation.  Restore that  
here.

+creds = self._authinfo
+if creds:
+u.user = creds[2]
+u.passwd = creds[3] or None
+self.path = str(u)


I didn't carefully review this patch, but is it safe to reuse the  
credential

for redirected server?


Hmmm.. Maybe not.  At least for the clone path, it isn't even necessary,  
because the password is removed before writing out the hgrc file.  I  
didn't see that until after I added this, and then forgot to remove it.   
The username is stored in the hgrc file though.


It looks like url.passwordmgr stores the username/password, but I don't  
have a handy setup that will password prompt and redirect to see if that  
info can easily be obtained here.  I have no problem with dropping the 'if  
creds' (and related changes not shown here) bits.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4 V2] serve: add support for Mercurial subrepositories

2017-02-20 Thread Matt Harbison

On Mon, 20 Feb 2017 09:27:44 -0500, Yuya Nishihara  wrote:


On Thu, 16 Feb 2017 16:41:08 -0500, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1486875517 18000
#  Sat Feb 11 23:58:37 2017 -0500
# Node ID 4f2862487d789edc1f36b5687d828a2914e1dc32
# Parent  afaf3c2b129c8940387fd9928ae4fdc28259d13c
serve: add support for Mercurial subrepositories

I've been using `hg serve --web-conf ...` with a simple '/=projects/**'  
[paths]
configuration for awhile without issue.  Let's ditch the need for the  
manual
configuration in this case, and limit the repos served to the actual  
subrepos.


This doesn't attempt to handle the case where a new subrepo appears  
while the
server is running.  That could probably be handled with a hook if  
somebody wants
it.  But it's such a rare case, it probably doesn't matter for the  
temporary

serves.

Unfortunately, the root of the webserver when serving multiple repos is  
the html
index file.  This makes the URL different for `hg serve` vs `hg serve  
-S`,
because the top level repo then needs to be part of the path.  That can  
be

fixed later.


I'm puzzled by this new version which extensively relies on somewhat  
magical
HTTP redirection. Instead, can't we fix hgwebdir to be able to host  
hgweb at

'/' URL, and add explicit URL to show the index page hidden by it?


This patch is the same as the first in V1, except that I dropped forcing  
the web.staticurl config, and I globbed away a bunch of the http  
parameters in the tests, since only the URI and status is of interest.


The first version did host the parent at '/', and the subrepos relative to  
it.  I switched from that, not because of the index hiding, but because of  
all the problems I ran into.


First were problems (I don't remember all of the details, but eventually  
managed to fix) with `hg` commands.  And then I noticed that the initial  
repo view wasn't rendering properly in the browser.  There was output from  
the server like this:


127.0.0.1 - - [20/Feb/2017 21:02:36] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2017 21:02:42] "GET /favicon.ico HTTP/1.1" 404 -

That seemed to be fixed by the staticurl config.  I was also able to load  
"http://localhost:8000/subrepo"; and get it to display properly, so I  
submitted it.  But I waved Augie off because then I noticed more problems  
in the browser:


- At http://localhost:8000, the links on the left side were corrupt (graph  
is simply 'graph/tip', tags is 'http://tags', etc.)  The pattern seemed to  
be that things ending in 'tip' are relative URLs, and the rest get an  
http: prefix.  It looks from the sources like it is just a matter of '/'  
not translating for the {repo} template.


- At http://localhost:8000/subrepo, all of the links on the left look  
proper.  But if you click on one that ends in 'tip' (like 'graph'), the  
page doesn't render properly (like when 'staticurl' wasn't set on the  
parent repo).  It does properly render pages that don't end in 'tip', like  
'branches'.


I also had a different failed attempt at hosting the parent at '/' a few  
years ago, which had the same rendering issues.  And I didn't check  
anything other than paper.  All in all, a week or so of nonstop problems  
convinced me that I was going about this the wrong way.


To me, the benefits of this series over the original is:

1) The repos aren't moved, and therefore don't incur these subtle bugs
2) These changes are totally isolated to subrepo serving, so there should  
be no risk to mainstream hgweb usage
3) This is completely compatible with existing serves with a simple  
'/=$projects_dir/**' config file, because the real repos are not anchored  
to '/'.




That will be useful without subrepos. Currently we can't see the index  
page '/foo' if we have a repository '/foo' and '/foo/bar'.


I actually wondered why there wasn't an explicit index.html handled where  
needed, and maybe a redirect to it.  I don't think doing that is  
incompatible with this series though.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 4 V2] serve: make the URL the same for `hg serve` and `hg serve -S`

2017-02-20 Thread Matt Harbison

On Mon, 20 Feb 2017 09:38:13 -0500, Yuya Nishihara  wrote:


On Thu, 16 Feb 2017 16:41:10 -0500, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1486877030 18000
#  Sun Feb 12 00:23:50 2017 -0500
# Node ID 38babd487181374325f3d27c5bc081dadf31b9b9
# Parent  27a4bc77e8b8e50abc76c387f117082e5853c47e
serve: make the URL the same for `hg serve` and `hg serve -S`



 elif not virtual:
+if self._rootrepo:
+# Redirect '/' to the main repo when -S is given.
+path = '/' + self._rootrepo
+if self.prefix:
+path = '/' + self.prefix + path
+req.headers.append(('Location', path))
+html = 'Moved here.'
+req.respond(HTTP_MOVED_PERMANENTLY, "text/html",  
body=html)

+return []


Suppose "hg serve" is used for temporarily serving random repositories,  
301

seems too strong.


The temporary serve is the case that I'm interested in.  It may not be  
clear from this snippet, but the redirect is only reachable when using `hg  
serve -S`, not random repos listed in a --web-conf file.


I guess I didn't think it was too strong, because the repo never is at  
'/'.  Once the `hg serve` process is killed, everything is gone.   
Everything goes away eventually.  But until then, it's a permanent  
redirect.


The temporary/permanent distinction is important, because there needs to  
be a trigger to update paths.default in hgrc without doing so for  
temporary redirects.  The updated hgrc path is important, because the  
subrepo is cloned relative to the parent repo's paths.default value.   
(Keeping both the sub=sub and sub=../sub style paths working in the two  
new tests were one of the many headaches with this.)


Since nothing other than hg clients should see the redirect, do you have a  
specific concern?  (I haven't paid much attention to chg to know if it  
would somehow cache the URL and get directed wrong when `hg serve` is  
killed and something else is served.  But the aggressive caching done by  
web browsers is why I limited the redirect as narrowly as possible.)

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 4 V3] update: also suggest --merge when non-linear update is aborted

2017-02-25 Thread Matt Harbison

On Tue, 21 Feb 2017 11:08:05 -0500, Augie Fackler  wrote:



On Feb 20, 2017, at 05:38, Gábor STEFANIK   
wrote:



On Wed, Feb 15, 2017 at 12:56:41PM -0800, Martin von Zweigbergk via
Mercurial-devel wrote:

# HG changeset patch
# User Martin von Zweigbergk  # Date

1487140898

28800
#  Tue Feb 14 22:41:38 2017 -0800
# Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
# Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
update: also suggest --merge when non-linear update is aborted


This makes me a touch nervous, since the merge can leave the user in an
state that's hard to recover from.


Basically "hg resolve -au; hg resolve -at:local; hg update --merge  
-r$(head -c40 .hg/merge/state) -t:local"; but we need to expose a less  
hacky way of doing so.


Not quite, because this isn't sure (I don't think) to get you back to  
exactly the pre-update-command state, as some files might have been  
merged behind your back?


Crazy thought- what if `hg update` were to do the equivalent under the  
hood:


$ hg ci --secret -m "backup for update"
$ src=$(hg log -r . -T "{rev}")
$ hg up $dest
$ hg rebase -r $src -d .

Rebase strips (or obsoletes), so the temp commit is gone.  If things go  
awry, `hg update --abort` is the equivalent of:


$ hg rebase --abort
$ hg up -C $src^
$ hg revert --all -r $src
$ hg strip --no-backup $src

This would restore files merged behind your back too.  Obviously it is  
only needed if a file changed in both branches between ancestor($src,  
$dest) -> $src and ancestor($src, $dest) -> $dest.  I've been pondering  
how to do that calculation with filesets, so at least there's an easy way  
to tell if there's a potential conflict beforehand.  Maybe a new  
'changed(rev)' fileset, that works like `hg status --change`?




"hg update --abort"?


I'd be a big fan of having an update --abort that just takes you back to  
where you were before the conflicts. To date, nobody has been motivated  
enough to do the work (I'd love to do it, but it's unlikely to be near  
the top of my stack for months/years).

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4 V2] serve: add support for Mercurial subrepositories

2017-02-25 Thread Matt Harbison

Sorry for the delay- I was swamped the last few days.

On Tue, 21 Feb 2017 09:33:58 -0500, Yuya Nishihara  wrote:


On Mon, 20 Feb 2017 22:00:20 -0500, Matt Harbison wrote:
On Mon, 20 Feb 2017 09:27:44 -0500, Yuya Nishihara   
wrote:

> On Thu, 16 Feb 2017 16:41:08 -0500, Matt Harbison wrote:
>> # HG changeset patch
>> # User Matt Harbison 
>> # Date 1486875517 18000
>> #  Sat Feb 11 23:58:37 2017 -0500
>> # Node ID 4f2862487d789edc1f36b5687d828a2914e1dc32
>> # Parent  afaf3c2b129c8940387fd9928ae4fdc28259d13c
>> serve: add support for Mercurial subrepositories
>>
>> I've been using `hg serve --web-conf ...` with a simple  
'/=projects/**'

>> [paths]
>> configuration for awhile without issue.  Let's ditch the need for the
>> manual
>> configuration in this case, and limit the repos served to the actual
>> subrepos.
>>
>> This doesn't attempt to handle the case where a new subrepo appears
>> while the
>> server is running.  That could probably be handled with a hook if
>> somebody wants
>> it.  But it's such a rare case, it probably doesn't matter for the
>> temporary
>> serves.
>>
>> Unfortunately, the root of the webserver when serving multiple repos  
is

>> the html
>> index file.  This makes the URL different for `hg serve` vs `hg serve
>> -S`,
>> because the top level repo then needs to be part of the path.  That  
can

>> be
>> fixed later.
>
> I'm puzzled by this new version which extensively relies on somewhat
> magical
> HTTP redirection. Instead, can't we fix hgwebdir to be able to host
> hgweb at
> '/' URL, and add explicit URL to show the index page hidden by it?

This patch is the same as the first in V1, except that I dropped forcing
the web.staticurl config, and I globbed away a bunch of the http
parameters in the tests, since only the URI and status is of interest.

The first version did host the parent at '/', and the subrepos relative  
to

it.


Yes, that seems intuitive way to serve a repo and its subrepos behind. I
thought there wasn't redirection magic as the parent repo was served at  
'/',

was there?


Correct. Redirection was only introduced in V2.

- At http://localhost:8000, the links on the left side were corrupt  
(graph
is simply 'graph/tip', tags is 'http://tags', etc.)  The pattern seemed  
to

be that things ending in 'tip' are relative URLs, and the rest get an
http: prefix.  It looks from the sources like it is just a matter of '/'
not translating for the {repo} template.


[snip]

I saw some of these problems in V1. However, the standalone hgweb can  
host
a repository at '/', so I don't think it's quite difficult to host the  
subrepo

parent at '/'.


That's a good point, so now I'm really puzzled over the subtle  
differences.  It looks like when it finds a hosted repo, it just farms out  
to hgweb, like the single serve would do.



To me, the benefits of this series over the original is:

1) The repos aren't moved, and therefore don't incur these subtle bugs
2) These changes are totally isolated to subrepo serving, so there  
should

be no risk to mainstream hgweb usage
3) This is completely compatible with existing serves with a simple
'/=$projects_dir/**' config file, because the real repos are not  
anchored

to '/'.


I think (2) and (3) are up to how we build a repository map.


What I mean for (2) is that in V2, none of the code changes are hit  
without -S.  That seems like a good thing, given the subtle breakage in V1.


What I mean by (3) is that the transition for current clones is to simply  
drop --web-conf=.. and start using -S on the server side.  Clients won't  
see a difference.


I assume that the hardcoded web.staticurl in V1 also means that it won't  
be able to serve a subrepo named 'static'?  (That's admittedly an edge  
case.)


I only see the two ways to build the repo map, so I'm not sure what you  
are saying here.



If a map has no
'/' entry, hgweb would serve nothing at '/' and is compatible with the  
current

behavior.


___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] subrepo: run the repo decoders when archiving

2017-02-25 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1488075239 18000
#  Sat Feb 25 21:13:59 2017 -0500
# Node ID 5ce388a91851dc6c0dc1be0342a105da659e1d47
# Parent  88203f26ea57627cabd7cf9c4f7843661d6c43ae
subrepo: run the repo decoders when archiving

The decoders were already run by default for the main repo, so this seemed like
an oversight.

The extdiff extension has been using 'archive' since 68822b7cdd01 to support -S,
and a colleague noticed that after diffing, making changes, and closing it, the
line endings were wrong for the diff-tool modified files in the subrepository.
(Files in the parent repo were correct, with the same .hgeol settings.)  The
editor (Visual Studio in this case) reloads the file, but doesn't notice the EOL
change.  It still adds new lines with the original EOL setting, and the file
ends up inconsistent.

Without this change, the first file `cat`d in the test prints '\r (esc)' EOL,
but the second doesn't on Windows or Linux.

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -993,9 +993,9 @@
 
 archiver.done()
 
-def hgsubrepoarchive(orig, repo, archiver, prefix, match=None):
+def hgsubrepoarchive(orig, repo, archiver, prefix, match=None, decode=True):
 if not repo._repo.lfstatus:
-return orig(repo, archiver, prefix, match)
+return orig(repo, archiver, prefix, match, decode)
 
 repo._get(repo._state + ('hg',))
 rev = repo._state[1]
@@ -1010,6 +1010,8 @@
 if match and not match(f):
 return
 data = getdata()
+if decode:
+data = repo._repo.wwritedata(name, data)
 
 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
 
@@ -1037,7 +1039,7 @@
 sub = ctx.workingsub(subpath)
 submatch = matchmod.subdirmatcher(subpath, match)
 sub._repo.lfstatus = True
-sub.archive(archiver, prefix + repo._path + '/', submatch)
+sub.archive(archiver, prefix + repo._path + '/', submatch, decode)
 
 # If a largefile is modified, the change is not reflected in its
 # standin until a commit. cmdutil.bailifchanged() raises an exception
diff --git a/mercurial/archival.py b/mercurial/archival.py
--- a/mercurial/archival.py
+++ b/mercurial/archival.py
@@ -331,7 +331,7 @@
 for subpath in sorted(ctx.substate):
 sub = ctx.workingsub(subpath)
 submatch = matchmod.subdirmatcher(subpath, matchfn)
-total += sub.archive(archiver, prefix, submatch)
+total += sub.archive(archiver, prefix, submatch, decode)
 
 if total == 0:
 raise error.Abort(_('no files match the archive pattern'))
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -542,8 +542,8 @@
 """return filename iterator"""
 raise NotImplementedError
 
-def filedata(self, name):
-"""return file data"""
+def filedata(self, name, decode):
+"""return file data, optionally passed through repo decoders"""
 raise NotImplementedError
 
 def fileflags(self, name):
@@ -558,7 +558,7 @@
 """handle the files command for this subrepo"""
 return 1
 
-def archive(self, archiver, prefix, match=None):
+def archive(self, archiver, prefix, match=None, decode=True):
 if match is not None:
 files = [f for f in self.files() if match(f)]
 else:
@@ -572,7 +572,7 @@
 mode = 'x' in flags and 0o755 or 0o644
 symlink = 'l' in flags
 archiver.addfile(prefix + self._path + '/' + name,
- mode, symlink, self.filedata(name))
+ mode, symlink, self.filedata(name, decode))
 self.ui.progress(_('archiving (%s)') % relpath, i + 1,
  unit=_('files'), total=total)
 self.ui.progress(_('archiving (%s)') % relpath, None)
@@ -782,7 +782,7 @@
   % (inst, subrelpath(self)))
 
 @annotatesubrepoerror
-def archive(self, archiver, prefix, match=None):
+def archive(self, archiver, prefix, match=None, decode=True):
 self._get(self._state + ('hg',))
 total = abstractsubrepo.archive(self, archiver, prefix, match)
 rev = self._state[1]
@@ -790,7 +790,8 @@
 for subpath in ctx.substate:
 s = subrepo(ctx, subpath, True)
 submatch = matchmod.subdirmatcher(subpath, match)
-total += s.archive(archiver, prefix + self._path + '/', submatch)
+total += s.archive(archiver, prefix + self._path + '/', submatch,
+   

[PATCH] wix: include the help for pager

2017-02-25 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1488077074 18000
#  Sat Feb 25 21:44:34 2017 -0500
# Node ID f3af642d13d78e7fcdea4468c024958a5ce2a745
# Parent  5ce388a91851dc6c0dc1be0342a105da659e1d47
wix: include the help for pager

Similar (I assume) to 65d2538ac993.

diff --git a/contrib/wix/help.wxs b/contrib/wix/help.wxs
--- a/contrib/wix/help.wxs
+++ b/contrib/wix/help.wxs
@@ -25,6 +25,7 @@
   
   
   
+  
   
   
   
diff --git a/tests/test-install.t b/tests/test-install.t
--- a/tests/test-install.t
+++ b/tests/test-install.t
@@ -166,7 +166,6 @@
 help/hg.1.txt
 help/hgignore.5.txt
 help/hgrc.5.txt
-help/pager.txt
   Not tracked:
 
   $ python wixxml.py templates
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 9 pager v2] pager: move pager-initiating code into core

2017-02-25 Thread Matt Harbison

On Thu, 16 Feb 2017 11:59:10 -0500, Augie Fackler  wrote:


# HG changeset patch
# User Augie Fackler 
# Date 1487198871 18000
#  Wed Feb 15 17:47:51 2017 -0500
# Node ID cd19a77477bcd18d1f7ab4fa73ee0dbf3c7a4e46
# Parent  791b4e846a7b9a0783440b9504585438777fe2d2
pager: move pager-initiating code into core

No functionality change.

A previous version of this API had a category argument on
ui.pager(). As I migrated the commands in core, I couldn't come up
with good enough consistency in any categorization scheme so I just
scrapped the whole idea. It may be worth revisiting in the future.

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
+# TODO: add a "system defaults" config section so this default
+# of more(1) can be easily replaced with a global
+# configuration file. For example, on OS X the sane default is
+# less(1), not more(1), and on debian it's
+# sensible-pager(1). We should probably also give the system
+# default editor command similar treatment.
+envpager = encoding.environ.get('PAGER', 'more')
+pagercmd = self.config('pager', 'pager', envpager)


Any thoughts on what this looks like?  It seems like it might be  
distantly(?) related to something I tried a couple years ago [1], and the  
discussions around it.


Does it seem reasonable to move the above to a method, similar to  
ui.editor()?  I'd like to detect MSYS and default to `less`.  IDK if we  
can pull that off with just a global config file.  (The only way I see to  
detect MSYS is to look for 'MSYSTEM' in env.)


In theory, the `less` command in GnuWin32 can be installed and made  
visible to cmd.exe too.  I wonder if (on some platforms anyway), there  
should be a list of default choices, and the first one found in $PATH  
used.  ui.editor() doesn't make sure the editor is valid, so I figured  
keeping that kind of check out of ui was purposeful.  A bad editor will  
produce an error that tries to indicate the problem (though I missed it  
the first time in the OS error output):


$ HGEDITOR=xzy ../hg ci
'xzy' is not recognized as an internal or external command,
operable program or batch file.
abort: edit failed: xzy exited with status 1

But not so much for the pager:

hg>set PAGER=less
hg>hg help filesets
'less' is not recognized as an internal or external command,
operable program or batch file.

I'm not sure if the right thing here is to error out, or to treat the  
pager as disabled.  Especially if it is on by default, with an env knob  
that isn't as obvious as the example above.  So it seems like we might  
need some sort of check, whether or not we try a list of defaults.



[1]  
https://www.mercurial-scm.org/pipermail/mercurial-devel/2015-March/067563.html

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 9 pager v2] pager: move pager-initiating code into core

2017-02-25 Thread Matt Harbison

On Sat, 25 Feb 2017 23:32:12 -0500, Augie Fackler  wrote:



On Feb 25, 2017, at 11:22 PM, Matt Harbison   
wrote:


On Thu, 16 Feb 2017 11:59:10 -0500, Augie Fackler   
wrote:



# HG changeset patch
# User Augie Fackler 
# Date 1487198871 18000
#  Wed Feb 15 17:47:51 2017 -0500
# Node ID cd19a77477bcd18d1f7ab4fa73ee0dbf3c7a4e46
# Parent  791b4e846a7b9a0783440b9504585438777fe2d2
pager: move pager-initiating code into core

No functionality change.

A previous version of this API had a category argument on
ui.pager(). As I migrated the commands in core, I couldn't come up
with good enough consistency in any categorization scheme so I just
scrapped the whole idea. It may be worth revisiting in the future.

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
+# TODO: add a "system defaults" config section so this default
+# of more(1) can be easily replaced with a global
+# configuration file. For example, on OS X the sane default is
+# less(1), not more(1), and on debian it's
+# sensible-pager(1). We should probably also give the system
+# default editor command similar treatment.
+envpager = encoding.environ.get('PAGER', 'more')
+pagercmd = self.config('pager', 'pager', envpager)


Any thoughts on what this looks like?  It seems like it might be  
distantly(?) related to something I tried a couple years ago [1], and  
the discussions around it.


It’s pretty different from the previous round in my mind: it’d be a  
config section, only advertised for sysadmins and packagers,  
specifically intended for setting more-reasonable defaults, e.g.:


(debian)
[systemdefaults]
editor = sensible-editor
pager = sensible-pager

(macOS)
[systemdefaults]
editor = nano
pager = less

(FreeBSD)
[systemdefaults]
editor = vi
pager = less

etc.

Does it seem reasonable to move the above to a method, similar to  
ui.editor()?  I'd like to detect MSYS and default to `less`.  IDK if we  
can pull that off with just a global config file.  (The only way I see  
to detect MSYS is to look for 'MSYSTEM' in env.)


In line with the above, I’d expect an mays-backed package to set  
systemdefaults.pager to less (maybe that’s not a thing? I dunno.)


I'm not thinking of an msys package, rather my personal usage.  If I'm  
doing anything of any substance on the command line, I'll use msys.  But  
TortoiseHg launches cmd.exe with a simple Ctrl + Shift + T, and sometimes  
that's good enough.  Therefore, I can't just set a pager value in  
%HOME%/mercurial.ini.  The hg.exe built from source and the one bundled  
with TortoiseHg are each visible to msys and cmd.exe, depending on what  
directory I'm in.  So even if TortoiseHg picked one (and we ignore hg  
built from the dev repo), it may or may not use the best pager available  
without a little help.



I’m extremely hesitant to add any kind of conditional logic in hgrc.


Agreed.  The conditional logic I'm thinking of is in python, similar to  
how plan9 sets its last-ditch editor to 'E' in ui.geteditor().  Based on  
the vision you've described, I don't see a list as useful.  And because I  
can't think of any other OS with such a bad pager (and a better one so  
tantalizingly close), maybe a one-off python conditional is OK?



Do you know of any other systems that use this kind of configuration
approach but don’t have a scripting language as their config language?


IDK what this means, so I'm gonna say no. :-)

Note that systemdefaults (which is a name I came up with in the process  
of writing this mail, and probably isn’t what we should keep) would  
*not* overwrite environment variables, so if the user has EDITOR or  
PAGER set, that takes precedence over systemdefaults - this new config  
section is explicitly about helping packagers get the best possible “out  
of the box” experience without having to patch hg (which the debian  
package currently has to for sensible-editor).


Makes sense.  This would get rid of the special case editor for plan9, for  
packages anyway.  It wouldn't for hg built from source, but that could  
presumably be set in ~/.hgrc.


In theory, the `less` command in GnuWin32 can be installed and made  
visible to cmd.exe too.  I wonder if (on some platforms anyway), there  
should be a list of default choices, and the first one found in $PATH  
used.  ui.editor() doesn't make sure the editor is valid, so I figured  
keeping that kind of check out of ui was purposeful.  A bad editor will  
produce an error that tries to indicate the problem (though I missed it  
the first time in the OS error output):


   $ HGEDITOR=xzy ../hg ci
   'xzy' is not recognized as an internal or external command,
   operable program or batch file.
   abort: edit failed: xzy exited with status 1

But not so much for th

Re: [PATCH 1 of 4 V2] serve: add support for Mercurial subrepositories

2017-02-26 Thread Matt Harbison

On Sun, 26 Feb 2017 08:28:01 -0500, Yuya Nishihara  wrote:


On Sat, 25 Feb 2017 15:25:30 -0500, Matt Harbison wrote:
On Tue, 21 Feb 2017 09:33:58 -0500, Yuya Nishihara   
wrote:

>> - At http://localhost:8000, the links on the left side were corrupt
>> (graph
>> is simply 'graph/tip', tags is 'http://tags', etc.)  The pattern  
seemed

>> to
>> be that things ending in 'tip' are relative URLs, and the rest get an
>> http: prefix.  It looks from the sources like it is just a matter of  
'/'

>> not translating for the {repo} template.
>
> [snip]
>
> I saw some of these problems in V1. However, the standalone hgweb can
> host
> a repository at '/', so I don't think it's quite difficult to host the
> subrepo
> parent at '/'.

That's a good point, so now I'm really puzzled over the subtle
differences.  It looks like when it finds a hosted repo, it just farms  
out

to hgweb, like the single serve would do.


Yes. hgwebdir is just a dispatcher except for generating an index page.

This is a dirty hack to make hgwebdir serve a repo at '/'.

diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -335,7 +335,7 @@ class hgweb(object):
 req.url = req.env['SCRIPT_NAME']
 if not req.url.endswith('/'):
 req.url += '/'
-if 'REPO_NAME' in req.env:
+if req.env.get('REPO_NAME'):
 req.url += req.env['REPO_NAME'] + '/'
if 'PATH_INFO' in req.env:
diff --git a/mercurial/hgweb/hgwebdir_mod.py  
b/mercurial/hgweb/hgwebdir_mod.py

--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -254,18 +254,19 @@ class hgwebdir(object):
 return []
# top-level index
-elif not virtual:
+elif False:
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl)
# nested indexes and hgwebs
repos = dict(self.repos)
-virtualrepo = virtual
-while virtualrepo:
-real = repos.get(virtualrepo)
+# XXX dirty hack to handle ''. IIRC, we have a helper  
function

+virtualrepo = '/' + virtual
+while True:
+real = repos.get(virtualrepo[1:])
 if real:
-req.env['REPO_NAME'] = virtualrepo
+req.env['REPO_NAME'] = virtualrepo[1:]
 try:
 # ensure caller gets private copy of ui
 repo = hg.repository(self.ui.copy(), real)


Oh, nice! Thanks for this.

Can you clarify what you mean by the hack? It seems like adding '/' to  
paths isn't all that uncommon (especially in subrepo code), and the  
closest I could find to a helper for removing '/' is  
hgwebdir_mod.cleannames().  But that takes a list and also does a  
util.pconvert().


Just a couple lines above this, 'virtual' is cleaned up with  
string.strip('/').  (That's interesting, because then I can't see how the  
"virtual.startswith('static/')" tests can ever be true.  It looks like  
this was papered over in 74f65f44a9aa?)



>> To me, the benefits of this series over the original is:
>>
>> 1) The repos aren't moved, and therefore don't incur these subtle  
bugs

>> 2) These changes are totally isolated to subrepo serving, so there
>> should
>> be no risk to mainstream hgweb usage
>> 3) This is completely compatible with existing serves with a simple
>> '/=$projects_dir/**' config file, because the real repos are not
>> anchored
>> to '/'.
>
> I think (2) and (3) are up to how we build a repository map.

What I mean for (2) is that in V2, none of the code changes are hit
without -S.  That seems like a good thing, given the subtle breakage in  
V1.


What I mean by (3) is that the transition for current clones is to  
simply

drop --web-conf=.. and start using -S on the server side.  Clients won't
see a difference.


No code change is nice, but I don't buy it much since the redirection  
thing

seemed unnecessarily complicated.


I assume that the hardcoded web.staticurl in V1 also means that it won't
be able to serve a subrepo named 'static'?  (That's admittedly an edge
case.)


Yes. Also, you can't see /rev/ page if there's a subrepo named 'rev'.


I only see the two ways to build the repo map, so I'm not sure what you
are saying here.


I meant we could delete the root repo from self.repos map on plain  
hgwebdir

server if that's considered a behavior change. (otherwise the root index
page would be replaced by the hgweb for the root repo.)

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] internals: add some brief documentation about censor

2017-02-28 Thread Matt Harbison

On Mon, 27 Feb 2017 18:11:15 -0500, Augie Fackler  wrote:


# HG changeset patch
# User Augie Fackler 
# Date 1485220644 18000
#  Mon Jan 23 20:17:24 2017 -0500
# Node ID 065219350c9ce3c31a35d13fe97be0673e321e09
# Parent  3f8f53190d6afed0aca6c6527236edad28ce785c
internals: add some brief documentation about censor


This is needed to keep test-install.t happy:

diff --git a/contrib/wix/help.wxs b/contrib/wix/help.wxs
--- a/contrib/wix/help.wxs
+++ b/contrib/wix/help.wxs
@@ -38,6 +38,7 @@
 
   Guid="$(var.help.internals.guid)" Win64='$(var.IsX64)'>
 KeyPath="yes" />

+
 />
 />

 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 8 of 8] fileset: add a 'status(...)' predicate to control evaluation context

2017-03-03 Thread Matt Harbison
On Fri, 03 Mar 2017 08:40:45 -0500, Pierre-Yves David  
 wrote:



# HG changeset patch
# User Pierre-Yves David 
# Date 1488546500 -3600
#  Fri Mar 03 14:08:20 2017 +0100
# Node ID 3e95bf7ed38189f6f56de89571fffc667280bb56
# Parent  9d6e733046b9aa7e2ded8c4207625fedcc2a8c04
# EXP-Topic filesetrev-func
# Available At  
https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
#  hg pull  
https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r  
3e95bf7ed381

fileset: add a 'status(...)' predicate to control evaluation context


This is awesome!  It unlocks the "what merge conflicts might I run into?"  
pre update/rebase test that I mentioned last week.  I did a test to see if  
the files listed for the 13bbcd56c57a merge agreed with TortoiseHg:


$ ../hg files --rev 'ancestor(6483e49204ee, a91c62752d08)'  
"set:status('ancestor(6483e49204ee, a91c62752d08)', 6483e49204ee,  
added()+modified()+removed()) & status('ancestor(6483e49204ee,  
a91c62752d08)', a91c62752d08, added()+modified()+removed())"

..\mercurial\ui.py
..\mercurial\worker.py

It does, but that's quite a mouthful.  Granted, doing this for real  
pre-merge would likely use the branch names, but not necessarily.   
(Consider an anonymous branch after pulling.)


I wonder if the parameters to this can have default values, to make it  
more concise, and more like the status command.  For example, leaving out  
the 3rd parameter implies added()+modified()+removed()+missing() (status  
doesn't list clean or ignored by default).  It seems like it would be  
convenient if one of the revisions (base?) defaulted to what --rev  
specified for the command.  The second --rev for status defaults to wdir().


I know this is meant for aggregating files _across_ revisions, but then  
`hg status` and `hg files 'set:status()'` would agree, without ORing  
together the MAR! predicates.


I did run into an oddity when testing with subrepos:

diff --git a/tests/test-subrepo-deep-nested-change.t  
b/tests/test-subrepo-deep-nested-change.t

--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -455,6 +455,17 @@
   sub1/sub2/sub2 (glob)
   sub1/sub2/test.txt (glob)

+  $ hg files 'set:status(0, "wdir()", added()+modified()+removed())'
+  .hgsubstate
+  foo\bar\abc
+
+  $ hg files -S 'set:status(0, tip, added()+modified()+removed())'
+  .hgsubstate
+  foo\bar\abc
+  sub1\.hgsubstate
+  sub1\foo
+  sub1\sub2\folder\bar
+
   $ hg files sub1
   sub1/.hgsub (glob)
   sub1/.hgsubstate (glob)

I'd expect .hgsub to show up in the main repo.  There may be some more  
missing in the subrepos for the second command, but I don't have any more  
time to investigate tonight.  I'll see if I can figure it out over the  
weekend.


When I quote 3rd parameter in those tests, the output is different.  It's  
unfortunate that revsets in arg 1 or 2 requires quoting, but quoting is  
wrong for the 3rd arg.


  $ hg files 'set:status(0, "wdir()", "added()+modified()+removed()")'
  [1]

  $ hg files -S 'set:status(0, tip, "added()+modified()+removed()")'
  abort: added()+modified()+removed() not under root  
'$TESTTMP\cloned\sub1' (in subrepo sub1)

  (consider using '--cwd sub1')
  [255]

If this is just because of the way the parser needs to be, mentioning it  
in the help may be sufficient.


Same as 'revs', this predicate does not select files but switches the  
evaluation
context. This allow to match file according arbitrary status call. We  
can now

express the same query as 'hg status'.

The API (two 'revsingle' class) have been picked instead of a single  
'revs'

revset for multiple reasons:

 * it is less confusing to express
 * it allow to express more query (eg: backward status, cross branch  
status)


diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -463,6 +463,25 @@ def revs(mctx, x):
 result.append(f)
 return result
+@predicate('status(base, rev, pattern)')
+def status(mctx, x):
+"""``status(base, rev, revspec)``
+
+Evaluate predicate using status change between ``base`` and
+``rev``. Examples:
+
+- ``status(3, 7, added())`` - matches files added from "3" to "7"
+"""
+repo = mctx.ctx.repo()
+# i18n: "status" is a keyword
+b, r, x = getargs(x, 3, 3, _("status takes three arguments"))
+# i18n: "status" is a keyword
+baserevspec = getstring(b, _("first argument to revs must be a  
revision"))
+revspec = getstring(r, _("second argument to revs must be a  
revision"))

+basectx = scmutil.revsingle(repo, baserevspec)
+ctx = scmutil.revsingle(repo, revspec)
+return getset(mctx.switch(ctx, _buildstatus(ctx, x,  
basectx=basectx)), x)

+
 @predicate('subrepo([pattern])')
 def subrepo(mctx, x):
 """Subrepositories whose paths match the given pattern.
@@ -538,6 +557,7 @@ class fullmatchctx(matchctx):
 # filesets using matchctx.switch()
 _switchcallers = [
 'revs',
+'sta

Re: [PATCH 8 of 8] fileset: add a 'status(...)' predicate to control evaluation context

2017-03-04 Thread Matt Harbison
On Fri, 03 Mar 2017 23:35:04 -0500, Matt Harbison   
wrote:


On Fri, 03 Mar 2017 08:40:45 -0500, Pierre-Yves David  
 wrote:



# HG changeset patch
# User Pierre-Yves David 
# Date 1488546500 -3600
#  Fri Mar 03 14:08:20 2017 +0100
# Node ID 3e95bf7ed38189f6f56de89571fffc667280bb56
# Parent  9d6e733046b9aa7e2ded8c4207625fedcc2a8c04
# EXP-Topic filesetrev-func
# Available At  
https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
#  hg pull  
https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r  
3e95bf7ed381

fileset: add a 'status(...)' predicate to control evaluation context


This is awesome!  It unlocks the "what merge conflicts might I run  
into?" pre update/rebase test that I mentioned last week.  I did a test  
to see if the files listed for the 13bbcd56c57a merge agreed with  
TortoiseHg:


$ ../hg files --rev 'ancestor(6483e49204ee, a91c62752d08)'  
"set:status('ancestor(6483e49204ee, a91c62752d08)', 6483e49204ee,  
added()+modified()+removed()) & status('ancestor(6483e49204ee,  
a91c62752d08)', a91c62752d08, added()+modified()+removed())"

..\mercurial\ui.py
..\mercurial\worker.py

It does, but that's quite a mouthful.  Granted, doing this for real  
pre-merge would likely use the branch names, but not necessarily.   
(Consider an anonymous branch after pulling.)


I wonder if the parameters to this can have default values, to make it  
more concise, and more like the status command.  For example, leaving  
out the 3rd parameter implies added()+modified()+removed()+missing()  
(status doesn't list clean or ignored by default).  It seems like it  
would be convenient if one of the revisions (base?) defaulted to what  
--rev specified for the command.  The second --rev for status defaults  
to wdir().


I know this is meant for aggregating files _across_ revisions, but then  
`hg status` and `hg files 'set:status()'` would agree, without ORing  
together the MAR! predicates.


I did run into an oddity when testing with subrepos:

diff --git a/tests/test-subrepo-deep-nested-change.t  
b/tests/test-subrepo-deep-nested-change.t

--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -455,6 +455,17 @@
sub1/sub2/sub2 (glob)
sub1/sub2/test.txt (glob)

+  $ hg files 'set:status(0, "wdir()", added()+modified()+removed())'
+  .hgsubstate
+  foo\bar\abc
+
+  $ hg files -S 'set:status(0, tip, added()+modified()+removed())'
+  .hgsubstate
+  foo\bar\abc
+  sub1\.hgsubstate
+  sub1\foo
+  sub1\sub2\folder\bar
+
$ hg files sub1
sub1/.hgsub (glob)
sub1/.hgsubstate (glob)

I'd expect .hgsub to show up in the main repo.


My misunderstanding on this one.  `hg status --rev 0` agrees with this  
output.  I read the doc saying "added from 3 to 7" as [3, 7], not (3, 7]  
as it actually is.  .hgsub was only changed in rev 0.  When I changed to  
null or , it showed as expected.  (Using -1 here raises a parse error,  
and using "-1" causes nothing to match.)


There may be some more missing in the subrepos for the second command,  
but I don't have any more time to investigate tonight.  I'll see if I  
can figure it out over the weekend.


Here's a test case:

diff --git a/tests/test-subrepo-deep-nested-change.t  
b/tests/test-subrepo-deep-nested-change.t

--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -455,6 +455,18 @@
   sub1/sub2/sub2 (glob)
   sub1/sub2/test.txt (glob)

+  $ hg files -r 2 -S 'set:status(1, 2, added()+modified()+removed())'
+  .hgsubstate
+  sub1\.hgsubstate
+  sub1\sub2\folder\test.txt
+  sub1\sub2\test.txt
+
+  $ hg status -S --rev 1 --rev 2 | sort -k2
+  M .hgsubstate
+  M sub1/.hgsubstate
+  A sub1/sub2/folder/test.txt
+  A sub1/sub2/test.txt
+
   $ hg files sub1
   sub1/.hgsub (glob)
   sub1/.hgsubstate (glob)

The fileset gets fully populated with what `hg status` shows.  But if you  
drop the "-r 2" arg to `hg files`, the two *.txt files don't show.  What's  
happening is the command is walking 'wdir()', and since those files don't  
exist, they aren't tested against the set.  IOW, there's an implicit &  
with the files in the revision of the command against the fileset.  That  
makes sense, but it initially surprised me.  I'm not sure what words to  
use, but that should be documented somehow.  I also think that's an  
argument for the command --rev and the base rev defaulting to the same  
value.  (Is there a usecase for the command revision not being one or the  
other fileset revisions?)


One cosmetic thing below that I missed the first time.

When I quote 3rd parameter in those tests, the output is different.   
It's unfortunate that revsets in arg 1 or 2 requires quoting, but  
quoting is wrong for the 3rd arg.


[PATCH] hgwebdir: add support for explicit index files

2017-03-05 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1488770552 18000
#  Sun Mar 05 22:22:32 2017 -0500
# Node ID 3ff768dd4fe9faeca8ccba040fa6a085584063aa
# Parent  023123a67b54d98bd4c8ef8ac8cfd7a96247519e
hgwebdir: add support for explicit index files

This is useful for when repositories are nested in --web-conf, and in the future
with hosted subrepositories.  The previous behavior was only to render an index
at each virtual directory.  There is now an explicit index.html for each virtual
directory.  Additionally, there is now an explicit index.html for every
repository directory with a nested repository below it.  This seems more
consistent with each virtual directory hosting an index, and more discoverable
than to only have an index for a directory that directly hosts a nested
repository.

I couldn't figure out how to close the loop and provide one in each directory
without a deeper nested repository, without blocking a committed 'index.html'.
Keeping that seems better than rendering an empty index.

diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -254,34 +254,50 @@
 return []
 
 # top-level index
-elif not virtual:
+elif not virtual or virtual == 'index.html':
+if virtual:
+req.env['PATH_INFO'] = '/'
+
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl)
 
 # nested indexes and hgwebs
 
 repos = dict(self.repos)
-virtualrepo = virtual
-while virtualrepo:
-real = repos.get(virtualrepo)
-if real:
-req.env['REPO_NAME'] = virtualrepo
-try:
-# ensure caller gets private copy of ui
-repo = hg.repository(self.ui.copy(), real)
-return hgweb_mod.hgweb(repo).run_wsgi(req)
-except IOError as inst:
-msg = inst.strerror
-raise ErrorResponse(HTTP_SERVER_ERROR, msg)
-except error.RepoError as inst:
-raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
 
-up = virtualrepo.rfind('/')
-if up < 0:
-break
-virtualrepo = virtualrepo[:up]
+def checkrepos():
+if not virtual.endswith('/index.html'):
+return True
+
+pdir = virtual[:-len('index.html')]
+return not any(r.startswith(pdir) for r in repos)
+
+if checkrepos():
+virtualrepo = virtual
+while virtualrepo:
+real = repos.get(virtualrepo)
+if real:
+req.env['REPO_NAME'] = virtualrepo
+try:
+# ensure caller gets private copy of ui
+repo = hg.repository(self.ui.copy(), real)
+return hgweb_mod.hgweb(repo).run_wsgi(req)
+except IOError as inst:
+msg = inst.strerror
+raise ErrorResponse(HTTP_SERVER_ERROR, msg)
+except error.RepoError as inst:
+raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
+
+up = virtualrepo.rfind('/')
+if up < 0:
+break
+virtualrepo = virtualrepo[:up]
 
 # browse subdirectories
+if virtual.endswith('/index.html'):
+virtual = virtual[:-len('/index.html')]
+req.env['PATH_INFO'] = '/' + virtual
+
 subdir = virtual + '/'
 if [r for r in repos if r.startswith(subdir)]:
 req.respond(HTTP_OK, ctype)
diff --git a/tests/test-hgwebdir.t b/tests/test-hgwebdir.t
--- a/tests/test-hgwebdir.t
+++ b/tests/test-hgwebdir.t
@@ -1566,6 +1566,96 @@
   /b/
   /c/
   
+  $ killdaemons.py
+  $ cat > paths.conf << EOF
+  > [paths]
+  > /dir1/a_repo = $root/a
+  > /dir1/a_repo/b_repo = $root/b
+  > EOF
+  $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ echo 'index file' > $root/a/index.html
+  $ hg --cwd $root/a ci -Am 'add index file'
+  adding index.html
+
+  $ get-with-headers.py localhost:$HGPORT1 '' | grep 'a_repo'
+  dir1/a_repo
+  
+  dir1/a_repo/b_repo
+  
+
+  $ get-with-headers.py localhost:$HGPORT1 'index.html' | grep 'a_repo'
+  dir1/a_repo
+  
+  dir1/a_repo/b_rep

Re: stable ordering of test output

2017-03-07 Thread Matt Harbison
On Fri, 03 Mar 2017 17:45:56 -0500, Danek Duvall   
wrote:



I frequently get failures like this:

--- .../mercurial.hg/tests/test-bundle2-exchange.t
+++ .../mercurial.hg/tests/test-bundle2-exchange.t.err
@@ -1042,11 +1042,11 @@
   $ hg --config devel.legacy.exchange=bundle1 clone  
ssh://user@dummy/bundle2onlyserver not-bundle2-ssh

   requesting all changes
   adding changesets
-  remote: abort: incompatible Mercurial client; bundle2 required
-  remote: (see  
https://www.mercurial-scm.org/wiki/IncompatibleClient)

   transaction abort!
   rollback completed
   abort: stream ended unexpectedly (got 0 bytes, expected 4)
+  remote: abort: incompatible Mercurial client; bundle2 required
+  remote: (see  
https://www.mercurial-scm.org/wiki/IncompatibleClient)

   [255]
  $ cat > bundle2onlyserver/.hg/hgrc << EOF

ERROR: test-bundle2-exchange.t output changed

It's usually fairly consistent, at least for a period of time, and then  
it

goes away.  Presumably it's some sort of fairly stable timing issue, and
possibly unique to the environment I'm running in (at least, I assume  
that

the official tests aren't showing this).


The symptoms seem similar to what was happening on Windows a few years ago.

https://www.mercurial-scm.org/repo/hg/rev/83f6c4733ecc
https://www.mercurial-scm.org/repo/hg/rev/2abbf4750915

The commit referenced in the first link's message might also be of  
interest.


I could patch the tests locally to reorder the lines, but if it's really  
an

environmental issue, then that's guaranteed to work consistently even for
me.

Is this (ever? frequently?) an issue for anyone else?

I can't think of any particularly satisfying solution to this, other than
perhaps separating the remote lines from the local lines, and comparing
each of those independently.  Would that make sense?

Thanks,
Danek
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V2] hgwebdir: add support for explicit index files

2017-03-14 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1488770552 18000
#  Sun Mar 05 22:22:32 2017 -0500
# Node ID d24cb60edbc782ea1ee4f5625accc83f9ec3e3ca
# Parent  1c48a8278b2f015fca607dfc652823560a5ac580
hgwebdir: add support for explicit index files

This is useful for when repositories are nested in --web-conf, and in the future
with hosted subrepositories.  The previous behavior was only to render an index
at each virtual directory.  There is now an explicit 'index' child for each
virtual directory.  The name was suggested by Yuya, for consistency with the
other method names.

Additionally, there is now an explicit 'index' child for every repository
directory with a nested repository somewhere below it.  This seems more
consistent with each virtual directory hosting an index, and more discoverable
than to only have an index for a directory that directly hosts a nested
repository.  I couldn't figure out how to close the loop and provide one in each
directory without a deeper nested repository, without blocking a committed
'index' file.  Keeping that seems better than rendering an empty index.

diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -254,13 +254,21 @@
 return []
 
 # top-level index
-elif not virtual:
+
+repos = dict(self.repos)
+
+if not virtual or (virtual == 'index' and virtual not in repos):
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl)
 
 # nested indexes and hgwebs
 
-repos = dict(self.repos)
+if virtual.endswith('/index') and virtual not in repos:
+subdir = virtual[:-len('index')]
+if any(r.startswith(subdir) for r in repos):
+req.respond(HTTP_OK, ctype)
+return self.makeindex(req, tmpl, subdir)
+
 virtualrepo = virtual
 while virtualrepo:
 real = repos.get(virtualrepo)
@@ -352,8 +360,7 @@
 pass
 
 parts = [name]
-if 'PATH_INFO' in req.env:
-parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
+parts.insert(0, '/' + subdir.rstrip('/'))
 if req.env['SCRIPT_NAME']:
 parts.insert(0, req.env['SCRIPT_NAME'])
 url = re.sub(r'/+', '/', '/'.join(parts) + '/')
diff --git a/tests/test-hgwebdir.t b/tests/test-hgwebdir.t
--- a/tests/test-hgwebdir.t
+++ b/tests/test-hgwebdir.t
@@ -1566,6 +1566,119 @@
   /b/
   /c/
   
+  $ killdaemons.py
+  $ cat > paths.conf << EOF
+  > [paths]
+  > /dir1/a_repo = $root/a
+  > /dir1/a_repo/b_repo = $root/b
+  > /dir1/dir2/index = $root/b
+  > EOF
+  $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ echo 'index file' > $root/a/index
+  $ hg --cwd $root/a ci -Am 'add index file'
+  adding index
+
+  $ get-with-headers.py localhost:$HGPORT1 '' | grep 'a_repo'
+  dir1/a_repo
+  
+  dir1/a_repo/b_repo
+  
+
+  $ get-with-headers.py localhost:$HGPORT1 'index' | grep 'a_repo'
+  dir1/a_repo
+  
+  dir1/a_repo/b_repo
+  
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1' | grep 'a_repo'
+  a_repo
+  
+  a_repo/b_repo
+  
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/index' | grep 'a_repo'
+  a_repo
+  
+  a_repo/b_repo
+  
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo' | grep 'a_repo'
+  
+  
+  
+  dir1/a_repo: log
+ href="/dir1/a_repo/atom-log" title="Atom feed for dir1/a_repo" />
+ href="/dir1/a_repo/rss-log" title="RSS feed for dir1/a_repo" />
+  
+  graph
+  tags
+  bookmarks
+  branches
+  changeset
+  browse
+   help
+  
+  
+  Mercurial > dir1 > a_repo 
+  
+  number or hash, or revset 
expression.
+  less
+  more
+  | rev 1: (0) tip 
+ add index file
+ a
+  less
+  more
+  | rev 1: (0) tip 
+  '/dir1/a_repo/shortlog/%next%',
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/index' | grep 'a_repo'
+  Mercurial > dir1 > a_repo 
+  b_repo
+  
+
+Files named 'index' are not blocked
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/raw-file/tip/index'
+  200 Script output follows
+  
+  index file
+
+Repos named 'index' take precedence over the index file
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/dir2/index' | grep 'index'
+  
+  
+  
+  
+  dir1/dir2/

[PATCH evolve-ext] checks: correct the shebang line filtering for python files

2017-03-16 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489713417 14400
#  Thu Mar 16 21:16:57 2017 -0400
# Node ID 6a3248558b6929378450b572bb27406afe703ffd
# Parent  e9d5f54765a27e09d35f48dda23db7e6f5b8320a
checks: correct the shebang line filtering for python files

As it is, the only related file is docs/test2rst.py, which was covered by **.py.
Not sure if it matters, but most patterns in core tests are for "#!.*?python".
(Though there are a couple "#!.*python" tests.)

diff --git a/tests/test-check-flake8.t b/tests/test-check-flake8.t
--- a/tests/test-check-flake8.t
+++ b/tests/test-check-flake8.t
@@ -14,5 +14,5 @@
 
 run flake8 if it exists; if it doesn't, then just skip
 
-  $ hg files -0 'set:(**.py or grep("^!#.*python")) - removed()' 2>/dev/null \
+  $ hg files -0 'set:(**.py or grep("^#!.*python")) - removed()' 2>/dev/null \
   > | xargs -0 flake8
diff --git a/tests/test-check-pyflakes.t b/tests/test-check-pyflakes.t
--- a/tests/test-check-pyflakes.t
+++ b/tests/test-check-pyflakes.t
@@ -7,5 +7,5 @@
 run pyflakes on all tracked files ending in .py or without a file ending
 (skipping binary file random-seed)
 
-  $ hg locate 'set:(**.py or grep("^!#.*python")) - removed()' 2>/dev/null \
+  $ hg locate 'set:(**.py or grep("^#!.*python")) - removed()' 2>/dev/null \
   > | xargs pyflakes 2>/dev/null
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH evolve-ext] tests: add glob for Windows

2017-03-16 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489720627 14400
#  Thu Mar 16 23:17:07 2017 -0400
# Node ID ab5c2bef148bfb60e1956a55de4b7ba00ebe1817
# Parent  6a3248558b6929378450b572bb27406afe703ffd
tests: add glob for Windows

diff --git a/tests/test-inhibit.t b/tests/test-inhibit.t
--- a/tests/test-inhibit.t
+++ b/tests/test-inhibit.t
@@ -911,7 +911,7 @@
   $ cd not-inhibit
   $ hg book -d foo
   $ hg pull
-  pulling from $TESTTMP/inhibit
+  pulling from $TESTTMP/inhibit (glob)
   searching for changes
   no changes found
   adding remote bookmark foo
diff --git a/tests/test-stablesort.t b/tests/test-stablesort.t
--- a/tests/test-stablesort.t
+++ b/tests/test-stablesort.t
@@ -138,7 +138,7 @@
   updating to branch default
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -R repo_B pull --rev 13
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -146,7 +146,7 @@
   added 4 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg -R repo_B pull --rev 14
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -154,7 +154,7 @@
   added 1 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads .' to see heads, 'hg merge' to merge)
   $ hg -R repo_B pull
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -204,7 +204,7 @@
   updating to branch default
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -R repo_C pull --rev 12
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -212,7 +212,7 @@
   added 2 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg -R repo_C pull --rev 15
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -220,7 +220,7 @@
   added 4 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads .' to see heads, 'hg merge' to merge)
   $ hg -R repo_C pull
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -270,7 +270,7 @@
   updating to branch default
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -R repo_D pull --rev 10
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -278,7 +278,7 @@
   added 5 changesets with 0 changes to 0 files
   (run 'hg update' to get a working copy)
   $ hg -R repo_D pull --rev 15
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -286,7 +286,7 @@
   added 4 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg -R repo_D pull
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -404,7 +404,7 @@
   updating to branch default
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -R repo_E pull --rev e7d9710d9fc6
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -420,7 +420,7 @@
   updating to branch default
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -R repo_F pull --rev d62d843c9a01
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -436,7 +436,7 @@
   updating to branch default
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -R repo_G pull --rev 43227190fef8
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -444,7 +444,7 @@
   added 1 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg -R repo_G pull --rev 2702dd0c91e7
-  pulling from $TESTTMP/repo_A
+  pulling from $TESTTMP/repo_A (glob)
   searching for changes
   adding changesets
   adding manifests
diff --git a/tests/test-topic-dest.t b/tests/test-topic-dest.t
--- a/tests/test-topic-dest.t
+++ b/tests/test-topic-dest.t
@@ -276,7 +276,7 @@
   $ hg add other
   $ hg ci -m 'c_other'
   $ hg pull -r default --rebase
-  pulling from $TESTTMP/jungle
+  pulling from $TESTTMP/jungle (glob)
   searching for c

[PATCH] color: sync text attributes and buffered text output on Windows (issue5508)

2017-03-19 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489941885 14400
#  Sun Mar 19 12:44:45 2017 -0400
# Node ID b1bebed54e9371708e1cd1eba63f0cedadfdf035
# Parent  da7d19324b1e3d2ce0636bf73e76bf8f3d68ed27
color: sync text attributes and buffered text output on Windows (issue5508)

I originally noticed that log output wasn't being colored after 3a4c0905f357,
but there were other complications too.  With a bunch of untracked files, only
the first 1K of characters were colored pink, and the rest were normal white.  A
single modified file at the top would also be colored pink.

Line buffering and full buffering are treated as the same thing in Windows [1],
meaning the stream is either buffered or not.  I can't find any explicit
documentation to say stdout is unbuffered by default when attached to a console
(but some internet postings indicated that is the case[2]).  Therefore, it seems
that explicit flushes are better than just not reopening stdout.

NB: pager is now on by default, and needs to be disabled to see any color on
Windows.

[1] https://msdn.microsoft.com/en-us/library/86cebhfs(v=vs.140).aspx
[2] https://sourceforge.net/p/mingw/mailman/message/27121137/

diff --git a/mercurial/color.py b/mercurial/color.py
--- a/mercurial/color.py
+++ b/mercurial/color.py
@@ -463,9 +463,11 @@
 for sattr in m.group(1).split(';'):
 if sattr:
 attr = mapcolor(int(sattr), attr)
+ui.flush()
 _kernel32.SetConsoleTextAttribute(stdout, attr)
 writefunc(m.group(2), **opts)
 m = re.match(ansire, m.group(3))
 finally:
 # Explicitly reset original attributes
+ui.flush()
 _kernel32.SetConsoleTextAttribute(stdout, origattr)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] test-check-help: fix to work on Windows

2017-03-19 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489948965 14400
#  Sun Mar 19 14:42:45 2017 -0400
# Node ID f5f429a6300ef16a477ce175899088bd06a616b1
# Parent  b1bebed54e9371708e1cd1eba63f0cedadfdf035
test-check-help: fix to work on Windows

The initial problem was `hg files` prints paths with '\', which gets removed
when piped (scanhelptopics.py failed to open 'hgext__init__.py').  Then, xargs
was invoking `hg help` with 'backout\r (esc)', which setting binary mode
prevents.

diff --git a/tests/test-check-help.t b/tests/test-check-help.t
--- a/tests/test-check-help.t
+++ b/tests/test-check-help.t
@@ -6,6 +6,9 @@
   > from __future__ import absolute_import, print_function
   > import re
   > import sys
+  > if sys.platform == "win32":
+  > import os, msvcrt
+  > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
   > topics = set()
   > topicre = re.compile(r':hg:`help ([a-z0-9\-.]+)`')
   > for fname in sys.argv:
@@ -20,6 +23,6 @@
 Check if ":hg:`help TOPIC`" is valid:
 (use "xargs -n1 -t" to see which help commands are executed)
 
-  $ hg files 'glob:{hgext,mercurial}/**/*.py' \
+  $ hg files 'glob:{hgext,mercurial}/**/*.py' | sed 's|\\|/|g' \
   > | xargs python "$TESTTMP/scanhelptopics.py" \
   > | xargs -n1 hg help > /dev/null
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3] pager: fix the invocation of `more` on Windows

2017-03-19 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489983573 14400
#  Mon Mar 20 00:19:33 2017 -0400
# Node ID a32b379ffe151b8b094dcd67ef5b6bd551203dbe
# Parent  b1bebed54e9371708e1cd1eba63f0cedadfdf035
pager: fix the invocation of `more` on Windows

After 9335dc6b2a9c, invoking `more` no longer works.  Instead, a warning is
printed and the pager is disabled.  Invoking `more.com` works.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -839,7 +839,10 @@
 # less(1), not more(1), and on debian it's
 # sensible-pager(1). We should probably also give the system
 # default editor command similar treatment.
-envpager = encoding.environ.get('PAGER', 'more')
+envpager = 'more'
+if pycompat.osname == 'nt':
+envpager = 'more.com'
+envpager = encoding.environ.get('PAGER', envpager)
 pagercmd = self.config('pager', 'pager', envpager)
 if not pagercmd:
 return
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 3] [RFC] dispatch: setup color before pager

2017-03-19 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489985511 14400
#  Mon Mar 20 00:51:51 2017 -0400
# Node ID 2a323109f8e7ec5548dd506c2cff05f27fa20c1e
# Parent  6e72bb689e57c985b138c580acb4cad8053dc180
[RFC] dispatch: setup color before pager

With the previous order, color was None for commands invoked with --pager=yes at
the time the pager was spawned, which meant the switch over to ANSI mode on
Windows didn't occur.  That left the color.win32print() in 'auto' mode, which
meant no color in the pager output.  Non Windows platforms are capable of
printing color with this option.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -760,6 +760,13 @@
 for ui_ in uis:
 ui_.setconfig('ui', 'interactive', 'off', '-y')
 
+# setup color handling
+coloropt = options['color']
+for ui_ in uis:
+if coloropt:
+ui_.setconfig('ui', 'color', coloropt, '--color')
+color.setup(ui_)
+
 if util.parsebool(options['pager']):
 ui.pager('internal-always-' + cmd)
 elif options['pager'] != 'auto':
@@ -769,13 +776,6 @@
 for ui_ in uis:
 ui_.insecureconnections = True
 
-# setup color handling
-coloropt = options['color']
-for ui_ in uis:
-if coloropt:
-ui_.setconfig('ui', 'color', coloropt, '--color')
-color.setup(ui_)
-
 if options['version']:
 return commands.version_(ui)
 if options['help']:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3] [RFC] color: allow color and pager to work on Windows with 'color.mode=auto'

2017-03-19 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489985292 14400
#  Mon Mar 20 00:48:12 2017 -0400
# Node ID 6e72bb689e57c985b138c580acb4cad8053dc180
# Parent  a32b379ffe151b8b094dcd67ef5b6bd551203dbe
[RFC] color: allow color and pager to work on Windows with 'color.mode=auto'

It took me awhile to figure out that '--config color.mode=ansi' would allow the
MSYS pager to print color, even though the default config colors fine if the
pager is disabled.  This is a hacky attempt to improve 'auto'.  The only thing
that I can't figure out is why 'pager=no' causes the output to print a green
background.  It seems that the lack of the on-the-fly update causes this.
Hopefully someone with more knowledge of color and pager knows, and/or can point
out a better way.

Previously, 'color.mode=auto' would color by setting console attributes, and
then print the text.  This doesn't help the pager at all.  This will print with
the ANSI color codes if a pager has been spawned, falling back to the previous
method otherwise.

Each of the built in `more` (more.com), python pager [1], and `less` from
GnuWin32 print the raw ANSI color codes to the screen instead of colorizing.
(The latter basically prints a blank screen if given '-R'.)  The `less` that
comes with MSYS on the other hand, will print color with or without '-R'.  I
expect that `more` and MSYS will be the most popular pagers, so this gives a
better experience for them out of the box.  If one of the more obscure pagers
are used, setting color.pagermode will disable color for paged output.

(As an aside, the fact that 'color.pagermode' is only consulted if the pager has
been spawned [2] gave me the impression that color.setup() could be called
multiple times, given that color is setup so early.  But it actually is
triggered when --pager=yes is given.  The fact that this setting only works if
paging is forced with --pager seems... surprising.)

The _effects map is no longer updated directly because some values were getting
overwritten with Win32 values on the first call to color.setup(), which
prevented the color codes from being output when changing the ANSI when the
pager is spawned.

[1] https://pypi.python.org/pypi/pager
[2] 
https://www.mercurial-scm.org/repo/hg/file/da7d19324b1e/mercurial/color.py#l205

diff --git a/mercurial/color.py b/mercurial/color.py
--- a/mercurial/color.py
+++ b/mercurial/color.py
@@ -72,6 +72,8 @@
 'white_background': 47,
 }
 
+_activeeffects = _effects.copy()
+
 _defaultstyles = {
 'grep.match': 'red bold',
 'grep.linenumber': 'green',
@@ -231,12 +233,14 @@
 if mode == realmode and ui.formatted():
 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
 
+_activeeffects = _effects.copy()
+
 if realmode == 'win32':
 ui._terminfoparams.clear()
 if not w32effects:
 modewarn()
 return None
-_effects.update(w32effects)
+_activeeffects.update(w32effects)
 elif realmode == 'ansi':
 ui._terminfoparams.clear()
 elif realmode == 'terminfo':
@@ -271,7 +275,7 @@
 
 def valideffect(ui, effect):
 'Determine if the effect is valid or not.'
-return ((not ui._terminfoparams and effect in _effects)
+return ((not ui._terminfoparams and effect in _activeeffects)
  or (effect in ui._terminfoparams
  or effect[:-11] in ui._terminfoparams))
 
@@ -305,9 +309,9 @@
 for effect in ['none'] + effects.split())
 stop = _effect_str(ui, 'none')
 else:
-start = [str(_effects[e]) for e in ['none'] + effects.split()]
+start = [str(_activeeffects[e]) for e in ['none'] + effects.split()]
 start = '\033[' + ';'.join(start) + 'm'
-stop = '\033[' + str(_effects['none']) + 'm'
+stop = '\033[' + str(_activeeffects['none']) + 'm'
 return ''.join([start, text, stop])
 
 def colorlabel(ui, msg, label):
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -854,6 +854,12 @@
 # auto-detection of things being formatted.
 self.setconfig('ui', 'formatted', self.formatted(), 'pager')
 self.setconfig('ui', 'interactive', False, 'pager')
+
+if self._colormode == 'win32' and not pagercmd.startswith('more.com'):
+if not self.hasconfig('color', 'pagermode'):
+self.setconfig('color', 'pagermode', 'ansi', source='pager')
+color.setup(self)
+
 if util.safehasattr(signal, "SIGPIPE"):
 signal.signal(signal.SIGPIPE, _catchterm)
 self._runpager(pagercmd)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 3] pager: fix the invocation of `more` on Windows

2017-03-21 Thread Matt Harbison

On Tue, 21 Mar 2017 17:40:58 -0400, Jun Wu  wrote:


Excerpts from Augie Fackler's message of 2017-03-21 17:34:39 -0400:

On Mon, Mar 20, 2017 at 12:53:17AM -0400, Matt Harbison wrote:
> pager: fix the invocation of `more` on Windows

I've taken this one. And I'm sad.

(Thanks! I blame windows for the sadness, not you.)


This does not look like a complete fix. Users setting  
"pager.pager=more", or

"pager.pager=somethingelse" will still have issues.


You're correct about the former, but I don't understand the latter.  It  
seems like *.com is the issue (I'm guessing cmd.exe handles it special,  
based on $PATHEXT).  I tried with pager.pager=notepad, and  
pager.pager=C:\Progra~2\GnuWin32\bin\less, and it had no problem invoking  
either *.exe without the extension.



A better fix seems to be disable shell=False for Windows.


I dunno.  If shell=True, you get a cryptic error and nothing else with a  
bad pager.  If shell=False, a bad pager is simply disabled with a warning,  
and normal output.  That seems more friendly.


Since I think we are in agreement that there will be a special case here  
in _some_ form, what I should have done is to translate more -> more.com  
*after* getting the config on Windows, instead of setting the default  
value.  I doubt there are any other *.com pagers, and I don't think anyone  
is trying to page through a *.bat file or anything like that.  (And if  
they want to do something crazy with these odd "executables",  
pager.pager="cmd.exe /c more" worked for me, so I assume it works for  
*.bat, etc.)  IDK how many Windows users would even bother to configure  
`more`, but we should be able to make it work.


I'll send V2 tomorrow, if there aren't any other comments before then.


>
> After 9335dc6b2a9c, invoking `more` no longer works.  Instead, a  
warning is

> printed and the pager is disabled.  Invoking `more.com` works.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 3] [RFC] dispatch: setup color before pager

2017-03-21 Thread Matt Harbison

(+CC: indygreg, since he added this functionality in 4e02418b4236)

On Tue, 21 Mar 2017 17:36:29 -0400, Augie Fackler  wrote:


On Mon, Mar 20, 2017 at 12:53:19AM -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1489985511 14400
#  Mon Mar 20 00:51:51 2017 -0400
# Node ID 2a323109f8e7ec5548dd506c2cff05f27fa20c1e
# Parent  6e72bb689e57c985b138c580acb4cad8053dc180
[RFC] dispatch: setup color before pager


Oy, these two I just dunno. I'll defer to other Windows experts.


Heh. You have no idea how sad my Sunday was :-/

Just to be clear, these last two can't be taken as-is.  The output on  
Windows without a pager is black text on a green background.


I did a little more playing, and if we don't do something, this will be a  
regression.  In 4.1, both of these commands colorize in MSYS:


[extensions]
color =

[pager]
pager = less

$ hg log -l 5 --config extensions.pager= --config color.pagermode=ansi

$ hg log -l 5 --config color.pagermode=ansi


Now, neither of them do (both are now paged).  You have to set  
'--pager=no' to get the color back, or add '--config color.mode=ansi'.   
But the latter breaks the output when disabling pager.  And even if that  
magically worked, that doesn't help with switching between MSYS and  
cmd.exe, which is why I'd love to make 'auto' smarter.  (I'd rather not  
resort to %include hacks).


IIRC, the inter-operation between these two extensions was why the ability  
to register an afterload callback was added.  I'll keep looking at this,  
but I suspect we need a color+pager expert more than a Windows expert.




With the previous order, color was None for commands invoked with  
--pager=yes at
the time the pager was spawned, which meant the switch over to ANSI  
mode on
Windows didn't occur.  That left the color.win32print() in 'auto' mode,  
which
meant no color in the pager output.  Non Windows platforms are capable  
of

printing color with this option.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -760,6 +760,13 @@
 for ui_ in uis:
 ui_.setconfig('ui', 'interactive', 'off', '-y')

+# setup color handling
+coloropt = options['color']
+for ui_ in uis:
+if coloropt:
+ui_.setconfig('ui', 'color', coloropt, '--color')
+color.setup(ui_)
+
 if util.parsebool(options['pager']):
 ui.pager('internal-always-' + cmd)
 elif options['pager'] != 'auto':
@@ -769,13 +776,6 @@
 for ui_ in uis:
 ui_.insecureconnections = True

-# setup color handling
-coloropt = options['color']
-for ui_ in uis:
-if coloropt:
-ui_.setconfig('ui', 'color', coloropt, '--color')
-color.setup(ui_)
-
 if options['version']:
 return commands.version_(ui)
 if options['help']:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V2] pager: fix the invocation of `more` on Windows

2017-03-21 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489983573 14400
#  Mon Mar 20 00:19:33 2017 -0400
# Node ID 8c2e2e2b2432bfa637ee569de11afcbc02b715b7
# Parent  d0b9e9803caff5f87020688c49ac6cdf017039d7
pager: fix the invocation of `more` on Windows

After 9335dc6b2a9c, with 'shell' being (mostly) set to False, invoking `more` no
longer worked.  Instead, a warning was printed and the pager was disabled.
Invoking `more.com` works.  Since a user may have configured 'pager.pager=more',
do this substitution at the end.  Surprisingly, `more` does allow for arguments,
so those are preserved.  This also allows `more` to work in MSYS.

Setting 'shell=False' runs the executable via CreateProcess(), which has rather
wonky rules for resolving an executable without an extension [1].  Resolving to
*.com is not among them.  Since 'shell=True' yields a cryptic error for a bad
$PAGER, and a *.exe program will work without specifying the extension, sticking
with current 'shell=False' seems like the right thing to do.  I don't think
there are any other *.com pagers out there, so this one special case seems OK.

If somebody wants to do something crazy that requires cmd.exe, I was able to get
normal paged output with 'pager.pager="cmd.exe /c more"'.  I assume you can
replace `more` with *.bat, *.vbs or various other creatures listed in $PATHEXT.

[1] 
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -844,6 +844,13 @@
 if not pagercmd:
 return
 
+if pycompat.osname == 'nt':
+# `more` cannot be invoked with shell=False, but `more.com` can.
+# Hide this implementation detail from the user, so we can also get
+# sane bad PAGER behavior.
+if pagercmd == 'more' or pagercmd.startswith('more '):
+pagercmd = 'more.com' + pagercmd[4:]
+
 self.debug('starting pager for command %r\n' % command)
 self.flush()
 self.pageractive = True
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH evolve-ext] tests: add glob for Windows

2017-03-23 Thread Matt Harbison

> On Mar 23, 2017, at 3:13 AM, Pierre-Yves David 
>  wrote:
> 
> 
> 
>> On 03/21/2017 06:48 PM, Ryan McElroy wrote:
>>> On 3/17/17 3:32 AM, Matt Harbison wrote:
>>> # HG changeset patch
>>> # User Matt Harbison 
>>> # Date 1489720627 14400
>>> #  Thu Mar 16 23:17:07 2017 -0400
>>> # Node ID ab5c2bef148bfb60e1956a55de4b7ba00ebe1817
>>> # Parent  6a3248558b6929378450b572bb27406afe703ffd
>>> tests: add glob for Windows
>> 
>> This looks good to me.
> 
> This one is pushed, thanks.
> 
> Does this mean someone is actually running the evolve test on windows ?

This is the first time I've run them in awhile.  There's still something broke 
around pruning bookmarks.  I was able to make it work a few years ago by 
calling invalidate(), but that seemed like a sledgehammer.  I'll post more 
detail next time I have the repo in front of me.

> -- 
> Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V3] pager: fix the invocation of `more` on Windows

2017-03-23 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1489983573 14400
#  Mon Mar 20 00:19:33 2017 -0400
# Node ID d0c2db2d9f13dca534c598de050eb1919ef79059
# Parent  df82f375fa005b9c71b463182e6b54aa47fa5999
pager: fix the invocation of `more` on Windows

After 9335dc6b2a9c, with 'shell' being (mostly) set to False, invoking `more` no
longer worked.  Instead, a warning was printed and the pager was disabled.
Invoking `more.com` works.  Since a user may have configured 'pager.pager=more',
do this substitution at the end.  Surprisingly, `more` does allow for arguments,
so those are preserved.  This also allows `more` to work in MSYS.

Setting 'shell=False' runs the executable via CreateProcess(), which has rather
wonky rules for resolving an executable without an extension [1].  Resolving to
*.com is not among them.  Since 'shell=True' yields a cryptic error for a bad
$PAGER, and a *.exe program will work without specifying the extension, sticking
with current 'shell=False' seems like the right thing to do.  I don't think
there are any other *.com pagers out there, so this one special case seems OK.

If somebody wants to do something crazy that requires cmd.exe, I was able to get
normal paged output with 'pager.pager="cmd.exe /c more"'.  I assume you can
replace `more` with *.bat, *.vbs or various other creatures listed in $PATHEXT.

[1] 
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -844,6 +844,15 @@
 if not pagercmd:
 return
 
+if pycompat.osname == 'nt':
+# `more` cannot be invoked with shell=False, but `more.com` can.
+# Hide this implementation detail from the user, so we can also get
+# sane bad PAGER behavior.  If args are also given, the space in 
the
+# command line forces shell=True, so that case doesn't need to be
+# handled here.
+if pagercmd == 'more':
+pagercmd = 'more.com'
+
 self.debug('starting pager for command %r\n' % command)
 self.flush()
 self.pageractive = True
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 3] [RFC] dispatch: setup color before pager

2017-03-23 Thread Matt Harbison
On Tue, 21 Mar 2017 23:10:36 -0400, Gregory Szorc  
 wrote:



On Tue, Mar 21, 2017 at 6:11 PM, Matt Harbison 
wrote:


(+CC: indygreg, since he added this functionality in 4e02418b4236)

On Tue, 21 Mar 2017 17:36:29 -0400, Augie Fackler   
wrote:


On Mon, Mar 20, 2017 at 12:53:19AM -0400, Matt Harbison wrote:



# HG changeset patch
# User Matt Harbison 
# Date 1489985511 14400
#  Mon Mar 20 00:51:51 2017 -0400
# Node ID 2a323109f8e7ec5548dd506c2cff05f27fa20c1e
# Parent  6e72bb689e57c985b138c580acb4cad8053dc180
[RFC] dispatch: setup color before pager



Oy, these two I just dunno. I'll defer to other Windows experts.



Heh. You have no idea how sad my Sunday was :-/

Just to be clear, these last two can't be taken as-is.  The output on
Windows without a pager is black text on a green background.

I did a little more playing, and if we don't do something, this will be  
a

regression.  In 4.1, both of these commands colorize in MSYS:

[extensions]
color =

[pager]
pager = less

$ hg log -l 5 --config extensions.pager= --config color.pagermode=ansi

$ hg log -l 5 --config color.pagermode=ansi


Now, neither of them do (both are now paged).  You have to set
'--pager=no' to get the color back, or add '--config color.mode=ansi'.   
But

the latter breaks the output when disabling pager.  And even if that
magically worked, that doesn't help with switching between MSYS and
cmd.exe, which is why I'd love to make 'auto' smarter.  (I'd rather not
resort to %include hacks).



So the whole reason behind 4e02418b4236 (as documented in the commit
message) is that different pagers support different escape sequences. At
the time, I couldn't figure out an elegant way to detect the pager's
capabilities at run time. So, I added a config option that could be  
defined

in certain environments (like a controlled msys environment where `less`
was installed as the pager such as the one that Mozilla uses to build
Firefox) so that pager+color would "just work" in both cmd.exe and an  
msys

environment. More info at
https://bugzilla.mozilla.org/show_bug.cgi?id=545432#c59 and below (search
for my name).

Core Mercurial should focus on behavior in a stock cmd.exe environment  
and

be best-effort - but not broken - for cygwin, msys, etc. This is what
a7d98606 aimed to achieve. If someone is running a non-cmd.exe
terminal, I think it is up to the packager to enable a reasonable default
(such as Mozilla setting color.pagermode in our MozillaBuild msys
environment).


That seems reasonable.  But color.pagermode seems broken for auto pager,  
now that everything has transitioned to the core.  It works on stable (if  
the color/pager load order is right).


4.1:

1) Color wrapped dispatch._runcommand() and pager wrapped color's wrapper.
2) Running a command will:
   a) Call the pager wrapper, set ui.pageractive, and spawn the pager if
  True
   b) Call the color wrapper, and examine ui.pageractive to see if it cares
  about color.pagermode
   c) Call the actual command

Default branch:

1) Pager settings are forced on or off in dispatch.  '--pager=on' fires up
   a pager; 'auto' pager mode defers spawning a pager.
2) Color is setup (examining ui.pageractive), and color.mode=auto is
   resolved
3) Run the command
   a) spawn a pager the pager, setting ui.pageractive=True

I think this means that the process of spawning the pager needs to be able  
to call color.setup() again, so that it can reexamine ui.pageractive.   
Otherwise, the only way 'ui.pageractive' is ever true when color is  
getting setup is if --pager != 'auto|off'.  IDK the implications of a  
second setup, and I'm perplexed by all of the various ui objects that  
exist.  I didn't check yet to see if there's any possibility to output  
before the calls to ui.pager() now.  (I wonder if there are instances in  
largefiles with all of its overrides.)


Thoughts?

Also, if you want a new challenge, the Windows console apparently  
supports

24-bit color (
https://blogs.msdn.microsoft.com/commandline/2016/09/22/24-bit-color-in-the-windows-console/)
and ANSI+VT-100 escape sequences now.
https://github.com/symfony/symfony/pull/18385 and
https://github.com/Microsoft/BashOnWindows/issues/1173 are somewhat
informative. We could likely detect the Windows version and active  
terminal

to call SetConsoleMode with ENABLE_VIRTUAL_TERMINAL_PROCESSING. Then
pager.color=ansi should "just work" on Windows.


Thanks for the tip- I forgot about this.  I'm not on Windows 10, so it  
isn't a high priority for me, but I'll look into it if I can find some  
spare time.




IIRC, the inter-operation between these two extensions was why the  
ability

to register an afterload callback was added.  I'll keep looking at this,
but I suspect we need a color+pager expert more than a Windows expert.



I think that 

Re: [PATCH V3] pager: fix the invocation of `more` on Windows

2017-03-24 Thread Matt Harbison

On Fri, 24 Mar 2017 10:17:46 -0400, Yuya Nishihara  wrote:


On Thu, 23 Mar 2017 21:57:50 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1489983573 14400
#  Mon Mar 20 00:19:33 2017 -0400
# Node ID d0c2db2d9f13dca534c598de050eb1919ef79059
# Parent  df82f375fa005b9c71b463182e6b54aa47fa5999
pager: fix the invocation of `more` on Windows



diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -844,6 +844,15 @@
 if not pagercmd:
 return

+if pycompat.osname == 'nt':
+# `more` cannot be invoked with shell=False, but  
`more.com` can.
+# Hide this implementation detail from the user, so we can  
also get
+# sane bad PAGER behavior.  If args are also given, the  
space in the
+# command line forces shell=True, so that case doesn't  
need to be

+# handled here.
+if pagercmd == 'more':
+pagercmd = 'more.com'


Given MSYS nor MSYS2 doesn't provide more.exe by default, this seems  
fine.
Can we document this hack in help just in case someone installed  
more.exe?


I know this is an edge case, but instead of documenting how a user can't  
just say 'more' and spawn 'more.exe', what do you think about calling  
util.findexe() if pagercmd == 'more'?  That finds 'more.com' too, so  
things should just work as if they were in cmd.exe.


___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] pager: improve support for various flavors of `more` on Windows

2017-03-24 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490409608 14400
#  Fri Mar 24 22:40:08 2017 -0400
# Node ID 6ee410f4af75125e9984c42100285ee70501655c
# Parent  62728577ba63efee83460a09ef311b330a5fea13
pager: improve support for various flavors of `more` on Windows

Hardcoding 'more' -> 'more.com' means that 'more.exe' from MSYS would need to be
configured with its *.exe extension.  This will resolve to either one, as
cmd.exe would have done if the command ran through the shell.

Something that's maybe problematic with this is it comes after 'pageractive' and
various ui configs have been set by the calling method.  But the other early
exits in this method don't undo those changes either.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -844,15 +844,6 @@
 if not pagercmd:
 return
 
-if pycompat.osname == 'nt':
-# `more` cannot be invoked with shell=False, but `more.com` can.
-# Hide this implementation detail from the user, so we can also get
-# sane bad PAGER behavior.  If args are also given, the space in 
the
-# command line forces shell=True, so that case doesn't need to be
-# handled here.
-if pagercmd == 'more':
-pagercmd = 'more.com'
-
 self.debug('starting pager for command %r\n' % command)
 self.flush()
 self.pageractive = True
@@ -879,6 +870,21 @@
 # simple pager command configurations, we can degrade
 # gracefully and tell the user about their broken pager.
 shell = any(c in command for c in "|&;<>()$`\\\"' \t\n*?[#~=%")
+
+if pycompat.osname == 'nt' and not shell:
+# Window's built-in `more` cannot be invoked with shell=False, but
+# its `more.com` can.  Hide this implementation detail from the
+# user so we can also get sane bad PAGER behavior.  MSYS has
+# `more.exe`, so do a cmd.exe style resolution of the executable to
+# determine which one to use.
+fullcmd = util.findexe(command)
+if not fullcmd:
+self.warn(_("missing pager command '%s', skipping pager\n")
+  % command)
+return
+
+command = fullcmd
+
 try:
 pager = subprocess.Popen(
 command, shell=shell, bufsize=-1,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] repair: use context manager for lock management

2017-03-24 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490327243 14400
#  Thu Mar 23 23:47:23 2017 -0400
# Node ID c053dc8a24afad24872397e5cd3f57411fc7d172
# Parent  d0c2db2d9f13dca534c598de050eb1919ef79059
repair: use context manager for lock management

If repo.lock() raised inside of the try block, 'tr' would have been None in the
finally block where it tries to release().  Modernize the syntax instead of just
winching the lock out of the try block.

I found several other instances of acquiring the lock inside of the 'try', but
those finally blocks handle None references.  I also started switching some
trivial try/finally blocks to context managers, but didn't get them all because
indenting over 3x for lock, wlock and transaction would have spilled over 80
characters.  That got me wondering if there should be a repo.rwlock(), to handle
locking and unlocking in the proper order.

It also looks like py27 supports supports multiple context managers for a single
'with' statement.  Should I hold off on the rest until py26 is dropped?

diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -214,15 +214,10 @@
 
 for m in updatebm:
 bm[m] = repo[newbmtarget].node()
-lock = tr = None
-try:
-lock = repo.lock()
-tr = repo.transaction('repair')
-bm.recordchange(tr)
-tr.close()
-finally:
-tr.release()
-lock.release()
+
+with repo.lock():
+with repo.transaction('repair') as tr:
+bm.recordchange(tr)
 
 # remove undo files
 for undovfs, undofile in repo.undofiles():
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] color: fix grammar in help text

2017-03-25 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490462963 14400
#  Sat Mar 25 13:29:23 2017 -0400
# Node ID 22533c3af63d5a67d9210596eafd4b99ab9c7904
# Parent  c60091fa1426892552dd6c0dd4b9c49e3c3da045
color: fix grammar in help text

diff --git a/hgext/color.py b/hgext/color.py
--- a/hgext/color.py
+++ b/hgext/color.py
@@ -7,7 +7,7 @@
 
 '''enable Mercurial color mode (DEPRECATED)
 
-This extensions enable Mercurial color mode. The feature is now directly
+This extension enables Mercurial color mode. The feature is now directly
 available in Mercurial core. You can access it using::
 
   [ui]
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] ui: rerun color.setup() once the pager has spawned to honor 'color.pagermode'

2017-03-25 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490483831 14400
#  Sat Mar 25 19:17:11 2017 -0400
# Node ID 4713a38672f2d0790477b6c22180bd453f61851d
# Parent  84bda5db69dbe3d550f45ccd6d6eda2aad760ee4
ui: rerun color.setup() once the pager has spawned to honor 'color.pagermode'

Otherwise, ui.pageractive is False when color is setup in dispatch.py (without
--pager=on), and this config option is ignored.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -861,6 +861,12 @@
 # auto-detection of things being formatted.
 self.setconfig('ui', 'formatted', wasformatted, 'pager')
 self.setconfig('ui', 'interactive', False, 'pager')
+
+# If pagermode differs from color.mode, reconfigure color now that
+# pageractive is set.
+cm = self._colormode
+if cm != self.config('color', 'pagermode', cm):
+color.setup(self)
 else:
 # If the pager can't be spawned in dispatch when --pager=on is
 # given, don't try again when the command runs, to avoid a 
duplicate
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] color: stop mutating the default effects map

2017-03-25 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490464217 14400
#  Sat Mar 25 13:50:17 2017 -0400
# Node ID a263702b064a5a3ce1ca74b227e8e624e4b05874
# Parent  22533c3af63d5a67d9210596eafd4b99ab9c7904
color: stop mutating the default effects map

A future change will make color.setup() callable a second time when the pager is
spawned, in order to honor the 'color.pagermode' setting.  The problem was that
when 'color.mode=auto' was resolved to 'win32' in the first pass, the default
ANSI effects were overwritten, making it impossible to honor 'pagermode=ansi'.
Also, the two separate maps didn't have the same keys.  The symmetric difference
is 'dim' and 'italic' (from ANSI), and 'bold_background' (from win32).  Thus,
the update left entries that didn't belong for the current mode.

As an added bonus, this now correctly enables color with MSYS `less` for a
command like this, where pager is forced on:

$ hg log --config color.pagermode=ansi --pager=yes

Previously, the output was corrupted.  The raw output, as seen through the ANSI
blind `more.com` was:

<-[-1;6mchangeset:   34840:50bcb95d40f5<-[-1m
...

which MSYS `less -FRX` rendered as:

1;6mchangeset:   34840:50bcb95d40f51m
...

(The two '<-' instances were actually an arrow character that TortoiseHg warned
couldn't be encoded, and notepad++ translated to a single '?'.)

diff --git a/mercurial/color.py b/mercurial/color.py
--- a/mercurial/color.py
+++ b/mercurial/color.py
@@ -233,12 +233,14 @@
 if mode == realmode and ui.formatted():
 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
 
+ui._coloreffects = _effects.copy()
+
 if realmode == 'win32':
 ui._terminfoparams.clear()
 if not w32effects:
 modewarn()
 return None
-_effects.update(w32effects)
+ui._coloreffects = w32effects.copy()
 elif realmode == 'ansi':
 ui._terminfoparams.clear()
 elif realmode == 'terminfo':
@@ -273,7 +275,7 @@
 
 def valideffect(ui, effect):
 'Determine if the effect is valid or not.'
-return ((not ui._terminfoparams and effect in _effects)
+return ((not ui._terminfoparams and effect in ui._coloreffects)
  or (effect in ui._terminfoparams
  or effect[:-11] in ui._terminfoparams))
 
@@ -324,9 +326,9 @@
 for effect in ['none'] + effects.split())
 stop = _effect_str(ui, 'none')
 else:
-start = [str(_effects[e]) for e in ['none'] + effects.split()]
+start = [str(ui._coloreffects[e]) for e in ['none'] + effects.split()]
 start = '\033[' + ';'.join(start) + 'm'
-stop = '\033[' + str(_effects['none']) + 'm'
+stop = '\033[' + str(ui._coloreffects['none']) + 'm'
 return _mergeeffects(text, start, stop)
 
 _ansieffectre = re.compile(br'\x1b\[[0-9;]*m')
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -157,6 +157,7 @@
 # Blocked time
 self.logblockedtimes = False
 # color mode: see mercurial/color.py for possible value
+self._coloreffects = {}
 self._colormode = None
 self._terminfoparams = {}
 self._styles = {}
@@ -176,6 +177,7 @@
 self.environ = src.environ
 self.callhooks = src.callhooks
 self.insecureconnections = src.insecureconnections
+self._coloreffects = src._coloreffects.copy()
 self._colormode = src._colormode
 self._terminfoparams = src._terminfoparams.copy()
 self._styles = src._styles.copy()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4] ui: defer setting pager related properties until the pager has spawned

2017-03-25 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490490720 14400
#  Sat Mar 25 21:12:00 2017 -0400
# Node ID 84bda5db69dbe3d550f45ccd6d6eda2aad760ee4
# Parent  a263702b064a5a3ce1ca74b227e8e624e4b05874
ui: defer setting pager related properties until the pager has spawned

When --pager=on is given, dispatch.py spawns a pager before setting up color.
If the pager failed to launch, ui.pageractive was left set to True, so color
configured itself based on 'color.pagermode'.  A typical MSYS setting would be
'color.mode=auto, color.pagermode=ansi'.  In the failure case, this would print
a warning, disable the pager, and then print the raw ANSI codes to the terminal.

Care needs to be taken, because it appears that leaving ui.pageractive=True was
the only thing that prevented an attempt at running the pager again from inside
the command.  This results in a double warning message, so pager is simply
disabled on failure.

I don't understand what chg is doing with pager, or how it signals a failure to
spawn the pager.  But this is no worse that the previous behavior.  The ui
config settings didn't need to be moved to fix this, but it seemed like the
right thing to do for consistency.

diff --git a/mercurial/chgserver.py b/mercurial/chgserver.py
--- a/mercurial/chgserver.py
+++ b/mercurial/chgserver.py
@@ -193,6 +193,7 @@
 def _runpager(self, cmd):
 self._csystem(cmd, util.shellenviron(), type='pager',
   cmdtable={'attachio': attachio})
+return True
 
 return chgui(srcui)
 
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -850,15 +850,22 @@
 
 self.debug('starting pager for command %r\n' % command)
 self.flush()
-self.pageractive = True
-# Preserve the formatted-ness of the UI. This is important
-# because we mess with stdout, which might confuse
-# auto-detection of things being formatted.
-self.setconfig('ui', 'formatted', self.formatted(), 'pager')
-self.setconfig('ui', 'interactive', False, 'pager')
+
+wasformatted = self.formatted()
 if util.safehasattr(signal, "SIGPIPE"):
 signal.signal(signal.SIGPIPE, _catchterm)
-self._runpager(pagercmd)
+if self._runpager(pagercmd):
+self.pageractive = True
+# Preserve the formatted-ness of the UI. This is important
+# because we mess with stdout, which might confuse
+# auto-detection of things being formatted.
+self.setconfig('ui', 'formatted', wasformatted, 'pager')
+self.setconfig('ui', 'interactive', False, 'pager')
+else:
+# If the pager can't be spawned in dispatch when --pager=on is
+# given, don't try again when the command runs, to avoid a 
duplicate
+# warning about a missing pager command.
+self.disablepager()
 
 def _runpager(self, command):
 """Actually start the pager and set up file descriptors.
@@ -868,7 +875,7 @@
 """
 if command == 'cat':
 # Save ourselves some work.
-return
+return False
 # If the command doesn't contain any of these characters, we
 # assume it's a binary and exec it directly. This means for
 # simple pager command configurations, we can degrade
@@ -898,7 +905,7 @@
 if e.errno == errno.ENOENT and not shell:
 self.warn(_("missing pager command '%s', skipping pager\n")
   % command)
-return
+return False
 raise
 
 # back up original file descriptors
@@ -919,6 +926,8 @@
 pager.stdin.close()
 pager.wait()
 
+return True
+
 def interface(self, feature):
 """what interface to use for interactive console features?
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 4] color: stop mutating the default effects map

2017-03-26 Thread Matt Harbison

On Sun, 26 Mar 2017 10:35:34 -0400, Yuya Nishihara  wrote:


On Sun, 26 Mar 2017 00:41:05 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1490464217 14400
#  Sat Mar 25 13:50:17 2017 -0400
# Node ID a263702b064a5a3ce1ca74b227e8e624e4b05874
# Parent  22533c3af63d5a67d9210596eafd4b99ab9c7904
color: stop mutating the default effects map


I re-read the code, and noticed that both _effects and w32effects are  
mostly

constants. Perhaps we can simply switch them by ui._colormode.

  if ui._colormode == 'win32':
  activeeffects = w32neffects
  else:
  activeeffects = _effects
  ... embed escape sequences by using activeeffects ...


Will we get into trouble with each ui instance having a _colormode, but  
the activeeffects map effectively being global?  I don't fully understand  
the purpose of all the separate ui objects.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 4] ui: rerun color.setup() once the pager has spawned to honor 'color.pagermode'

2017-03-26 Thread Matt Harbison

On Sun, 26 Mar 2017 10:44:01 -0400, Yuya Nishihara  wrote:


On Sun, 26 Mar 2017 00:41:07 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1490483831 14400
#  Sat Mar 25 19:17:11 2017 -0400
# Node ID 4713a38672f2d0790477b6c22180bd453f61851d
# Parent  84bda5db69dbe3d550f45ccd6d6eda2aad760ee4
ui: rerun color.setup() once the pager has spawned to honor  
'color.pagermode'


Otherwise, ui.pageractive is False when color is setup in dispatch.py  
(without

--pager=on), and this config option is ignored.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -861,6 +861,12 @@
 # auto-detection of things being formatted.
 self.setconfig('ui', 'formatted', wasformatted, 'pager')
 self.setconfig('ui', 'interactive', False, 'pager')
+
+# If pagermode differs from color.mode, reconfigure color  
now that

+# pageractive is set.
+cm = self._colormode
+if cm != self.config('color', 'pagermode', cm):
+color.setup(self)


This also looks good. Maybe we can refactor color._modesetup() further  
so that

we can do something like

  newmode = color.mode(self)
  if self._colormode != newmode:
  color.setup(self, newmode)


Is a follow up OK?  There are some warnings being printed in _modesetup()  
that I don't think we want firing more than once, so it may not be a  
trivial refactoring.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] repair: use context manager for lock management

2017-03-26 Thread Matt Harbison
On Sun, 26 Mar 2017 13:34:10 -0400, Gregory Szorc  
 wrote:



On Sun, Mar 26, 2017 at 4:20 AM, Yuya Nishihara  wrote:


On Fri, 24 Mar 2017 23:34:28 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison 
> # Date 1490327243 14400
> #  Thu Mar 23 23:47:23 2017 -0400
> # Node ID c053dc8a24afad24872397e5cd3f57411fc7d172
> # Parent  d0c2db2d9f13dca534c598de050eb1919ef79059
> repair: use context manager for lock management

Sure. Queued this, thanks.

> I found several other instances of acquiring the lock inside of the
'try', but
> those finally blocks handle None references.  I also started switching
some
> trivial try/finally blocks to context managers, but didn't get them  
all

because
> indenting over 3x for lock, wlock and transaction would have spilled
over 80
> characters.  That got me wondering if there should be a repo.rwlock(),
to handle
> locking and unlocking in the proper order.

We have lockmod.release() helper. We also have util.ctxmanager(), but  
IMHO

it
doesn't improve code readability that much.

> It also looks like py27 supports supports multiple context managers  
for

a single
> 'with' statement.  Should I hold off on the rest until py26 is  
dropped?




I think there is room for a helper context manager (like repo.rwlock())
that obtains multiple locks and/or a transaction. This would cut down on  
a
lot of excessive indentation while simultaneously ensuring we're doing  
the

correct thing with regards to locking and transaction semantics.


The excessive indentation is why I raised the issue.  I went looking for  
how to use util.ctxmanager, and can't find a single usage instance in the  
entire history.  I went back to the ML, and it seems like mpm ruled out  
using it [1].  The referenced context manager series he mentioned taking  
80% of seems to be something else [2].


I'm not sure if we want to revisit that decision, and even if so, I'm not  
sure if we want to start using a crutch for py26 if we are close to  
dumping it.  I only got off on this tangent when I noticed the  
first-lock-inside-try construct while trying to figure out bookmark  
pruning test failures on Windows.  So I don't have a strong opinion either  
way.


[1]  
https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-January/078755.html
[2]  
https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-January/078262.html

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2 V3] serve: make the URL the same for `hg serve` and `hg serve -S`

2017-03-26 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1488146777 18000
#  Sun Feb 26 17:06:17 2017 -0500
# Node ID d584ca4bc33bd2ebeaf9a7bd86440b3cdcecc138
# Parent  0ff9bef3e0f67422cf29c200fa4a671d861d060b
serve: make the URL the same for `hg serve` and `hg serve -S`

It's perfectly workable to serve up the parent repo without the -S for push and
pull, as long as there are no subrepo changes in play.  Therefore, having a
different URL for the main repo based on the presence of this option seems like
it would get annoying.

diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -335,7 +335,7 @@
 req.url = req.env['SCRIPT_NAME']
 if not req.url.endswith('/'):
 req.url += '/'
-if 'REPO_NAME' in req.env:
+if req.env.get('REPO_NAME'):
 req.url += req.env['REPO_NAME'] + '/'
 
 if 'PATH_INFO' in req.env:
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -257,7 +257,7 @@
 
 repos = dict(self.repos)
 
-if not virtual or (virtual == 'index' and virtual not in repos):
+if (not virtual or virtual == 'index') and virtual not in repos:
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl)
 
@@ -269,8 +269,15 @@
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl, subdir)
 
-virtualrepo = virtual
-while virtualrepo:
+def _virtualdirs():
+yield virtual
+
+for p in util.finddirs(virtual):
+yield p
+
+yield ''
+
+for virtualrepo in _virtualdirs():
 real = repos.get(virtualrepo)
 if real:
 req.env['REPO_NAME'] = virtualrepo
@@ -284,11 +291,6 @@
 except error.RepoError as inst:
 raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
 
-up = virtualrepo.rfind('/')
-if up < 0:
-break
-virtualrepo = virtualrepo[:up]
-
 # browse subdirectories
 subdir = virtual + '/'
 if [r for r in repos if r.startswith(subdir)]:
diff --git a/mercurial/server.py b/mercurial/server.py
--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -147,8 +147,7 @@
 # message as long as webconf is None.
 if repo:
 webconf = dict()
-cmdutil.addwebdirpath(repo, repo.wvfs.basename(repo.root) + '/',
-  webconf)
+cmdutil.addwebdirpath(repo, "", webconf)
 else:
 servui = ui
 
diff --git a/tests/test-subrepo-deep-nested-change.t 
b/tests/test-subrepo-deep-nested-change.t
--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -75,29 +75,29 @@
 
 #if serve
   $ hg serve -R main --debug -S -p $HGPORT -d --pid-file=hg1.pid -E error.log 
-A access.log
-  adding main/ = $TESTTMP/main (glob)
-  adding sub1/ = $TESTTMP/main/sub1 (glob)
-  adding sub2/ = $TESTTMP/main/sub1/sub2 (glob)
+  adding  = $TESTTMP/main (glob)
+  adding ../sub1/ = $TESTTMP/main/sub1 (glob)
+  adding ../sub2/ = $TESTTMP/main/sub1/sub2 (glob)
   listening at http://*:$HGPORT/ (bound to *:$HGPORT) (glob)
-  adding main/ = $TESTTMP/main (glob)
-  adding sub1/ = $TESTTMP/main/sub1 (glob)
-  adding sub2/ = $TESTTMP/main/sub1/sub2 (glob)
+  adding  = $TESTTMP/main (glob)
+  adding ../sub1/ = $TESTTMP/main/sub1 (glob)
+  adding ../sub2/ = $TESTTMP/main/sub1/sub2 (glob)
   $ cat hg1.pid >> $DAEMON_PIDS
 
-  $ hg clone http://localhost:$HGPORT/main httpclone --config 
progress.disable=True
+  $ hg clone http://localhost:$HGPORT httpclone --config progress.disable=True
   requesting all changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 3 changes to 3 files
   updating to branch default
-  cloning subrepo sub1 from http://localhost:$HGPORT/sub1
+  cloning subrepo sub1 from http://localhost:$HGPORT/../sub1
   requesting all changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 3 changes to 3 files
-  cloning subrepo sub1/sub2 from http://localhost:$HGPORT/sub2 (glob)
+  cloning subrepo sub1/sub2 from http://localhost:$HGPORT/../sub2 (glob)
   requesting all changes
   adding changesets
   adding manifests
@@ -106,15 +106,15 @@
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ cat access.log
-  * "GET /main?cmd=capabilities HTTP/1.1" 200 - (glob)
-  * "GET /main?cmd=batch HTTP/1.

[PATCH 1 of 2 V3] serve: add support for Mercurial subrepositories

2017-03-26 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1488146743 18000
#  Sun Feb 26 17:05:43 2017 -0500
# Node ID 0ff9bef3e0f67422cf29c200fa4a671d861d060b
# Parent  c60091fa1426892552dd6c0dd4b9c49e3c3da045
serve: add support for Mercurial subrepositories

I've been using `hg serve --web-conf ...` with a simple '/=projects/**' [paths]
configuration for awhile without issue.  Let's ditch the need for the manual
configuration in this case, and limit the repos served to the actual subrepos.

This doesn't attempt to handle the case where a new subrepo appears while the
server is running.  That could probably be handled with a hook if somebody wants
it.  But it's such a rare case, it probably doesn't matter for the temporary
serves.

Unfortunately, the root of the webserver when serving multiple repos is the
implicit html index file.  This makes the URL different for `hg serve` vs
`hg serve -S`, because the top level repo then needs to be part of the path.
That will be fixed next.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2285,6 +2285,15 @@
 bad.extend(f for f in rejected if f in match.files())
 return bad
 
+def addwebdirpath(repo, serverpath, webconf):
+webconf[serverpath] = repo.root
+repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
+
+for r in repo.revs('filelog("path:.hgsub")'):
+ctx = repo[r]
+for subpath in ctx.substate:
+ctx.sub(subpath).addwebdirpath(serverpath, webconf)
+
 def forget(ui, repo, match, prefix, explicitonly):
 join = lambda f: os.path.join(prefix, f)
 bad = []
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4602,7 +4602,8 @@
 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
 ('', 'style', '', _('template style to use'), _('STYLE')),
 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
-('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
+('', 'certificate', '', _('SSL certificate file'), _('FILE'))]
+ + subrepoopts,
 _('[OPTION]...'),
 optionalrepo=True)
 def serve(ui, repo, **opts):
diff --git a/mercurial/help/subrepos.txt b/mercurial/help/subrepos.txt
--- a/mercurial/help/subrepos.txt
+++ b/mercurial/help/subrepos.txt
@@ -136,6 +136,11 @@
 subrepository changes are available when referenced by top-level
 repositories.  Push is a no-op for Subversion subrepositories.
 
+:serve: serve does not recurse into subrepositories unless
+-S/--subrepos is specified.  Git and Subversion subrepositories
+are currently silently ignored.  Mercurial subrepositories with a
+URL source are also silently ignored.
+
 :status: status does not recurse into subrepositories unless
 -S/--subrepos is specified. Subrepository changes are displayed as
 regular Mercurial changes on the subrepository
diff --git a/mercurial/server.py b/mercurial/server.py
--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -15,6 +15,7 @@
 
 from . import (
 chgserver,
+cmdutil,
 commandserver,
 error,
 hgweb,
@@ -130,11 +131,24 @@
 baseui = ui
 webconf = opts.get('web_conf') or opts.get('webdir_conf')
 if webconf:
+if opts.get('subrepos'):
+raise error.Abort(_('--web-conf cannot be used with --subrepos'))
+
 # load server settings (e.g. web.port) to "copied" ui, which allows
 # hgwebdir to reload webconf cleanly
 servui = ui.copy()
 servui.readconfig(webconf, sections=['web'])
 alluis.add(servui)
+elif opts.get('subrepos'):
+servui = ui.copy()
+alluis.add(servui)
+
+# If repo is None, hgweb.createapp() already raises a proper abort
+# message as long as webconf is None.
+if repo:
+webconf = dict()
+cmdutil.addwebdirpath(repo, repo.wvfs.basename(repo.root) + '/',
+  webconf)
 else:
 servui = ui
 
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -444,6 +444,15 @@
 self._ctx = ctx
 self._path = path
 
+def addwebdirpath(self, serverpath, webconf):
+"""Add the hgwebdir entries for this subrepo, and any of its subrepos.
+
+``serverpath`` is the path component of the URL for this repo.
+
+``webconf`` is the dictionary of hgwebdir entries.
+"""
+pass
+
 def storeclean(self, path):
 &qu

[PATCH 3 of 3 V2] ui: rerun color.setup() once the pager has spawned to honor 'color.pagermode'

2017-03-27 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490483831 14400
#  Sat Mar 25 19:17:11 2017 -0400
# Node ID 3fa40378c88e3b9149054de48b9b880d93653488
# Parent  1c73c5cde39463e03c3c7be10b6fe1256a6e5143
ui: rerun color.setup() once the pager has spawned to honor 'color.pagermode'

Otherwise, ui.pageractive is False when color is setup in dispatch.py (without
--pager=on), and this config option is ignored.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -859,6 +859,12 @@
 # auto-detection of things being formatted.
 self.setconfig('ui', 'formatted', wasformatted, 'pager')
 self.setconfig('ui', 'interactive', False, 'pager')
+
+# If pagermode differs from color.mode, reconfigure color now that
+# pageractive is set.
+cm = self._colormode
+if cm != self.config('color', 'pagermode', cm):
+color.setup(self)
 else:
 # If the pager can't be spawned in dispatch when --pager=on is
 # given, don't try again when the command runs, to avoid a 
duplicate
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3 V2] ui: defer setting pager related properties until the pager has spawned

2017-03-27 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490490720 14400
#  Sat Mar 25 21:12:00 2017 -0400
# Node ID 1c73c5cde39463e03c3c7be10b6fe1256a6e5143
# Parent  2566b7eac73c4851edc21b73a833f86bf878285e
ui: defer setting pager related properties until the pager has spawned

When --pager=on is given, dispatch.py spawns a pager before setting up color.
If the pager failed to launch, ui.pageractive was left set to True, so color
configured itself based on 'color.pagermode'.  A typical MSYS setting would be
'color.mode=auto, color.pagermode=ansi'.  In the failure case, this would print
a warning, disable the pager, and then print the raw ANSI codes to the terminal.

Care needs to be taken, because it appears that leaving ui.pageractive=True was
the only thing that prevented an attempt at running the pager again from inside
the command.  This results in a double warning message, so pager is simply
disabled on failure.

The ui config settings didn't need to be moved to fix this, but it seemed like
the right thing to do for consistency.

diff --git a/mercurial/chgserver.py b/mercurial/chgserver.py
--- a/mercurial/chgserver.py
+++ b/mercurial/chgserver.py
@@ -193,6 +193,7 @@
 def _runpager(self, cmd):
 self._csystem(cmd, util.shellenviron(), type='pager',
   cmdtable={'attachio': attachio})
+return True
 
 return chgui(srcui)
 
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -848,15 +848,22 @@
 
 self.debug('starting pager for command %r\n' % command)
 self.flush()
-self.pageractive = True
-# Preserve the formatted-ness of the UI. This is important
-# because we mess with stdout, which might confuse
-# auto-detection of things being formatted.
-self.setconfig('ui', 'formatted', self.formatted(), 'pager')
-self.setconfig('ui', 'interactive', False, 'pager')
+
+wasformatted = self.formatted()
 if util.safehasattr(signal, "SIGPIPE"):
 signal.signal(signal.SIGPIPE, _catchterm)
-self._runpager(pagercmd)
+if self._runpager(pagercmd):
+self.pageractive = True
+# Preserve the formatted-ness of the UI. This is important
+# because we mess with stdout, which might confuse
+# auto-detection of things being formatted.
+self.setconfig('ui', 'formatted', wasformatted, 'pager')
+self.setconfig('ui', 'interactive', False, 'pager')
+else:
+# If the pager can't be spawned in dispatch when --pager=on is
+# given, don't try again when the command runs, to avoid a 
duplicate
+# warning about a missing pager command.
+self.disablepager()
 
 def _runpager(self, command):
 """Actually start the pager and set up file descriptors.
@@ -866,7 +873,7 @@
 """
 if command == 'cat':
 # Save ourselves some work.
-return
+return False
 # If the command doesn't contain any of these characters, we
 # assume it's a binary and exec it directly. This means for
 # simple pager command configurations, we can degrade
@@ -896,7 +903,7 @@
 if e.errno == errno.ENOENT and not shell:
 self.warn(_("missing pager command '%s', skipping pager\n")
   % command)
-return
+return False
 raise
 
 # back up original file descriptors
@@ -917,6 +924,8 @@
 pager.stdin.close()
 pager.wait()
 
+return True
+
 def interface(self, feature):
 """what interface to use for interactive console features?
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3 V2] color: stop mutating the default effects map

2017-03-27 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490464217 14400
#  Sat Mar 25 13:50:17 2017 -0400
# Node ID 2566b7eac73c4851edc21b73a833f86bf878285e
# Parent  e86eb75e74ce1b0803c26d86a229b9b711f6d76a
color: stop mutating the default effects map

A future change will make color.setup() callable a second time when the pager is
spawned, in order to honor the 'color.pagermode' setting.  The problem was that
when 'color.mode=auto' was resolved to 'win32' in the first pass, the default
ANSI effects were overwritten, making it impossible to honor 'pagermode=ansi'.
Also, the two separate maps didn't have the same keys.  The symmetric difference
is 'dim' and 'italic' (from ANSI), and 'bold_background' (from win32).  Thus,
the update left entries that didn't belong for the current mode.  This bled
through `hg debugcolor`, where the unsupported ANSI keys were listed in 'win32'
mode.

As an added bonus, this now correctly enables color with MSYS `less` for a
command like this, where pager is forced on:

$ hg log --config color.pagermode=ansi --pager=yes --color=auto

Previously, the output was corrupted.  The raw output, as seen through the ANSI
blind `more.com` was:

<-[-1;6mchangeset:   34840:3580d1197af9<-[-1m
...

which MSYS `less -FRX` rendered as:

1;6mchangeset:   34840:3580d1197af91m
...

(The two '<-' instances were actually an arrow character that TortoiseHg warned
couldn't be encoded, and notepad++ translated to a single '?'.)

Returning an empty map for 'ui._colormode == None' seems better that defaulting
to '_effects' (since some keys are mode dependent), and is better than None,
which blows up `hg debugcolor --color=never`.

diff --git a/mercurial/color.py b/mercurial/color.py
--- a/mercurial/color.py
+++ b/mercurial/color.py
@@ -238,7 +238,6 @@
 if not w32effects:
 modewarn()
 return None
-_effects.update(w32effects)
 elif realmode == 'ansi':
 ui._terminfoparams.clear()
 elif realmode == 'terminfo':
@@ -271,9 +270,17 @@
 % (e, status))
 ui._styles[status] = ' '.join(good)
 
+def _activeeffects(ui):
+'''Return the effects map for the color mode set on the ui.'''
+if ui._colormode == 'win32':
+return w32effects
+elif ui._colormode != None:
+return _effects
+return {}
+
 def valideffect(ui, effect):
 'Determine if the effect is valid or not.'
-return ((not ui._terminfoparams and effect in _effects)
+return ((not ui._terminfoparams and effect in _activeeffects(ui))
  or (effect in ui._terminfoparams
  or effect[:-11] in ui._terminfoparams))
 
@@ -324,9 +331,10 @@
 for effect in ['none'] + effects.split())
 stop = _effect_str(ui, 'none')
 else:
-start = [str(_effects[e]) for e in ['none'] + effects.split()]
+activeeffects = _activeeffects(ui)
+start = [str(activeeffects[e]) for e in ['none'] + effects.split()]
 start = '\033[' + ';'.join(start) + 'm'
-stop = '\033[' + str(_effects['none']) + 'm'
+stop = '\033[' + str(activeeffects['none']) + 'm'
 return _mergeeffects(text, start, stop)
 
 _ansieffectre = re.compile(br'\x1b\[[0-9;]*m')
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -360,7 +360,7 @@
 def _debugdisplaycolor(ui):
 ui = ui.copy()
 ui._styles.clear()
-for effect in color._effects.keys():
+for effect in color._activeeffects(ui).keys():
 ui._styles[effect] = effect
 if ui._terminfoparams:
 for k, v in ui.configitems('color'):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2 V3] serve: add support for Mercurial subrepositories

2017-03-30 Thread Matt Harbison

On Tue, 28 Mar 2017 10:11:15 -0400, Yuya Nishihara  wrote:


On Sun, 26 Mar 2017 23:04:30 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1488146743 18000
#  Sun Feb 26 17:05:43 2017 -0500
# Node ID 0ff9bef3e0f67422cf29c200fa4a671d861d060b
# Parent  c60091fa1426892552dd6c0dd4b9c49e3c3da045
serve: add support for Mercurial subrepositories



+def addwebdirpath(repo, serverpath, webconf):
+webconf[serverpath] = repo.root
+repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
+
+for r in repo.revs('filelog("path:.hgsub")'):
+ctx = repo[r]
+for subpath in ctx.substate:
+ctx.sub(subpath).addwebdirpath(serverpath, webconf)


[...]


--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -15,6 +15,7 @@

 from . import (
 chgserver,
+cmdutil,
 commandserver,
 error,
 hgweb,
@@ -130,11 +131,24 @@
 baseui = ui
 webconf = opts.get('web_conf') or opts.get('webdir_conf')
 if webconf:
+if opts.get('subrepos'):
+raise error.Abort(_('--web-conf cannot be used with  
--subrepos'))

+
 # load server settings (e.g. web.port) to "copied" ui, which  
allows

 # hgwebdir to reload webconf cleanly
 servui = ui.copy()
 servui.readconfig(webconf, sections=['web'])
 alluis.add(servui)
+elif opts.get('subrepos'):
+servui = ui.copy()
+alluis.add(servui)


No need to make a copy of ui since nothing loaded into servui.


+@annotatesubrepoerror
+def addwebdirpath(self, serverpath, webconf):
+# The URL request contains the subrepo source path, not the  
local
+# subrepo path.  The distinction matters for 'foo = ../foo'  
type
+# entries.  It isn't possible to serve up 'foo = http://..'  
type
+# entries, because the server path is relative to this local  
server.

+src = self._state[0]
+if util.url(src).islocal():
+path = util.normpath(serverpath + src)
+cmdutil.addwebdirpath(self._repo, path + '/', webconf)


What happens if src is '../../escape_from_web_root' ?

I don't think it's correct to lay out subrepositories by peer URL since  
we're
exporting a _local_ clone. If you do "hg clone sub1 sub2", you'll see  
sub1

in local-path layout. "hg serve -S" just allows us to see sub1 over http.


That was actually how I first coded it, but switched it because it wasn't  
handling the test in test-subrepo-deep-nested-change.t properly.  I forget  
what exactly the problem was.  I'll take another look this weekend.



Maybe it's okay to add all repositories found under repo.root to webconf.
For strictness, we could check if a subrepo path exists in .hgsub of any
revision.


I'd like to avoid searching through the directory tree, if possible.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2 V3] serve: make the URL the same for `hg serve` and `hg serve -S`

2017-03-30 Thread Matt Harbison

On Tue, 28 Mar 2017 10:02:34 -0400, Yuya Nishihara  wrote:


On Sun, 26 Mar 2017 23:04:31 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1488146777 18000
#  Sun Feb 26 17:06:17 2017 -0500
# Node ID d584ca4bc33bd2ebeaf9a7bd86440b3cdcecc138
# Parent  0ff9bef3e0f67422cf29c200fa4a671d861d060b
serve: make the URL the same for `hg serve` and `hg serve -S`

It's perfectly workable to serve up the parent repo without the -S for  
push and
pull, as long as there are no subrepo changes in play.  Therefore,  
having a
different URL for the main repo based on the presence of this option  
seems like

it would get annoying.


This looks good, but more detailed commit message will help since some
changes in hgweb/hgwebdir are really subtle.


Other than noting that this change allows repos to be hosted at "", is  
there something else to mention on this one?

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] sslutil: clarify internal documentation

2017-03-30 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1490795674 14400
#  Wed Mar 29 09:54:34 2017 -0400
# Node ID 9505a8771bb00e56230e4c4b265e8369e659a54f
# Parent  2632df096fc0ac7582382b1f94ea4b9ad0bce8f2
sslutil: clarify internal documentation

I ran into this python issue with an incomplete certificate chain on Windows
recently, and this is the clarification that came from that experimenting.  The
comment I left on the bug tracker [1] with a reference to the CPython code [2]
indicates that the original problem I had is a different bug, but happened to
be mentioned under issue20916 on the Python bug tracker.

[1] https://bz.mercurial-scm.org/show_bug.cgi?id=5313#c7
[2] https://hg.python.org/cpython/file/v2.7.12/Modules/_ssl.c#l628

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -414,8 +414,10 @@
 # a hint to the user.
 # Only modern ssl module exposes SSLContext.get_ca_certs() so we can
 # only show this warning if modern ssl is available.
-# The exception handler is here because of
-# https://bugs.python.org/issue20916.
+# The exception handler is here to handle bugs around cert attributes:
+# https://bugs.python.org/issue20916#msg213479.  (See issues5313.)
+# When the main 20916 bug occurs, 'sslcontext.get_ca_certs()' is a
+# non-empty list, but the following conditional is otherwise True.
 try:
 if (caloaded and settings['verifymode'] == ssl.CERT_REQUIRED and
 modernssl and not sslcontext.get_ca_certs()):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] templatefilter: add support for 'long' to json()

2017-04-01 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491020477 14400
#  Sat Apr 01 00:21:17 2017 -0400
# Node ID a3d441253abc38df20c9890b207c1ab454bb691d
# Parent  2632df096fc0ac7582382b1f94ea4b9ad0bce8f2
templatefilter: add support for 'long' to json()

When disabling the '#requires serve' check in test-hgwebdir.t and running it on
Windows, several 500 errors popped up when querying '?style=json', with the
following in the error log:

File "...\\mercurial\\templater.py", line 393, in runfilter
  "keyword '%s'") % (filt.func_name, dt))
Abort: template filter 'json' is not compatible with keyword 'lastchange'

The swallowed exception at that point was:

File "...\\mercurial\\templatefilters.py", line 242, in json
  raise TypeError('cannot encode type %s' % obj.__class__.__name__)
TypeError: cannot encode type long

This corresponds to 'lastchange' being populated by hgweb.common.get_stat(),
which uses os.stat().st_mtime.  os.stat_float_times() is being disabled in util,
so the type for the times is 'long' on Windows, and 'int' on Linux.

diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -221,7 +221,8 @@
 def json(obj):
 if obj is None or obj is False or obj is True:
 return {None: 'null', False: 'false', True: 'true'}[obj]
-elif isinstance(obj, int) or isinstance(obj, float):
+elif (isinstance(obj, int) or isinstance(obj, long)
+  or isinstance(obj, float)):
 return str(obj)
 elif isinstance(obj, str):
 return '"%s"' % encoding.jsonescape(obj, paranoid=True)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] templatefilter: add support for 'long' to json()

2017-04-01 Thread Matt Harbison
On Sat, 01 Apr 2017 14:06:24 -0400, Matt Harbison   
wrote:



# HG changeset patch
# User Matt Harbison 
# Date 1491020477 14400
#  Sat Apr 01 00:21:17 2017 -0400
# Node ID a3d441253abc38df20c9890b207c1ab454bb691d
# Parent  2632df096fc0ac7582382b1f94ea4b9ad0bce8f2
templatefilter: add support for 'long' to json()

When disabling the '#requires serve' check in test-hgwebdir.t and  
running it on
Windows, several 500 errors popped up when querying '?style=json', with  
the

following in the error log:


BTW, does anybody know why the 'serve' tests are disabled on Windows?   
hghave.has_serve() simply says "platform and python can manage 'hg serve  
-d'", and the commit that introduces it doesn't explain what the issues  
were.  I made has_serve() return True unconditionally, and while there  
were errors in the newly run code, none looked like 'serve -d' were  
malfunctioning.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] templatefilter: add support for 'long' to json()

2017-04-01 Thread Matt Harbison
On Sat, 01 Apr 2017 15:20:02 -0400, Gregory Szorc  
 wrote:



On Sat, Apr 1, 2017 at 11:06 AM, Matt Harbison 
wrote:


# HG changeset patch
# User Matt Harbison 
# Date 1491020477 14400
#  Sat Apr 01 00:21:17 2017 -0400
# Node ID a3d441253abc38df20c9890b207c1ab454bb691d
# Parent  2632df096fc0ac7582382b1f94ea4b9ad0bce8f2
templatefilter: add support for 'long' to json()

When disabling the '#requires serve' check in test-hgwebdir.t and  
running

it on
Windows, several 500 errors popped up when querying '?style=json', with  
the

following in the error log:

File "...\\mercurial\\templater.py", line 393, in runfilter
  "keyword '%s'") % (filt.func_name, dt))
Abort: template filter 'json' is not compatible with keyword
'lastchange'

The swallowed exception at that point was:

File "...\\mercurial\\templatefilters.py", line 242, in json
  raise TypeError('cannot encode type %s' % obj.__class__.__name__)
TypeError: cannot encode type long

This corresponds to 'lastchange' being populated by
hgweb.common.get_stat(),
which uses os.stat().st_mtime.  os.stat_float_times() is being disabled  
in

util,
so the type for the times is 'long' on Windows, and 'int' on Linux.

diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -221,7 +221,8 @@
 def json(obj):
 if obj is None or obj is False or obj is True:
 return {None: 'null', False: 'false', True: 'true'}[obj]
-elif isinstance(obj, int) or isinstance(obj, float):
+elif (isinstance(obj, int) or isinstance(obj, long)
+  or isinstance(obj, float)):



isinstance() accepts a tuple of types as its second argument. Let's use
that to make this code shorter. (This could probably be done in flight.)



Ah, thanks.  I meant to look into if it did, but spent a lot of time  
tracking down the int vs float vs long part, and forgot.


I've got a growing series of fixes for hg serve tests on Windows, so I'll  
just send a v2 if nobody does a fix-in-flight in the meantime.



 return str(obj)
 elif isinstance(obj, str):
 return '"%s"' % encoding.jsonescape(obj, paranoid=True)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8] test-http: update output for Windows

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491085851 14400
#  Sat Apr 01 18:30:51 2017 -0400
# Node ID ade96da6680ba993018effdf73b391fc6bed0531
# Parent  54fd6d15228e8e2f8e735beac0db0930c60af9ad
test-http: update output for Windows

The http test simply wasn't updated in 161ab32b44a1 for Windows.  It looks like
the https test meant to glob away the error message in 3e2d8120528b, but forgot
the '*', and was subsequently removed in 408f2202bd80.

diff --git a/tests/test-http.t b/tests/test-http.t
--- a/tests/test-http.t
+++ b/tests/test-http.t
@@ -19,7 +19,7 @@
 
 #if windows
   $ hg serve -p $HGPORT1 2>&1
-  abort: cannot start server at ':$HGPORT1': * (glob)
+  abort: cannot start server at 'localhost:$HGPORT1': * (glob)
   [255]
 #else
   $ hg serve -p $HGPORT1 2>&1
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -36,7 +36,7 @@
 
 #if windows
   $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
-  abort: cannot start server at 'localhost:$HGPORT':
+  abort: cannot start server at 'localhost:$HGPORT': * (glob)
   [255]
 #else
   $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8] tests: add globs for Windows

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491072519 14400
#  Sat Apr 01 14:48:39 2017 -0400
# Node ID 46f601b676cecfcc318f6852fe6ab6962703d2be
# Parent  d1a1f21e86b2f976f5e968371f6cff145b98712a
tests: add globs for Windows

diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -581,12 +581,12 @@
 be exchanged)
 
   $ hg -R repo1 incoming -B
-  comparing with $TESTTMP/bmcomparison/source
+  comparing with $TESTTMP/bmcomparison/source (glob)
   searching for changed bookmarks
   no changed bookmarks found
   [1]
   $ hg -R repo1 outgoing -B
-  comparing with $TESTTMP/bmcomparison/source
+  comparing with $TESTTMP/bmcomparison/source (glob)
   searching for changed bookmarks
   no changed bookmarks found
   [1]
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -97,11 +97,12 @@
   [255]
 #endif
 
-Specifying a per-host certificate file that doesn't exist will abort
+Specifying a per-host certificate file that doesn't exist will abort.  The full
+C:/path/to/msysroot will print on Windows.
 
   $ hg --config hostsecurity.localhost:verifycertsfile=/does/not/exist clone 
https://localhost:$HGPORT/
   warning: connecting to localhost using legacy security technology (TLS 1.0); 
see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
-  abort: path specified by hostsecurity.localhost:verifycertsfile does not 
exist: /does/not/exist
+  abort: path specified by hostsecurity.localhost:verifycertsfile does not 
exist: */does/not/exist (glob)
   [255]
 
 A malformed per-host certificate file will raise an error
diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t
--- a/tests/test-largefiles-cache.t
+++ b/tests/test-largefiles-cache.t
@@ -223,7 +223,7 @@
   $ hg push http://localhost:$HGPORT1 -f --config files.usercache=nocache
   pushing to http://localhost:$HGPORT1/
   searching for changes
-  abort: remotestore: could not open file 
$TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020: HTTP 
Error 403: ssl required
+  abort: remotestore: could not open file 
$TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020: HTTP 
Error 403: ssl required (glob)
   [255]
 
   $ rm .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -116,11 +116,11 @@
 
   $ f --dump --recurse *
   d2: directory with 2 files
-  d2/f3:
+  d2/f3: (glob)
   >>>
   0 base
   <<<
-  d2/f4:
+  d2/f4: (glob)
   >>>
   0 base
   <<<
@@ -222,11 +222,11 @@
 
   $ f --dump --recurse *
   d2: directory with 2 files
-  d2/f3:
+  d2/f3: (glob)
   >>>
   0 base
   <<<
-  d2/f4:
+  d2/f4: (glob)
   >>>
   0 base
   <<<
@@ -308,11 +308,11 @@
 
   $ f --dump --recurse *
   d2: directory with 2 files
-  d2/f3:
+  d2/f3: (glob)
   >>>
   0 base
   <<<
-  d2/f4:
+  d2/f4: (glob)
   >>>
   0 base
   <<<
diff --git a/tests/test-share.t b/tests/test-share.t
--- a/tests/test-share.t
+++ b/tests/test-share.t
@@ -367,7 +367,7 @@
   $ hg share -U thisdir/orig thisdir/abs
   $ hg share -U --relative thisdir/abs thisdir/rel
   $ cat thisdir/rel/.hg/sharedpath
-  ../../orig/.hg (no-eol)
+  ../../orig/.hg (no-eol) (glob)
   $ grep shared thisdir/*/.hg/requires
   thisdir/abs/.hg/requires:shared
   thisdir/rel/.hg/requires:shared
@@ -377,22 +377,22 @@
 
   $ cd thisdir
   $ hg -R rel root
-  $TESTTMP/thisdir/rel
+  $TESTTMP/thisdir/rel (glob)
   $ cd ..
 
 now test that relative paths really are relative, survive across
 renames and changes of PWD
 
   $ hg -R thisdir/abs root
-  $TESTTMP/thisdir/abs
+  $TESTTMP/thisdir/abs (glob)
   $ hg -R thisdir/rel root
-  $TESTTMP/thisdir/rel
+  $TESTTMP/thisdir/rel (glob)
   $ mv thisdir thatdir
   $ hg -R thatdir/abs root
-  abort: .hg/sharedpath points to nonexistent directory 
$TESTTMP/thisdir/orig/.hg!
+  abort: .hg/sharedpath points to nonexistent directory 
$TESTTMP/thisdir/orig/.hg! (glob)
   [255]
   $ hg -R thatdir/rel root
-  $TESTTMP/thatdir/rel
+  $TESTTMP/thatdir/rel (glob)
 
 test unshare relshared repo
 
diff --git a/tests/test-status.t b/tests/test-status.t
--- a/tests/test-status.t
+++ b/tests/test-status.t
@@ -121,11 +121,11 @@
   ? ../b/in_b
   ? ../in_root
   $ HGPLAIN=1 hg status --cwd a
-  ? a/1/in_a_1
-  ? a/in_a
-  ? b/1/in_b_1
-  ? b/2/in_b_2
-  ? b/in_b
+  ? a/1/in_a_1 (glob)
+  ? a/in_a (glob)
+  ? b/1/in_b_1 (glob)
+  ? b/2/in_b_2 (glob)
+  ? b/in_b (glob)
   ? in_root
 
   $ cd ..
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8] test-blackbox: glob away quoting differences on Windows

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491114591 14400
#  Sun Apr 02 02:29:51 2017 -0400
# Node ID a3ff64b0d0dedde5f2a5103083ad09e0bee7193e
# Parent  eb4094d2421a9fc49c8342ff244840a6c085697b
test-blackbox: glob away quoting differences on Windows

Windows uses double quotes in these places.

diff --git a/tests/test-blackbox.t b/tests/test-blackbox.t
--- a/tests/test-blackbox.t
+++ b/tests/test-blackbox.t
@@ -25,7 +25,7 @@
   1970/01/01 00:00:00 bob @ (5000)> 
add a
   1970/01/01 00:00:00 bob @ (5000)> 
add a exited 0 after * seconds (glob)
   1970/01/01 00:00:00 bob @+ (5000)> 
blackbox
-  1970/01/01 00:00:00 bob @+ (5000)> 
blackbox --config 'blackbox.dirty=True' exited 0 after * seconds (glob)
+  1970/01/01 00:00:00 bob @+ (5000)> 
blackbox --config *blackbox.dirty=True* exited 0 after * seconds (glob)
   1970/01/01 00:00:00 bob @ (5000)> 
confuse
   1970/01/01 00:00:00 bob @ (5000)> 
alias 'confuse' expands to 'log --limit 3'
   1970/01/01 00:00:00 bob @ (5000)> 
confuse exited 0 after * seconds (glob)
diff --git a/tests/test-devel-warnings.t b/tests/test-devel-warnings.t
--- a/tests/test-devel-warnings.t
+++ b/tests/test-devel-warnings.t
@@ -139,7 +139,7 @@
   $ hg blackbox -l 9
   1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> 
devel-warn: revset "oldstyle" uses list instead of smartset
   (compatibility will be dropped after Mercurial-3.9, update your code.) at: 
*mercurial/revset.py:* (mfunc) (glob)
-  1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> 
log -r 'oldstyle()' -T '{rev}\n' exited 0 after * seconds (glob)
+  1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> 
log -r *oldstyle()* -T *{rev}\n* exited 0 after * seconds (glob)
   1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> 
oldanddeprecated
   1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> 
devel-warn: foorbar is deprecated, go shopping
   (compatibility will be dropped after Mercurial-42.1337, update your code.) 
at: $TESTTMP/buggylocking.py:* (oldanddeprecated) (glob)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8] test-serve: make the 'listening at *' lines optional

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491109012 14400
#  Sun Apr 02 00:56:52 2017 -0400
# Node ID b574417618632d500281b17ff0caf8cc78a3e2a0
# Parent  ade96da6680ba993018effdf73b391fc6bed0531
test-serve: make the 'listening at *' lines optional

The daemonized serve process doesn't print these lines out (see 448d0c452140).
I was able to get it to with the following hack:

 diff --git a/mercurial/win32.py b/mercurial/win32.py
 --- a/mercurial/win32.py
 +++ b/mercurial/win32.py
 @@ -418,6 +418,11 @@
  return str(ppid)

  def spawndetached(args):
 +
 +import subprocess
 +return subprocess.Popen(args, cwd=pycompat.getcwd(), env=encoding.environ,
 +
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP).pid
 +
  # No standard library function really spawns a fully detached
  # process under win32 because they allocate pipes or other objects
  # to handle standard streams communications. Passing these objects

However, MSYS translates --prefixes starting with '/' to 'C:/MinGW/msys/1.0',
which changes the output.  The output isn't so important that I want to spend a
bunch of time on this, and risk breaking some subtle behavior of `hg serve -d`
with the more complicated code.

diff --git a/tests/test-hgwebdir.t b/tests/test-hgwebdir.t
--- a/tests/test-hgwebdir.t
+++ b/tests/test-hgwebdir.t
@@ -1421,7 +1421,7 @@
   > EOF
   $ hg serve -d --pid-file=hg.pid --web-conf paths.conf \
   > -A access-paths.log -E error-paths-9.log
-  listening at http://*:$HGPORT1/ (bound to *$LOCALIP*:$HGPORT1) (glob)
+  listening at http://*:$HGPORT1/ (bound to *$LOCALIP*:$HGPORT1) (glob) (?)
   $ cat hg.pid >> $DAEMON_PIDS
   $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
   200 Script output follows
@@ -1433,7 +1433,7 @@
   $ killdaemons.py
   $ hg serve -p $HGPORT2 -d -v --pid-file=hg.pid --web-conf paths.conf \
   > -A access-paths.log -E error-paths-10.log
-  listening at http://*:$HGPORT2/ (bound to *$LOCALIP*:$HGPORT2) (glob)
+  listening at http://*:$HGPORT2/ (bound to *$LOCALIP*:$HGPORT2) (glob) (?)
   $ cat hg.pid >> $DAEMON_PIDS
   $ get-with-headers.py localhost:$HGPORT2 '?style=raw'
   200 Script output follows
diff --git a/tests/test-patchbomb-tls.t b/tests/test-patchbomb-tls.t
--- a/tests/test-patchbomb-tls.t
+++ b/tests/test-patchbomb-tls.t
@@ -7,7 +7,7 @@
 
   $ python "$TESTDIR/dummysmtpd.py" -p $HGPORT --pid-file a.pid -d \
   > --tls smtps --certificate `pwd`/server.pem
-  listening at localhost:$HGPORT
+  listening at localhost:$HGPORT (?)
   $ cat a.pid >> $DAEMON_PIDS
 
 Set up repository:
diff --git a/tests/test-serve.t b/tests/test-serve.t
--- a/tests/test-serve.t
+++ b/tests/test-serve.t
@@ -34,13 +34,13 @@
 With -v
 
   $ hgserve
-  listening at http://localhost/ (bound to *$LOCALIP*:HGPORT1) (glob)
+  listening at http://localhost/ (bound to *$LOCALIP*:HGPORT1) (glob) (?)
   % errors
 
 With -v and -p HGPORT2
 
   $ hgserve -p "$HGPORT2"
-  listening at http://localhost/ (bound to *$LOCALIP*:HGPORT2) (glob)
+  listening at http://localhost/ (bound to *$LOCALIP*:HGPORT2) (glob) (?)
   % errors
 
 With -v and -p daytime (should fail because low port)
@@ -57,25 +57,25 @@
 With --prefix foo
 
   $ hgserve --prefix foo
-  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob)
+  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob) (?)
   % errors
 
 With --prefix /foo
 
   $ hgserve --prefix /foo
-  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob)
+  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob) (?)
   % errors
 
 With --prefix foo/
 
   $ hgserve --prefix foo/
-  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob)
+  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob) (?)
   % errors
 
 With --prefix /foo/
 
   $ hgserve --prefix /foo/
-  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob)
+  listening at http://localhost/foo/ (bound to *$LOCALIP*:HGPORT1) (glob) (?)
   % errors
 
   $ cd ..
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 8] tests: quote paths in shell script hooks

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491074606 14400
#  Sat Apr 01 15:23:26 2017 -0400
# Node ID 54fd6d15228e8e2f8e735beac0db0930c60af9ad
# Parent  46f601b676cecfcc318f6852fe6ab6962703d2be
tests: quote paths in shell script hooks

Without the quoting, MSYS will remove the '\' directory separators, and the repo
can't be opened.

diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -924,9 +924,9 @@
 
   $ cat > $TESTTMP/checkpending.sh < echo "@repo"
-  > hg -R $TESTTMP/repo bookmarks
+  > hg -R "$TESTTMP/repo" bookmarks
   > echo "@unrelated"
-  > hg -R $TESTTMP/unrelated bookmarks
+  > hg -R "$TESTTMP/unrelated" bookmarks
   > exit 1 # to avoid adding new bookmark for subsequent tests
   > EOF
 
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -857,9 +857,9 @@
 
   $ cat > $TESTTMP/checkpending.sh < echo '@a'
-  > hg -R $TESTTMP/a tip -q
+  > hg -R "$TESTTMP/a" tip -q
   > echo '@a/nested'
-  > hg -R $TESTTMP/a/nested tip -q
+  > hg -R "$TESTTMP/a/nested" tip -q
   > exit 1 # to avoid adding new revision for subsequent tests
   > EOF
   $ hg init nested
diff --git a/tests/test-phases.t b/tests/test-phases.t
--- a/tests/test-phases.t
+++ b/tests/test-phases.t
@@ -609,9 +609,9 @@
 
   $ cat > $TESTTMP/checkpending.sh < echo '@initialrepo'
-  > hg -R $TESTTMP/initialrepo phase 7
+  > hg -R "$TESTTMP/initialrepo" phase 7
   > echo '@push-dest'
-  > hg -R $TESTTMP/push-dest phase 6
+  > hg -R "$TESTTMP/push-dest" phase 6
   > exit 1 # to avoid changing phase for subsequent tests
   > EOF
   $ cd ../initialrepo
diff --git a/tests/test-share.t b/tests/test-share.t
--- a/tests/test-share.t
+++ b/tests/test-share.t
@@ -168,11 +168,11 @@
 
   $ cat > $TESTTMP/checkbookmarks.sh < echo "@repo1"
-  > hg -R $TESTTMP/repo1 bookmarks
+  > hg -R "$TESTTMP/repo1" bookmarks
   > echo "@repo2"
-  > hg -R $TESTTMP/repo2 bookmarks
+  > hg -R "$TESTTMP/repo2" bookmarks
   > echo "@repo3"
-  > hg -R $TESTTMP/repo3 bookmarks
+  > hg -R "$TESTTMP/repo3" bookmarks
   > exit 1 # to avoid adding new bookmark for subsequent tests
   > EOF
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8] test-subrepo: update output for Windows

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491114249 14400
#  Sun Apr 02 02:24:09 2017 -0400
# Node ID eb4094d2421a9fc49c8342ff244840a6c085697b
# Parent  f2df1dcd45d44a7cb79663fdc22054797703385a
test-subrepo: update output for Windows

diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t
--- a/tests/test-subrepo.t
+++ b/tests/test-subrepo.t
@@ -311,6 +311,7 @@
branchmerge: True, force: False, partial: False
ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
preserving t for resolve of t
+  starting 4 threads for background file closing (?)
t: versions differ -> m (premerge)
   picked tool ':merge' for t (binary False symlink False changedelete False)
   merging t
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8] test-serve: kill daemons before deleting the access and error logs

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491110885 14400
#  Sun Apr 02 01:28:05 2017 -0400
# Node ID 3196a52c528f537c04a9fdc61d6ee0f75ffb3223
# Parent  b574417618632d500281b17ff0caf8cc78a3e2a0
test-serve: kill daemons before deleting the access and error logs

On Windows, `rm` will fail with 'Permission denied' if another process has it
open.  It looks like the rollback test was missing the kill entirely.

diff --git a/tests/test-largefiles-wireproto.t 
b/tests/test-largefiles-wireproto.t
--- a/tests/test-largefiles-wireproto.t
+++ b/tests/test-largefiles-wireproto.t
@@ -441,7 +441,7 @@
   1 largefiles updated, 0 removed
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+  $ killdaemons.py
   $ rm hg.pid access.log
-  $ killdaemons.py
 
 #endif
diff --git a/tests/test-rollback.t b/tests/test-rollback.t
--- a/tests/test-rollback.t
+++ b/tests/test-rollback.t
@@ -148,6 +148,8 @@
   working directory now based on revision 0
   $ hg id default
   791dd2169706
+
+  $ killdaemons.py
 #endif
 
 update to older changeset and then refuse rollback, because
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8] test-serve: disable unfixable tests on Windows

2017-04-02 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491112267 14400
#  Sun Apr 02 01:51:07 2017 -0400
# Node ID f2df1dcd45d44a7cb79663fdc22054797703385a
# Parent  3196a52c528f537c04a9fdc61d6ee0f75ffb3223
test-serve: disable unfixable tests on Windows

These tests would run if hghave.has_serve() were enabled on Windows.  Windows
has no issue allowing an unpriviledged process to open port 13, so it doesn't
abort.  The other tests are related to how MSYS tries to be helpful and converts
Unix constructs to the Windows equivalent.  There isn't any way to disable this
behavior, though it supposedly doesn't happen if the exe is linked against the
MSYS library.

diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t
--- a/tests/test-hgweb-commands.t
+++ b/tests/test-hgweb-commands.t
@@ -2216,6 +2216,11 @@
 
   $ cat errors.log
 
+MSYS changes environment variables starting with '/' into 'C:/MinGW/msys/1.0',
+which changes the status line to '400 no such method: C:'.
+
+#if no-msys
+
 bookmarks view doesn't choke on bookmarks on secret changesets (issue3774)
 
   $ hg phase -fs 4
@@ -2381,7 +2386,7 @@
   node:(0, 6) (color 1)
   
   
-
+#endif
 
 
   $ cd ..
diff --git a/tests/test-pull.t b/tests/test-pull.t
--- a/tests/test-pull.t
+++ b/tests/test-pull.t
@@ -88,7 +88,11 @@
   abort: file:// URLs can only refer to localhost
   [255]
 
+MSYS changes 'file:' into 'file;'
+
+#if no-msys
   $ hg pull -q file:../test  # no-msys
+#endif
 
 It's tricky to make file:// URLs working on every platform with
 regular shell commands.
diff --git a/tests/test-serve.t b/tests/test-serve.t
--- a/tests/test-serve.t
+++ b/tests/test-serve.t
@@ -45,7 +45,7 @@
 
 With -v and -p daytime (should fail because low port)
 
-#if no-root
+#if no-root no-windows
   $ KILLQUIETLY=Y
   $ hgserve -p daytime
   abort: cannot start server at 'localhost:13': Permission denied
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 8] tests: quote paths in shell script hooks

2017-04-02 Thread Matt Harbison

On Sun, 02 Apr 2017 20:41:29 -0400, Jun Wu  wrote:


Excerpts from Matt Harbison's message of 2017-04-02 19:12:48 -0400:

# HG changeset patch
# User Matt Harbison 
# Date 1491074606 14400
#  Sat Apr 01 15:23:26 2017 -0400
# Node ID 54fd6d15228e8e2f8e735beac0db0930c60af9ad
# Parent  46f601b676cecfcc318f6852fe6ab6962703d2be
tests: quote paths in shell script hooks

Without the quoting, MSYS will remove the '\' directory separators, and  
the repo

can't be opened.

diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -924,9 +924,9 @@

   $ cat > $TESTTMP/checkpending.sh < echo "@repo"
-  > hg -R $TESTTMP/repo bookmarks
+  > hg -R "$TESTTMP/repo" bookmarks
   > echo "@unrelated"
-  > hg -R $TESTTMP/unrelated bookmarks
+  > hg -R "$TESTTMP/unrelated" bookmarks


Maybe this is worth a check-code rule.


It would definitely be nice, but I'm not sure how to do that and limit the  
scope.  Not every instance of $TESTTMP/.. needs quoting- just the ones in  
things that will be executed by the shell.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 8] tests: add globs for Windows

2017-04-03 Thread Matt Harbison
On Mon, 03 Apr 2017 05:09:39 -0400, Kostia Balytskyi   
wrote:


What is stopping us from making run-tests match these things without  
globs? Can we just always match smth1.replace('\', '//') vs  
smth2.replace('\', '//') if ran on Windows?


I'm guessing it was just to be extra careful.

It might be a little more complicated though.  For example, without the  
glob, this diff occurs (note the double '\', and line ending difference.   
I'm not sure where the string compare is done vs adding the escaping '\'  
to the string.):


--- c:/Users/Matt/Projects/hg/tests/test-merge-criss-cross.t
+++ c:/Users/Matt/Projects/hg/tests/test-merge-criss-cross.t.err
@@ -116,11 +116,11 @@

   $ f --dump --recurse *
   d2: directory with 2 files
-  d2/f3:
-  >>>
-  0 base
-  <<<
-  d2/f4:
+  d2\\f3:\r (esc)
+  >>>
+  0 base
+  <<<
+  d2\\f4:\r (esc)
   >>>
   0 base
   <<<

It might also help for tests like this, where you can't put a glob IIRC:

diff --git a/tests/test-trusted.py.out b/tests/test-trusted.py.out
--- a/tests/test-trusted.py.out
+++ b/tests/test-trusted.py.out
@@ -184,7 +184,7 @@
 # suboptions, trusted and untrusted
 (None, []) ('main', [('one', 'one'), ('two', 'two')])
 # path, trusted and untrusted
-None .hg/monty/python
+None .hg\monty/python
 # bool, trusted and untrusted
 False True
 # int, trusted and untrusted


I can send a patch if people think this is a good idea.


I'd be interested in trying that.  FWIW, in the past several years I've  
been playing whack-a-mole with this, the test runner never appended a  
(glob) inappropriately, so the logic must be in there already.




-Original Message-
From: Mercurial-devel [mailto:mercurial-devel-boun...@mercurial-scm.org]  
On Behalf Of Matt Harbison

Sent: Monday, 3 April, 2017 00:13
To: mercurial-devel@mercurial-scm.org
Subject: [PATCH 1 of 8] tests: add globs for Windows

# HG changeset patch
# User Matt Harbison  # Date 1491072519 14400
#  Sat Apr 01 14:48:39 2017 -0400
# Node ID 46f601b676cecfcc318f6852fe6ab6962703d2be
# Parent  d1a1f21e86b2f976f5e968371f6cff145b98712a
tests: add globs for Windows

diff --git a/tests/test-bookmarks-pushpull.t  
b/tests/test-bookmarks-pushpull.t

--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -581,12 +581,12 @@
 be exchanged)
  $ hg -R repo1 incoming -B
-  comparing with $TESTTMP/bmcomparison/source
+  comparing with $TESTTMP/bmcomparison/source (glob)
   searching for changed bookmarks
   no changed bookmarks found
   [1]
   $ hg -R repo1 outgoing -B
-  comparing with $TESTTMP/bmcomparison/source
+  comparing with $TESTTMP/bmcomparison/source (glob)
   searching for changed bookmarks
   no changed bookmarks found
   [1]
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -97,11 +97,12 @@
   [255]
 #endif
-Specifying a per-host certificate file that doesn't exist will abort
+Specifying a per-host certificate file that doesn't exist will abort.
+The full C:/path/to/msysroot will print on Windows.
  $ hg --config hostsecurity.localhost:verifycertsfile=/does/not/exist  
clone  
https://urldefense.proofpoint.com/v2/url?u=https-3A__localhost-3A-24HGPORT_&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Pp-gQYFgs4tKlSFPF5kfCw&m=fkrqwBluYFCGdESYJYi8xhAZhP2kV1dBW30IT06QPIc&s=hiM2bF33c6k7YO7L2hPmdgCwx0RL-6mJn8xZTkJAdWU&e=
   warning: connecting to localhost using legacy security technology  
(TLS 1.0); see  
https://urldefense.proofpoint.com/v2/url?u=https-3A__mercurial-2Dscm.org_wiki_SecureConnections&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Pp-gQYFgs4tKlSFPF5kfCw&m=fkrqwBluYFCGdESYJYi8xhAZhP2kV1dBW30IT06QPIc&s=ovg3Pxm76NuFsItFtCq16Mp53e7D5LsyYF2r_yJcGQE&e=   
for more info (?)
-  abort: path specified by hostsecurity.localhost:verifycertsfile does  
not exist: /does/not/exist

+  abort: path specified by hostsecurity.localhost:verifycertsfile does
+ not exist: */does/not/exist (glob)
   [255]
A malformed per-host certificate file will raise an error diff --git  
a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t

--- a/tests/test-largefiles-cache.t
+++ b/tests/test-largefiles-cache.t
@@ -223,7 +223,7 @@
   $ hg push  
https://urldefense.proofpoint.com/v2/url?u=http-3A__localhost-3A-24HGPORT1&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Pp-gQYFgs4tKlSFPF5kfCw&m=fkrqwBluYFCGdESYJYi8xhAZhP2kV1dBW30IT06QPIc&s=ju5I1GImXMqktvYrqwpmCDXdgiKm0RuiHYcrjUY_frw&e=   
-f --config files.usercache=nocache
   pushing to  
https://urldefense.proofpoint.com/v2/url?u=http-3A__localhost-3A-24HGPORT1_&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Pp-gQYFgs4tKlSFPF5kfCw&m=fkrqwBluYFCGdESYJYi8xhAZhP2kV1dBW30IT06QPIc&s=4xcqfRg-K4IM5qtnN75gCmlA8bWdZY27a8gBV712RpY&e=

   searching 

Re: [PATCH 4 of 6] hgweb: introduce staticimmutable web command

2017-04-03 Thread Matt Harbison
On Sat, 01 Apr 2017 03:29:08 -0400, Gregory Szorc  
 wrote:



# HG changeset patch
# User Gregory Szorc 
# Date 1491021501 25200
#  Fri Mar 31 21:38:21 2017 -0700
# Node ID 0b8be3d244585f5a2874821418fce41bf7631f6c
# Parent  4cec8e88d09775ee6478e307e9dde94af5b9fcfd
hgweb: introduce staticimmutable web command


Should these caching related patches be sensitive to '--config  
web.cache=False'?  I can't imagine why you wouldn't want to cache in a  
production environment.  It has been useful for development testing, but  
it's not documented as experimental/developer only.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH RFC] run-tests: support per-line conditional output in tests

2017-04-03 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491275149 14400
#  Mon Apr 03 23:05:49 2017 -0400
# Node ID cfefdb4546a3a38918303ed43447ebe93051de51
# Parent  81abd0d12c8641df666d356f6033d84cd55977a8
run-tests: support per-line conditional output in tests

Duplicating entire tests just because the output is different is both error
prone and can make the tests harder to read.  This harnesses the existing '(?)'
infrastructure, both to improve readability, and because it seemed like the path
of least resistance.

I think this syntax seems natural.  For example, this:

  2 r4/.hg/cache/checkisexec (execbit ?)

pretty naturally reads as "checkisexec, if execbit".  In some ways though, this
inverts the meaning of '?'.  For '(?)', the line is purely optional.  In the
example, it is mandatory iff execbit.  Otherwise, it is carried forward as
optional, to preserve the test output.  I tried it the other way, (listing
'no-exec' in the example), but that is too confusing to read.

The only thing that I haven't figured out yet is why the '(glob)' interferes
in the first hardlink.t hunk.  If it is kept, that line falls to the bottom of
the (xxx ?) sequence on Windows.  As it is, this test runs cleanly on Linux.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -497,6 +497,9 @@
 # sans \t, \n and \r
 CDATA_EVIL = re.compile(br"[\000-\010\013\014\016-\037]")
 
+#optline = re.compile(b'(.*) \(([a-z0-9 +.]*) \?\)\n$')
+optline = re.compile(b'(.+) \((.+?) \?\)\n$')
+
 def cdatasafe(data):
 """Make a string safe to include in a CDATA block.
 
@@ -1271,8 +1274,19 @@
 if r:
 els.pop(i)
 break
-if el and el.endswith(b" (?)\n"):
-optional.append(i)
+if el:
+if el.endswith(b" (?)\n"):
+optional.append(i)
+else:
+m = optline.match(el)
+if m:
+conditions = [c for c in m.group(2).split(' ')]
+
+if self._hghave(conditions)[0]:
+lout = el
+else:
+optional.append(i)
+
 i += 1
 
 if r:
@@ -1298,8 +1312,10 @@
 # clean up any optional leftovers
 while expected.get(pos, None):
 el = expected[pos].pop(0)
-if el and not el.endswith(b" (?)\n"):
-break
+if el:
+if (not optline.match(el)
+and not el.endswith(b" (?)\n")):
+break
 postout.append(b'  ' + el)
 
 if lcmd:
@@ -1371,6 +1387,12 @@
 if el.endswith(b" (?)\n"):
 retry = "retry"
 el = el[:-5] + b"\n"
+else:
+m = optline.match(el)
+if m:
+el = m.group(1) + b"\n"
+retry = "retry"
+
 if el.endswith(b" (esc)\n"):
 if PYTHON3:
 el = el[:-7].decode('unicode_escape') + '\n'
diff --git a/tests/test-clone.t b/tests/test-clone.t
--- a/tests/test-clone.t
+++ b/tests/test-clone.t
@@ -31,10 +31,10 @@
   default   10:a7949464abda
   $ ls .hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
-  checknoexec
+  checkisexec (execbit ?)
+  checklink (symlink ?)
+  checklink-target (symlink ?)
+  checknoexec (execbit ?)
   rbc-names-v1
   rbc-revs-v1
 
@@ -49,9 +49,9 @@
 
   $ ls .hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
+  checkisexec (execbit ?)
+  checklink (symlink ?)
+  checklink-target (symlink ?)
 
   $ cat a
   a
diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -441,10 +441,10 @@
   M b2
   A 1k
   A 2k
-  A b2link
+  A b2link (no-windows ?)
   A bin
   A c1
-  A con.xml
+  A con.xml (no-windows ?)
   R a2
   $ hg status --change 2
   M b2
@@ -452,10 +452,10 @@
   M b2
   A 1k
   A 2k
-  A b2link
+  A b2link (no-windows ?)
   A bin
   A c1
-  A con.xml
+  A con.xml (no-windows ?)
   R a2
   $ hg status --change 4
   A .hgsub
@@ -464,7 +464,7 @@
   A dos
   A mac
   A mixed
-  R con.xml
+  R con.xml (no-windows ?)
   ! a1
   ? b2.orig
   ? c3
@@ -551,9 +551,9 @@
 
 
   $ hg status --removed  --rev 4
-  R con.xml
+  R con.xml (no-windows ?)
   $ fileset "status(4, 'wdir(

Re: [PATCH 2 of 8] tests: quote paths in shell script hooks

2017-04-04 Thread Matt Harbison
On Tue, 04 Apr 2017 13:39:54 -0400, FUJIWARA Katsunori  
 wrote:



At Sun, 02 Apr 2017 20:45:58 -0400,
Matt Harbison wrote:


On Sun, 02 Apr 2017 20:41:29 -0400, Jun Wu  wrote:

> Excerpts from Matt Harbison's message of 2017-04-02 19:12:48 -0400:
>> # HG changeset patch
>> # User Matt Harbison 
>> # Date 1491074606 14400
>> #  Sat Apr 01 15:23:26 2017 -0400
>> # Node ID 54fd6d15228e8e2f8e735beac0db0930c60af9ad
>> # Parent  46f601b676cecfcc318f6852fe6ab6962703d2be
>> tests: quote paths in shell script hooks
>>
>> Without the quoting, MSYS will remove the '\' directory separators,  
and

>> the repo
>> can't be opened.
>>
>> diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
>> --- a/tests/test-bookmarks.t
>> +++ b/tests/test-bookmarks.t
>> @@ -924,9 +924,9 @@
>>
>>$ cat > $TESTTMP/checkpending.sh <>> echo "@repo"
>> -  > hg -R $TESTTMP/repo bookmarks
>> +  > hg -R "$TESTTMP/repo" bookmarks
>>> echo "@unrelated"
>> -  > hg -R $TESTTMP/unrelated bookmarks
>> +  > hg -R "$TESTTMP/unrelated" bookmarks
>
> Maybe this is worth a check-code rule.

It would definitely be nice, but I'm not sure how to do that and limit  
the
scope.  Not every instance of $TESTTMP/.. needs quoting- just the ones  
in

things that will be executed by the shell.


With current check-code implementation, all here-doc fragments in *.t
script are completely ignored, because all non-whitespace letters in
here-doc are replaced with 'x' by rephere() at filtering stage of
checkfile().

  
https://www.mercurial-scm.org/repo/hg/file/68f263f52d2e/contrib/check-code.py#l96

This ignorance may cause overlooking outdated here-doc python code in
*.t script, too.

In fact, I have a suspending series to check here-doc fragments in *.t
script. I'll finish it in a hurry!


OK, thanks!  No rush from me though.  There are still more than a handful  
of broken tests on Windows, so I'm not too worried about this case.




___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH RFC] run-tests: support per-line conditional output in tests

2017-04-04 Thread Matt Harbison
On Tue, 04 Apr 2017 00:01:55 -0400, Matt Harbison   
wrote:



# HG changeset patch
# User Matt Harbison 
# Date 1491275149 14400
#  Mon Apr 03 23:05:49 2017 -0400
# Node ID cfefdb4546a3a38918303ed43447ebe93051de51
# Parent  81abd0d12c8641df666d356f6033d84cd55977a8
run-tests: support per-line conditional output in tests

Duplicating entire tests just because the output is different is both  
error
prone and can make the tests harder to read.  This harnesses the  
existing '(?)'
infrastructure, both to improve readability, and because it seemed like  
the path

of least resistance.

I think this syntax seems natural.  For example, this:

  2 r4/.hg/cache/checkisexec (execbit ?)

pretty naturally reads as "checkisexec, if execbit".  In some ways  
though, this
inverts the meaning of '?'.  For '(?)', the line is purely optional.  In  
the
example, it is mandatory iff execbit.  Otherwise, it is carried forward  
as
optional, to preserve the test output.  I tried it the other way,  
(listing

'no-exec' in the example), but that is too confusing to read.

The only thing that I haven't figured out yet is why the '(glob)'  
interferes
in the first hardlink.t hunk.  If it is kept, that line falls to the  
bottom of
the (xxx ?) sequence on Windows.  As it is, this test runs cleanly on  
Linux.


Actually, this is an existing problem with '(?)' too.  Changing (xxx ?) to  
(?) without the *.py changes yields the same behavior.




diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -497,6 +497,9 @@
 # sans \t, \n and \r
 CDATA_EVIL = re.compile(br"[\000-\010\013\014\016-\037]")
+#optline = re.compile(b'(.*) \(([a-z0-9 +.]*) \?\)\n$')
+optline = re.compile(b'(.+) \((.+?) \?\)\n$')
+
 def cdatasafe(data):
 """Make a string safe to include in a CDATA block.
@@ -1271,8 +1274,19 @@
 if r:
 els.pop(i)
 break
-if el and el.endswith(b" (?)\n"):
-optional.append(i)
+if el:
+if el.endswith(b" (?)\n"):
+optional.append(i)
+else:
+m = optline.match(el)
+if m:
+conditions = [c for c in  
m.group(2).split(' ')]

+
+if self._hghave(conditions)[0]:
+lout = el
+else:
+optional.append(i)
+
 i += 1
if r:
@@ -1298,8 +1312,10 @@
 # clean up any optional leftovers
 while expected.get(pos, None):
 el = expected[pos].pop(0)
-if el and not el.endswith(b" (?)\n"):
-break
+if el:
+if (not optline.match(el)
+and not el.endswith(b" (?)\n")):
+break
 postout.append(b'  ' + el)
if lcmd:
@@ -1371,6 +1387,12 @@
 if el.endswith(b" (?)\n"):
 retry = "retry"
 el = el[:-5] + b"\n"
+else:
+m = optline.match(el)
+if m:
+el = m.group(1) + b"\n"
+retry = "retry"
+
 if el.endswith(b" (esc)\n"):
 if PYTHON3:
 el = el[:-7].decode('unicode_escape') + '\n'
diff --git a/tests/test-clone.t b/tests/test-clone.t
--- a/tests/test-clone.t
+++ b/tests/test-clone.t
@@ -31,10 +31,10 @@
   default   10:a7949464abda
   $ ls .hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
-  checknoexec
+  checkisexec (execbit ?)
+  checklink (symlink ?)
+  checklink-target (symlink ?)
+  checknoexec (execbit ?)
   rbc-names-v1
   rbc-revs-v1
@@ -49,9 +49,9 @@
  $ ls .hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
+  checkisexec (execbit ?)
+  checklink (symlink ?)
+  checklink-target (symlink ?)
  $ cat a
   a
diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -441,10 +441,10 @@
   M b2
   A 1k
   A 2k
-  A b2link
+  A b2link (no-windows ?)
   A bin
   A c1
-  A con.xml
+  A con.xml (no-windows ?)
   R a2
   $ hg status --change 2
   M b2
@@ -452,10 +452,10 @@
   M b2
   A 1k
   A 2k
-  A b2link
+  A b2link (no-windows ?)
   A bin
   A c1
-  A con.xml
+  A con.xml (no-windows ?)
   R a2
   $ hg status --change 4
   A .hgsub
@@ -464,7 +464,7 @@
   A dos
   A mac
   A mixed
-  R co

Re: [PATCH RFC] run-tests: support per-line conditional output in tests

2017-04-06 Thread Matt Harbison

On Thu, 06 Apr 2017 18:27:31 -0400, Jun Wu  wrote:


Excerpts from Matt Harbison's message of 2017-04-04 00:01:55 -0400:
The only thing that I haven't figured out yet is why the '(glob)'  
interferes
in the first hardlink.t hunk.  If it is kept, that line falls to the  
bottom of
the (xxx ?) sequence on Windows.  As it is, this test runs cleanly on  
Linux.


From 6a672c3b7860, it seems we may be able to just say 2 there:

  -  ? r4/.hg/cache/checklink-target (glob)
  +  2 r4/.hg/cache/checklink-target


Interesting.  That's the commit that changed it from a number to the glob,  
so I assumed that it was important.  I did manage to fix the issue, and  
don't have OS X in front of me, so I'll leave that alone for now.



I like this feature.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4 V2] run-tests: prevent a (glob) declaration from reordering (?) lines

2017-04-06 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491444033 14400
#  Wed Apr 05 22:00:33 2017 -0400
# Node ID c0789426514615cd841a31f60688516f2cdeaae0
# Parent  81abd0d12c8641df666d356f6033d84cd55977a8
run-tests: prevent a (glob) declaration from reordering (?) lines

Previously, if a series of optional output lines marked with '(?)' had a (glob)
in one of the first lines, the output would be reordered such that it came last
if none of the lines were output.  The (re) declaration wasn't affected, which
was helpful in figuring this out.  There were no tests for '(re) (?)' so add
that to make sure everything plays nice.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1385,7 +1385,7 @@
 # ignore '(glob)' added to l by 'replacements'
 if l.endswith(b" (glob)\n"):
 l = l[:-8] + b"\n"
-return TTest.globmatch(el[:-8], l)
+return TTest.globmatch(el[:-8], l) or retry
 if os.altsep and l.replace(b'\\', b'/') == el:
 return b'+glob'
 return retry
diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t
--- a/tests/test-run-tests.t
+++ b/tests/test-run-tests.t
@@ -55,7 +55,10 @@
   >   $ echo babar
   >   babar
   >   $ echo xyzzy
+  >   dont_print (?)
+  >   nothing[42]line (re) (?)
   >   never*happens (glob) (?)
+  >   more_nothing (?)
   >   xyzzy
   >   nor this (?)
   >   $ printf 'abc\ndef\nxyz\n'
@@ -326,14 +329,14 @@
   *SALT* 2 0 (glob)
   + echo xyzzy
   xyzzy
-  + echo *SALT* 6 0 (glob)
-  *SALT* 6 0 (glob)
+  + echo *SALT* 9 0 (glob)
+  *SALT* 9 0 (glob)
   + printf *abc\ndef\nxyz\n* (glob)
   abc
   def
   xyz
-  + echo *SALT* 12 0 (glob)
-  *SALT* 12 0 (glob)
+  + echo *SALT* 15 0 (glob)
+  *SALT* 15 0 (glob)
   .
   # Ran 2 tests, 0 skipped, 0 warned, 0 failed.
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4 V2] test-run-tests: pad the failure test to preserve the run order

2017-04-06 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491447584 14400
#  Wed Apr 05 22:59:44 2017 -0400
# Node ID 7c5e861f39fbffdfae0e31d1edba419a62391afe
# Parent  c0789426514615cd841a31f60688516f2cdeaae0
test-run-tests: pad the failure test to preserve the run order

Test size seems to dictate the order in which the tests are run, and the next
patch will add to test-success.t.  Similar to c0cecc153d25.

diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t
--- a/tests/test-run-tests.t
+++ b/tests/test-run-tests.t
@@ -107,6 +107,10 @@
   > this test is still more bytes than success.
   > pad pad pad pad
   > pad pad pad pad
+  > pad pad pad pad
+  > pad pad pad pad
+  > pad pad pad pad
+  > pad pad pad pad
   > EOF
 
   >>> fh = open('test-failure-unicode.t', 'wb')
@@ -319,8 +323,8 @@
   *SALT* 0 0 (glob)
   + echo babar
   babar
-  + echo *SALT* 6 0 (glob)
-  *SALT* 6 0 (glob)
+  + echo *SALT* 10 0 (glob)
+  *SALT* 10 0 (glob)
   *+ echo *SALT* 0 0 (glob)
   *SALT* 0 0 (glob)
   + echo babar
@@ -415,6 +419,10 @@
   this test is still more bytes than success.
   pad pad pad pad
   pad pad pad pad
+  pad pad pad pad
+  pad pad pad pad
+  pad pad pad pad
+  pad pad pad pad
 
 Interactive with custom view
 
@@ -452,13 +460,15 @@
   
   --- $TESTTMP/test-failure.t
   +++ $TESTTMP/test-failure.t.err
-  @@ -1,11 +1,11 @@
+  @@ -1,5 +1,5 @@
  $ echo babar
   -  rataxes
   +  babar
This is a noop statement so that
this test is still more bytes than success.
pad pad pad pad
+  @@ -9,7 +9,7 @@
+   pad pad pad pad
pad pad pad pad
  $ echo 'saved backup bundle to $TESTTMP/foo.hg'
   -  saved backup bundle to $TESTTMP/foo.hg
@@ -476,6 +486,10 @@
   this test is still more bytes than success.
   pad pad pad pad
   pad pad pad pad
+  pad pad pad pad
+  pad pad pad pad
+  pad pad pad pad
+  pad pad pad pad
 $ echo 'saved backup bundle to $TESTTMP/foo.hg'
 saved backup bundle to $TESTTMP/foo.hg (glob)<
 $ echo 'saved backup bundle to $TESTTMP/foo.hg'
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4 V2] tests: add per-line output conditionals for Windows

2017-04-06 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491450262 14400
#  Wed Apr 05 23:44:22 2017 -0400
# Node ID 8ccde224a46cd70f1586fcc769ff65a80ddbf354
# Parent  8e3cf915084723551d0b68094cede7e65f49cf39
tests: add per-line output conditionals for Windows

diff --git a/tests/test-clone.t b/tests/test-clone.t
--- a/tests/test-clone.t
+++ b/tests/test-clone.t
@@ -31,10 +31,10 @@
   default   10:a7949464abda
   $ ls .hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
-  checknoexec
+  checkisexec (execbit !)
+  checklink (symlink !)
+  checklink-target (symlink !)
+  checknoexec (execbit !)
   rbc-names-v1
   rbc-revs-v1
 
@@ -49,9 +49,9 @@
 
   $ ls .hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
+  checkisexec (execbit !)
+  checklink (symlink !)
+  checklink-target (symlink !)
 
   $ cat a
   a
diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -441,10 +441,10 @@
   M b2
   A 1k
   A 2k
-  A b2link
+  A b2link (no-windows !)
   A bin
   A c1
-  A con.xml
+  A con.xml (no-windows !)
   R a2
   $ hg status --change 2
   M b2
@@ -452,10 +452,10 @@
   M b2
   A 1k
   A 2k
-  A b2link
+  A b2link (no-windows !)
   A bin
   A c1
-  A con.xml
+  A con.xml (no-windows !)
   R a2
   $ hg status --change 4
   A .hgsub
@@ -464,7 +464,7 @@
   A dos
   A mac
   A mixed
-  R con.xml
+  R con.xml (no-windows !)
   ! a1
   ? b2.orig
   ? c3
@@ -551,9 +551,9 @@
 
 
   $ hg status --removed  --rev 4
-  R con.xml
+  R con.xml (no-windows !)
   $ fileset "status(4, 'wdir()', removed())"
-  con.xml
+  con.xml (no-windows !)
 
   $ hg status --removed --rev 2
   R a2
@@ -585,19 +585,19 @@
   A .hgsubstate
   A 1k
   A 2k
-  A b2link
+  A b2link (no-windows !)
   A bin
   A c1
-  A con.xml
+  A con.xml (no-windows !)
   $ fileset "status('0:1', '3:4', added())"
   .hgsub
   .hgsubstate
   1k
   2k
-  b2link
+  b2link (no-windows !)
   bin
   c1
-  con.xml
+  con.xml (no-windows !)
 
 tests with empty value
 --
diff --git a/tests/test-hardlinks.t b/tests/test-hardlinks.t
--- a/tests/test-hardlinks.t
+++ b/tests/test-hardlinks.t
@@ -211,10 +211,10 @@
   2 r4/.hg/00changelog.i
   2 r4/.hg/branch
   2 r4/.hg/cache/branch2-served
-  2 r4/.hg/cache/checkisexec
+  2 r4/.hg/cache/checkisexec (execbit !)
   3 r4/.hg/cache/checklink (?)
-  ? r4/.hg/cache/checklink-target (glob)
-  2 r4/.hg/cache/checknoexec
+  ? r4/.hg/cache/checklink-target (glob) (symlink !)
+  2 r4/.hg/cache/checknoexec (execbit !)
   2 r4/.hg/cache/rbc-names-v1
   2 r4/.hg/cache/rbc-revs-v1
   2 r4/.hg/dirstate
@@ -251,9 +251,9 @@
   2 r4/.hg/00changelog.i
   1 r4/.hg/branch
   2 r4/.hg/cache/branch2-served
-  2 r4/.hg/cache/checkisexec
-  2 r4/.hg/cache/checklink-target
-  2 r4/.hg/cache/checknoexec
+  2 r4/.hg/cache/checkisexec (execbit !)
+  2 r4/.hg/cache/checklink-target (symlink !)
+  2 r4/.hg/cache/checknoexec (execbit !)
   2 r4/.hg/cache/rbc-names-v1
   2 r4/.hg/cache/rbc-revs-v1
   1 r4/.hg/dirstate
diff --git a/tests/test-tags.t b/tests/test-tags.t
--- a/tests/test-tags.t
+++ b/tests/test-tags.t
@@ -672,9 +672,9 @@
 
   $ ls tagsclient/.hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
+  checkisexec (execbit !)
+  checklink (symlink !)
+  checklink-target (symlink !)
   hgtagsfnodes1
   rbc-names-v1
   rbc-revs-v1
@@ -699,9 +699,9 @@
 
   $ ls tagsclient/.hg/cache
   branch2-served
-  checkisexec
-  checklink
-  checklink-target
+  checkisexec (execbit !)
+  checklink (symlink !)
+  checklink-target (symlink !)
   hgtagsfnodes1
   rbc-names-v1
   rbc-revs-v1
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4 V2] run-tests: support per-line conditional output in tests

2017-04-06 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491448647 14400
#  Wed Apr 05 23:17:27 2017 -0400
# Node ID 8e3cf915084723551d0b68094cede7e65f49cf39
# Parent  7c5e861f39fbffdfae0e31d1edba419a62391afe
run-tests: support per-line conditional output in tests

Duplicating entire tests just because the output is different is both error
prone and can make the tests harder to read.  This harnesses the existing '(?)'
infrastructure, both to improve readability, and because it seemed like the path
of least resistance.

The form is:

  $ test_cmd
  output (hghave-feature !) # required if hghave.has_feature(), else optional
  out2 (no-hghave-feature2 !) # req if not hghave.has_feature2(), else optional

I originally extended the '(?)' syntax.  For example, this:

  2 r4/.hg/cache/checkisexec (execbit ?)

pretty naturally reads as "checkisexec, if execbit".  In some ways though, this
inverts the meaning of '?'.  For '(?)', the line is purely optional.  In the
example, it is mandatory iff execbit.  Otherwise, it is carried forward as
optional, to preserve the test output.  I tried it the other way, (listing
'no-exec' in the example), but that is too confusing to read.  Kostia suggested
using '!', and that seems fine.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -497,6 +497,12 @@
 # sans \t, \n and \r
 CDATA_EVIL = re.compile(br"[\000-\010\013\014\016-\037]")
 
+# Match feature conditionalized output lines in the form, capturing the feature
+# list in group 2, and the preceeding line output in group 1:
+#
+#   output..output (feature !)\n
+optline = re.compile(b'(.+) \((.+?) !\)\n$')
+
 def cdatasafe(data):
 """Make a string safe to include in a CDATA block.
 
@@ -1271,8 +1277,19 @@
 if r:
 els.pop(i)
 break
-if el and el.endswith(b" (?)\n"):
-optional.append(i)
+if el:
+if el.endswith(b" (?)\n"):
+optional.append(i)
+else:
+m = optline.match(el)
+if m:
+conditions = [c for c in m.group(2).split(' ')]
+
+if self._hghave(conditions)[0]:
+lout = el
+else:
+optional.append(i)
+
 i += 1
 
 if r:
@@ -1298,8 +1315,10 @@
 # clean up any optional leftovers
 while expected.get(pos, None):
 el = expected[pos].pop(0)
-if el and not el.endswith(b" (?)\n"):
-break
+if el:
+if (not optline.match(el)
+and not el.endswith(b" (?)\n")):
+break
 postout.append(b'  ' + el)
 
 if lcmd:
@@ -1371,6 +1390,12 @@
 if el.endswith(b" (?)\n"):
 retry = "retry"
 el = el[:-5] + b"\n"
+else:
+m = optline.match(el)
+if m:
+el = m.group(1) + b"\n"
+retry = "retry"
+
 if el.endswith(b" (esc)\n"):
 if PYTHON3:
 el = el[:-7].decode('unicode_escape') + '\n'
diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t
--- a/tests/test-run-tests.t
+++ b/tests/test-run-tests.t
@@ -39,6 +39,19 @@
   $ rm hg
 #endif
 
+Features for testing optional lines
+===
+
+  $ cat > hghaveaddon.py < import hghave
+  > @hghave.check("custom", "custom hghave feature")
+  > def has_custom():
+  > return True
+  > @hghave.check("missing", "missing hghave feature")
+  > def has_missing():
+  > return False
+  > EOF
+
 an empty test
 ===
 
@@ -67,6 +80,13 @@
   >   def (?)
   >   456 (?)
   >   xyz
+  >   $ printf 'zyx\nwvu\ntsr\n'
+  >   abc (?)
+  >   zyx (custom !)
+  >   wvu
+  >   no_print (no-custom !)
+  >   tsr (no-missing !)
+  >   missing (missing !)
   > EOF
 
   $ rt
@@ -341,6 +361,12 @@
   xyz
   + echo *SALT* 15 0 (glob)
   *SALT* 15 0 (glob)
+  + printf 'zyx\nwvu\ntsr\n'
+  zyx
+  wvu
+  tsr
+  + echo *SALT* 22 0 (glob)
+  *SALT* 22 0 (glob)
   .
   # Ran 2 tests, 0 skipped, 0 warned, 0 failed.
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 07 of 10 V5] rcutil: let environ override system configs (BC)

2017-04-06 Thread Matt Harbison

On Mon, 27 Mar 2017 02:02:06 -0400, Jun Wu  wrote:


# HG changeset patch
# User Jun Wu 
# Date 1490589217 25200
#  Sun Mar 26 21:33:37 2017 -0700
# Node ID 38572bb2cffd815526a727bc6f3aacdca2902f4f
# Parent  9b0aa30bf151b6c0e999b017fd328e29440bd447
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r  
38572bb2cffd

rcutil: let environ override system configs (BC)

This is BC because system configs won't be able to override $EDITOR,  
$PAGER.

The new behavior is arguably more rational.


I'm not sure if this is a broader concern than just the test suite with  
env-based config, but I bisected a new Windows failure back to this change.


--- c:/Users/Matt/Projects/hg/tests/test-check-code.t
+++ c:/Users/Matt/Projects/hg/tests/test-check-code.t.err
@@ -9,34 +9,7 @@

   $ hg locate -X contrib/python-zstandard -X hgext/fsmonitor/pywatchman |
   > sed 's-\\-/-g' | xargs "$check_code" --warnings --per-file=0 || false
-  Skipping i18n/polib.py it has no-che?k-code (glob)
-  mercurial/demandimport.py:312:
-   > if os.environ.get('HGDEMANDIMPORT') != 'disable':
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:54:
-   > environ = os.environ
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:56:
-   > environ = os.environb
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:61:
-   >for k, v in os.environ.items())
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:221:
-   >for k, v in os.environ.items())
-   use encoding.environ instead (py3)
-  Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
-  Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob)
-  mercurial/policy.py:46:
-   > if 'HGMODULEPOLICY' in os.environ:
-   use encoding.environ instead (py3)
-  mercurial/policy.py:47:
-   > policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
-   use encoding.environ instead (py3)
-  mercurial/policy.py:49:
-   > policy = os.environ.get('HGMODULEPOLICY', policy)
-   use encoding.environ instead (py3)
-  Skipping mercurial/statprof.py it has no-che?k-code (glob)
+  /usr/bin/env: python: Bad file number
   [1]

 @commands in debugcommands.py should be in alphabetical order.



diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1807,4 +1807,6 @@ def config(ui, repo, *values, **opts):
 if t == 'path':
 ui.debug('read config from: %s\n' % f)
+elif t == 'items':
+pass
 else:
 raise error.ProgrammingError('unknown rctype: %s' % t)
diff --git a/mercurial/rcutil.py b/mercurial/rcutil.py
--- a/mercurial/rcutil.py
+++ b/mercurial/rcutil.py
@@ -77,8 +77,12 @@ def rccomponents():
 name, value, source) that should fill the config directly.
 '''
+envrc = ('items', envrcitems())
+
 global _rccomponents
 if _rccomponents is None:
 if 'HGRCPATH' in encoding.environ:
-_rccomponents = []
+# assume HGRCPATH is all about user configs so environments  
can be

+# overridden.
+_rccomponents = [envrc]
 for p in  
encoding.environ['HGRCPATH'].split(pycompat.ospathsep):

 if not p:
@@ -86,5 +90,8 @@ def rccomponents():
 _rccomponents.extend(('path', p) for p in  
_expandrcpath(p))

 else:
-paths = defaultrcpath() + systemrcpath() + userrcpath()
+paths = defaultrcpath() + systemrcpath()
 _rccomponents = [('path', os.path.normpath(p)) for p in  
paths]

+_rccomponents.append(envrc)
+paths = userrcpath()
+_rccomponents.extend(('path', os.path.normpath(p)) for p in  
paths)

 return _rccomponents
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -212,8 +212,18 @@ class ui(object):
 """Create a ui and load global and user configs"""
 u = cls()
-# we always trust global config files
+# we always trust global config files and environment variables
 for t, f in rcutil.rccomponents():
 if t == 'path':
 u.readconfig(f, trust=True)
+elif t == 'items':
+sections = set()
+for section, name, value, source in f:
+# do not set u._ocfg
+# XXX clean this up once immutable config object is  
a thing

+u._tcfg.set(section, name, value, source)
+u._ucfg.set(section, name, value, source)
+sections.add(section)
+for section in sections:
+u.fixconfig(section=section)
 else:
 raise error.ProgrammingError('unknown rctype: %s' % t)
diff --git a/tests/test-config-env.py b/tests/test-config-env.py
new fil

Re: [PATCH RFC] run-tests: support per-line conditional output in tests

2017-04-06 Thread Matt Harbison

On Thu, 06 Apr 2017 20:15:41 -0400, Jun Wu  wrote:


Excerpts from Matt Harbison's message of 2017-04-06 20:06:02 -0400:

On Thu, 06 Apr 2017 18:27:31 -0400, Jun Wu  wrote:

> Excerpts from Matt Harbison's message of 2017-04-04 00:01:55 -0400:
>> The only thing that I haven't figured out yet is why the '(glob)'
>> interferes
>> in the first hardlink.t hunk.  If it is kept, that line falls to the
>> bottom of
>> the (xxx ?) sequence on Windows.  As it is, this test runs cleanly on
>> Linux.
>
> From 6a672c3b7860, it seems we may be able to just say 2 there:
>
>   -  ? r4/.hg/cache/checklink-target (glob)
>   +  2 r4/.hg/cache/checklink-target

Interesting.  That's the commit that changed it from a number to the  
glob,

so I assumed that it was important.  I did manage to fix the issue, and
don't have OS X in front of me, so I'll leave that alone for now.


The minus and plus signs are the change I think we can make, not the  
patch

introduced.


Yep.  I misread original commit.

6a672c3b7860 is inconsistent about "checklink-target" it added to the  
test.
One of them uses "?", the other uses "2". So I think we can change it to  
"2"

without issues.


If that's true, then I guess the 'checklink (?)' line is unnecessary too,  
because it isn't in the later test either.  I don't have access to  
Solaris, but I'll try to check on OS X tomorrow if I remember.




> I like this feature.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 07 of 10 V5] rcutil: let environ override system configs (BC)

2017-04-06 Thread Matt Harbison

On Thu, 06 Apr 2017 23:50:31 -0400, Jun Wu  wrote:


Excerpts from Matt Harbison's message of 2017-04-06 23:14:50 -0400:

On Mon, 27 Mar 2017 02:02:06 -0400, Jun Wu  wrote:

> # HG changeset patch
> # User Jun Wu 
> # Date 1490589217 25200
> #  Sun Mar 26 21:33:37 2017 -0700
> # Node ID 38572bb2cffd815526a727bc6f3aacdca2902f4f
> # Parent  9b0aa30bf151b6c0e999b017fd328e29440bd447
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #  hg pull https://bitbucket.org/quark-zju/hg-draft  -r
> 38572bb2cffd
> rcutil: let environ override system configs (BC)
>
> This is BC because system configs won't be able to override $EDITOR,
> $PAGER.
> The new behavior is arguably more rational.

I'm not sure if this is a broader concern than just the test suite with
env-based config, but I bisected a new Windows failure back to this  
change.


How did you run tests under Windows? I couldn't reproduce this using  
cygwin.

(and I have difficulty with "sh" when using the MSVC compiler)


I have MinGW installed, and from the tests directory just run "./run-tests  
--local test-check-code.t".  I have MSVC 2008 installed, which I assume is  
what is used.




--- c:/Users/Matt/Projects/hg/tests/test-check-code.t
+++ c:/Users/Matt/Projects/hg/tests/test-check-code.t.err
@@ -9,34 +9,7 @@

$ hg locate -X contrib/python-zstandard -X  
hgext/fsmonitor/pywatchman |
> sed 's-\\-/-g' | xargs "$check_code" --warnings --per-file=0 ||  
false

-  Skipping i18n/polib.py it has no-che?k-code (glob)
-  mercurial/demandimport.py:312:
-   > if os.environ.get('HGDEMANDIMPORT') != 'disable':
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:54:
-   > environ = os.environ
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:56:
-   > environ = os.environb
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:61:
-   >for k, v in os.environ.items())
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:221:
-   >for k, v in os.environ.items())
-   use encoding.environ instead (py3)
-  Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
-  Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob)
-  mercurial/policy.py:46:
-   > if 'HGMODULEPOLICY' in os.environ:
-   use encoding.environ instead (py3)
-  mercurial/policy.py:47:
-   > policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
-   use encoding.environ instead (py3)
-  mercurial/policy.py:49:
-   > policy = os.environ.get('HGMODULEPOLICY', policy)
-   use encoding.environ instead (py3)
-  Skipping mercurial/statprof.py it has no-che?k-code (glob)
+  /usr/bin/env: python: Bad file number
[1]

  @commands in debugcommands.py should be in alphabetical order.

> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -1807,4 +1807,6 @@ def config(ui, repo, *values, **opts):
>  if t == 'path':
>  ui.debug('read config from: %s\n' % f)
> +elif t == 'items':
> +pass
>  else:
>  raise error.ProgrammingError('unknown rctype: %s' % t)
> diff --git a/mercurial/rcutil.py b/mercurial/rcutil.py
> --- a/mercurial/rcutil.py
> +++ b/mercurial/rcutil.py
> @@ -77,8 +77,12 @@ def rccomponents():
>  name, value, source) that should fill the config directly.
>  '''
> +envrc = ('items', envrcitems())
> +
>  global _rccomponents
>  if _rccomponents is None:
>  if 'HGRCPATH' in encoding.environ:
> -_rccomponents = []
> +# assume HGRCPATH is all about user configs so  
environments

> can be
> +# overridden.
> +_rccomponents = [envrc]
>  for p in
> encoding.environ['HGRCPATH'].split(pycompat.ospathsep):
>  if not p:
> @@ -86,5 +90,8 @@ def rccomponents():
>  _rccomponents.extend(('path', p) for p in
> _expandrcpath(p))
>  else:
> -paths = defaultrcpath() + systemrcpath() + userrcpath()
> +paths = defaultrcpath() + systemrcpath()
>  _rccomponents = [('path', os.path.normpath(p)) for p in
> paths]
> +_rccomponents.append(envrc)
> +paths = userrcpath()
> +_rccomponents.extend(('path', os.path.normpath(p)) for p  
in

> paths)
>  return _rccomponents
> diff --git a/mercurial/ui.py b/mercurial/ui.py
> --- a/mercurial/ui.py
> +++ b/mercurial/ui.py
> @@ -212,8 +212,18 @@ class ui(object):
>  """Create a ui and load global and user configs"""
>  u = cls()
> -# we always trust global config files
> +# we always trust global config files and environment  
variables

>  for t, f in rcutil.rccomponents():
>  if t == 'path':
>  u.readconfig(f, trust=True)
> +elif t == 'items':
> +sections = set()
> +for section, name

Re: [PATCH 07 of 10 V5] rcutil: let environ override system configs (BC)

2017-04-06 Thread Matt Harbison

On Fri, 07 Apr 2017 00:25:03 -0400, Jun Wu  wrote:


Excerpts from Matt Harbison's message of 2017-04-07 00:09:54 -0400:

On Thu, 06 Apr 2017 23:50:31 -0400, Jun Wu  wrote:

> Excerpts from Matt Harbison's message of 2017-04-06 23:14:50 -0400:
>> On Mon, 27 Mar 2017 02:02:06 -0400, Jun Wu  wrote:
>>
>> > # HG changeset patch
>> > # User Jun Wu 
>> > # Date 1490589217 25200
>> > #  Sun Mar 26 21:33:37 2017 -0700
>> > # Node ID 38572bb2cffd815526a727bc6f3aacdca2902f4f
>> > # Parent  9b0aa30bf151b6c0e999b017fd328e29440bd447
>> > # Available At https://bitbucket.org/quark-zju/hg-draft
>> > #  hg pull https://bitbucket.org/quark-zju/hg-draft
-r

>> > 38572bb2cffd
>> > rcutil: let environ override system configs (BC)
>> >
>> > This is BC because system configs won't be able to override  
$EDITOR,

>> > $PAGER.
>> > The new behavior is arguably more rational.
>>
>> I'm not sure if this is a broader concern than just the test suite  
with

>> env-based config, but I bisected a new Windows failure back to this
>> change.
>
> How did you run tests under Windows? I couldn't reproduce this using
> cygwin.
> (and I have difficulty with "sh" when using the MSVC compiler)

I have MinGW installed, and from the tests directory just run  
"./run-tests
--local test-check-code.t".  I have MSVC 2008 installed, which I assume  
is

what is used.


Just to confirm: if you run "make local", it will say "cl.exe ..."  
instead

of "gcc ..." (where gcc could come from MinGW).


Yep.

$ make local | grep cl.exe
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\cl.exe /c  
/nologo /Ox /MD /W3 /GS- /DNDEBUG -Ic:\Python27\include -Ic:\Python27\PC  
/Tcmercurial/bdiff.c  
/Fobuild\temp.win-amd64-2.7\Release\mercurial/bdiff.obj

...


And you are using Python for
Windows, not some cygwin or mingw Python.


Correct.  2.7.13, from the python.org Windows installer.


And the shell is provided by MinGW.


I've never had cygwin or anything else installed.  The titlebar says  
"MINGW32", and $SHELL is /bin/sh.  Not sure if there's something specific  
I should check here.




>>
>> --- c:/Users/Matt/Projects/hg/tests/test-check-code.t
>> +++ c:/Users/Matt/Projects/hg/tests/test-check-code.t.err
>> @@ -9,34 +9,7 @@
>>
>> $ hg locate -X contrib/python-zstandard -X
>> hgext/fsmonitor/pywatchman |
>> > sed 's-\\-/-g' | xargs "$check_code" --warnings --per-file=0 ||
>> false
>> -  Skipping i18n/polib.py it has no-che?k-code (glob)
>> -  mercurial/demandimport.py:312:
>> -   > if os.environ.get('HGDEMANDIMPORT') != 'disable':
>> -   use encoding.environ instead (py3)
>> -  mercurial/encoding.py:54:
>> -   > environ = os.environ
>> -   use encoding.environ instead (py3)
>> -  mercurial/encoding.py:56:
>> -   > environ = os.environb
>> -   use encoding.environ instead (py3)
>> -  mercurial/encoding.py:61:
>> -   >for k, v in os.environ.items())
>> -   use encoding.environ instead (py3)
>> -  mercurial/encoding.py:221:
>> -   >for k, v in os.environ.items())
>> -   use encoding.environ instead (py3)
>> -  Skipping mercurial/httpclient/__init__.py it has no-che?k-code  
(glob)
>> -  Skipping mercurial/httpclient/_readers.py it has no-che?k-code  
(glob)

>> -  mercurial/policy.py:46:
>> -   > if 'HGMODULEPOLICY' in os.environ:
>> -   use encoding.environ instead (py3)
>> -  mercurial/policy.py:47:
>> -   > policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
>> -   use encoding.environ instead (py3)
>> -  mercurial/policy.py:49:
>> -   > policy = os.environ.get('HGMODULEPOLICY', policy)
>> -   use encoding.environ instead (py3)
>> -  Skipping mercurial/statprof.py it has no-che?k-code (glob)
>> +  /usr/bin/env: python: Bad file number
>> [1]
>>
>>   @commands in debugcommands.py should be in alphabetical order.
>>
>> > diff --git a/mercurial/commands.py b/mercurial/commands.py
>> > --- a/mercurial/commands.py
>> > +++ b/mercurial/commands.py
>> > @@ -1807,4 +1807,6 @@ def config(ui, repo, *values, **opts):
>> >  if t == 'path':
>> >  ui.debug('read config from: %s\n' % f)
>> > +elif t == 'items':
>> > +pass
>> >  else:
>> >  raise error.ProgrammingError('unknown rctype: %s' % t)
>> > diff --git a/mercurial/rcutil.py b/mercurial/rcutil.py
>> > --- a/mercurial/rcutil.py
>> > +++ b/mercurial/rcutil.py
>> > @@ -77,8 +77,12 @@ def rccomponents():
>> >  name, value, source) that should fill the config directly.
>> >  '''
>> > +envrc = ('items', envrcitems())
>> > +
>> >  global _rccomponents
>> >  if _rccomponents is None:
>> >  if 'HGRCPATH' in encoding.environ:
>> > -_rccomponents = []
>> > +# assume HGRCPATH is all about user configs so
>> environments
>> > can be
>> > +# overridden.
>> > +_rccomponents = [envrc]
>> >  for p in
>> > encoding.environ['HGRCPATH'].split(pycompat.ospathsep):
>> >  

Re: [PATCH 3 of 4 V2] run-tests: support per-line conditional output in tests

2017-04-07 Thread Matt Harbison

> On Apr 7, 2017, at 5:23 AM, Ryan McElroy  wrote:
> 
>> On 4/7/17 2:11 AM, Matt Harbison wrote:
>> # HG changeset patch
>> # User Matt Harbison 
>> # Date 1491448647 14400
>> #  Wed Apr 05 23:17:27 2017 -0400
>> # Node ID 8e3cf915084723551d0b68094cede7e65f49cf39
>> # Parent  7c5e861f39fbffdfae0e31d1edba419a62391afe
>> run-tests: support per-line conditional output in tests
> 
> This series looks like a huge win for test de-duplication! Thanks for working 
> on it.
> 
>> 
>> Duplicating entire tests just because the output is different is both error
>> prone and can make the tests harder to read.  This harnesses the existing 
>> '(?)'
>> infrastructure, both to improve readability, and because it seemed like the 
>> path
>> of least resistance.
>> 
>> The form is:
>> 
>>   $ test_cmd
>>   output (hghave-feature !) # required if hghave.has_feature(), else optional
>>   out2 (no-hghave-feature2 !) # req if not hghave.has_feature2(), else 
>> optional
> 
> My only question is: why is it optional if the feature is not present? It 
> seems like maybe we should have two things:
> 
> ! = must be present iff feature
> !? = must be present if feature
> 
> (NOTE: that the first is two-f "iff" -- as in "if and only if" -- so if the 
> feature is not present, and the line is still there, that would be a failure. 
> The second one is the one-f "if", as in, "optional if not true".)

It's an inherent property of the (?) infrastructure that was used, rather than 
a design goal.  I have no problem with someone refining it like you propose.  
But I think that splitting will only prevent cruft from accumulating (which 
isn't a bad thing). I'm struggling to come up with a scenario where we want to 
fail the iff case other than because the condition is unnecessary.

> Regardless, I think this could be done as a follow-up and I only if it's a 
> good idea. I've marked this series as pre-reviewed in patchwork.
> 
>> 
>> I originally extended the '(?)' syntax.  For example, this:
>> 
>>   2 r4/.hg/cache/checkisexec (execbit ?)
>> 
>> pretty naturally reads as "checkisexec, if execbit".  In some ways though, 
>> this
>> inverts the meaning of '?'.  For '(?)', the line is purely optional.  In the
>> example, it is mandatory iff execbit.  Otherwise, it is carried forward as
>> optional, to preserve the test output.  I tried it the other way, (listing
>> 'no-exec' in the example), but that is too confusing to read.  Kostia 
>> suggested
>> using '!', and that seems fine.
>> 
>> diff --git a/tests/run-tests.py b/tests/run-tests.py
>> --- a/tests/run-tests.py
>> +++ b/tests/run-tests.py
>> @@ -497,6 +497,12 @@
>>  # sans \t, \n and \r
>>  CDATA_EVIL = re.compile(br"[\000-\010\013\014\016-\037]")
>>  +# Match feature conditionalized output lines in the form, capturing the 
>> feature
>> +# list in group 2, and the preceeding line output in group 1:
>> +#
>> +#   output..output (feature !)\n
>> +optline = re.compile(b'(.+) \((.+?) !\)\n$')
>> +
>>  def cdatasafe(data):
>>  """Make a string safe to include in a CDATA block.
>>  @@ -1271,8 +1277,19 @@
>>  if r:
>>  els.pop(i)
>>  break
>> -if el and el.endswith(b" (?)\n"):
>> -optional.append(i)
>> +if el:
>> +if el.endswith(b" (?)\n"):
>> +optional.append(i)
>> +else:
>> +m = optline.match(el)
>> +if m:
>> +conditions = [c for c in m.group(2).split(' 
>> ')]
>> +
>> +if self._hghave(conditions)[0]:
>> +lout = el
>> +else:
>> +optional.append(i)
>> +
>>  i += 1
>>if r:
>> @@ -1298,8 +1315,10 @@
>>  # clean up any optional leftovers
>>  while expected.get(pos, None):
>>  el = expected[pos].pop(0)
>> -if el and not el.endswith(b" (?)\n"):
>> -break
>> +if el:
>> 

Re: [PATCH 07 of 10 V5] rcutil: let environ override system configs (BC)

2017-04-07 Thread Matt Harbison

On Fri, 07 Apr 2017 01:13:20 -0400, Jun Wu  wrote:


Excerpts from Matt Harbison's message of 2017-04-07 00:35:42 -0400:

> Just to confirm: if you run "make local", it will say "cl.exe ..."
> instead
> of "gcc ..." (where gcc could come from MinGW).

Yep.

$ make local | grep cl.exe
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\cl.exe  
/c

/nologo /Ox /MD /W3 /GS- /DNDEBUG -Ic:\Python27\include -Ic:\Python27\PC
/Tcmercurial/bdiff.c
/Fobuild\temp.win-amd64-2.7\Release\mercurial/bdiff.obj
...

> And you are using Python for
> Windows, not some cygwin or mingw Python.

Correct.  2.7.13, from the python.org Windows installer.

> And the shell is provided by MinGW.

I've never had cygwin or anything else installed.  The titlebar says
"MINGW32", and $SHELL is /bin/sh.  Not sure if there's something  
specific

I should check here.


Thanks. I have sent a fix.


That did the trick, thanks.  Out of curiosity, how did you figure you the  
problem from that error message?  xargs would have been the last thing I  
would have suspected.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] setup: use setuptools on Windows (issue5400)

2017-04-08 Thread Matt Harbison
On Thu, 09 Mar 2017 23:06:34 -0500, Gregory Szorc  
 wrote:



# HG changeset patch
# User Gregory Szorc 
# Date 1489118392 28800
#  Thu Mar 09 19:59:52 2017 -0800
# Node ID b51f9adb41e68d9f3d88582f044d2742ae29ce09
# Parent  cd29673cebdbe2d998009322e4c3657389d6aed0
setup: use setuptools on Windows (issue5400)

We've had a long, complicated history with setuptools. We want to
make it the universal default. But when we do, it breaks things.

`python setup.py build` is broken on Windows today. Forcing
the use of setuptools via FORCE_SETUPTOOLS=1 unbreaks things.

Since the previous bustage with making setuptools the default
was on !Windows, it seems safe to move ahead with the setuptools
transition on Windows. So this patch does that.


I'm not sure why, or what we should do about it, but test-hghave.t fails  
with this on Windows.  I can get a similar failure on Linux with  
FORCE_SETUPTOOLS=1.  Is this an expected diff with setuptools (and  
deserving a '(glob) (?)'?


--- c:/Users/Matt/Projects/hg/tests/test-hghave.t
+++ c:/Users/Matt/Projects/hg/tests/test-hghave.t.err
@@ -19,7 +19,11 @@
   >   foo
   > EOF
   $ run-tests.py $HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
+  warning: Testing with unexpected mercurial lib:  
C:\Users\Matt\AppData\Local\Temp\hgtests.ie8k3minstall\lib\python\mercurial-4.1.1-py2.7-win-amd64.egg\mercurial
+   (expected  
C:\Users\Matt\AppData\Local\Temp\hgtests.ie8k3m\install\lib\python\mercurial)

   .
+  warning: Tested with unexpected mercurial lib:  
C:\Users\Matt\AppData\Local\Temp\hgtests.ie8k3minstall\lib\python\mercurial-4.1.1-py2.7-win-amd64.egg\mercurial
+   (expected  
C:\Users\Matt\AppData\Local\Temp\hgtests.ie8k3m\install\lib\python\mercurial)

   # Ran 1 tests, 0 skipped, 0 warned, 0 failed.



diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -63,7 +63,10 @@ import re
 import shutil
 import tempfile
 from distutils import log
-if 'FORCE_SETUPTOOLS' in os.environ:
+# We have issues with setuptools on some platforms and builders. Until
+# those are resolved, setuptools is opt-in except for platforms where
+# we don't have issues.
+if os.name == 'nt' or 'FORCE_SETUPTOOLS' in os.environ:
 from setuptools import setup
 else:
 from distutils.core import setup
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] test-http-proxy: add the Windows variant of "connection refused"

2017-04-08 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491678405 14400
#  Sat Apr 08 15:06:45 2017 -0400
# Node ID 42c7df6da065e310c5685fbba2799ffe77d73afd
# Parent  651cf90e65f6c5f5717caa9779f268319e2bc676
test-http-proxy: add the Windows variant of "connection refused"

The full error is "No connection could be made because the target machine
actively refused it".

diff --git a/tests/test-http-proxy.t b/tests/test-http-proxy.t
--- a/tests/test-http-proxy.t
+++ b/tests/test-http-proxy.t
@@ -87,7 +87,7 @@
 misconfigured hosts)
 
   $ http_proxy=localhost:$HGPORT2 hg clone --config http_proxy.always=True 
http://localhost:$HGPORT/ f
-  abort: error: (Connection refused|Protocol not supported) (re)
+  abort: error: (Connection refused|Protocol not supported|.* actively refused 
it) (re)
   [255]
 
 do not use the proxy if it is in the no list
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] test-bundle: glob away a URL protocol separator

2017-04-08 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491677199 14400
#  Sat Apr 08 14:46:39 2017 -0400
# Node ID c6379326f01a27b12a8bd6c90c6a5995dfe70edf
# Parent  c39e7c4b535c654d5b2f7790efebff2909986a04
test-bundle: glob away a URL protocol separator

MSYS thinks the ':' is a Unix path separator, and replaces it with ';'.

diff --git a/tests/test-bundle.t b/tests/test-bundle.t
--- a/tests/test-bundle.t
+++ b/tests/test-bundle.t
@@ -232,7 +232,7 @@
   adding manifests
   adding file changes
   added 9 changesets with 7 changes to 4 files (+1 heads)
-  changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup 
HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 
HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull 
HG_TXNID=TXN:$ID$ HG_URL=bundle:../full.hg
+  changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup 
HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 
HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull 
HG_TXNID=TXN:$ID$ HG_URL=bundle*../full.hg (glob)
   (run 'hg heads' to see heads, 'hg merge' to merge)
 
 Rollback empty
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4] test-fileset: eliminate a duplicate test that was conditionalized for output

2017-04-08 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491678109 14400
#  Sat Apr 08 15:01:49 2017 -0400
# Node ID 651cf90e65f6c5f5717caa9779f268319e2bc676
# Parent  d236dca9355d6af70f20ba7966ccf903657a61c8
test-fileset: eliminate a duplicate test that was conditionalized for output

diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -348,7 +348,6 @@
 
 Test safety of 'encoding' on removed files
 
-#if symlink
   $ fileset 'encoding("ascii")'
   dos
   mac
@@ -359,23 +358,9 @@
   2k
   b1
   b2
-  b2link
+  b2link (symlink !)
   bin
   c1
-#else
-  $ fileset 'encoding("ascii")'
-  dos
-  mac
-  mixed
-  .hgsub
-  .hgsubstate
-  1k
-  2k
-  b1
-  b2
-  bin
-  c1
-#endif
 
 Test detection of unintentional 'matchctx.existing()' invocation
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] test-fileset: glob away hash differences

2017-04-08 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491677744 14400
#  Sat Apr 08 14:55:44 2017 -0400
# Node ID d236dca9355d6af70f20ba7966ccf903657a61c8
# Parent  c6379326f01a27b12a8bd6c90c6a5995dfe70edf
test-fileset: glob away hash differences

There are various files committed above that can't be used on Windows because of
the name, or being a symlink.

diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -403,15 +403,15 @@
 small reminder of the repository state
 
   $ hg log -G
-  @  changeset:   4:160936123545
+  @  changeset:   4:* (glob)
   |  tag: tip
   |  user:test
   |  date:Thu Jan 01 00:00:00 1970 +
   |  summary: subrepo
   |
-  ochangeset:   3:9d594e11b8c9
+  ochangeset:   3:* (glob)
   |\   parent:  2:55b05bdebf36
-  | |  parent:  1:830839835f98
+  | |  parent:  1:* (glob)
   | |  user:test
   | |  date:Thu Jan 01 00:00:00 1970 +
   | |  summary: merge
@@ -422,7 +422,7 @@
   | |  date:Thu Jan 01 00:00:00 1970 +
   | |  summary: diverging
   | |
-  o |  changeset:   1:830839835f98
+  o |  changeset:   1:* (glob)
   |/   user:test
   |date:Thu Jan 01 00:00:00 1970 +
   |summary: manychanges
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] templatekw: clarify the result of {latesttag} when no tag exists

2017-04-08 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491711054 14400
#  Sun Apr 09 00:10:54 2017 -0400
# Node ID 8b5a325adc7a011fbbed18886290684793ff8a35
# Parent  42c7df6da065e310c5685fbba2799ffe77d73afd
templatekw: clarify the result of {latesttag} when no tag exists

My initial expectation was that the list would be empty, and therefore
detectable with {if()}.  The map for {latesttag()} is populated with real values
in this case (except {tag}), so it probably doesn't make any sense to change
this to an empty list.

diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -432,7 +432,8 @@
 @templatekeyword('latesttag')
 def showlatesttag(**args):
 """List of strings. The global tags on the most recent globally
-tagged ancestor of this changeset.
+tagged ancestor of this changeset.  If no such tags exist, the list
+consists of the single string "null".
 """
 return showlatesttags(None, **args)
 
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -719,7 +719,9 @@
 @templatefunc('latesttag([pattern])')
 def latesttag(context, mapping, args):
 """The global tags matching the given pattern on the
-most recent globally tagged ancestor of this changeset."""
+most recent globally tagged ancestor of this changeset.
+If no such tags exist, the "{tag}" template resolves to
+the string "null"."""
 if len(args) > 1:
 # i18n: "latesttag" is a keyword
 raise error.ParseError(_("latesttag expects at most one argument"))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] setup: use setuptools on Windows (issue5400)

2017-04-09 Thread Matt Harbison

On Sun, 09 Apr 2017 09:28:04 -0400, Yuya Nishihara  wrote:


On Sat, 08 Apr 2017 20:30:53 -0400, Matt Harbison wrote:

On Thu, 09 Mar 2017 23:06:34 -0500, Gregory Szorc
 wrote:

> # HG changeset patch
> # User Gregory Szorc 
> # Date 1489118392 28800
> #  Thu Mar 09 19:59:52 2017 -0800
> # Node ID b51f9adb41e68d9f3d88582f044d2742ae29ce09
> # Parent  cd29673cebdbe2d998009322e4c3657389d6aed0
> setup: use setuptools on Windows (issue5400)
>
> We've had a long, complicated history with setuptools. We want to
> make it the universal default. But when we do, it breaks things.
>
> `python setup.py build` is broken on Windows today. Forcing
> the use of setuptools via FORCE_SETUPTOOLS=1 unbreaks things.
>
> Since the previous bustage with making setuptools the default
> was on !Windows, it seems safe to move ahead with the setuptools
> transition on Windows. So this patch does that.

I'm not sure why, or what we should do about it, but test-hghave.t fails
with this on Windows.  I can get a similar failure on Linux with
FORCE_SETUPTOOLS=1.  Is this an expected diff with setuptools (and
deserving a '(glob) (?)'?

--- c:/Users/Matt/Projects/hg/tests/test-hghave.t
+++ c:/Users/Matt/Projects/hg/tests/test-hghave.t.err
@@ -19,7 +19,11 @@
>   foo
> EOF
$ run-tests.py $HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
+  warning: Testing with unexpected mercurial lib:
C:\Users\Matt\AppData\Local\Temp\hgtests.ie8k3minstall\lib\python\mercurial-4.1.1-py2.7-win-amd64.egg\mercurial
+   (expected
C:\Users\Matt\AppData\Local\Temp\hgtests.ie8k3m\install\lib\python\mercurial)


Perhaps this assumption isn't true for setuptools.

https://www.mercurial-scm.org/repo/hg/file/4.1.2/tests/run-tests.py#l2469

I have no idea if setuptools can be configured to use simple installation
layout.


That's a good tip, thanks.  The output above is from the original patch,  
but it is simpler for @ committed:


+  warning: Testing with unexpected mercurial lib:  
c:\Users\Matt\Projects\hg\mercurial
+   (expected  
C:\Users\Matt\AppData\Local\Temp\hgtests.q1ldmg\install\lib\python\mercurial)


Without setuptools:

expecthg:  
C:\Users\Matt\AppData\Local\Temp\hgtests.kshzjl\install\lib\python\mercurial
actualhg:  
C:\Users\Matt\AppData\Local\Temp\hgtests.kshzjl\install\lib\python\mercurial

bindir:   C:\Users\Matt\AppData\Local\Temp\hgtests.kshzjl\install\bin
pydir: 
C:\Users\Matt\AppData\Local\Temp\hgtests.kshzjl\install\lib\python

tmpdir:   C:\Users\Matt\AppData\Local\Temp\hgtests.kshzjl\install\bin

With setuptools:

expecthg:  
C:\Users\Matt\AppData\Local\Temp\hgtests.q1ldmg\install\lib\python\mercurial

actualhg: c:\Users\Matt\Projects\hg\mercurial
bindir:   C:\Users\Matt\AppData\Local\Temp\hgtests.q1ldmg\install\bin
pydir: 
C:\Users\Matt\AppData\Local\Temp\hgtests.q1ldmg\install\lib\python

tmpdir:   C:\Users\Matt\AppData\Local\Temp\hgtests.q1ldmg\install\bin

So it seems like the test is importing the 'hg' module that the main test  
runner is using?  It looks like test-run-tests.t papers over this by  
invoking run-tests.py with '--with-hg=`which hg`', which also works here.   
But someone who understands the underlying issue should take a look before  
doing that.  The function you referenced bails in this case, so it feels  
like subverting a valid check.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] test-patchbomb: convert the pretendmail program from *.sh to *.py

2017-04-09 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491785368 14400
#  Sun Apr 09 20:49:28 2017 -0400
# Node ID 1de38b5ca1886aa41844dc7a80c1b92b65a8171e
# Parent  9259cf823690e4fcd34a4d2ecd57ced2060d2b3d
test-patchbomb: convert the pretendmail program from *.sh to *.py

Windows doesn't know how to execute *.sh, so tests were failing with:

  abort: 'pretendmail.py' specified as email transport, but not in PATH

I was able to create a *.bat file to do the same thing, but neither the *.py nor
*.bat were able to read from stdin[1] and write to stdout on Windows, like `cat`
was doing in the shell script.  The *.py script is infinitely more readable.

It isn't possible to specify 'method = python `pwd`/*.py', because everything
specified on the RHS ends up quoted, because of the space.  Therefore, $PATHEXT
is modified to include *.py, which causes a registry lookup and Windows to
figure out that it should open *.py with python.exe.  Unlike the python
installer, the MSYS installer doesn't add registry entries for *.sh, so it isn't
possible to execute shell scripts directly.

[1] 
https://stackoverflow.com/questions/6979747/read-stdin-stream-in-a-batch-file

diff --git a/tests/test-patchbomb.t b/tests/test-patchbomb.t
--- a/tests/test-patchbomb.t
+++ b/tests/test-patchbomb.t
@@ -2849,15 +2849,31 @@
 
 Set up a fake sendmail program
 
-  $ cat > pretendmail.sh << 'EOF'
-  > #!/bin/sh
-  > echo "$@"
-  > cat
+  $ cat > pretendmail.py << 'EOF'
+  > #!/usr/bin/env python
+  > 
+  > from __future__ import print_function
+  > import sys
+  > 
+  > print(sys.argv)
+  > 
+  > for line in sys.stdin:
+  > print(line.rstrip())
+  > exit(0)
   > EOF
-  $ chmod +x pretendmail.sh
+
+Make it possible to execute *.py directly in cmd.exe for this test
+
+#if windows
+  $ export PATHEXT='.COM;.EXE;.BAT;.CMD;.PY'
+#endif
+
+#if execbit
+  $ chmod +x pretendmail.py
+#endif
 
   $ echo '[email]' >> $HGRCPATH
-  $ echo "method=`pwd`/pretendmail.sh" >> $HGRCPATH
+  $ echo "method=`pwd`/pretendmail.py" >> $HGRCPATH
 
 Test introduction configuration
 =
@@ -2950,7 +2966,7 @@
   
   warning: invalid patchbomb.intro value "mpmwearaclownnose"
   (should be one of always, never, auto)
-  -f test foo
+  ['$TESTTMP/t2/pretendmail.py', '-f', 'test', 'foo']
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -2982,7 +2998,7 @@
   +d
   
   sending [PATCH] test ...
-  sending mail: $TESTTMP/t2/pretendmail.sh -f test foo
+  sending mail: $TESTTMP/t2/pretendmail.py -f test foo
 
 Test pull url header
 =
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] test-patchbomb: disable a failing test on Windows

2017-04-09 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491787400 14400
#  Sun Apr 09 21:23:20 2017 -0400
# Node ID 548c1c174b937b1512ea689661c591dcf778ebe1
# Parent  1de38b5ca1886aa41844dc7a80c1b92b65a8171e
test-patchbomb: disable a failing test on Windows

It's unknown where or why the patch content is being lost.  Echoing into the
same script from inside cmd.exe (not MSYS) will print out the echoed strings.

diff --git a/tests/test-patchbomb.t b/tests/test-patchbomb.t
--- a/tests/test-patchbomb.t
+++ b/tests/test-patchbomb.t
@@ -2960,6 +2960,23 @@
 
 single rev
 
+For reasons unknown, pretendmail isn't transferring stdin to stdout on Windows,
+so the mail content is lost.
+
+#if windows
+
+  $ hg email --date '1980-1-1 0:1' -v -t foo -s test -r '10'
+  From [test]: test
+  this patch series consists of 1 patches.
+  
+  warning: invalid patchbomb.intro value "mpmwearaclownnose"
+  (should be one of always, never, auto)
+  
+  sending [PATCH] test ...
+  sending mail: $TESTTMP/t2/pretendmail.py -f test foo
+
+#else
+
   $ hg email --date '1980-1-1 0:1' -v -t foo -s test -r '10'
   From [test]: test
   this patch series consists of 1 patches.
@@ -3000,6 +3017,8 @@
   sending [PATCH] test ...
   sending mail: $TESTTMP/t2/pretendmail.py -f test foo
 
+#endif
+
 Test pull url header
 =
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] tests: print Unix style paths in *.py tests

2017-04-09 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491790767 14400
#  Sun Apr 09 22:19:27 2017 -0400
# Node ID f5ea3f4ee8206f99c7038814e87b34ae3124be98
# Parent  548c1c174b937b1512ea689661c591dcf778ebe1
tests: print Unix style paths in *.py tests

These tests don't support (glob).  I didn't audit all tests, but these ones were
failing.

diff --git a/tests/test-config-env.py b/tests/test-config-env.py
--- a/tests/test-config-env.py
+++ b/tests/test-config-env.py
@@ -8,6 +8,7 @@
 encoding,
 rcutil,
 ui as uimod,
+util,
 )
 
 testtmp = encoding.environ['TESTTMP']
@@ -40,7 +41,7 @@
 ui = uimod.ui.load()
 for section, name, value in ui.walkconfig():
 source = ui.configsource(section, name)
-print('%s.%s=%s # %s' % (section, name, value, source))
+print('%s.%s=%s # %s' % (section, name, value, util.pconvert(source)))
 print('')
 
 # environment variable overrides
diff --git a/tests/test-trusted.py b/tests/test-trusted.py
--- a/tests/test-trusted.py
+++ b/tests/test-trusted.py
@@ -74,14 +74,14 @@
 return u
 print('trusted')
 for name, path in u.configitems('paths'):
-print('   ', name, '=', path)
+print('   ', name, '=', util.pconvert(path))
 print('untrusted')
 for name, path in u.configitems('paths', untrusted=True):
 print('.', end=' ')
 u.config('paths', name) # warning with debug=True
 print('.', end=' ')
 u.config('paths', name, untrusted=True) # no warnings
-print(name, '=', path)
+print(name, '=', util.pconvert(path))
 print()
 
 return u
@@ -217,6 +217,12 @@
 list=spam,ham,eggs
 ''')
 u = testui(user='abc', group='def', cuser='foo', silent=True)
+def configpath(section, name, default=None, untrusted=False):
+path = u.configpath(section, name, default, untrusted)
+if path is None:
+return None
+return util.pconvert(path)
+
 print('# suboptions, trusted and untrusted')
 trusted = u.configsuboptions('foo', 'sub')
 untrusted = u.configsuboptions('foo', 'sub', untrusted=True)
@@ -224,7 +230,7 @@
 (trusted[0], sorted(trusted[1].items())),
 (untrusted[0], sorted(untrusted[1].items(
 print('# path, trusted and untrusted')
-print(u.configpath('foo', 'path'), u.configpath('foo', 'path', untrusted=True))
+print(configpath('foo', 'path'), configpath('foo', 'path', untrusted=True))
 print('# bool, trusted and untrusted')
 print(u.configbool('foo', 'bool'), u.configbool('foo', 'bool', untrusted=True))
 print('# int, trusted and untrusted')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


SSL troubleshooting on Windows

2017-04-09 Thread Matt Harbison
I had a little adventure a couple of weeks ago, changing a certificate on  
the server.  I'm not sure if it's worth doing anything, or if this just  
serves as a heads up to others using Windows.


We use SCM Manager (which uses tomcat) on CentOS, with Mercurial 4.0.2.   
The certificate had expired over the weekend.  So the admin imported the  
new certificate into the tomcat keystore, saw that the main page loaded in  
a web browser (probably Chrome, and I think I subsequently tried FireFox),  
and declared victory.  But Mercurial was still failing the verification.   
After a bit of fiddling around, he eventually imported the root and  
intermediate certificates for the chain into the keystore as well, and  
then Mercurial clients worked.  Except for one Windows machine.  (I'm a  
bit puzzled that the web browsers were OK with this config, but not  
Mercurial.)


I was able to get the one failing machine working by temporarily setting  
the fingerprint.  After awhile of debugging, I realized that this is a  
python bug [1].  Basically, Windows doesn't ship with a full set of  
certificates, and instead downloads them on demand.  But python isn't  
triggering the download.  In this case, Windows had the root certificate  
and the leaf certificate from the website, but was missing the  
intermediate certificate.  So the "fix" was to load the main web page in  
Internet Explorer, which silently builds the certificate chain on Windows,  
and then Mercurial works.  An additional problem is that the error message  
is the same for both this failure, and a real certificate problem.


I started adding code to:

1) Detect and fix this without Internet Explorer via a debug function that  
calls CertGetCertificateChain()
2) Detect the problem when connecting, and print out a message pointing to  
the debug command
3) Just fix the problem when connecting, so that the debug command isn't  
necessary


The problem is that you need to successfully connect to the server in  
order to get the certificate to pass to the Win32 function.  Since the  
connection fails if verification is on, a second (non verifying)  
connection needs to be established to get the certificate, and then a  
third (verifying) connection to retry the original.  Ugh.  I tried turning  
off SSL verification on Windows, so that only the first connection is  
needed.  It looks like there are Win32 functions that can also verify the  
certificate chain, so we shouldn't be missing any functionality.  But  
python doesn't return the non-binary certificate when verification is off,  
so another check we do fails [2].


I assume the chance of landing this hacky code is about 0.  The other  
alternative seems to be to package certifi or similar in the binary  
Windows installers.  That was mentioned when Greg overhauled the SSL stuff  
last year, but I think it was deferred because there wasn't any real  
reason to when python can access the Windows certificate store.  Maybe  
this is a reason?


[1] https://bugs.python.org/issue20916
[2]  
https://www.mercurial-scm.org/repo/hg/file/e0dc40530c5a/mercurial/sslutil.py#l623

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] test-patchbomb: convert the pretendmail program from *.sh to *.py

2017-04-10 Thread Matt Harbison

On Mon, 10 Apr 2017 08:52:52 -0400, Yuya Nishihara  wrote:


On Sun, 09 Apr 2017 21:52:30 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1491785368 14400
#  Sun Apr 09 20:49:28 2017 -0400
# Node ID 1de38b5ca1886aa41844dc7a80c1b92b65a8171e
# Parent  9259cf823690e4fcd34a4d2ecd57ced2060d2b3d
test-patchbomb: convert the pretendmail program from *.sh to *.py

Windows doesn't know how to execute *.sh, so tests were failing with:

  abort: 'pretendmail.py' specified as email transport, but not in PATH

I was able to create a *.bat file to do the same thing, but neither the  
*.py nor
*.bat were able to read from stdin[1] and write to stdout on Windows,  
like `cat`
was doing in the shell script.  The *.py script is infinitely more  
readable.


It isn't possible to specify 'method = python `pwd`/*.py', because  
everything
specified on the RHS ends up quoted, because of the space.  Therefore,  
$PATHEXT
is modified to include *.py, which causes a registry lookup and Windows  
to

figure out that it should open *.py with python.exe.  Unlike the python
installer, the MSYS installer doesn't add registry entries for *.sh, so  
it isn't

possible to execute shell scripts directly.


Does it mean there's still a risk the test will fail? e.g. because .py is
associated with python3, or not associated at all.


It seems like a small risk to be associated with something other than  
python, but not impossible.  If it was associated with python3, that seems  
OK since it's just reading stdin and writing to stdout (assuming this is  
valid py3 code- I didn't try that).


I'm fine with disabling the tests though.


I think it's okay to disable the sendmail test at all on Windows because
sendmail is a Unix thing.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V2] test-patchbomb: disable sendmail tests on Windows

2017-04-10 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491873174 14400
#  Mon Apr 10 21:12:54 2017 -0400
# Node ID bfa323bbeebb534f3540e9198648f1bd317b059a
# Parent  08fbc97d1364b08b53d538efc33b3ed41cea51a0
test-patchbomb: disable sendmail tests on Windows

These tests were failing, and there isn't a trivial way to execute a script on
Windows [1].

[1] 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-April/096497.html

diff --git a/tests/test-patchbomb.t b/tests/test-patchbomb.t
--- a/tests/test-patchbomb.t
+++ b/tests/test-patchbomb.t
@@ -2846,6 +2846,7 @@
   @@ -0,0 +1,1 @@
   +d
   
+#if no-windows
 
 Set up a fake sendmail program
 
@@ -3026,3 +3027,4 @@
   (use 'hg push $TESTTMP/t3 -r ff2c9fa2018b -r 3b6f1ec9dde9')
   [255]
 
+#endif
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] windows: add context manager support to mixedfilemodewrapper

2017-04-11 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491961091 14400
#  Tue Apr 11 21:38:11 2017 -0400
# Node ID ef3aa25da8e5b3137b917e9a1756df7a7eac5c3a
# Parent  7b6f5632f09d85b96b2f986961576eb165d44cbf
windows: add context manager support to mixedfilemodewrapper

I stumbled into this in the next patch.  The difference between getting a
context manager capable object or not from vfs classes was as subtle as adding a
'+' to the file mode.

diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -64,6 +64,12 @@
 object.__setattr__(self, r'_fp', fp)
 object.__setattr__(self, r'_lastop', 0)
 
+def __enter__(self):
+return self._fp.__enter__()
+
+def __exit__(self, exc_type, exc_val, exc_tb):
+self._fp.__exit__(exc_type, exc_val, exc_tb)
+
 def __getattr__(self, name):
 return getattr(self._fp, name)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] largefiles: set the extension as enabled locally after a share requiring it

2017-04-11 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491958490 14400
#  Tue Apr 11 20:54:50 2017 -0400
# Node ID 9b4202740173227e232659964725c4152d87e469
# Parent  ef3aa25da8e5b3137b917e9a1756df7a7eac5c3a
largefiles: set the extension as enabled locally after a share requiring it

This has been done for clone since e1dbe0b215ae, so it makes sense here for the
same reasons.

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -903,6 +903,14 @@
 
 return result
 
+def hgpostshare(orig, sourcerepo, destrepo, bookmarks=True, defaultpath=None):
+orig(sourcerepo, destrepo, bookmarks, defaultpath)
+
+# If largefiles is required for this repo, permanently enable it locally
+if 'largefiles' in destrepo.requirements:
+with destrepo.vfs('hgrc', 'a+', text=True) as fp:
+fp.write('\n[extensions]\nlargefiles=\n')
+
 def overriderebase(orig, ui, repo, **opts):
 if not util.safehasattr(repo, '_largefilesenabled'):
 return orig(ui, repo, **opts)
diff --git a/hgext/largefiles/uisetup.py b/hgext/largefiles/uisetup.py
--- a/hgext/largefiles/uisetup.py
+++ b/hgext/largefiles/uisetup.py
@@ -120,6 +120,7 @@
  _('download all versions of all largefiles'))]
 entry[1].extend(cloneopt)
 entry = extensions.wrapfunction(hg, 'clone', overrides.hgclone)
+entry = extensions.wrapfunction(hg, 'postshare', overrides.hgpostshare)
 
 entry = extensions.wrapcommand(commands.table, 'cat',
overrides.overridecat)
diff --git a/tests/test-largefiles-misc.t b/tests/test-largefiles-misc.t
--- a/tests/test-largefiles-misc.t
+++ b/tests/test-largefiles-misc.t
@@ -212,6 +212,18 @@
   date:Thu Jan 01 00:00:00 1970 +
   summary: add files
   
+sharing a largefile repo automatically enables largefiles on the share
+
+  $ hg share --config extensions.share= . ../shared_lfrepo
+  updating working directory
+  getting changed largefiles
+  1 largefiles updated, 0 removed
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cat ../shared_lfrepo/.hg/hgrc
+  
+  [extensions]
+  largefiles=
+
 verify that large files in subrepos handled properly
   $ hg init subrepo
   $ echo "subrepo = subrepo" > .hgsub
diff --git a/tests/test-share.t b/tests/test-share.t
--- a/tests/test-share.t
+++ b/tests/test-share.t
@@ -240,6 +240,14 @@
  bm3   4:62f4ded848e4
   $ cd ..
 
+non largefiles repos won't enable largefiles
+
+  $ hg share --config extensions.largefiles= repo3 sharedrepo
+  updating working directory
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ [ -f sharedrepo/.hg/hgrc ]
+  [1]
+
 test pushing bookmarks works
 
   $ hg clone repo3 repo4
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: stable ordering of test output

2017-04-13 Thread Matt Harbison

On Thu, 13 Apr 2017 16:17:34 -0400, Augie Fackler  wrote:


On Thu, Apr 13, 2017 at 3:55 PM, Augie Fackler  wrote:

On Wed, Mar 8, 2017 at 10:44 AM, Yuya Nishihara  wrote:

On Tue, 7 Mar 2017 17:56:58 +0100, Pierre-Yves David wrote:

On the other hand, this is probably not so bundle2 specific. We have
some "select" logic to read stdout and stderr as soon as possible.  
This

is the main suspect as it is possible that this logic behave different
under linux and other unix (not too much effort have been put into  
it).


posix.poll() waits every type of operation no matter if fd is e.g.  
writable
or not. IIRC, this doesn't always work on FreeBSD since the underlying  
resource

of read/write ends might be shared in the kernel.

But I don't think this is the source of the unstable output.


I've had a little time today between things to try and debug this.
What I've found so far:

1) when the test passes, the remote: output is printed by the
_forwardoutput method in sshpeer, presumably since stderr makes it to
the client before the close of stdout.
2) When the test fails (as on BSD, and I guess Solaris), the client
notices that stdout closed before stderr. It then aborts the
transaction and sshpeer.cleanup() notices some data chilling on stderr
and ensures it gets read and printed.

I'm not really sure why BSD systems would be quicker at communicating
the closed FD than other systems. I'm poking at dummyssh now to see if
maybe it's weirdness from there...


Here's a patch that seems to work. I'm not happy about it, but it
makes the behavior consistent, and it looks mostly harmless.


This fixes it for Windows too.  Thanks!


# HG changeset patch
# User Augie Fackler 
# Date 1492114180 14400
#  Thu Apr 13 16:09:40 2017 -0400
# Node ID ec81fd7580f3e31aa92e8834ffbcf2a8e80e72e3
# Parent  35afb54dbb4df2975dbbf0e1525b98611f18ba85
sshpeer: try harder to snag stderr when stdout closes unexpectedly

Resolves test failures on FreeBSD, but I'm not happy about the fix.

diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py
--- a/mercurial/sshpeer.py
+++ b/mercurial/sshpeer.py
@@ -110,9 +110,17 @@ class doublepipe(object):
 if mainready:
 meth = getattr(self._main, methname)
 if data is None:
-return meth()
+r = meth()
 else:
-return meth(data)
+r = meth(data)
+if not r and data != 0:
+# We've observed a condition that indicates the
+# stdout closed unexpectedly. Check stderr one
+# more time and snag anything that's there before
+# letting anyone know the main part of the pipe
+# closed prematurely.
+_forwardoutput(self._ui, self._side)
+return r

 def close(self):
 return self._main.close()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2 V3] serve: add support for Mercurial subrepositories

2017-04-15 Thread Matt Harbison
On Thu, 30 Mar 2017 21:19:01 -0400, Matt Harbison   
wrote:



On Tue, 28 Mar 2017 10:11:15 -0400, Yuya Nishihara  wrote:


On Sun, 26 Mar 2017 23:04:30 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1488146743 18000
#  Sun Feb 26 17:05:43 2017 -0500
# Node ID 0ff9bef3e0f67422cf29c200fa4a671d861d060b
# Parent  c60091fa1426892552dd6c0dd4b9c49e3c3da045
serve: add support for Mercurial subrepositories



+def addwebdirpath(repo, serverpath, webconf):
+webconf[serverpath] = repo.root
+repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
+
+for r in repo.revs('filelog("path:.hgsub")'):
+ctx = repo[r]
+for subpath in ctx.substate:
+ctx.sub(subpath).addwebdirpath(serverpath, webconf)


[...]


--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -15,6 +15,7 @@

 from . import (
 chgserver,
+cmdutil,
 commandserver,
 error,
 hgweb,
@@ -130,11 +131,24 @@
 baseui = ui
 webconf = opts.get('web_conf') or opts.get('webdir_conf')
 if webconf:
+if opts.get('subrepos'):
+raise error.Abort(_('--web-conf cannot be used with  
--subrepos'))

+
 # load server settings (e.g. web.port) to "copied" ui, which  
allows

 # hgwebdir to reload webconf cleanly
 servui = ui.copy()
 servui.readconfig(webconf, sections=['web'])
 alluis.add(servui)
+elif opts.get('subrepos'):
+servui = ui.copy()
+alluis.add(servui)


No need to make a copy of ui since nothing loaded into servui.


+@annotatesubrepoerror
+def addwebdirpath(self, serverpath, webconf):
+# The URL request contains the subrepo source path, not the  
local
+# subrepo path.  The distinction matters for 'foo = ../foo'  
type
+# entries.  It isn't possible to serve up 'foo = http://..'  
type
+# entries, because the server path is relative to this local  
server.

+src = self._state[0]
+if util.url(src).islocal():
+path = util.normpath(serverpath + src)
+cmdutil.addwebdirpath(self._repo, path + '/', webconf)


What happens if src is '../../escape_from_web_root' ?

I don't think it's correct to lay out subrepositories by peer URL since  
we're
exporting a _local_ clone. If you do "hg clone sub1 sub2", you'll see  
sub1
in local-path layout. "hg serve -S" just allows us to see sub1 over  
http.


That was actually how I first coded it, but switched it because it  
wasn't handling the test in test-subrepo-deep-nested-change.t properly.   
I forget what exactly the problem was.  I'll take another look this  
weekend.


I finally got back to this, now that I've got the serve tests working on  
Windows.  The problem I had run into is that in  
test-subrepo-deep-nested-change.t, the repos exist in the filesystem as:


  main
  sub1
  sub2

If you clone `hg clone main` right after the "main import" commit around  
line 74, it builds a tree like:


  cloning subrepo sub1 from $TESTTMP/sub1
  cloning subrepo sub1\sub2 from $TESTTMP/sub2

The fact that you can locally clone the original 'main' strongly suggests  
that we should be able to serve the original main, and be able to clone  
from it too.  The subsequent test I added there does that.  It took using  
the peer layout to do this.  (Though it really isn't a peer- it's what is  
in the local filesystem where the serve is happening.)


It's easy enough to setup the dictionary such that the repos would be  
served up as:


  /
  /sub1
  /sub1/sub2

But clone seems to want to follow the peer layout specified in .hgsub of  
the parent.  (I can see  "GET /../sub1?cmd=capabilities ..." in  
access.log, which is where clone is dying with a 404.)


I know that escaping '/' is generally a security concern.  But I'm not  
sure that it is here, since the only thing served above '/' is something  
explicitly in the repository (via .hgsub).  So it can't be anything else  
that is potentially sensitive.


I don't care too much about this case.  I'd rather have the functionality  
for the recommended nested subrepo case, than not at all.  But I don't  
want to sneak something in that is broken, with no obvious way to fix if  
somebody complains.


Thoughts?

Maybe it's okay to add all repositories found under repo.root to  
webconf.

For strictness, we could check if a subrepo path exists in .hgsub of any
revision.


I'd like to avoid searching through the directory tree, if possible.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V4] hgwebdir: allow a repository to be hosted at "/"

2017-04-15 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1491015641 14400
#  Fri Mar 31 23:00:41 2017 -0400
# Node ID 3fd50d5f9314a96f43eb73480763f224c4d05831
# Parent  4c2c30bc38b4f84ce8f215146bbf158e299065b3
hgwebdir: allow a repository to be hosted at "/"

This can be useful in general, but will also be useful for hosting subrepos,
with the main repo at /.

diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -335,7 +335,7 @@
 req.url = req.env['SCRIPT_NAME']
 if not req.url.endswith('/'):
 req.url += '/'
-if 'REPO_NAME' in req.env:
+if req.env.get('REPO_NAME'):
 req.url += req.env['REPO_NAME'] + '/'
 
 if 'PATH_INFO' in req.env:
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -257,7 +257,7 @@
 
 repos = dict(self.repos)
 
-if not virtual or (virtual == 'index' and virtual not in repos):
+if (not virtual or virtual == 'index') and virtual not in repos:
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl)
 
@@ -269,8 +269,17 @@
 req.respond(HTTP_OK, ctype)
 return self.makeindex(req, tmpl, subdir)
 
-virtualrepo = virtual
-while virtualrepo:
+def _virtualdirs():
+# Check the full virtual path, each parent, and the root ('')
+if virtual != '':
+yield virtual
+
+for p in util.finddirs(virtual):
+yield p
+
+yield ''
+
+for virtualrepo in _virtualdirs():
 real = repos.get(virtualrepo)
 if real:
 req.env['REPO_NAME'] = virtualrepo
@@ -284,11 +293,6 @@
 except error.RepoError as inst:
 raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
 
-up = virtualrepo.rfind('/')
-if up < 0:
-break
-virtualrepo = virtualrepo[:up]
-
 # browse subdirectories
 subdir = virtual + '/'
 if [r for r in repos if r.startswith(subdir)]:
diff --git a/tests/test-hgwebdir.t b/tests/test-hgwebdir.t
--- a/tests/test-hgwebdir.t
+++ b/tests/test-hgwebdir.t
@@ -1680,6 +1680,22 @@
 
   $ killdaemons.py
 
+  $ cat > paths.conf << EOF
+  > [paths]
+  > / = $root/a
+  > EOF
+  $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ hg id http://localhost:$HGPORT1
+  71a89161f014
+
+  $ get-with-headers.py localhost:$HGPORT1 '' | grep 'index'
+  
+ add index file
+
+  $ killdaemons.py
+
 paths errors 1
 
   $ cat error-paths-1.log
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2 V3] serve: add support for Mercurial subrepositories

2017-04-15 Thread Matt Harbison
On Sat, 15 Apr 2017 15:04:32 -0400, Matt Harbison   
wrote:


On Thu, 30 Mar 2017 21:19:01 -0400, Matt Harbison  
 wrote:


On Tue, 28 Mar 2017 10:11:15 -0400, Yuya Nishihara   
wrote:



On Sun, 26 Mar 2017 23:04:30 -0400, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1488146743 18000
#  Sun Feb 26 17:05:43 2017 -0500
# Node ID 0ff9bef3e0f67422cf29c200fa4a671d861d060b
# Parent  c60091fa1426892552dd6c0dd4b9c49e3c3da045
serve: add support for Mercurial subrepositories



+def addwebdirpath(repo, serverpath, webconf):
+webconf[serverpath] = repo.root
+repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
+
+for r in repo.revs('filelog("path:.hgsub")'):
+ctx = repo[r]
+for subpath in ctx.substate:
+ctx.sub(subpath).addwebdirpath(serverpath, webconf)


[...]


--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -15,6 +15,7 @@

 from . import (
 chgserver,
+cmdutil,
 commandserver,
 error,
 hgweb,
@@ -130,11 +131,24 @@
 baseui = ui
 webconf = opts.get('web_conf') or opts.get('webdir_conf')
 if webconf:
+if opts.get('subrepos'):
+raise error.Abort(_('--web-conf cannot be used with  
--subrepos'))

+
 # load server settings (e.g. web.port) to "copied" ui, which  
allows

 # hgwebdir to reload webconf cleanly
 servui = ui.copy()
 servui.readconfig(webconf, sections=['web'])
 alluis.add(servui)
+elif opts.get('subrepos'):
+servui = ui.copy()
+alluis.add(servui)


No need to make a copy of ui since nothing loaded into servui.


+@annotatesubrepoerror
+def addwebdirpath(self, serverpath, webconf):
+# The URL request contains the subrepo source path, not the  
local
+# subrepo path.  The distinction matters for 'foo = ../foo'  
type
+# entries.  It isn't possible to serve up 'foo = http://..'  
type
+# entries, because the server path is relative to this local  
server.

+src = self._state[0]
+if util.url(src).islocal():
+path = util.normpath(serverpath + src)
+cmdutil.addwebdirpath(self._repo, path + '/', webconf)


What happens if src is '../../escape_from_web_root' ?

I don't think it's correct to lay out subrepositories by peer URL  
since we're
exporting a _local_ clone. If you do "hg clone sub1 sub2", you'll see  
sub1
in local-path layout. "hg serve -S" just allows us to see sub1 over  
http.


That was actually how I first coded it, but switched it because it  
wasn't handling the test in test-subrepo-deep-nested-change.t  
properly.  I forget what exactly the problem was.  I'll take another  
look this weekend.


I finally got back to this, now that I've got the serve tests working on  
Windows.  The problem I had run into is that in  
test-subrepo-deep-nested-change.t, the repos exist in the filesystem as:


   main
   sub1
   sub2

If you clone `hg clone main` right after the "main import" commit around  
line 74, it builds a tree like:


   cloning subrepo sub1 from $TESTTMP/sub1
   cloning subrepo sub1\sub2 from $TESTTMP/sub2

The fact that you can locally clone the original 'main' strongly  
suggests that we should be able to serve the original main, and be able  
to clone  from it too.  The subsequent test I added there does that.  It  
took using the peer layout to do this.  (Though it really isn't a peer-  
it's what is in the local filesystem where the serve is happening.)


Ugh, nevermind.  I see now that the extra copies of the subrepos allow the  
local cloning to work:


  main
  main/sub1
  main/sub1/sub2
  sub1
  sub2

The nested repos are used for commits, but not `hg clone`.  And that's  
what allows the filesystem clone to work.  I thought you could only clone  
foo=../foo type hierarchies once, but I was able to clone a clone in this  
test.  Until I renamed the top level sub{1,2} repos, and then it doesn't  
even work once.  So I guess it's not a big deal that you can't clone this  
setup over http.


I wonder what else these extra copies are masking in the tests...

It's easy enough to setup the dictionary such that the repos would be  
served up as:


   /
   /sub1
   /sub1/sub2

But clone seems to want to follow the peer layout specified in .hgsub of  
the parent.  (I can see  "GET /../sub1?cmd=capabilities ..." in  
access.log, which is where clone is dying with a 404.)


I know that escaping '/' is generally a security concern.  But I'm not  
sure that it is here, since the only thing served above '/' is something  
explicitly in the repository (via .hgsub).  So it can't be anything else  
that is potentially sensitive.


I

  1   2   3   4   5   6   7   8   9   10   >