wireproto: implement command executor interface for version 1 peers
Now that we've defined our new interface for issuing commands,
let's implement it.
We add the interface to the base peer interface. This means all
peer types must implement it.
The only peer types that we have are the local peer in localrepo
and a shared wire peer for version 1 of the wire protocol.
The local peer implementation is pretty straightforward. We
don't do anything fancy and just return a resolved future with
the result of a method call. This is similar to what
localiterbatcher does.
The wire protocol version 1 implementation is a bit more complicated
and is a more robust implementation.
The wire executor queues commands by default. And because the new
executor interface always allows multiple commands but not all version
1 commands are @batchable, it has to check that the requested commands
are batchable if multiple commands are being requested.
The wire executor currently only supports executing a single command.
This is for simplicity reasons. Support for multiple commands will
be added in a separate commit.
To prove the new interface works, a call to the "known" command
during discovery has been updated to use the new API.
It's worth noting that both implementations require a method having
the command name to exist on the peer. There is at least one caller
in core that don't have a method calls peer._call() directly. We
may need to shore up the requirements later...
Differential Revision: https://phab.mercurial-scm.org/D3268
Test interactions between mq and patch.eol
$ cat <<EOF >> $HGRCPATH
> [extensions]
> mq =
> [diff]
> nodates = 1
> EOF
$ cat > makepatch.py <<EOF
> f = open('eol.diff', 'wb')
> w = f.write
> w(b'test message\n')
> w(b'diff --git a/a b/a\n')
> w(b'--- a/a\n')
> w(b'+++ b/a\n')
> w(b'@@ -1,5 +1,5 @@\n')
> w(b' a\n')
> w(b'-b\r\n')
> w(b'+y\r\n')
> w(b' c\r\n')
> w(b' d\n')
> w(b'-e\n')
> w(b'\ No newline at end of file\n')
> w(b'+z\r\n')
> w(b'\ No newline at end of file\r\n')
> EOF
$ cat > cateol.py <<EOF
> import sys
> for line in open(sys.argv[1], 'rb'):
> line = line.replace(b'\r', b'<CR>')
> line = line.replace(b'\n', b'<LF>')
> print(line)
> EOF
$ hg init repo
$ cd repo
$ echo '\.diff' > .hgignore
$ echo '\.rej' >> .hgignore
Test different --eol values
$ $PYTHON -c 'open("a", "wb").write(b"a\nb\nc\nd\ne")'
$ hg ci -Am adda
adding .hgignore
adding a
$ $PYTHON ../makepatch.py
$ hg qimport eol.diff
adding eol.diff to series file
should fail in strict mode
$ hg qpush
applying eol.diff
patching file a
Hunk #1 FAILED at 0
1 out of 1 hunks FAILED -- saving rejects to file a.rej
patch failed, unable to continue (try -v)
patch failed, rejects left in working directory
errors during apply, please fix and qrefresh eol.diff
[2]
$ hg qpop
popping eol.diff
patch queue now empty
invalid eol
$ hg --config patch.eol='LFCR' qpush
applying eol.diff
patch failed, unable to continue (try -v)
patch failed, rejects left in working directory
errors during apply, please fix and qrefresh eol.diff
[2]
$ hg qpop
popping eol.diff
patch queue now empty
force LF
$ hg --config patch.eol='CRLF' qpush
applying eol.diff
now at: eol.diff
$ hg qrefresh
$ $PYTHON ../cateol.py .hg/patches/eol.diff
# HG changeset patch<LF>
# Parent 0d0bf99a8b7a3842c6f8ef09e34f69156c4bd9d0<LF>
test message<LF>
<LF>
diff -r 0d0bf99a8b7a a<LF>
--- a/a<LF>
+++ b/a<LF>
@@ -1,5 +1,5 @@<LF>
-a<LF>
-b<LF>
-c<LF>
-d<LF>
-e<LF>
\ No newline at end of file<LF>
+a<CR><LF>
+y<CR><LF>
+c<CR><LF>
+d<CR><LF>
+z<LF>
\ No newline at end of file<LF>
$ $PYTHON ../cateol.py a
a<CR><LF>
y<CR><LF>
c<CR><LF>
d<CR><LF>
z
$ hg qpop
popping eol.diff
patch queue now empty
push again forcing LF and compare revisions
$ hg --config patch.eol='CRLF' qpush
applying eol.diff
now at: eol.diff
$ $PYTHON ../cateol.py a
a<CR><LF>
y<CR><LF>
c<CR><LF>
d<CR><LF>
z
$ hg qpop
popping eol.diff
patch queue now empty
push again without LF and compare revisions
$ hg qpush
applying eol.diff
now at: eol.diff
$ $PYTHON ../cateol.py a
a<CR><LF>
y<CR><LF>
c<CR><LF>
d<CR><LF>
z
$ hg qpop
popping eol.diff
patch queue now empty
$ cd ..
Test .rej file EOL are left unchanged
$ hg init testeol
$ cd testeol
$ $PYTHON -c "open('a', 'wb').write(b'1\r\n2\r\n3\r\n4')"
$ hg ci -Am adda
adding a
$ $PYTHON -c "open('a', 'wb').write(b'1\r\n2\r\n33\r\n4')"
$ hg qnew patch1
$ hg qpop
popping patch1
patch queue now empty
$ $PYTHON -c "open('a', 'wb').write(b'1\r\n22\r\n33\r\n4')"
$ hg ci -m changea
$ hg --config 'patch.eol=LF' qpush
applying patch1
patching file a
Hunk #1 FAILED at 0
1 out of 1 hunks FAILED -- saving rejects to file a.rej
patch failed, unable to continue (try -v)
patch failed, rejects left in working directory
errors during apply, please fix and qrefresh patch1
[2]
$ hg qpop
popping patch1
patch queue now empty
$ cat a.rej
--- a
+++ a
@@ -1,4 +1,4 @@
1\r (esc)
2\r (esc)
-3\r (esc)
+33\r (esc)
4
\ No newline at end of file
$ hg --config 'patch.eol=auto' qpush
applying patch1
patching file a
Hunk #1 FAILED at 0
1 out of 1 hunks FAILED -- saving rejects to file a.rej
patch failed, unable to continue (try -v)
patch failed, rejects left in working directory
errors during apply, please fix and qrefresh patch1
[2]
$ hg qpop
popping patch1
patch queue now empty
$ cat a.rej
--- a
+++ a
@@ -1,4 +1,4 @@
1\r (esc)
2\r (esc)
-3\r (esc)
+33\r (esc)
4
\ No newline at end of file
$ cd ..