--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/heptapod-ci.yml Sat Feb 08 03:13:45 2020 +0530
@@ -0,0 +1,75 @@
+image: octobus/ci-mercurial-core
+
+# The runner made a clone as root.
+# We make a new clone owned by user used to run the step.
+before_script:
+ - hg clone . /tmp/mercurial-ci/ --noupdate
+ - hg -R /tmp/mercurial-ci/ update `hg log --rev '.' --template '{node}'`
+ - cd /tmp/mercurial-ci/
+ - (cd tests; ls -1 test-check-*.*) > /tmp/check-tests.txt
+
+variables:
+ PYTHON: python
+
+.runtests_template: &runtests
+ script:
+ - cd tests/
+ - echo "python used, $PYTHON"
+ - echo "$RUNTEST_ARGS"
+ - $PYTHON run-tests.py --color=always $RUNTEST_ARGS
+
+checks-py2:
+ <<: *runtests
+ variables:
+ RUNTEST_ARGS: "--time --test-list /tmp/check-tests.txt"
+
+checks-py3:
+ <<: *runtests
+ variables:
+ RUNTEST_ARGS: "--time --test-list /tmp/check-tests.txt"
+ PYTHON: python3
+
+rust-cargo-test-py2: &rust_cargo_test
+ script:
+ - echo "python used, $PYTHON"
+ - make rust-tests
+
+rust-cargo-test-py3:
+ <<: *rust_cargo_test
+ variables:
+ PYTHON: python3
+
+test-py2:
+ <<: *runtests
+ variables:
+ RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
+
+test-py3:
+ <<: *runtests
+ variables:
+ RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
+ PYTHON: python3
+
+test-py2-pure:
+ <<: *runtests
+ variables:
+ RUNTEST_ARGS: "--pure --blacklist /tmp/check-tests.txt"
+
+test-py3-pure:
+ <<: *runtests
+ variables:
+ RUNTEST_ARGS: "--pure --blacklist /tmp/check-tests.txt"
+ PYTHON: python3
+
+test-py2-rust:
+ <<: *runtests
+ variables:
+ HGWITHRUSTEXT: cpython
+ RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
+
+test-py3-rust:
+ <<: *runtests
+ variables:
+ HGWITHRUSTEXT: cpython
+ RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
+ PYTHON: python3
--- a/contrib/packaging/hgpackaging/wix.py Thu Feb 06 16:55:39 2020 -0500
+++ b/contrib/packaging/hgpackaging/wix.py Sat Feb 08 03:13:45 2020 +0530
@@ -343,7 +343,9 @@
dist_dir = source_dir / 'dist'
wix_dir = source_dir / 'contrib' / 'packaging' / 'wix'
- requirements_txt = 'requirements_win32.txt'
+ requirements_txt = (
+ source_dir / 'contrib' / 'packaging' / 'requirements_win32.txt'
+ )
build_py2exe(
source_dir,
--- a/hgext/zeroconf/__init__.py Thu Feb 06 16:55:39 2020 -0500
+++ b/hgext/zeroconf/__init__.py Sat Feb 08 03:13:45 2020 +0530
@@ -35,6 +35,7 @@
extensions,
hg,
pycompat,
+ rcutil,
ui as uimod,
)
from mercurial.hgweb import server as servermod
@@ -144,7 +145,8 @@
prefix = app.ui.config(b"web", b"prefix", b"").strip(b'/') + b'/'
for repo, path in repos:
u = app.ui.copy()
- u.readconfig(os.path.join(path, b'.hg', b'hgrc'))
+ if rcutil.use_repo_hgrc():
+ u.readconfig(os.path.join(path, b'.hg', b'hgrc'))
name = os.path.basename(repo)
path = (prefix + repo).strip(b'/')
desc = u.config(b'web', b'description')
--- a/mercurial/bundle2.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/bundle2.py Sat Feb 08 03:13:45 2020 +0530
@@ -1014,8 +1014,8 @@
self.mandatory = mandatory
def __repr__(self):
- cls = b"%s.%s" % (self.__class__.__module__, self.__class__.__name__)
- return b'<%s object at %x; id: %s; type: %s; mandatory: %s>' % (
+ cls = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
+ return '<%s object at %x; id: %s; type: %s; mandatory: %s>' % (
cls,
id(self),
self.id,
--- a/mercurial/dispatch.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/dispatch.py Sat Feb 08 03:13:45 2020 +0530
@@ -37,6 +37,7 @@
hook,
profiling,
pycompat,
+ rcutil,
registrar,
scmutil,
ui as uimod,
@@ -902,17 +903,20 @@
_(b"error getting current working directory: %s")
% encoding.strtolocal(e.strerror)
)
+
path = cmdutil.findrepo(wd) or b""
if not path:
lui = ui
else:
lui = ui.copy()
- lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
+ if rcutil.use_repo_hgrc():
+ lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
if rpath:
path = lui.expandpath(rpath)
lui = ui.copy()
- lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
+ if rcutil.use_repo_hgrc():
+ lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
return path, lui
--- a/mercurial/hgweb/hgwebdir_mod.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/hgweb/hgwebdir_mod.py Sat Feb 08 03:13:45 2020 +0530
@@ -35,6 +35,7 @@
pathutil,
profiling,
pycompat,
+ rcutil,
registrar,
scmutil,
templater,
@@ -192,11 +193,12 @@
continue
u = ui.copy()
- try:
- u.readconfig(os.path.join(path, b'.hg', b'hgrc'))
- except Exception as e:
- u.warn(_(b'error reading %s/.hg/hgrc: %s\n') % (path, e))
- continue
+ if rcutil.use_repo_hgrc():
+ try:
+ u.readconfig(os.path.join(path, b'.hg', b'hgrc'))
+ except Exception as e:
+ u.warn(_(b'error reading %s/.hg/hgrc: %s\n') % (path, e))
+ continue
def get(section, name, default=uimod._unset):
return u.config(section, name, default, untrusted=True)
--- a/mercurial/linelog.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/linelog.py Sat Feb 08 03:13:45 2020 +0530
@@ -255,7 +255,7 @@
)
def __repr__(self):
- return b'<linelog at %s: maxrev=%d size=%d>' % (
+ return '<linelog at %s: maxrev=%d size=%d>' % (
hex(id(self)),
self._maxrev,
len(self._program),
--- a/mercurial/localrepo.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/localrepo.py Sat Feb 08 03:13:45 2020 +0530
@@ -53,6 +53,7 @@
phases,
pushkey,
pycompat,
+ rcutil,
repoview,
revset,
revsetlang,
@@ -676,7 +677,7 @@
configs are loaded. For example, an extension may wish to pull in
configs from alternate files or sources.
"""
- if b'HGRCSKIPREPO' in encoding.environ:
+ if not rcutil.use_repo_hgrc():
return False
try:
ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
--- a/mercurial/manifest.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/manifest.py Sat Feb 08 03:13:45 2020 +0530
@@ -21,6 +21,7 @@
)
from .pycompat import getattr
from . import (
+ encoding,
error,
mdiff,
pathutil,
@@ -868,9 +869,10 @@
self._loadalllazy()
return not self._dirs or all(m._isempty() for m in self._dirs.values())
+ @encoding.strmethod
def __repr__(self):
return (
- b'<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>'
+ b'<treemanifest dir=%s, node=%s, loaded=%r, dirty=%r at 0x%x>'
% (
self._dir,
hex(self._node),
--- a/mercurial/patch.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/patch.py Sat Feb 08 03:13:45 2020 +0530
@@ -1090,6 +1090,7 @@
def filename(self):
return self.header.filename()
+ @encoding.strmethod
def __repr__(self):
return b'<hunk %r@%d>' % (self.filename(), self.fromline)
--- a/mercurial/rcutil.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/rcutil.py Sat Feb 08 03:13:45 2020 +0530
@@ -112,3 +112,8 @@
intended to be set before starting a pager.
'''
return {b'LESS': b'FRX', b'LV': b'-c'}
+
+
+def use_repo_hgrc():
+ """True if repositories `.hg/hgrc` config should be read"""
+ return b'HGRCSKIPREPO' not in encoding.environ
--- a/mercurial/worker.py Thu Feb 06 16:55:39 2020 -0500
+++ b/mercurial/worker.py Sat Feb 08 03:13:45 2020 +0530
@@ -65,6 +65,41 @@
return min(max(countcpus(), 4), 32)
+if pycompat.ispy3:
+
+ class _blockingreader(object):
+ def __init__(self, wrapped):
+ self._wrapped = wrapped
+
+ def __getattr__(self, attr):
+ return getattr(self._wrapped, attr)
+
+ # issue multiple reads until size is fulfilled
+ def read(self, size=-1):
+ if size < 0:
+ return self._wrapped.readall()
+
+ buf = bytearray(size)
+ view = memoryview(buf)
+ pos = 0
+
+ while pos < size:
+ ret = self._wrapped.readinto(view[pos:])
+ if not ret:
+ break
+ pos += ret
+
+ del view
+ del buf[pos:]
+ return buf
+
+
+else:
+
+ def _blockingreader(wrapped):
+ return wrapped
+
+
if pycompat.isposix or pycompat.iswindows:
_STARTUP_COST = 0.01
# The Windows worker is thread based. If tasks are CPU bound, threads
@@ -226,7 +261,7 @@
selector = selectors.DefaultSelector()
for rfd, wfd in pipes:
os.close(wfd)
- selector.register(os.fdopen(rfd, 'rb'), selectors.EVENT_READ)
+ selector.register(os.fdopen(rfd, 'rb', 0), selectors.EVENT_READ)
def cleanup():
signal.signal(signal.SIGINT, oldhandler)
@@ -240,7 +275,7 @@
while openpipes > 0:
for key, events in selector.select():
try:
- res = util.pickle.load(key.fileobj)
+ res = util.pickle.load(_blockingreader(key.fileobj))
if hasretval and res[0]:
retval.update(res[1])
else:
--- a/tests/test-hgrc.t Thu Feb 06 16:55:39 2020 -0500
+++ b/tests/test-hgrc.t Sat Feb 08 03:13:45 2020 +0530
@@ -271,3 +271,39 @@
$ HGRCSKIPREPO=1 hg path
foo = $TESTTMP/bar
+ $ cat >> .hg/hgrc <<EOF
+ > [broken
+ > EOF
+
+ $ hg path
+ hg: parse error at $TESTTMP/.hg/hgrc:3: [broken
+ [255]
+ $ HGRCSKIPREPO=1 hg path
+ foo = $TESTTMP/bar
+
+Check that hgweb respect HGRCSKIPREPO=1
+
+ $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+ hg: parse error at $TESTTMP/.hg/hgrc:3: [broken
+ [255]
+ $ test -f hg.pid && (cat hg.pid >> $DAEMON_PIDS)
+ [1]
+ $ killdaemons.py
+ $ test -f access.log && cat access.log
+ [1]
+ $ test -f errors.log && cat errors.log
+ [1]
+
+ $ HGRCSKIPREPO=1 hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+ $ cat hg.pid >> $DAEMON_PIDS
+ $ killdaemons.py
+ $ cat access.log
+ $ cat errors.log
+
+Check that zeroconf respect HGRCSKIPREPO=1
+
+ $ hg paths --config extensions.zeroconf=
+ hg: parse error at $TESTTMP/.hg/hgrc:3: [broken
+ [255]
+ $ HGRCSKIPREPO=1 hg paths --config extensions.zeroconf=
+ foo = $TESTTMP/bar
--- a/tests/test-worker.t Thu Feb 06 16:55:39 2020 -0500
+++ b/tests/test-worker.t Sat Feb 08 03:13:45 2020 +0530
@@ -131,4 +131,35 @@
abort: known exception
[255]
+Do not crash on partially read result
+
+ $ cat > $TESTTMP/detecttruncated.py <<EOF
+ > from __future__ import absolute_import
+ > import os
+ > import sys
+ > import time
+ > sys.unraisablehook = lambda x: None
+ > oldwrite = os.write
+ > def splitwrite(fd, string):
+ > ret = oldwrite(fd, string[:9])
+ > if ret == 9:
+ > time.sleep(0.1)
+ > ret += oldwrite(fd, string[9:])
+ > return ret
+ > os.write = splitwrite
+ > EOF
+
+ $ hg --config "extensions.t=$abspath" --config worker.numcpus=8 --config \
+ > "extensions.d=$TESTTMP/detecttruncated.py" test 100000.0
+ start
+ run
+ run
+ run
+ run
+ run
+ run
+ run
+ run
+ done
+
#endif