Show More
@@ -1,103 +1,115 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # |
|
3 | 3 | # Copyright 2014 Matt Mackall <mpm@selenic.com> |
|
4 | 4 | # |
|
5 | 5 | # A tool/hook to run basic sanity checks on commits/patches for |
|
6 | 6 | # submission to Mercurial. Install by adding the following to your |
|
7 | 7 | # .hg/hgrc: |
|
8 | 8 | # |
|
9 | 9 | # [hooks] |
|
10 | 10 | # pretxncommit = contrib/check-commit |
|
11 | 11 | # |
|
12 | 12 | # The hook can be temporarily bypassed with: |
|
13 | 13 | # |
|
14 | 14 | # $ BYPASS= hg commit |
|
15 | 15 | # |
|
16 | 16 | # See also: https://mercurial-scm.org/wiki/ContributingChanges |
|
17 | 17 | |
|
18 | 18 | from __future__ import absolute_import, print_function |
|
19 | 19 | |
|
20 | 20 | import os |
|
21 | 21 | import re |
|
22 | 22 | import sys |
|
23 | 23 | |
|
24 | 24 | commitheader = r"^(?:# [^\n]*\n)*" |
|
25 | 25 | afterheader = commitheader + r"(?!#)" |
|
26 | 26 | beforepatch = afterheader + r"(?!\n(?!@@))" |
|
27 | 27 | |
|
28 | 28 | errors = [ |
|
29 | 29 | (beforepatch + r".*[(]bc[)]", "(BC) needs to be uppercase"), |
|
30 | (beforepatch + r".*[(]issue \d\d\d", | |
|
31 | "no space allowed between issue and number"), | |
|
30 | ( | |
|
31 | beforepatch + r".*[(]issue \d\d\d", | |
|
32 | "no space allowed between issue and number", | |
|
33 | ), | |
|
32 | 34 | (beforepatch + r".*[(]bug(\d|\s)", "use (issueDDDD) instead of bug"), |
|
33 | 35 | (commitheader + r"# User [^@\n]+\n", "username is not an email address"), |
|
34 | (commitheader + r"(?!merge with )[^#]\S+[^:] ", | |
|
35 | "summary line doesn't start with 'topic: '"), | |
|
36 | ( | |
|
37 | commitheader + r"(?!merge with )[^#]\S+[^:] ", | |
|
38 | "summary line doesn't start with 'topic: '", | |
|
39 | ), | |
|
36 | 40 | (afterheader + r"[A-Z][a-z]\S+", "don't capitalize summary lines"), |
|
37 | 41 | (afterheader + r"^\S+: *[A-Z][a-z]\S+", "don't capitalize summary lines"), |
|
38 | (afterheader + r"\S*[^A-Za-z0-9-_]\S*: ", | |
|
39 | "summary keyword should be most user-relevant one-word command or topic"), | |
|
42 | ( | |
|
43 | afterheader + r"\S*[^A-Za-z0-9-_]\S*: ", | |
|
44 | "summary keyword should be most user-relevant one-word command or topic", | |
|
45 | ), | |
|
40 | 46 | (afterheader + r".*\.\s*\n", "don't add trailing period on summary line"), |
|
41 | 47 | (afterheader + r".{79,}", "summary line too long (limit is 78)"), |
|
42 | 48 | ] |
|
43 | 49 | |
|
44 | 50 | word = re.compile(r'\S') |
|
51 | ||
|
52 | ||
|
45 | 53 | def nonempty(first, second): |
|
46 | 54 | if word.search(first): |
|
47 | 55 | return first |
|
48 | 56 | return second |
|
49 | 57 | |
|
58 | ||
|
50 | 59 | def checkcommit(commit, node=None): |
|
51 | 60 | exitcode = 0 |
|
52 | 61 | printed = node is None |
|
53 | 62 | hits = [] |
|
54 |
signtag = ( |
|
|
55 |
r'Added (tag [^ ]+|signature) for changeset [a-f0-9]{12}' |
|
|
63 | signtag = ( | |
|
64 | afterheader + r'Added (tag [^ ]+|signature) for changeset [a-f0-9]{12}' | |
|
65 | ) | |
|
56 | 66 | if re.search(signtag, commit): |
|
57 | 67 | return 0 |
|
58 | 68 | for exp, msg in errors: |
|
59 | 69 | for m in re.finditer(exp, commit): |
|
60 | 70 | end = m.end() |
|
61 | 71 | trailing = re.search(r'(\\n)+$', exp) |
|
62 | 72 | if trailing: |
|
63 | 73 | end -= len(trailing.group()) / 2 |
|
64 | 74 | hits.append((end, exp, msg)) |
|
65 | 75 | if hits: |
|
66 | 76 | hits.sort() |
|
67 | 77 | pos = 0 |
|
68 | 78 | last = '' |
|
69 | 79 | for n, l in enumerate(commit.splitlines(True)): |
|
70 | 80 | pos += len(l) |
|
71 | 81 | while len(hits): |
|
72 | 82 | end, exp, msg = hits[0] |
|
73 | 83 | if pos < end: |
|
74 | 84 | break |
|
75 | 85 | if not printed: |
|
76 | 86 | printed = True |
|
77 | 87 | print("node: %s" % node) |
|
78 | 88 | print("%d: %s" % (n, msg)) |
|
79 | 89 | print(" %s" % nonempty(l, last)[:-1]) |
|
80 | 90 | if "BYPASS" not in os.environ: |
|
81 | 91 | exitcode = 1 |
|
82 | 92 | del hits[0] |
|
83 | 93 | last = nonempty(l, last) |
|
84 | 94 | |
|
85 | 95 | return exitcode |
|
86 | 96 | |
|
97 | ||
|
87 | 98 | def readcommit(node): |
|
88 | 99 | return os.popen("hg export %s" % node).read() |
|
89 | 100 | |
|
101 | ||
|
90 | 102 | if __name__ == "__main__": |
|
91 | 103 | exitcode = 0 |
|
92 | 104 | node = os.environ.get("HG_NODE") |
|
93 | 105 | |
|
94 | 106 | if node: |
|
95 | 107 | commit = readcommit(node) |
|
96 | 108 | exitcode = checkcommit(commit) |
|
97 | 109 | elif sys.argv[1:]: |
|
98 | 110 | for node in sys.argv[1:]: |
|
99 | 111 | exitcode |= checkcommit(readcommit(node), node) |
|
100 | 112 | else: |
|
101 | 113 | commit = sys.stdin.read() |
|
102 | 114 | exitcode = checkcommit(commit) |
|
103 | 115 | sys.exit(exitcode) |
@@ -1,44 +1,47 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # Dump revlogs as raw data stream |
|
3 | 3 | # $ find .hg/store/ -name "*.i" | xargs dumprevlog > repo.dump |
|
4 | 4 | |
|
5 | 5 | from __future__ import absolute_import, print_function |
|
6 | 6 | |
|
7 | 7 | import sys |
|
8 | 8 | from mercurial import ( |
|
9 | 9 | encoding, |
|
10 | 10 | node, |
|
11 | 11 | pycompat, |
|
12 | 12 | revlog, |
|
13 | 13 | ) |
|
14 |
from mercurial.utils import |
|
|
15 | procutil, | |
|
16 | ) | |
|
14 | from mercurial.utils import procutil | |
|
17 | 15 | |
|
18 | 16 | for fp in (sys.stdin, sys.stdout, sys.stderr): |
|
19 | 17 | procutil.setbinary(fp) |
|
20 | 18 | |
|
19 | ||
|
21 | 20 | def binopen(path, mode=b'rb'): |
|
22 | 21 | if b'b' not in mode: |
|
23 | 22 | mode = mode + b'b' |
|
24 | 23 | return open(path, pycompat.sysstr(mode)) |
|
24 | ||
|
25 | ||
|
25 | 26 | binopen.options = {} |
|
26 | 27 | |
|
28 | ||
|
27 | 29 | def printb(data, end=b'\n'): |
|
28 | 30 | sys.stdout.flush() |
|
29 | 31 | pycompat.stdout.write(data + end) |
|
30 | 32 | |
|
33 | ||
|
31 | 34 | for f in sys.argv[1:]: |
|
32 | 35 | r = revlog.revlog(binopen, encoding.strtolocal(f)) |
|
33 | 36 | print("file:", f) |
|
34 | 37 | for i in r: |
|
35 | 38 | n = r.node(i) |
|
36 | 39 | p = r.parents(n) |
|
37 | 40 | d = r.revision(n) |
|
38 | 41 | printb(b"node: %s" % node.hex(n)) |
|
39 | 42 | printb(b"linkrev: %d" % r.linkrev(i)) |
|
40 | 43 | printb(b"parents: %s %s" % (node.hex(p[0]), node.hex(p[1]))) |
|
41 | 44 | printb(b"length: %d" % len(d)) |
|
42 | 45 | printb(b"-start-") |
|
43 | 46 | printb(d) |
|
44 | 47 | printb(b"-end-") |
@@ -1,97 +1,111 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # |
|
3 | 3 | # Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de> |
|
4 | 4 | # |
|
5 | 5 | # Author(s): |
|
6 | 6 | # Thomas Arendsen Hein <thomas@intevation.de> |
|
7 | 7 | # |
|
8 | 8 | # This software may be used and distributed according to the terms of the |
|
9 | 9 | # GNU General Public License version 2 or any later version. |
|
10 | 10 | |
|
11 | 11 | """ |
|
12 | 12 | hg-ssh - a wrapper for ssh access to a limited set of mercurial repos |
|
13 | 13 | |
|
14 | 14 | To be used in ~/.ssh/authorized_keys with the "command" option, see sshd(8): |
|
15 | 15 | command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ... |
|
16 | 16 | (probably together with these other useful options: |
|
17 | 17 | no-port-forwarding,no-X11-forwarding,no-agent-forwarding) |
|
18 | 18 | |
|
19 | 19 | This allows pull/push over ssh from/to the repositories given as arguments. |
|
20 | 20 | |
|
21 | 21 | If all your repositories are subdirectories of a common directory, you can |
|
22 | 22 | allow shorter paths with: |
|
23 | 23 | command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2" |
|
24 | 24 | |
|
25 | 25 | You can use pattern matching of your normal shell, e.g.: |
|
26 | 26 | command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}" |
|
27 | 27 | |
|
28 | 28 | You can also add a --read-only flag to allow read-only access to a key, e.g.: |
|
29 | 29 | command="hg-ssh --read-only repos/*" |
|
30 | 30 | """ |
|
31 | 31 | from __future__ import absolute_import |
|
32 | 32 | |
|
33 | 33 | import os |
|
34 | 34 | import shlex |
|
35 | 35 | import sys |
|
36 | 36 | |
|
37 | 37 | # enable importing on demand to reduce startup time |
|
38 |
import hgdemandimport |
|
|
38 | import hgdemandimport | |
|
39 | ||
|
40 | hgdemandimport.enable() | |
|
39 | 41 | |
|
40 | 42 | from mercurial import ( |
|
41 | 43 | dispatch, |
|
42 | 44 | pycompat, |
|
43 | 45 | ui as uimod, |
|
44 | 46 | ) |
|
45 | 47 | |
|
48 | ||
|
46 | 49 | def main(): |
|
47 | 50 | # Prevent insertion/deletion of CRs |
|
48 | 51 | dispatch.initstdio() |
|
49 | 52 | |
|
50 | 53 | cwd = os.getcwd() |
|
51 | 54 | readonly = False |
|
52 | 55 | args = sys.argv[1:] |
|
53 | 56 | while len(args): |
|
54 | 57 | if args[0] == '--read-only': |
|
55 | 58 | readonly = True |
|
56 | 59 | args.pop(0) |
|
57 | 60 | else: |
|
58 | 61 | break |
|
59 | allowed_paths = [os.path.normpath(os.path.join(cwd, | |
|
60 | os.path.expanduser(path))) | |
|
61 |
|
|
|
62 | allowed_paths = [ | |
|
63 | os.path.normpath(os.path.join(cwd, os.path.expanduser(path))) | |
|
64 | for path in args | |
|
65 | ] | |
|
62 | 66 | orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?') |
|
63 | 67 | try: |
|
64 | 68 | cmdargv = shlex.split(orig_cmd) |
|
65 | 69 | except ValueError as e: |
|
66 | 70 | sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e)) |
|
67 | 71 | sys.exit(255) |
|
68 | 72 | |
|
69 | 73 | if cmdargv[:2] == ['hg', '-R'] and cmdargv[3:] == ['serve', '--stdio']: |
|
70 | 74 | path = cmdargv[2] |
|
71 | 75 | repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path))) |
|
72 | 76 | if repo in allowed_paths: |
|
73 | 77 | cmd = [b'-R', pycompat.fsencode(repo), b'serve', b'--stdio'] |
|
74 | 78 | req = dispatch.request(cmd) |
|
75 | 79 | if readonly: |
|
76 | 80 | if not req.ui: |
|
77 | 81 | req.ui = uimod.ui.load() |
|
78 |
req.ui.setconfig( |
|
|
79 | b'python:__main__.rejectpush', b'hg-ssh') | |
|
80 |
|
|
|
81 |
|
|
|
82 | req.ui.setconfig( | |
|
83 | b'hooks', | |
|
84 | b'pretxnopen.hg-ssh', | |
|
85 | b'python:__main__.rejectpush', | |
|
86 | b'hg-ssh', | |
|
87 | ) | |
|
88 | req.ui.setconfig( | |
|
89 | b'hooks', | |
|
90 | b'prepushkey.hg-ssh', | |
|
91 | b'python:__main__.rejectpush', | |
|
92 | b'hg-ssh', | |
|
93 | ) | |
|
82 | 94 | dispatch.dispatch(req) |
|
83 | 95 | else: |
|
84 | 96 | sys.stderr.write('Illegal repository "%s"\n' % repo) |
|
85 | 97 | sys.exit(255) |
|
86 | 98 | else: |
|
87 | 99 | sys.stderr.write('Illegal command "%s"\n' % orig_cmd) |
|
88 | 100 | sys.exit(255) |
|
89 | 101 | |
|
102 | ||
|
90 | 103 | def rejectpush(ui, **kwargs): |
|
91 | 104 | ui.warn((b"Permission denied\n")) |
|
92 | 105 | # mercurial hooks use unix process conventions for hook return values |
|
93 | 106 | # so a truthy return means failure |
|
94 | 107 | return True |
|
95 | 108 | |
|
109 | ||
|
96 | 110 | if __name__ == '__main__': |
|
97 | 111 | main() |
@@ -1,97 +1,112 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # |
|
3 | 3 | # hgperf - measure performance of Mercurial commands |
|
4 | 4 | # |
|
5 | 5 | # Copyright 2014 Matt Mackall <mpm@selenic.com> |
|
6 | 6 | # |
|
7 | 7 | # This software may be used and distributed according to the terms of the |
|
8 | 8 | # GNU General Public License version 2 or any later version. |
|
9 | 9 | |
|
10 | 10 | '''measure performance of Mercurial commands |
|
11 | 11 | |
|
12 | 12 | Using ``hgperf`` instead of ``hg`` measures performance of the target |
|
13 | 13 | Mercurial command. For example, the execution below measures |
|
14 | 14 | performance of :hg:`heads --topo`:: |
|
15 | 15 | |
|
16 | 16 | $ hgperf heads --topo |
|
17 | 17 | |
|
18 | 18 | All command output via ``ui`` is suppressed, and just measurement |
|
19 | 19 | result is displayed: see also "perf" extension in "contrib". |
|
20 | 20 | |
|
21 | 21 | Costs of processing before dispatching to the command function like |
|
22 | 22 | below are not measured:: |
|
23 | 23 | |
|
24 | 24 | - parsing command line (e.g. option validity check) |
|
25 | 25 | - reading configuration files in |
|
26 | 26 | |
|
27 | 27 | But ``pre-`` and ``post-`` hook invocation for the target command is |
|
28 | 28 | measured, even though these are invoked before or after dispatching to |
|
29 | 29 | the command function, because these may be required to repeat |
|
30 | 30 | execution of the target command correctly. |
|
31 | 31 | ''' |
|
32 | 32 | |
|
33 | 33 | import os |
|
34 | 34 | import sys |
|
35 | 35 | |
|
36 | 36 | libdir = '@LIBDIR@' |
|
37 | 37 | |
|
38 | 38 | if libdir != '@' 'LIBDIR' '@': |
|
39 | 39 | if not os.path.isabs(libdir): |
|
40 | libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), | |
|
41 | libdir) | |
|
40 | libdir = os.path.join( | |
|
41 | os.path.dirname(os.path.realpath(__file__)), libdir | |
|
42 | ) | |
|
42 | 43 | libdir = os.path.abspath(libdir) |
|
43 | 44 | sys.path.insert(0, libdir) |
|
44 | 45 | |
|
45 | 46 | # enable importing on demand to reduce startup time |
|
46 | 47 | try: |
|
47 |
from mercurial import demandimport |
|
|
48 | from mercurial import demandimport | |
|
49 | ||
|
50 | demandimport.enable() | |
|
48 | 51 | except ImportError: |
|
49 | 52 | import sys |
|
50 | sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" % | |
|
51 | ' '.join(sys.path)) | |
|
53 | ||
|
54 | sys.stderr.write( | |
|
55 | "abort: couldn't find mercurial libraries in [%s]\n" | |
|
56 | % ' '.join(sys.path) | |
|
57 | ) | |
|
52 | 58 | sys.stderr.write("(check your install and PYTHONPATH)\n") |
|
53 | 59 | sys.exit(-1) |
|
54 | 60 | |
|
55 | 61 | from mercurial import ( |
|
56 | 62 | dispatch, |
|
57 | 63 | util, |
|
58 | 64 | ) |
|
59 | 65 | |
|
66 | ||
|
60 | 67 | def timer(func, title=None): |
|
61 | 68 | results = [] |
|
62 | 69 | begin = util.timer() |
|
63 | 70 | count = 0 |
|
64 | 71 | while True: |
|
65 | 72 | ostart = os.times() |
|
66 | 73 | cstart = util.timer() |
|
67 | 74 | r = func() |
|
68 | 75 | cstop = util.timer() |
|
69 | 76 | ostop = os.times() |
|
70 | 77 | count += 1 |
|
71 | 78 | a, b = ostart, ostop |
|
72 | results.append((cstop - cstart, b[0] - a[0], b[1]-a[1])) | |
|
79 | results.append((cstop - cstart, b[0] - a[0], b[1] - a[1])) | |
|
73 | 80 | if cstop - begin > 3 and count >= 100: |
|
74 | 81 | break |
|
75 | 82 | if cstop - begin > 10 and count >= 3: |
|
76 | 83 | break |
|
77 | 84 | if title: |
|
78 | 85 | sys.stderr.write("! %s\n" % title) |
|
79 | 86 | if r: |
|
80 | 87 | sys.stderr.write("! result: %s\n" % r) |
|
81 | 88 | m = min(results) |
|
82 | sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n" | |
|
83 | % (m[0], m[1] + m[2], m[1], m[2], count)) | |
|
89 | sys.stderr.write( | |
|
90 | "! wall %f comb %f user %f sys %f (best of %d)\n" | |
|
91 | % (m[0], m[1] + m[2], m[1], m[2], count) | |
|
92 | ) | |
|
93 | ||
|
84 | 94 | |
|
85 | 95 | orgruncommand = dispatch.runcommand |
|
86 | 96 | |
|
97 | ||
|
87 | 98 | def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions): |
|
88 | 99 | ui.pushbuffer() |
|
89 | 100 | lui.pushbuffer() |
|
90 | timer(lambda : orgruncommand(lui, repo, cmd, fullargs, ui, | |
|
91 | options, d, cmdpats, cmdoptions)) | |
|
101 | timer( | |
|
102 | lambda: orgruncommand( | |
|
103 | lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions | |
|
104 | ) | |
|
105 | ) | |
|
92 | 106 | ui.popbuffer() |
|
93 | 107 | lui.popbuffer() |
|
94 | 108 | |
|
109 | ||
|
95 | 110 | dispatch.runcommand = runcommand |
|
96 | 111 | |
|
97 | 112 | dispatch.run() |
@@ -1,19 +1,22 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # |
|
3 | 3 | # An example FastCGI script for use with flup, edit as necessary |
|
4 | 4 | |
|
5 | 5 | # Path to repo or hgweb config to serve (see 'hg help hgweb') |
|
6 | 6 | config = "/path/to/repo/or/config" |
|
7 | 7 | |
|
8 | 8 | # Uncomment and adjust if Mercurial is not installed system-wide |
|
9 | 9 | # (consult "installed modules" path from 'hg debuginstall'): |
|
10 | #import sys; sys.path.insert(0, "/path/to/python/lib") | |
|
10 | # import sys; sys.path.insert(0, "/path/to/python/lib") | |
|
11 | 11 | |
|
12 | 12 | # Uncomment to send python tracebacks to the browser if an error occurs: |
|
13 | #import cgitb; cgitb.enable() | |
|
13 | # import cgitb; cgitb.enable() | |
|
14 | 14 | |
|
15 |
from mercurial import demandimport |
|
|
15 | from mercurial import demandimport | |
|
16 | ||
|
17 | demandimport.enable() | |
|
16 | 18 | from mercurial.hgweb import hgweb |
|
17 | 19 | from flup.server.fcgi import WSGIServer |
|
20 | ||
|
18 | 21 | application = hgweb(config) |
|
19 | 22 | WSGIServer(application).run() |
@@ -1,116 +1,129 b'' | |||
|
1 | 1 | #!/usr/bin/env python3 |
|
2 | 2 | # |
|
3 | 3 | # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> |
|
4 | 4 | # |
|
5 | 5 | # This software may be used and distributed according to the terms of the |
|
6 | 6 | # GNU General Public License version 2 or any later version. |
|
7 | 7 | |
|
8 | 8 | import argparse |
|
9 | 9 | import pathlib |
|
10 | 10 | import shutil |
|
11 | 11 | import subprocess |
|
12 | 12 | import sys |
|
13 | 13 | |
|
14 | ||
|
14 | 15 | def get_docker() -> str: |
|
15 | 16 | docker = shutil.which('docker.io') or shutil.which('docker') |
|
16 | 17 | if not docker: |
|
17 | 18 | print('could not find docker executable') |
|
18 | 19 | return 1 |
|
19 | 20 | |
|
20 | 21 | try: |
|
21 | 22 | out = subprocess.check_output([docker, '-h'], stderr=subprocess.STDOUT) |
|
22 | 23 | |
|
23 | 24 | if b'Jansens' in out: |
|
24 | print('%s is the Docking System Tray; try installing docker.io' % | |
|
25 | docker) | |
|
25 | print( | |
|
26 | '%s is the Docking System Tray; try installing docker.io' | |
|
27 | % docker | |
|
28 | ) | |
|
26 | 29 | sys.exit(1) |
|
27 | 30 | except subprocess.CalledProcessError as e: |
|
28 | 31 | print('error calling `%s -h`: %s' % (docker, e.output)) |
|
29 | 32 | sys.exit(1) |
|
30 | 33 | |
|
31 | out = subprocess.check_output([docker, 'version'], | |
|
32 | stderr=subprocess.STDOUT) | |
|
34 | out = subprocess.check_output([docker, 'version'], stderr=subprocess.STDOUT) | |
|
33 | 35 | |
|
34 | 36 | lines = out.splitlines() |
|
35 | 37 | if not any(l.startswith((b'Client:', b'Client version:')) for l in lines): |
|
36 | 38 | print('`%s version` does not look like Docker' % docker) |
|
37 | 39 | sys.exit(1) |
|
38 | 40 | |
|
39 | 41 | if not any(l.startswith((b'Server:', b'Server version:')) for l in lines): |
|
40 | 42 | print('`%s version` does not look like Docker' % docker) |
|
41 | 43 | sys.exit(1) |
|
42 | 44 | |
|
43 | 45 | return docker |
|
44 | 46 | |
|
47 | ||
|
45 | 48 | def get_dockerfile(path: pathlib.Path, args: list) -> bytes: |
|
46 | 49 | with path.open('rb') as fh: |
|
47 | 50 | df = fh.read() |
|
48 | 51 | |
|
49 | 52 | for k, v in args: |
|
50 | 53 | df = df.replace(bytes('%%%s%%' % k.decode(), 'utf-8'), v) |
|
51 | 54 | |
|
52 | 55 | return df |
|
53 | 56 | |
|
57 | ||
|
54 | 58 | def build_docker_image(dockerfile: pathlib.Path, params: list, tag: str): |
|
55 | 59 | """Build a Docker image from a templatized Dockerfile.""" |
|
56 | 60 | docker = get_docker() |
|
57 | 61 | |
|
58 | 62 | dockerfile_path = pathlib.Path(dockerfile) |
|
59 | 63 | |
|
60 | 64 | dockerfile = get_dockerfile(dockerfile_path, params) |
|
61 | 65 | |
|
62 | 66 | print('building Dockerfile:') |
|
63 | 67 | print(dockerfile.decode('utf-8', 'replace')) |
|
64 | 68 | |
|
65 | 69 | args = [ |
|
66 | 70 | docker, |
|
67 | 71 | 'build', |
|
68 |
'--build-arg', |
|
|
69 |
' |
|
|
70 |
'-- |
|
|
72 | '--build-arg', | |
|
73 | 'http_proxy', | |
|
74 | '--build-arg', | |
|
75 | 'https_proxy', | |
|
76 | '--tag', | |
|
77 | tag, | |
|
71 | 78 | '-', |
|
72 | 79 | ] |
|
73 | 80 | |
|
74 | 81 | print('executing: %r' % args) |
|
75 | 82 | p = subprocess.Popen(args, stdin=subprocess.PIPE) |
|
76 | 83 | p.communicate(input=dockerfile) |
|
77 | 84 | if p.returncode: |
|
78 | 85 | raise subprocess.CalledProcessException( |
|
79 | p.returncode, 'failed to build docker image: %s %s' | |
|
80 |
% (p.stdout, p.stderr) |
|
|
86 | p.returncode, | |
|
87 | 'failed to build docker image: %s %s' % (p.stdout, p.stderr), | |
|
88 | ) | |
|
89 | ||
|
81 | 90 | |
|
82 | 91 | def command_build(args): |
|
83 | 92 | build_args = [] |
|
84 | 93 | for arg in args.build_arg: |
|
85 | 94 | k, v = arg.split('=', 1) |
|
86 | 95 | build_args.append((k.encode('utf-8'), v.encode('utf-8'))) |
|
87 | 96 | |
|
88 | build_docker_image(pathlib.Path(args.dockerfile), | |
|
89 | build_args, | |
|
90 | args.tag) | |
|
97 | build_docker_image(pathlib.Path(args.dockerfile), build_args, args.tag) | |
|
98 | ||
|
91 | 99 | |
|
92 | 100 | def command_docker(args): |
|
93 | 101 | print(get_docker()) |
|
94 | 102 | |
|
103 | ||
|
95 | 104 | def main() -> int: |
|
96 | 105 | parser = argparse.ArgumentParser() |
|
97 | 106 | |
|
98 | 107 | subparsers = parser.add_subparsers(title='subcommands') |
|
99 | 108 | |
|
100 | 109 | build = subparsers.add_parser('build', help='Build a Docker image') |
|
101 | 110 | build.set_defaults(func=command_build) |
|
102 | build.add_argument('--build-arg', action='append', default=[], | |
|
103 | help='Substitution to perform in Dockerfile; ' | |
|
104 | 'format: key=value') | |
|
111 | build.add_argument( | |
|
112 | '--build-arg', | |
|
113 | action='append', | |
|
114 | default=[], | |
|
115 | help='Substitution to perform in Dockerfile; ' 'format: key=value', | |
|
116 | ) | |
|
105 | 117 | build.add_argument('dockerfile', help='path to Dockerfile to use') |
|
106 | 118 | build.add_argument('tag', help='Tag to apply to created image') |
|
107 | 119 | |
|
108 | 120 | docker = subparsers.add_parser('docker-path', help='Resolve path to Docker') |
|
109 | 121 | docker.set_defaults(func=command_docker) |
|
110 | 122 | |
|
111 | 123 | args = parser.parse_args() |
|
112 | 124 | |
|
113 | 125 | return args.func(args) |
|
114 | 126 | |
|
127 | ||
|
115 | 128 | if __name__ == '__main__': |
|
116 | 129 | sys.exit(main()) |
@@ -1,204 +1,207 b'' | |||
|
1 | 1 | #!/usr/bin/env python3 |
|
2 | 2 | """Generate release notes from our commit log. |
|
3 | 3 | |
|
4 | 4 | This uses the relnotes extension directives when they're available, |
|
5 | 5 | and falls back to our old pre-relnotes logic that used to live in the |
|
6 | 6 | release-tools repo. |
|
7 | 7 | """ |
|
8 | 8 | import argparse |
|
9 | 9 | import re |
|
10 | 10 | import subprocess |
|
11 | 11 | |
|
12 | 12 | rules = { |
|
13 | 13 | # keep |
|
14 | 14 | r"\(issue": 100, |
|
15 | 15 | r"\(BC\)": 100, |
|
16 | 16 | r"\(API\)": 100, |
|
17 | 17 | r"\(SEC\)": 100, |
|
18 | 18 | # core commands, bump up |
|
19 | 19 | r"(commit|files|log|pull|push|patch|status|tag|summary)(|s|es):": 20, |
|
20 | 20 | r"(annotate|alias|branch|bookmark|clone|graft|import|verify).*:": 20, |
|
21 | 21 | # extensions, bump up |
|
22 | 22 | r"(mq|shelve|rebase):": 20, |
|
23 | 23 | # newsy |
|
24 | 24 | r": deprecate": 20, |
|
25 | 25 | r": new.*(extension|flag|module)": 10, |
|
26 | 26 | r"( ability|command|feature|option|support)": 10, |
|
27 | 27 | # experimental |
|
28 | 28 | r"hg-experimental": 20, |
|
29 | 29 | r"(from|graduate).*experimental": 15, |
|
30 | 30 | r"(hide|mark).*experimental": -10, |
|
31 | 31 | # bug-like? |
|
32 | 32 | r"(fix|don't break|improve)": 7, |
|
33 | 33 | r"(not|n't|avoid|fix|prevent).*crash": 10, |
|
34 | 34 | r"vulnerab": 10, |
|
35 | 35 | # boring stuff, bump down |
|
36 | 36 | r"^contrib": -5, |
|
37 | 37 | r"debug": -5, |
|
38 | 38 | r"help": -5, |
|
39 | 39 | r"minor": -5, |
|
40 | 40 | r"(doc|metavar|bundle2|obsolete|obsmarker|rpm|setup|debug\S+:)": -15, |
|
41 | 41 | r"(check-code|check-commit|check-config|import-checker)": -20, |
|
42 | 42 | r"(flake8|lintian|pyflakes|pylint)": -20, |
|
43 | 43 | # cleanups and refactoring |
|
44 | 44 | r"(clean ?up|white ?space|spelling|quoting)": -20, |
|
45 | 45 | r"(flatten|dedent|indent|nesting|unnest)": -20, |
|
46 | 46 | r"(typo|hint|note|comment|TODO|FIXME)": -20, |
|
47 | 47 | r"(style:|convention|one-?liner)": -20, |
|
48 | 48 | r"(argument|absolute_import|attribute|assignment|mutable)": -15, |
|
49 | 49 | r"(scope|True|False)": -10, |
|
50 | 50 | r"(unused|useless|unnecessar|superfluous|duplicate|deprecated)": -10, |
|
51 | 51 | r"(redundant|pointless|confusing|uninitialized|meaningless|dead)": -10, |
|
52 | 52 | r": (drop|remove|delete|rip out)": -10, |
|
53 | 53 | r": (inherit|rename|simplify|naming|inline)": -10, |
|
54 | 54 | r"(correct doc|docstring|document .* method)": -20, |
|
55 | 55 | r"(abstract|factor|extract|prepare|split|replace| import)": -20, |
|
56 | 56 | r": add.*(function|method|implementation|example)": -10, |
|
57 | 57 | r": (move|extract) .* (to|into|from|out of)": -20, |
|
58 | 58 | r": implement ": -5, |
|
59 | 59 | r": use .* implementation": -20, |
|
60 | 60 | r": use .* instead of": -20, |
|
61 | 61 | # code |
|
62 | 62 | r"_": -10, |
|
63 | 63 | r"__": -5, |
|
64 | 64 | r"\(\)": -5, |
|
65 | 65 | r"\S\S\S+\.\S\S\S\S+": -5, |
|
66 | 66 | # dumb keywords |
|
67 | 67 | r"\S+/\S+:": -10, |
|
68 | 68 | r"\S+\.\S+:": -10, |
|
69 | 69 | # python compatibility |
|
70 | 70 | r"[Pp]y(|thon) ?[23]": -20, |
|
71 | 71 | r"pycompat": -20, |
|
72 | 72 | r"(coerce|convert|encode) .*to (byte|sys|)(s|str|string)": -20, |
|
73 | 73 | # tests |
|
74 | 74 | r"^test(|s|ing|runner|-\S+):": -20, |
|
75 | 75 | r"^(f|hghave|run-tests):": -20, |
|
76 | 76 | r"add.* tests?": -20, |
|
77 | 77 | r"(buildbot|fuzz|mock|ratchet)": -10, |
|
78 | 78 | # drop |
|
79 | 79 | r"^i18n-": -50, |
|
80 | 80 | r"^i18n:.*(hint|comment)": -50, |
|
81 | 81 | r"perf:": -50, |
|
82 | 82 | r"Added.*for changeset": -50, |
|
83 | 83 | r"^_": -50, |
|
84 | 84 | } |
|
85 | 85 | |
|
86 | 86 | cutoff = 10 |
|
87 | 87 | commits = [] |
|
88 | 88 | |
|
89 | 89 | groupings = [ |
|
90 | 90 | (r"util|parsers|repo|ctx|context|revlog|filelog|alias|cmdutil", "core"), |
|
91 | 91 | (r"revset|template|ui|dirstate|hook|i18n|transaction|wire|vfs", "core"), |
|
92 | 92 | (r"dispatch|exchange|localrepo|streamclone|color|pager", "core"), |
|
93 | 93 | (r"hgweb|paper|coal|gitweb|monoblue|spartan", "hgweb"), |
|
94 | 94 | (r"pull|push|revert|resolve|annotate|bookmark|branch|clone", "commands"), |
|
95 | 95 | (r"commands|commit|config|files|graft|import|log|merge|patch", "commands"), |
|
96 | 96 | (r"phases|status|summary|amend|tag|help|verify", "commands"), |
|
97 | 97 | (r"rebase|mq|convert|eol|histedit|largefiles", "extensions"), |
|
98 | 98 | (r"shelve|unshelve", "extensions"), |
|
99 | 99 | ] |
|
100 | 100 | |
|
101 | ||
|
101 | 102 | def wikify(desc): |
|
102 | 103 | desc = desc.replace("(issue", "(Bts:issue") |
|
103 | 104 | desc = re.sub(r"\b([0-9a-f]{12})\b", r"Cset:\1", desc) |
|
104 | 105 | # stop ParseError from being recognized as a (nonexistent) wiki page |
|
105 | 106 | desc = re.sub(r" ([A-Z][a-z]+[A-Z][a-z]+)\b", r" !\1", desc) |
|
106 | 107 | # prevent wiki markup of magic methods |
|
107 | 108 | desc = re.sub(r"\b(\S*__\S*)\b", r"`\1`", desc) |
|
108 | 109 | return desc |
|
109 | 110 | |
|
111 | ||
|
110 | 112 | def main(): |
|
111 | 113 | desc = "example: %(prog)s 4.7.2 --stoprev 4.8rc0" |
|
112 | 114 | ap = argparse.ArgumentParser(description=desc) |
|
113 | 115 | ap.add_argument( |
|
114 | 116 | "startrev", |
|
115 | 117 | metavar="REV", |
|
116 | 118 | type=str, |
|
117 | 119 | help=( |
|
118 | 120 | "Starting revision for the release notes. This revision " |
|
119 | 121 | "won't be included, but later revisions will." |
|
120 | 122 | ), |
|
121 | 123 | ) |
|
122 | 124 | ap.add_argument( |
|
123 | 125 | "--stoprev", |
|
124 | 126 | metavar="REV", |
|
125 | 127 | type=str, |
|
126 | 128 | default="@", |
|
127 | 129 | help=( |
|
128 | 130 | "Stop revision for release notes. This revision will be included," |
|
129 | 131 | " but no later revisions will. This revision needs to be " |
|
130 | 132 | "a descendant of startrev." |
|
131 | 133 | ), |
|
132 | 134 | ) |
|
133 | 135 | args = ap.parse_args() |
|
134 | 136 | fromext = subprocess.check_output( |
|
135 | 137 | [ |
|
136 | 138 | "hg", |
|
137 | 139 | "--config", |
|
138 | 140 | "extensions.releasenotes=", |
|
139 | 141 | "releasenotes", |
|
140 | 142 | "-r", |
|
141 | 143 | "only(%s, %s)" % (args.stoprev, args.startrev), |
|
142 | 144 | ] |
|
143 | 145 | ).decode("utf-8") |
|
144 | 146 | # Find all release notes from un-relnotes-flagged commits. |
|
145 | 147 | for entry in sorted( |
|
146 | 148 | subprocess.check_output( |
|
147 | 149 | [ |
|
148 | 150 | "hg", |
|
149 | 151 | "log", |
|
150 | 152 | "-r", |
|
151 | 153 | "only(%s, %s) - merge()" % (args.stoprev, args.startrev), |
|
152 | 154 | "-T", |
|
153 | 155 | r"{desc|firstline}\n", |
|
154 | 156 | ] |
|
155 | 157 | ) |
|
156 | 158 | .decode("utf-8") |
|
157 | 159 | .splitlines() |
|
158 | 160 | ): |
|
159 | 161 | desc = entry.replace("`", "'") |
|
160 | 162 | |
|
161 | 163 | score = 0 |
|
162 | 164 | for rule, val in rules.items(): |
|
163 | 165 | if re.search(rule, desc): |
|
164 | 166 | score += val |
|
165 | 167 | |
|
166 | 168 | if score >= cutoff: |
|
167 | 169 | commits.append(wikify(desc)) |
|
168 | 170 | # Group unflagged notes. |
|
169 | 171 | groups = {} |
|
170 | 172 | bcs = [] |
|
171 | 173 | apis = [] |
|
172 | 174 | |
|
173 | 175 | for d in commits: |
|
174 | 176 | if "(BC)" in d: |
|
175 | 177 | bcs.append(d) |
|
176 | 178 | if "(API)" in d: |
|
177 | 179 | apis.append(d) |
|
178 | 180 | for rule, g in groupings: |
|
179 | 181 | if re.match(rule, d): |
|
180 | 182 | groups.setdefault(g, []).append(d) |
|
181 | 183 | break |
|
182 | 184 | else: |
|
183 | 185 | groups.setdefault("unsorted", []).append(d) |
|
184 | 186 | print(fromext) |
|
185 | 187 | # print legacy release notes sections |
|
186 | 188 | for g in sorted(groups): |
|
187 | 189 | print("\n=== %s ===" % g) |
|
188 | 190 | for d in sorted(groups[g]): |
|
189 | 191 | print(" * %s" % d) |
|
190 | 192 | |
|
191 | 193 | if bcs: |
|
192 | 194 | print("\n=== Behavior Changes ===\n") |
|
193 | 195 | |
|
194 | 196 | for d in sorted(bcs): |
|
195 | 197 | print(" * %s" % d) |
|
196 | 198 | |
|
197 | 199 | if apis: |
|
198 | 200 | print("\n=== Internal API Changes ===\n") |
|
199 | 201 | |
|
200 | 202 | for d in sorted(apis): |
|
201 | 203 | print(" * %s" % d) |
|
202 | 204 | |
|
205 | ||
|
203 | 206 | if __name__ == "__main__": |
|
204 | 207 | main() |
@@ -1,87 +1,102 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | from __future__ import absolute_import |
|
3 | 3 | |
|
4 | 4 | import getopt |
|
5 | 5 | import sys |
|
6 | 6 | |
|
7 | 7 | import hgdemandimport |
|
8 | ||
|
8 | 9 | hgdemandimport.enable() |
|
9 | 10 | |
|
10 | 11 | from mercurial.i18n import _ |
|
11 | 12 | from mercurial import ( |
|
12 | 13 | context, |
|
13 | 14 | error, |
|
14 | 15 | fancyopts, |
|
15 | 16 | pycompat, |
|
16 | 17 | simplemerge, |
|
17 | 18 | ui as uimod, |
|
18 | 19 | ) |
|
19 |
from mercurial.utils import |
|
|
20 | procutil, | |
|
21 | stringutil | |
|
22 | ) | |
|
20 | from mercurial.utils import procutil, stringutil | |
|
23 | 21 | |
|
24 | options = [(b'L', b'label', [], _(b'labels to use on conflict markers')), | |
|
25 | (b'a', b'text', None, _(b'treat all files as text')), | |
|
26 | (b'p', b'print', None, | |
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
22 | options = [ | |
|
23 | (b'L', b'label', [], _(b'labels to use on conflict markers')), | |
|
24 | (b'a', b'text', None, _(b'treat all files as text')), | |
|
25 | (b'p', b'print', None, _(b'print results instead of overwriting LOCAL')), | |
|
26 | (b'', b'no-minimal', None, _(b'no effect (DEPRECATED)')), | |
|
27 | (b'h', b'help', None, _(b'display help and exit')), | |
|
28 | (b'q', b'quiet', None, _(b'suppress output')), | |
|
29 | ] | |
|
31 | 30 | |
|
32 | usage = _(b'''simplemerge [OPTS] LOCAL BASE OTHER | |
|
31 | usage = _( | |
|
32 | b'''simplemerge [OPTS] LOCAL BASE OTHER | |
|
33 | 33 | |
|
34 | 34 | Simple three-way file merge utility with a minimal feature set. |
|
35 | 35 | |
|
36 | 36 | Apply to LOCAL the changes necessary to go from BASE to OTHER. |
|
37 | 37 | |
|
38 | 38 | By default, LOCAL is overwritten with the results of this operation. |
|
39 |
''' |
|
|
39 | ''' | |
|
40 | ) | |
|
41 | ||
|
40 | 42 | |
|
41 | 43 | class ParseError(Exception): |
|
42 | 44 | """Exception raised on errors in parsing the command line.""" |
|
43 | 45 | |
|
46 | ||
|
44 | 47 | def showhelp(): |
|
45 | 48 | pycompat.stdout.write(usage) |
|
46 | 49 | pycompat.stdout.write(b'\noptions:\n') |
|
47 | 50 | |
|
48 | 51 | out_opts = [] |
|
49 | 52 | for shortopt, longopt, default, desc in options: |
|
50 | out_opts.append((b'%2s%s' % (shortopt and b'-%s' % shortopt, | |
|
51 | longopt and b' --%s' % longopt), | |
|
52 |
|
|
|
53 | out_opts.append( | |
|
54 | ( | |
|
55 | b'%2s%s' | |
|
56 | % ( | |
|
57 | shortopt and b'-%s' % shortopt, | |
|
58 | longopt and b' --%s' % longopt, | |
|
59 | ), | |
|
60 | b'%s' % desc, | |
|
61 | ) | |
|
62 | ) | |
|
53 | 63 | opts_len = max([len(opt[0]) for opt in out_opts]) |
|
54 | 64 | for first, second in out_opts: |
|
55 | 65 | pycompat.stdout.write(b' %-*s %s\n' % (opts_len, first, second)) |
|
56 | 66 | |
|
67 | ||
|
57 | 68 | try: |
|
58 | 69 | for fp in (sys.stdin, pycompat.stdout, sys.stderr): |
|
59 | 70 | procutil.setbinary(fp) |
|
60 | 71 | |
|
61 | 72 | opts = {} |
|
62 | 73 | try: |
|
63 | 74 | bargv = [a.encode('utf8') for a in sys.argv[1:]] |
|
64 | 75 | args = fancyopts.fancyopts(bargv, options, opts) |
|
65 | 76 | except getopt.GetoptError as e: |
|
66 | 77 | raise ParseError(e) |
|
67 | 78 | if opts[b'help']: |
|
68 | 79 | showhelp() |
|
69 | 80 | sys.exit(0) |
|
70 | 81 | if len(args) != 3: |
|
71 |
|
|
|
82 | raise ParseError(_(b'wrong number of arguments').decode('utf8')) | |
|
72 | 83 | local, base, other = args |
|
73 | sys.exit(simplemerge.simplemerge(uimod.ui.load(), | |
|
74 | context.arbitraryfilectx(local), | |
|
75 | context.arbitraryfilectx(base), | |
|
76 |
|
|
|
77 | **pycompat.strkwargs(opts))) | |
|
84 | sys.exit( | |
|
85 | simplemerge.simplemerge( | |
|
86 | uimod.ui.load(), | |
|
87 | context.arbitraryfilectx(local), | |
|
88 | context.arbitraryfilectx(base), | |
|
89 | context.arbitraryfilectx(other), | |
|
90 | **pycompat.strkwargs(opts) | |
|
91 | ) | |
|
92 | ) | |
|
78 | 93 | except ParseError as e: |
|
79 | 94 | e = stringutil.forcebytestr(e) |
|
80 | 95 | pycompat.stdout.write(b"%s: %s\n" % (sys.argv[0].encode('utf8'), e)) |
|
81 | 96 | showhelp() |
|
82 | 97 | sys.exit(1) |
|
83 | 98 | except error.Abort as e: |
|
84 | 99 | pycompat.stderr.write(b"abort: %s\n" % e) |
|
85 | 100 | sys.exit(255) |
|
86 | 101 | except KeyboardInterrupt: |
|
87 | 102 | sys.exit(255) |
@@ -1,50 +1,49 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # Undump a dump from dumprevlog |
|
3 | 3 | # $ hg init |
|
4 | 4 | # $ undumprevlog < repo.dump |
|
5 | 5 | |
|
6 | 6 | from __future__ import absolute_import, print_function |
|
7 | 7 | |
|
8 | 8 | import sys |
|
9 | 9 | from mercurial import ( |
|
10 | 10 | encoding, |
|
11 | 11 | node, |
|
12 | 12 | pycompat, |
|
13 | 13 | revlog, |
|
14 | 14 | transaction, |
|
15 | 15 | vfs as vfsmod, |
|
16 | 16 | ) |
|
17 |
from mercurial.utils import |
|
|
18 | procutil, | |
|
19 | ) | |
|
17 | from mercurial.utils import procutil | |
|
20 | 18 | |
|
21 | 19 | for fp in (sys.stdin, sys.stdout, sys.stderr): |
|
22 | 20 | procutil.setbinary(fp) |
|
23 | 21 | |
|
24 | 22 | opener = vfsmod.vfs(b'.', False) |
|
25 | tr = transaction.transaction(sys.stderr.write, opener, {b'store': opener}, | |
|
26 | b"undump.journal") | |
|
23 | tr = transaction.transaction( | |
|
24 | sys.stderr.write, opener, {b'store': opener}, b"undump.journal" | |
|
25 | ) | |
|
27 | 26 | while True: |
|
28 | 27 | l = sys.stdin.readline() |
|
29 | 28 | if not l: |
|
30 | 29 | break |
|
31 | 30 | if l.startswith("file:"): |
|
32 | 31 | f = encoding.strtolocal(l[6:-1]) |
|
33 | 32 | r = revlog.revlog(opener, f) |
|
34 | 33 | pycompat.stdout.write(b'%s\n' % f) |
|
35 | 34 | elif l.startswith("node:"): |
|
36 | 35 | n = node.bin(l[6:-1]) |
|
37 | 36 | elif l.startswith("linkrev:"): |
|
38 | 37 | lr = int(l[9:-1]) |
|
39 | 38 | elif l.startswith("parents:"): |
|
40 | 39 | p = l[9:-1].split() |
|
41 | 40 | p1 = node.bin(p[0]) |
|
42 | 41 | p2 = node.bin(p[1]) |
|
43 | 42 | elif l.startswith("length:"): |
|
44 | 43 | length = int(l[8:-1]) |
|
45 | sys.stdin.readline() # start marker | |
|
44 | sys.stdin.readline() # start marker | |
|
46 | 45 | d = encoding.strtolocal(sys.stdin.read(length)) |
|
47 | sys.stdin.readline() # end marker | |
|
46 | sys.stdin.readline() # end marker | |
|
48 | 47 | r.addrevision(d, tr, lr, p1, p2) |
|
49 | 48 | |
|
50 | 49 | tr.close() |
@@ -1,36 +1,43 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # |
|
3 | 3 | # mercurial - scalable distributed SCM |
|
4 | 4 | # |
|
5 | 5 | # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
|
6 | 6 | # |
|
7 | 7 | # This software may be used and distributed according to the terms of the |
|
8 | 8 | # GNU General Public License version 2 or any later version. |
|
9 | 9 | from __future__ import absolute_import |
|
10 | 10 | |
|
11 | 11 | import os |
|
12 | 12 | import sys |
|
13 | 13 | |
|
14 | 14 | libdir = '@LIBDIR@' |
|
15 | 15 | |
|
16 | 16 | if libdir != '@' 'LIBDIR' '@': |
|
17 | 17 | if not os.path.isabs(libdir): |
|
18 | libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), | |
|
19 | libdir) | |
|
18 | libdir = os.path.join( | |
|
19 | os.path.dirname(os.path.realpath(__file__)), libdir | |
|
20 | ) | |
|
20 | 21 | libdir = os.path.abspath(libdir) |
|
21 | 22 | sys.path.insert(0, libdir) |
|
22 | 23 | |
|
23 | 24 | from hgdemandimport import tracing |
|
25 | ||
|
24 | 26 | with tracing.log('hg script'): |
|
25 | 27 | # enable importing on demand to reduce startup time |
|
26 | 28 | try: |
|
27 | 29 | if sys.version_info[0] < 3 or sys.version_info >= (3, 6): |
|
28 |
import hgdemandimport |
|
|
30 | import hgdemandimport | |
|
31 | ||
|
32 | hgdemandimport.enable() | |
|
29 | 33 | except ImportError: |
|
30 | sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" % | |
|
31 | ' '.join(sys.path)) | |
|
34 | sys.stderr.write( | |
|
35 | "abort: couldn't find mercurial libraries in [%s]\n" | |
|
36 | % ' '.join(sys.path) | |
|
37 | ) | |
|
32 | 38 | sys.stderr.write("(check your install and PYTHONPATH)\n") |
|
33 | 39 | sys.exit(-1) |
|
34 | 40 | |
|
35 | 41 | from mercurial import dispatch |
|
42 | ||
|
36 | 43 | dispatch.run() |
General Comments 0
You need to be logged in to leave comments.
Login now