Mercurial > public > mercurial-scm > hg
annotate mercurial/util.py @ 31720:dea2a17cbfd0
hardlink: check directory's st_dev when copying files
Previously, when copying a file, copyfiles will compare src's st_dev with
dirname(dst)'s st_dev, to decide whether to enable hardlink or not.
That could have issues on Linux's overlayfs, where stating directories could
result in different st_dev from st_dev of stating files, even if both the
directories and the files exist in the overlay's upperdir.
This patch fixes it by checking dirname(src) instead. It's more consistent
because we are checking directories for both src and dest.
That fixes test-hardlinks.t running on common Docker setups.
author | Jun Wu <quark@fb.com> |
---|---|
date | Wed, 29 Mar 2017 12:37:03 -0700 |
parents | 456efd1b51fd |
children | fe9b33bcec6a |
rev | line source |
---|---|
17515 | 1 # util.py - Mercurial utility functions and platform specific implementations |
8226
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
2 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
6 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
7 # This software may be used and distributed according to the terms of the |
10263 | 8 # GNU General Public License version 2 or any later version. |
1082 | 9 |
17515 | 10 """Mercurial utility functions and platform specific implementations. |
1082 | 11 |
8227
0a9542703300
turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents:
8226
diff
changeset
|
12 This contains helper routines that are independent of the SCM core and |
0a9542703300
turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents:
8226
diff
changeset
|
13 hide platform-specific details from the core. |
1082 | 14 """ |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
15 |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
16 from __future__ import absolute_import |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
17 |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
18 import bz2 |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
19 import calendar |
31453
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31451
diff
changeset
|
20 import codecs |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
21 import collections |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
22 import datetime |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
23 import errno |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
24 import gc |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
25 import hashlib |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
26 import imp |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
27 import os |
30418
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
28 import platform as pyplatform |
21907
7e5dfa00e3c2
util: rename 're' to 'remod'
Siddharth Agarwal <sid0@fb.com>
parents:
21857
diff
changeset
|
29 import re as remod |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
30 import shutil |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
31 import signal |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
32 import socket |
30418
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
33 import stat |
30054
8b89521a69ba
util: use string.hexdigits instead of defining it ourselves
Augie Fackler <augie@google.com>
parents:
30053
diff
changeset
|
34 import string |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
35 import subprocess |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
36 import sys |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
37 import tempfile |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
38 import textwrap |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
39 import time |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
40 import traceback |
26266
1e042e31bd0c
changegroup: move all compressions utilities in util
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26201
diff
changeset
|
41 import zlib |
3769 | 42 |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
43 from . import ( |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
44 encoding, |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
45 error, |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
46 i18n, |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
47 osutil, |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
48 parsers, |
28818
6041fb8f2da8
pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
28497
diff
changeset
|
49 pycompat, |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
50 ) |
3769 | 51 |
30471
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
52 empty = pycompat.empty |
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
53 httplib = pycompat.httplib |
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
54 httpserver = pycompat.httpserver |
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
55 pickle = pycompat.pickle |
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
56 queue = pycompat.queue |
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
57 socketserver = pycompat.socketserver |
30472
277f4fe6d01a
py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents:
30471
diff
changeset
|
58 stderr = pycompat.stderr |
277f4fe6d01a
py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents:
30471
diff
changeset
|
59 stdin = pycompat.stdin |
277f4fe6d01a
py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents:
30471
diff
changeset
|
60 stdout = pycompat.stdout |
30471
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
61 stringio = pycompat.stringio |
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
62 urlerr = pycompat.urlerr |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
63 urlreq = pycompat.urlreq |
30471
00c9ac4ce816
util: rewrite pycompat imports to make pyflakes always happy
Yuya Nishihara <yuya@tcha.org>
parents:
30442
diff
changeset
|
64 xmlrpclib = pycompat.xmlrpclib |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
65 |
30876
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
66 def isatty(fp): |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
67 try: |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
68 return fp.isatty() |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
69 except AttributeError: |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
70 return False |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
71 |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
72 # glibc determines buffering on first write to stdout - if we replace a TTY |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
73 # destined stdout with a pipe destined stdout (e.g. pager), we want line |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
74 # buffering |
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
75 if isatty(stdout): |
30988
d194f0dba7ac
py3: convert the mode argument of os.fdopen to unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30975
diff
changeset
|
76 stdout = os.fdopen(stdout.fileno(), pycompat.sysstr('wb'), 1) |
30876
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
77 |
30639
d524c88511a7
py3: replace os.name with pycompat.osname (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30637
diff
changeset
|
78 if pycompat.osname == 'nt': |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
79 from . import windows as platform |
30876
3a4c0905f357
util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents:
30854
diff
changeset
|
80 stdout = platform.winstdout(stdout) |
14912
ec46a7da9f2c
util: move windows and posix wildcard imports to begin of file
Adrian Buehlmann <adrian@cadifra.com>
parents:
14911
diff
changeset
|
81 else: |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
82 from . import posix as platform |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
83 |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
84 _ = i18n._ |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
85 |
29530
3239e2fdd2e2
chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents:
29455
diff
changeset
|
86 bindunixsocket = platform.bindunixsocket |
14927
2aa3e07b2f07
posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents:
14926
diff
changeset
|
87 cachestat = platform.cachestat |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
88 checkexec = platform.checkexec |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
89 checklink = platform.checklink |
15011
5e44e4b3a0a3
util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
15010
diff
changeset
|
90 copymode = platform.copymode |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
91 executablepath = platform.executablepath |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
92 expandglobs = platform.expandglobs |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
93 explainexit = platform.explainexit |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
94 findexe = platform.findexe |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
95 gethgcmd = platform.gethgcmd |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
96 getuser = platform.getuser |
28027
14033c5dd261
util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents:
27785
diff
changeset
|
97 getpid = os.getpid |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
98 groupmembers = platform.groupmembers |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
99 groupname = platform.groupname |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
100 hidewindow = platform.hidewindow |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
101 isexec = platform.isexec |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
102 isowner = platform.isowner |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
103 localpath = platform.localpath |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
104 lookupreg = platform.lookupreg |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
105 makedir = platform.makedir |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
106 nlinks = platform.nlinks |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
107 normpath = platform.normpath |
15488
6eff984d8e76
dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents:
15392
diff
changeset
|
108 normcase = platform.normcase |
24605
98744856b7d3
util: add normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents:
24439
diff
changeset
|
109 normcasespec = platform.normcasespec |
98744856b7d3
util: add normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents:
24439
diff
changeset
|
110 normcasefallback = platform.normcasefallback |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
111 openhardlinks = platform.openhardlinks |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
112 oslink = platform.oslink |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
113 parsepatchoutput = platform.parsepatchoutput |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
114 pconvert = platform.pconvert |
25420
c2ec81891502
util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25406
diff
changeset
|
115 poll = platform.poll |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
116 popen = platform.popen |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
117 posixfile = platform.posixfile |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
118 quotecommand = platform.quotecommand |
22245
234e4c24b980
platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
21914
diff
changeset
|
119 readpipe = platform.readpipe |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
120 rename = platform.rename |
24692
144883a8d0d4
util: add removedirs as platform depending function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
24635
diff
changeset
|
121 removedirs = platform.removedirs |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
122 samedevice = platform.samedevice |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
123 samefile = platform.samefile |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
124 samestat = platform.samestat |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
125 setbinary = platform.setbinary |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
126 setflags = platform.setflags |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
127 setsignalhandler = platform.setsignalhandler |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
128 shellquote = platform.shellquote |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
129 spawndetached = platform.spawndetached |
17560
9ee25d7b1aed
util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents:
17537
diff
changeset
|
130 split = platform.split |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
131 sshargs = platform.sshargs |
18026
ddc0323db78b
osutil: write a C implementation of statfiles for unix
Bryan O'Sullivan <bryano@fb.com>
parents:
18013
diff
changeset
|
132 statfiles = getattr(osutil, 'statfiles', platform.statfiles) |
18868
cafa447a7d3b
util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents:
18775
diff
changeset
|
133 statisexec = platform.statisexec |
cafa447a7d3b
util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents:
18775
diff
changeset
|
134 statislink = platform.statislink |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
135 testpid = platform.testpid |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
136 umask = platform.umask |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
137 unlink = platform.unlink |
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
138 username = platform.username |
14912
ec46a7da9f2c
util: move windows and posix wildcard imports to begin of file
Adrian Buehlmann <adrian@cadifra.com>
parents:
14911
diff
changeset
|
139 |
6470
ac0bcd951c2c
python 2.6 compatibility: compatibility wrappers for hash functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6339
diff
changeset
|
140 # Python compatibility |
3769 | 141 |
15656
4f5a78fa4917
util: clean up function ordering
Matt Mackall <mpm@selenic.com>
parents:
15611
diff
changeset
|
142 _notset = object() |
4f5a78fa4917
util: clean up function ordering
Matt Mackall <mpm@selenic.com>
parents:
15611
diff
changeset
|
143 |
27015
341cb90ffd18
util: disable floating point stat times (issue4836)
Matt Mackall <mpm@selenic.com>
parents:
26847
diff
changeset
|
144 # disable Python's problematic floating point timestamps (issue4836) |
341cb90ffd18
util: disable floating point stat times (issue4836)
Matt Mackall <mpm@selenic.com>
parents:
26847
diff
changeset
|
145 # (Python hypocritically says you shouldn't change this behavior in |
341cb90ffd18
util: disable floating point stat times (issue4836)
Matt Mackall <mpm@selenic.com>
parents:
26847
diff
changeset
|
146 # libraries, and sure enough Mercurial is not a library.) |
341cb90ffd18
util: disable floating point stat times (issue4836)
Matt Mackall <mpm@selenic.com>
parents:
26847
diff
changeset
|
147 os.stat_float_times(False) |
341cb90ffd18
util: disable floating point stat times (issue4836)
Matt Mackall <mpm@selenic.com>
parents:
26847
diff
changeset
|
148 |
15656
4f5a78fa4917
util: clean up function ordering
Matt Mackall <mpm@selenic.com>
parents:
15611
diff
changeset
|
149 def safehasattr(thing, attr): |
4f5a78fa4917
util: clean up function ordering
Matt Mackall <mpm@selenic.com>
parents:
15611
diff
changeset
|
150 return getattr(thing, attr, _notset) is not _notset |
4f5a78fa4917
util: clean up function ordering
Matt Mackall <mpm@selenic.com>
parents:
15611
diff
changeset
|
151 |
30745 | 152 def bitsfrom(container): |
153 bits = 0 | |
154 for bit in container: | |
155 bits |= bit | |
156 return bits | |
157 | |
22962
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
158 DIGESTS = { |
29342
c27dc3c31222
util: drop local aliases for md5, sha1, sha256, and sha512
Augie Fackler <raf@durin42.com>
parents:
29324
diff
changeset
|
159 'md5': hashlib.md5, |
c27dc3c31222
util: drop local aliases for md5, sha1, sha256, and sha512
Augie Fackler <raf@durin42.com>
parents:
29324
diff
changeset
|
160 'sha1': hashlib.sha1, |
c27dc3c31222
util: drop local aliases for md5, sha1, sha256, and sha512
Augie Fackler <raf@durin42.com>
parents:
29324
diff
changeset
|
161 'sha512': hashlib.sha512, |
22962
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
162 } |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
163 # List of digest types from strongest to weakest |
27357
7f5a0bd4c9aa
util: make hashlib import unconditional
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27112
diff
changeset
|
164 DIGESTS_BY_STRENGTH = ['sha512', 'sha1', 'md5'] |
22962
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
165 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
166 for k in DIGESTS_BY_STRENGTH: |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
167 assert k in DIGESTS |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
168 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
169 class digester(object): |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
170 """helper to compute digests. |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
171 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
172 This helper can be used to compute one or more digests given their name. |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
173 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
174 >>> d = digester(['md5', 'sha1']) |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
175 >>> d.update('foo') |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
176 >>> [k for k in sorted(d)] |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
177 ['md5', 'sha1'] |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
178 >>> d['md5'] |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
179 'acbd18db4cc2f85cedef654fccc4a4d8' |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
180 >>> d['sha1'] |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
181 '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33' |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
182 >>> digester.preferred(['md5', 'sha1']) |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
183 'sha1' |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
184 """ |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
185 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
186 def __init__(self, digests, s=''): |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
187 self._hashes = {} |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
188 for k in digests: |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
189 if k not in DIGESTS: |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
190 raise Abort(_('unknown digest type: %s') % k) |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
191 self._hashes[k] = DIGESTS[k]() |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
192 if s: |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
193 self.update(s) |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
194 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
195 def update(self, data): |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
196 for h in self._hashes.values(): |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
197 h.update(data) |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
198 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
199 def __getitem__(self, key): |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
200 if key not in DIGESTS: |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
201 raise Abort(_('unknown digest type: %s') % k) |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
202 return self._hashes[key].hexdigest() |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
203 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
204 def __iter__(self): |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
205 return iter(self._hashes) |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
206 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
207 @staticmethod |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
208 def preferred(supported): |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
209 """returns the strongest digest type in both supported and DIGESTS.""" |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
210 |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
211 for k in DIGESTS_BY_STRENGTH: |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
212 if k in supported: |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
213 return k |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
214 return None |
4d58f4083148
util: add a helper class to compute digests
Mike Hommey <mh@glandium.org>
parents:
22958
diff
changeset
|
215 |
22963
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
216 class digestchecker(object): |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
217 """file handle wrapper that additionally checks content against a given |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
218 size and digests. |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
219 |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
220 d = digestchecker(fh, size, {'md5': '...'}) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
221 |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
222 When multiple digests are given, all of them are validated. |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
223 """ |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
224 |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
225 def __init__(self, fh, size, digests): |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
226 self._fh = fh |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
227 self._size = size |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
228 self._got = 0 |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
229 self._digests = dict(digests) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
230 self._digester = digester(self._digests.keys()) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
231 |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
232 def read(self, length=-1): |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
233 content = self._fh.read(length) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
234 self._digester.update(content) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
235 self._got += len(content) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
236 return content |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
237 |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
238 def validate(self): |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
239 if self._size != self._got: |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
240 raise Abort(_('size mismatch: expected %d, got %d') % |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
241 (self._size, self._got)) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
242 for k, v in self._digests.items(): |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
243 if v != self._digester[k]: |
23076
c312ef382033
i18n: add hint to digest mismatch message
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
23030
diff
changeset
|
244 # i18n: first parameter is a digest name |
22963
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
245 raise Abort(_('%s mismatch: expected %s, got %s') % |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
246 (k, v, self._digester[k])) |
56e04741bbf1
util: add a file handle wrapper class that does hash digest validation
Mike Hommey <mh@glandium.org>
parents:
22962
diff
changeset
|
247 |
11565
7546d4a272c8
util: improved the check for the existence of the 'buffer' builtin
Renato Cunha <renatoc@gmail.com>
parents:
11469
diff
changeset
|
248 try: |
15657
d976b1ef6760
util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents:
15656
diff
changeset
|
249 buffer = buffer |
11565
7546d4a272c8
util: improved the check for the existence of the 'buffer' builtin
Renato Cunha <renatoc@gmail.com>
parents:
11469
diff
changeset
|
250 except NameError: |
30030
0f6d6fdd3c2a
pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents:
29977
diff
changeset
|
251 if not pycompat.ispy3: |
30821
7005c03f7387
util: add length argument to util.buffer()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30798
diff
changeset
|
252 def buffer(sliceable, offset=0, length=None): |
7005c03f7387
util: add length argument to util.buffer()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30798
diff
changeset
|
253 if length is not None: |
7005c03f7387
util: add length argument to util.buffer()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30798
diff
changeset
|
254 return sliceable[offset:offset + length] |
15657
d976b1ef6760
util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents:
15656
diff
changeset
|
255 return sliceable[offset:] |
d976b1ef6760
util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents:
15656
diff
changeset
|
256 else: |
30821
7005c03f7387
util: add length argument to util.buffer()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30798
diff
changeset
|
257 def buffer(sliceable, offset=0, length=None): |
7005c03f7387
util: add length argument to util.buffer()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30798
diff
changeset
|
258 if length is not None: |
7005c03f7387
util: add length argument to util.buffer()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30798
diff
changeset
|
259 return memoryview(sliceable)[offset:offset + length] |
15657
d976b1ef6760
util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents:
15656
diff
changeset
|
260 return memoryview(sliceable)[offset:] |
10756
cb681cc59a8d
util: fake the builtin buffer if it's missing (jython)
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10487
diff
changeset
|
261 |
30639
d524c88511a7
py3: replace os.name with pycompat.osname (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30637
diff
changeset
|
262 closefds = pycompat.osname == 'posix' |
10197
29e3c4a7699b
subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents:
9996
diff
changeset
|
263 |
25406
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
264 _chunksize = 4096 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
265 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
266 class bufferedinputpipe(object): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
267 """a manually buffered input pipe |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
268 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
269 Python will not let us use buffered IO and lazy reading with 'polling' at |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
270 the same time. We cannot probe the buffer state and select will not detect |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
271 that data are ready to read if they are already buffered. |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
272 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
273 This class let us work around that by implementing its own buffering |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
274 (allowing efficient readline) while offering a way to know if the buffer is |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
275 empty from the output (allowing collaboration of the buffer with polling). |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
276 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
277 This class lives in the 'util' module because it makes use of the 'os' |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
278 module from the python stdlib. |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
279 """ |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
280 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
281 def __init__(self, input): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
282 self._input = input |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
283 self._buffer = [] |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
284 self._eof = False |
25672
050dc6eabc92
bufferedinputpipe: remove N^2 computation of buffer length (issue4735)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25671
diff
changeset
|
285 self._lenbuf = 0 |
25406
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
286 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
287 @property |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
288 def hasbuffer(self): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
289 """True is any data is currently buffered |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
290 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
291 This will be used externally a pre-step for polling IO. If there is |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
292 already data then no polling should be set in place.""" |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
293 return bool(self._buffer) |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
294 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
295 @property |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
296 def closed(self): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
297 return self._input.closed |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
298 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
299 def fileno(self): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
300 return self._input.fileno() |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
301 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
302 def close(self): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
303 return self._input.close() |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
304 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
305 def read(self, size): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
306 while (not self._eof) and (self._lenbuf < size): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
307 self._fillbuffer() |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
308 return self._frombuffer(size) |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
309 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
310 def readline(self, *args, **kwargs): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
311 if 1 < len(self._buffer): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
312 # this should not happen because both read and readline end with a |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
313 # _frombuffer call that collapse it. |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
314 self._buffer = [''.join(self._buffer)] |
25672
050dc6eabc92
bufferedinputpipe: remove N^2 computation of buffer length (issue4735)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25671
diff
changeset
|
315 self._lenbuf = len(self._buffer[0]) |
25406
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
316 lfi = -1 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
317 if self._buffer: |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
318 lfi = self._buffer[-1].find('\n') |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
319 while (not self._eof) and lfi < 0: |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
320 self._fillbuffer() |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
321 if self._buffer: |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
322 lfi = self._buffer[-1].find('\n') |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
323 size = lfi + 1 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
324 if lfi < 0: # end of file |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
325 size = self._lenbuf |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
326 elif 1 < len(self._buffer): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
327 # we need to take previous chunks into account |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
328 size += self._lenbuf - len(self._buffer[-1]) |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
329 return self._frombuffer(size) |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
330 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
331 def _frombuffer(self, size): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
332 """return at most 'size' data from the buffer |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
333 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
334 The data are removed from the buffer.""" |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
335 if size == 0 or not self._buffer: |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
336 return '' |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
337 buf = self._buffer[0] |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
338 if 1 < len(self._buffer): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
339 buf = ''.join(self._buffer) |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
340 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
341 data = buf[:size] |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
342 buf = buf[len(data):] |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
343 if buf: |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
344 self._buffer = [buf] |
25672
050dc6eabc92
bufferedinputpipe: remove N^2 computation of buffer length (issue4735)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25671
diff
changeset
|
345 self._lenbuf = len(buf) |
25406
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
346 else: |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
347 self._buffer = [] |
25672
050dc6eabc92
bufferedinputpipe: remove N^2 computation of buffer length (issue4735)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25671
diff
changeset
|
348 self._lenbuf = 0 |
25406
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
349 return data |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
350 |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
351 def _fillbuffer(self): |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
352 """read data to the buffer""" |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
353 data = os.read(self._input.fileno(), _chunksize) |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
354 if not data: |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
355 self._eof = True |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
356 else: |
25672
050dc6eabc92
bufferedinputpipe: remove N^2 computation of buffer length (issue4735)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25671
diff
changeset
|
357 self._lenbuf += len(data) |
25406
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
358 self._buffer.append(data) |
be930f16a52a
util: introduce a bufferedinputpipe utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25245
diff
changeset
|
359 |
10199
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
360 def popen2(cmd, env=None, newlines=False): |
9089
8ec39725d966
util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents:
9084
diff
changeset
|
361 # Setting bufsize to -1 lets the system decide the buffer size. |
8ec39725d966
util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents:
9084
diff
changeset
|
362 # The default for bufsize is 0, meaning unbuffered. This leads to |
8ec39725d966
util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents:
9084
diff
changeset
|
363 # poor performance on Mac OS X: http://bugs.python.org/issue4194 |
8ec39725d966
util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents:
9084
diff
changeset
|
364 p = subprocess.Popen(cmd, shell=True, bufsize=-1, |
9083
ec171737aaf1
Backed out changeset fce065538bcf: it caused a 5x performance regression on OS X
Bryan O'Sullivan <bos@serpentine.com>
parents:
8340
diff
changeset
|
365 close_fds=closefds, |
10197
29e3c4a7699b
subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents:
9996
diff
changeset
|
366 stdin=subprocess.PIPE, stdout=subprocess.PIPE, |
10199
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
367 universal_newlines=newlines, |
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
368 env=env) |
8280
0b02d98d44d0
util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents:
8257
diff
changeset
|
369 return p.stdin, p.stdout |
10197
29e3c4a7699b
subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents:
9996
diff
changeset
|
370 |
10199
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
371 def popen3(cmd, env=None, newlines=False): |
18759
9baf4330d88f
sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents:
18736
diff
changeset
|
372 stdin, stdout, stderr, p = popen4(cmd, env, newlines) |
9baf4330d88f
sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents:
18736
diff
changeset
|
373 return stdin, stdout, stderr |
9baf4330d88f
sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents:
18736
diff
changeset
|
374 |
25245
504ef9c49f4a
util: allow to specify buffer size in popen4
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25211
diff
changeset
|
375 def popen4(cmd, env=None, newlines=False, bufsize=-1): |
504ef9c49f4a
util: allow to specify buffer size in popen4
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25211
diff
changeset
|
376 p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, |
9083
ec171737aaf1
Backed out changeset fce065538bcf: it caused a 5x performance regression on OS X
Bryan O'Sullivan <bos@serpentine.com>
parents:
8340
diff
changeset
|
377 close_fds=closefds, |
8280
0b02d98d44d0
util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents:
8257
diff
changeset
|
378 stdin=subprocess.PIPE, stdout=subprocess.PIPE, |
10197
29e3c4a7699b
subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents:
9996
diff
changeset
|
379 stderr=subprocess.PIPE, |
10199
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
380 universal_newlines=newlines, |
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
381 env=env) |
18759
9baf4330d88f
sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents:
18736
diff
changeset
|
382 return p.stdin, p.stdout, p.stderr, p |
7106
4674706b5b95
python2.6: use subprocess if available
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6884
diff
changeset
|
383 |
7632 | 384 def version(): |
385 """Return version information if available.""" | |
386 try: | |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
387 from . import __version__ |
7632 | 388 return __version__.version |
389 except ImportError: | |
390 return 'unknown' | |
391 | |
27112
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
392 def versiontuple(v=None, n=4): |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
393 """Parses a Mercurial version string into an N-tuple. |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
394 |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
395 The version string to be parsed is specified with the ``v`` argument. |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
396 If it isn't defined, the current Mercurial version string will be parsed. |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
397 |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
398 ``n`` can be 2, 3, or 4. Here is how some version strings map to |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
399 returned values: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
400 |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
401 >>> v = '3.6.1+190-df9b73d2d444' |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
402 >>> versiontuple(v, 2) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
403 (3, 6) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
404 >>> versiontuple(v, 3) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
405 (3, 6, 1) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
406 >>> versiontuple(v, 4) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
407 (3, 6, 1, '190-df9b73d2d444') |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
408 |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
409 >>> versiontuple('3.6.1+190-df9b73d2d444+20151118') |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
410 (3, 6, 1, '190-df9b73d2d444+20151118') |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
411 |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
412 >>> v = '3.6' |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
413 >>> versiontuple(v, 2) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
414 (3, 6) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
415 >>> versiontuple(v, 3) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
416 (3, 6, None) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
417 >>> versiontuple(v, 4) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
418 (3, 6, None, None) |
29613
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
419 |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
420 >>> v = '3.9-rc' |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
421 >>> versiontuple(v, 2) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
422 (3, 9) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
423 >>> versiontuple(v, 3) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
424 (3, 9, None) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
425 >>> versiontuple(v, 4) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
426 (3, 9, None, 'rc') |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
427 |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
428 >>> v = '3.9-rc+2-02a8fea4289b' |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
429 >>> versiontuple(v, 2) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
430 (3, 9) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
431 >>> versiontuple(v, 3) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
432 (3, 9, None) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
433 >>> versiontuple(v, 4) |
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
434 (3, 9, None, 'rc+2-02a8fea4289b') |
27112
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
435 """ |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
436 if not v: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
437 v = version() |
29613
616cbcb59e05
util: better handle '-' in version string (issue5302)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29592
diff
changeset
|
438 parts = remod.split('[\+-]', v, 1) |
27112
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
439 if len(parts) == 1: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
440 vparts, extra = parts[0], None |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
441 else: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
442 vparts, extra = parts |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
443 |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
444 vints = [] |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
445 for i in vparts.split('.'): |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
446 try: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
447 vints.append(int(i)) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
448 except ValueError: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
449 break |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
450 # (3, 6) -> (3, 6, None) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
451 while len(vints) < 3: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
452 vints.append(None) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
453 |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
454 if n == 2: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
455 return (vints[0], vints[1]) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
456 if n == 3: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
457 return (vints[0], vints[1], vints[2]) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
458 if n == 4: |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
459 return (vints[0], vints[1], vints[2], extra) |
39c14e89b881
util: add versiontuple() for returning parsed version information
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27066
diff
changeset
|
460 |
2609
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
461 # used by parsedate |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
462 defaultdateformats = ( |
29638
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
463 '%Y-%m-%dT%H:%M:%S', # the 'real' ISO8601 |
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
464 '%Y-%m-%dT%H:%M', # without seconds |
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
465 '%Y-%m-%dT%H%M%S', # another awful but legal variant without : |
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
466 '%Y-%m-%dT%H%M', # without seconds |
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
467 '%Y-%m-%d %H:%M:%S', # our common legal variant |
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
468 '%Y-%m-%d %H:%M', # without seconds |
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
469 '%Y-%m-%d %H%M%S', # without : |
491ee264b9f6
date: accept broader range of ISO 8601 time specs
Matt Mackall <mpm@selenic.com>
parents:
29637
diff
changeset
|
470 '%Y-%m-%d %H%M', # without seconds |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
471 '%Y-%m-%d %I:%M:%S%p', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
472 '%Y-%m-%d %H:%M', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
473 '%Y-%m-%d %I:%M%p', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
474 '%Y-%m-%d', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
475 '%m-%d', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
476 '%m/%d', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
477 '%m/%d/%y', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
478 '%m/%d/%Y', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
479 '%a %b %d %H:%M:%S %Y', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
480 '%a %b %d %I:%M:%S%p %Y', |
4708
01f9ee4de1ad
Add support for RFC2822 to util.parsedate().
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents:
4686
diff
changeset
|
481 '%a, %d %b %Y %H:%M:%S', # GNU coreutils "/bin/date --rfc-2822" |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
482 '%b %d %H:%M:%S %Y', |
3812 | 483 '%b %d %I:%M:%S%p %Y', |
484 '%b %d %H:%M:%S', | |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
485 '%b %d %I:%M:%S%p', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
486 '%b %d %H:%M', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
487 '%b %d %I:%M%p', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
488 '%b %d %Y', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
489 '%b %d', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
490 '%H:%M:%S', |
9383
7116494c48ab
util: Fix date format for 12-hour time.
Carey Evans <carey@carey.geek.nz>
parents:
9097
diff
changeset
|
491 '%I:%M:%S%p', |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
492 '%H:%M', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
493 '%I:%M%p', |
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
494 ) |
2609
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
495 |
3812 | 496 extendeddateformats = defaultdateformats + ( |
497 "%Y", | |
498 "%Y-%m", | |
499 "%b", | |
500 "%b %Y", | |
501 ) | |
2609
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
502 |
3145
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
503 def cachefunc(func): |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
504 '''cache the result of function calls''' |
3147
97420a49188d
add comments in cachefunc
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3145
diff
changeset
|
505 # XXX doesn't handle keywords args |
28832
f5ff10f6fa6b
util: use __code__ (available since py2.6)
timeless <timeless@mozdev.org>
parents:
28826
diff
changeset
|
506 if func.__code__.co_argcount == 0: |
20835
0e8417131a29
util: add the code path to "cachefunc()" for the function taking no arguments
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20679
diff
changeset
|
507 cache = [] |
0e8417131a29
util: add the code path to "cachefunc()" for the function taking no arguments
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20679
diff
changeset
|
508 def f(): |
0e8417131a29
util: add the code path to "cachefunc()" for the function taking no arguments
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20679
diff
changeset
|
509 if len(cache) == 0: |
0e8417131a29
util: add the code path to "cachefunc()" for the function taking no arguments
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20679
diff
changeset
|
510 cache.append(func()) |
0e8417131a29
util: add the code path to "cachefunc()" for the function taking no arguments
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20679
diff
changeset
|
511 return cache[0] |
0e8417131a29
util: add the code path to "cachefunc()" for the function taking no arguments
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20679
diff
changeset
|
512 return f |
3145
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
513 cache = {} |
28832
f5ff10f6fa6b
util: use __code__ (available since py2.6)
timeless <timeless@mozdev.org>
parents:
28826
diff
changeset
|
514 if func.__code__.co_argcount == 1: |
3147
97420a49188d
add comments in cachefunc
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3145
diff
changeset
|
515 # we gain a small amount of time because |
97420a49188d
add comments in cachefunc
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3145
diff
changeset
|
516 # we don't need to pack/unpack the list |
3145
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
517 def f(arg): |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
518 if arg not in cache: |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
519 cache[arg] = func(arg) |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
520 return cache[arg] |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
521 else: |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
522 def f(*args): |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
523 if args not in cache: |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
524 cache[args] = func(*args) |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
525 return cache[args] |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
526 |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
527 return f |
e4ea47c21480
Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents:
3131
diff
changeset
|
528 |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
529 class sortdict(dict): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
530 '''a simple sorted dictionary''' |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
531 def __init__(self, data=None): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
532 self._list = [] |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
533 if data: |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
534 self.update(data) |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
535 def copy(self): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
536 return sortdict(self) |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
537 def __setitem__(self, key, val): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
538 if key in self: |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
539 self._list.remove(key) |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
540 self._list.append(key) |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
541 dict.__setitem__(self, key, val) |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
542 def __iter__(self): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
543 return self._list.__iter__() |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
544 def update(self, src): |
24236
de14c3972c2f
sortdict: have update() accept either dict or iterable of key/value pairs
Yuya Nishihara <yuya@tcha.org>
parents:
24188
diff
changeset
|
545 if isinstance(src, dict): |
de14c3972c2f
sortdict: have update() accept either dict or iterable of key/value pairs
Yuya Nishihara <yuya@tcha.org>
parents:
24188
diff
changeset
|
546 src = src.iteritems() |
de14c3972c2f
sortdict: have update() accept either dict or iterable of key/value pairs
Yuya Nishihara <yuya@tcha.org>
parents:
24188
diff
changeset
|
547 for k, v in src: |
de14c3972c2f
sortdict: have update() accept either dict or iterable of key/value pairs
Yuya Nishihara <yuya@tcha.org>
parents:
24188
diff
changeset
|
548 self[k] = v |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
549 def clear(self): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
550 dict.clear(self) |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
551 self._list = [] |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
552 def items(self): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
553 return [(k, self[k]) for k in self._list] |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
554 def __delitem__(self, key): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
555 dict.__delitem__(self, key) |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
556 self._list.remove(key) |
22643
3b1c0e1ede4c
util: fix sorteddict.pop
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22638
diff
changeset
|
557 def pop(self, key, *args, **kwargs): |
3b1c0e1ede4c
util: fix sorteddict.pop
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22638
diff
changeset
|
558 dict.pop(self, key, *args, **kwargs) |
3b1c0e1ede4c
util: fix sorteddict.pop
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22638
diff
changeset
|
559 try: |
3b1c0e1ede4c
util: fix sorteddict.pop
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22638
diff
changeset
|
560 self._list.remove(key) |
3b1c0e1ede4c
util: fix sorteddict.pop
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22638
diff
changeset
|
561 except ValueError: |
3b1c0e1ede4c
util: fix sorteddict.pop
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22638
diff
changeset
|
562 pass |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
563 def keys(self): |
30854
0126e422450e
util: make sortdict.keys() return a copy
Martin von Zweigbergk <martinvonz@google.com>
parents:
30821
diff
changeset
|
564 return self._list[:] |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
565 def iterkeys(self): |
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
566 return self._list.__iter__() |
23260
565f97e71ce3
sortdict: add iteritems method
Sean Farley <sean.michael.farley@gmail.com>
parents:
23139
diff
changeset
|
567 def iteritems(self): |
565f97e71ce3
sortdict: add iteritems method
Sean Farley <sean.michael.farley@gmail.com>
parents:
23139
diff
changeset
|
568 for k in self._list: |
565f97e71ce3
sortdict: add iteritems method
Sean Farley <sean.michael.farley@gmail.com>
parents:
23139
diff
changeset
|
569 yield k, self[k] |
23261
79858e66a7ce
sortdict: add insert method
Sean Farley <sean.michael.farley@gmail.com>
parents:
23260
diff
changeset
|
570 def insert(self, index, key, val): |
79858e66a7ce
sortdict: add insert method
Sean Farley <sean.michael.farley@gmail.com>
parents:
23260
diff
changeset
|
571 self._list.insert(index, key) |
79858e66a7ce
sortdict: add insert method
Sean Farley <sean.michael.farley@gmail.com>
parents:
23260
diff
changeset
|
572 dict.__setitem__(self, key, val) |
29592
37cccad55410
util: implement a deterministic __repr__ on sortdict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29566
diff
changeset
|
573 def __repr__(self): |
37cccad55410
util: implement a deterministic __repr__ on sortdict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29566
diff
changeset
|
574 if not self: |
37cccad55410
util: implement a deterministic __repr__ on sortdict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29566
diff
changeset
|
575 return '%s()' % self.__class__.__name__ |
37cccad55410
util: implement a deterministic __repr__ on sortdict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29566
diff
changeset
|
576 return '%s(%r)' % (self.__class__.__name__, self.items()) |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
21046
diff
changeset
|
577 |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
578 class _lrucachenode(object): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
579 """A node in a doubly linked list. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
580 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
581 Holds a reference to nodes on either side as well as a key-value |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
582 pair for the dictionary entry. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
583 """ |
30038
42ead5b3aa7b
py3: use unicodes in __slots__
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30036
diff
changeset
|
584 __slots__ = (u'next', u'prev', u'key', u'value') |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
585 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
586 def __init__(self): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
587 self.next = None |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
588 self.prev = None |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
589 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
590 self.key = _notset |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
591 self.value = None |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
592 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
593 def markempty(self): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
594 """Mark the node as emptied.""" |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
595 self.key = _notset |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
596 |
18603
2251b3184e6e
util: add an LRU cache dict
Siddharth Agarwal <sid0@fb.com>
parents:
18537
diff
changeset
|
597 class lrucachedict(object): |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
598 """Dict that caches most recent accesses and sets. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
599 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
600 The dict consists of an actual backing dict - indexed by original |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
601 key - and a doubly linked circular list defining the order of entries in |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
602 the cache. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
603 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
604 The head node is the newest entry in the cache. If the cache is full, |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
605 we recycle head.prev and make it the new head. Cache accesses result in |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
606 the node being moved to before the existing head and being marked as the |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
607 new head node. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
608 """ |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
609 def __init__(self, max): |
18603
2251b3184e6e
util: add an LRU cache dict
Siddharth Agarwal <sid0@fb.com>
parents:
18537
diff
changeset
|
610 self._cache = {} |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
611 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
612 self._head = head = _lrucachenode() |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
613 head.prev = head |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
614 head.next = head |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
615 self._size = 1 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
616 self._capacity = max |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
617 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
618 def __len__(self): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
619 return len(self._cache) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
620 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
621 def __contains__(self, k): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
622 return k in self._cache |
18603
2251b3184e6e
util: add an LRU cache dict
Siddharth Agarwal <sid0@fb.com>
parents:
18537
diff
changeset
|
623 |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
624 def __iter__(self): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
625 # We don't have to iterate in cache order, but why not. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
626 n = self._head |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
627 for i in range(len(self._cache)): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
628 yield n.key |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
629 n = n.next |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
630 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
631 def __getitem__(self, k): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
632 node = self._cache[k] |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
633 self._movetohead(node) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
634 return node.value |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
635 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
636 def __setitem__(self, k, v): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
637 node = self._cache.get(k) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
638 # Replace existing value and mark as newest. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
639 if node is not None: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
640 node.value = v |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
641 self._movetohead(node) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
642 return |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
643 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
644 if self._size < self._capacity: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
645 node = self._addcapacity() |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
646 else: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
647 # Grab the last/oldest item. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
648 node = self._head.prev |
18603
2251b3184e6e
util: add an LRU cache dict
Siddharth Agarwal <sid0@fb.com>
parents:
18537
diff
changeset
|
649 |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
650 # At capacity. Kill the old entry. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
651 if node.key is not _notset: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
652 del self._cache[node.key] |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
653 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
654 node.key = k |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
655 node.value = v |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
656 self._cache[k] = node |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
657 # And mark it as newest entry. No need to adjust order since it |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
658 # is already self._head.prev. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
659 self._head = node |
18603
2251b3184e6e
util: add an LRU cache dict
Siddharth Agarwal <sid0@fb.com>
parents:
18537
diff
changeset
|
660 |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
661 def __delitem__(self, k): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
662 node = self._cache.pop(k) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
663 node.markempty() |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
664 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
665 # Temporarily mark as newest item before re-adjusting head to make |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
666 # this node the oldest item. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
667 self._movetohead(node) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
668 self._head = node.next |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
669 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
670 # Additional dict methods. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
671 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
672 def get(self, k, default=None): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
673 try: |
29828
79add5a4e857
util: properly implement lrucachedict.get()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29776
diff
changeset
|
674 return self._cache[k].value |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
675 except KeyError: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
676 return default |
18603
2251b3184e6e
util: add an LRU cache dict
Siddharth Agarwal <sid0@fb.com>
parents:
18537
diff
changeset
|
677 |
19710
887ffa22fd0d
lrucachedict: implement clear()
Siddharth Agarwal <sid0@fb.com>
parents:
19461
diff
changeset
|
678 def clear(self): |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
679 n = self._head |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
680 while n.key is not _notset: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
681 n.markempty() |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
682 n = n.next |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
683 |
19710
887ffa22fd0d
lrucachedict: implement clear()
Siddharth Agarwal <sid0@fb.com>
parents:
19461
diff
changeset
|
684 self._cache.clear() |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
685 |
27576
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
686 def copy(self): |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
687 result = lrucachedict(self._capacity) |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
688 n = self._head.prev |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
689 # Iterate in oldest-to-newest order, so the copy has the right ordering |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
690 for i in range(len(self._cache)): |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
691 result[n.key] = n.value |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
692 n = n.prev |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
693 return result |
6cd3044985c2
lrucachedict: add copy method
Eric Sumner <ericsumner@fb.com>
parents:
27391
diff
changeset
|
694 |
27371
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
695 def _movetohead(self, node): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
696 """Mark a node as the newest, making it the new head. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
697 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
698 When a node is accessed, it becomes the freshest entry in the LRU |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
699 list, which is denoted by self._head. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
700 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
701 Visually, let's make ``N`` the new head node (* denotes head): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
702 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
703 previous/oldest <-> head <-> next/next newest |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
704 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
705 ----<->--- A* ---<->----- |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
706 | | |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
707 E <-> D <-> N <-> C <-> B |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
708 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
709 To: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
710 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
711 ----<->--- N* ---<->----- |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
712 | | |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
713 E <-> D <-> C <-> B <-> A |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
714 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
715 This requires the following moves: |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
716 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
717 C.next = D (node.prev.next = node.next) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
718 D.prev = C (node.next.prev = node.prev) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
719 E.next = N (head.prev.next = node) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
720 N.prev = E (node.prev = head.prev) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
721 N.next = A (node.next = head) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
722 A.prev = N (head.prev = node) |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
723 """ |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
724 head = self._head |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
725 # C.next = D |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
726 node.prev.next = node.next |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
727 # D.prev = C |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
728 node.next.prev = node.prev |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
729 # N.prev = E |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
730 node.prev = head.prev |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
731 # N.next = A |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
732 # It is tempting to do just "head" here, however if node is |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
733 # adjacent to head, this will do bad things. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
734 node.next = head.prev.next |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
735 # E.next = N |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
736 node.next.prev = node |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
737 # A.prev = N |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
738 node.prev.next = node |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
739 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
740 self._head = node |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
741 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
742 def _addcapacity(self): |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
743 """Add a node to the circular linked list. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
744 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
745 The new node is inserted before the head node. |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
746 """ |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
747 head = self._head |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
748 node = _lrucachenode() |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
749 head.prev.next = node |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
750 node.prev = head.prev |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
751 node.next = head |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
752 head.prev = node |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
753 self._size += 1 |
45d996a566d7
util: reimplement lrucachedict
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27363
diff
changeset
|
754 return node |
19710
887ffa22fd0d
lrucachedict: implement clear()
Siddharth Agarwal <sid0@fb.com>
parents:
19461
diff
changeset
|
755 |
9097
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
756 def lrucachefunc(func): |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
757 '''cache most recent results of function calls''' |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
758 cache = {} |
25113
0ca8410ea345
util: drop alias for collections.deque
Martin von Zweigbergk <martinvonz@google.com>
parents:
25112
diff
changeset
|
759 order = collections.deque() |
28832
f5ff10f6fa6b
util: use __code__ (available since py2.6)
timeless <timeless@mozdev.org>
parents:
28826
diff
changeset
|
760 if func.__code__.co_argcount == 1: |
9097
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
761 def f(arg): |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
762 if arg not in cache: |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
763 if len(cache) > 20: |
16803
107a3270a24a
cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents:
16769
diff
changeset
|
764 del cache[order.popleft()] |
9097
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
765 cache[arg] = func(arg) |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
766 else: |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
767 order.remove(arg) |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
768 order.append(arg) |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
769 return cache[arg] |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
770 else: |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
771 def f(*args): |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
772 if args not in cache: |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
773 if len(cache) > 20: |
16803
107a3270a24a
cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents:
16769
diff
changeset
|
774 del cache[order.popleft()] |
9097
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
775 cache[args] = func(*args) |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
776 else: |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
777 order.remove(args) |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
778 order.append(args) |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
779 return cache[args] |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
780 |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
781 return f |
431462bd8478
fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents:
9089
diff
changeset
|
782 |
8207
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
783 class propertycache(object): |
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
784 def __init__(self, func): |
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
785 self.func = func |
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
786 self.name = func.__name__ |
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
787 def __get__(self, obj, type=None): |
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
788 result = self.func(obj) |
18013
98c867ac1330
clfilter: add a propertycache that must be unfiltered
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
17962
diff
changeset
|
789 self.cachevalue(obj, result) |
8207
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
790 return result |
dd8d5be57d65
util: take propertycache from context.py
Matt Mackall <mpm@selenic.com>
parents:
8181
diff
changeset
|
791 |
18013
98c867ac1330
clfilter: add a propertycache that must be unfiltered
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
17962
diff
changeset
|
792 def cachevalue(self, obj, value): |
19951
d51c4d85ec23
spelling: random spell checker fixes
Mads Kiilerich <madski@unity3d.com>
parents:
19852
diff
changeset
|
793 # __dict__ assignment required to bypass __setattr__ (eg: repoview) |
19845
a1237a4b437d
repoview: make propertycache.setcache compatible with repoview
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
19461
diff
changeset
|
794 obj.__dict__[self.name] = value |
18013
98c867ac1330
clfilter: add a propertycache that must be unfiltered
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
17962
diff
changeset
|
795 |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
796 def pipefilter(s, cmd): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
797 '''filter string S through command CMD, returning its output''' |
8302
d2ad8c066676
util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents:
8299
diff
changeset
|
798 p = subprocess.Popen(cmd, shell=True, close_fds=closefds, |
d2ad8c066676
util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents:
8299
diff
changeset
|
799 stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
d2ad8c066676
util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents:
8299
diff
changeset
|
800 pout, perr = p.communicate(s) |
d2ad8c066676
util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents:
8299
diff
changeset
|
801 return pout |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
802 |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
803 def tempfilter(s, cmd): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
804 '''filter string S through a pair of temporary files with CMD. |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
805 CMD is used as a template to create the real command to be run, |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
806 with the strings INFILE and OUTFILE replaced by the real names of |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
807 the temporary files generated.''' |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
808 inname, outname = None, None |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
809 try: |
2165
d821918e3bee
Use better names (hg-{usage}-{random}.{suffix}) for temporary files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2153
diff
changeset
|
810 infd, inname = tempfile.mkstemp(prefix='hg-filter-in-') |
30925
82f1ef8b4477
py3: convert the mode argument of os.fdopen to unicodes (2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30876
diff
changeset
|
811 fp = os.fdopen(infd, pycompat.sysstr('wb')) |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
812 fp.write(s) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
813 fp.close() |
2165
d821918e3bee
Use better names (hg-{usage}-{random}.{suffix}) for temporary files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2153
diff
changeset
|
814 outfd, outname = tempfile.mkstemp(prefix='hg-filter-out-') |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
815 os.close(outfd) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
816 cmd = cmd.replace('INFILE', inname) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
817 cmd = cmd.replace('OUTFILE', outname) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
818 code = os.system(cmd) |
30642
e995f00a9e9a
py3: replace sys.platform with pycompat.sysplatform (part 2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30639
diff
changeset
|
819 if pycompat.sysplatform == 'OpenVMS' and code & 1: |
4720
72fb6f10fac1
OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents:
4708
diff
changeset
|
820 code = 0 |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
821 if code: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
822 raise Abort(_("command '%s' failed: %s") % |
14234
600e64004eb5
rename explain_exit to explainexit
Adrian Buehlmann <adrian@cadifra.com>
parents:
14230
diff
changeset
|
823 (cmd, explainexit(code))) |
27768
5ef99738a562
util: replace file I/O with readfile
Bryan O'Sullivan <bryano@fb.com>
parents:
27766
diff
changeset
|
824 return readfile(outname) |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
825 finally: |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
826 try: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
827 if inname: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
828 os.unlink(inname) |
14004
97ed99d1f419
eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents:
13985
diff
changeset
|
829 except OSError: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
830 pass |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
831 try: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
832 if outname: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
833 os.unlink(outname) |
14004
97ed99d1f419
eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents:
13985
diff
changeset
|
834 except OSError: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
835 pass |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
836 |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
837 filtertable = { |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
838 'tempfile:': tempfilter, |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
839 'pipe:': pipefilter, |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
840 } |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
841 |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
842 def filter(s, cmd): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
843 "filter a string through a command that transforms its input to its output" |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
844 for name, fn in filtertable.iteritems(): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
845 if cmd.startswith(name): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
846 return fn(s, cmd[len(name):].lstrip()) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
847 return pipefilter(s, cmd) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
848 |
1015
22571b8d35d3
Add automatic binary file detection to diff and export
mpm@selenic.com
parents:
917
diff
changeset
|
849 def binary(s): |
6507
9699864de219
Let util.binary check entire data for \0 (issue1066, issue1079)
Christian Ebert <blacktrash@gmx.net>
parents:
6501
diff
changeset
|
850 """return true if a string is binary data""" |
8118
35f7fda52c92
util: return boolean result directly in util.binary
Martin Geisler <mg@lazybytes.net>
parents:
8011
diff
changeset
|
851 return bool(s and '\0' in s) |
6762 | 852 |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
853 def increasingchunks(source, min=1024, max=65536): |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
854 '''return no less than min bytes per chunk while data remains, |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
855 doubling min after each chunk until it reaches max''' |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
856 def log2(x): |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
857 if not x: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
858 return 0 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
859 i = 0 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
860 while x: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
861 x >>= 1 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
862 i += 1 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
863 return i - 1 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
864 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
865 buf = [] |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
866 blen = 0 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
867 for chunk in source: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
868 buf.append(chunk) |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
869 blen += len(chunk) |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
870 if blen >= min: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
871 if min < max: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
872 min = min << 1 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
873 nmin = 1 << log2(blen) |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
874 if nmin > min: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
875 min = nmin |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
876 if min > max: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
877 min = max |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
878 yield ''.join(buf) |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
879 blen = 0 |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
880 buf = [] |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
881 if buf: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
882 yield ''.join(buf) |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7301
diff
changeset
|
883 |
7947
a454eeb1b827
move util.Abort to error.py
Matt Mackall <mpm@selenic.com>
parents:
7913
diff
changeset
|
884 Abort = error.Abort |
508 | 885 |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
886 def always(fn): |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
887 return True |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
888 |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
889 def never(fn): |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
890 return False |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
891 |
23495
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
892 def nogc(func): |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
893 """disable garbage collector |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
894 |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
895 Python's garbage collector triggers a GC each time a certain number of |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
896 container objects (the number being defined by gc.get_threshold()) are |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
897 allocated even when marked not to be tracked by the collector. Tracking has |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
898 no effect on when GCs are triggered, only on what objects the GC looks |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23495
diff
changeset
|
899 into. As a workaround, disable GC while building complex (huge) |
23495
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
900 containers. |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
901 |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
902 This garbage collector issue have been fixed in 2.7. |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
903 """ |
30053
dbcef8918bbd
util: correct check of sys.version_info
Augie Fackler <augie@google.com>
parents:
30039
diff
changeset
|
904 if sys.version_info >= (2, 7): |
29776
279cd80059d4
performance: disable workaround for an old bug of Python gc
Maciej Fijalkowski <fijall@gmail.com>
parents:
29730
diff
changeset
|
905 return func |
23495
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
906 def wrapper(*args, **kwargs): |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
907 gcenabled = gc.isenabled() |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
908 gc.disable() |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
909 try: |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
910 return func(*args, **kwargs) |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
911 finally: |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
912 if gcenabled: |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
913 gc.enable() |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
914 return wrapper |
b25f07cb5399
util: add a 'nogc' decorator to disable the garbage collection
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23370
diff
changeset
|
915 |
4229
24c22a3f2ef8
pass repo.root to util.pathto() in preparation for the next patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4129
diff
changeset
|
916 def pathto(root, n1, n2): |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
917 '''return the relative path from one place to another. |
4229
24c22a3f2ef8
pass repo.root to util.pathto() in preparation for the next patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4129
diff
changeset
|
918 root should use os.sep to separate directories |
3669
48768b1ab23c
fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3629
diff
changeset
|
919 n1 should use os.sep to separate directories |
48768b1ab23c
fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3629
diff
changeset
|
920 n2 should use "/" to separate directories |
48768b1ab23c
fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3629
diff
changeset
|
921 returns an os.sep-separated path. |
4229
24c22a3f2ef8
pass repo.root to util.pathto() in preparation for the next patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4129
diff
changeset
|
922 |
24c22a3f2ef8
pass repo.root to util.pathto() in preparation for the next patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4129
diff
changeset
|
923 If n1 is a relative path, it's assumed it's |
24c22a3f2ef8
pass repo.root to util.pathto() in preparation for the next patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4129
diff
changeset
|
924 relative to root. |
24c22a3f2ef8
pass repo.root to util.pathto() in preparation for the next patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4129
diff
changeset
|
925 n2 should always be relative to root. |
3669
48768b1ab23c
fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3629
diff
changeset
|
926 ''' |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
927 if not n1: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
928 return localpath(n2) |
4230
c93562fb12cc
Fix handling of paths when run outside the repo.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4229
diff
changeset
|
929 if os.path.isabs(n1): |
c93562fb12cc
Fix handling of paths when run outside the repo.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4229
diff
changeset
|
930 if os.path.splitdrive(root)[0] != os.path.splitdrive(n1)[0]: |
c93562fb12cc
Fix handling of paths when run outside the repo.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4229
diff
changeset
|
931 return os.path.join(root, localpath(n2)) |
c93562fb12cc
Fix handling of paths when run outside the repo.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4229
diff
changeset
|
932 n2 = '/'.join((pconvert(root), n2)) |
5844
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
933 a, b = splitpath(n1), n2.split('/') |
1541
bf4e7ef08741
fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents:
1528
diff
changeset
|
934 a.reverse() |
bf4e7ef08741
fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents:
1528
diff
changeset
|
935 b.reverse() |
884
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
936 while a and b and a[-1] == b[-1]: |
1541
bf4e7ef08741
fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents:
1528
diff
changeset
|
937 a.pop() |
bf4e7ef08741
fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents:
1528
diff
changeset
|
938 b.pop() |
884
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
939 b.reverse() |
30613
1112ff99d965
py3: replace os.sep with pycompat.ossep (part 1 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30536
diff
changeset
|
940 return pycompat.ossep.join((['..'] * len(a)) + b) or '.' |
884
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
941 |
14228
116de1da2154
rename util.main_is_frozen to mainfrozen
Adrian Buehlmann <adrian@cadifra.com>
parents:
14167
diff
changeset
|
942 def mainfrozen(): |
6499
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
943 """return True if we are a frozen executable. |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
944 |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
945 The code supports py2exe (most common, Windows only) and tools/freeze |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
946 (portable, not much used). |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
947 """ |
14968
b7dbe957585c
util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14942
diff
changeset
|
948 return (safehasattr(sys, "frozen") or # new py2exe |
b7dbe957585c
util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14942
diff
changeset
|
949 safehasattr(sys, "importers") or # old py2exe |
30039
ff7697b436ab
py3: use unicode in is_frozen()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30038
diff
changeset
|
950 imp.is_frozen(u"__main__")) # tools/freeze |
6499
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
951 |
22633
92b54547ac5d
util: introduce datapath for getting the location of supporting data files
Mads Kiilerich <madski@unity3d.com>
parents:
22632
diff
changeset
|
952 # the location of data files matching the source code |
27764
dd0c5f4d1b53
util: adjust 'datapath' to be correct in a frozen OS X package
Matt Harbison <matt_harbison@yahoo.com>
parents:
27755
diff
changeset
|
953 if mainfrozen() and getattr(sys, 'frozen', None) != 'macosx_app': |
22633
92b54547ac5d
util: introduce datapath for getting the location of supporting data files
Mads Kiilerich <madski@unity3d.com>
parents:
22632
diff
changeset
|
954 # executable version (py2exe) doesn't support __file__ |
30669
10b17ed9b591
py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30642
diff
changeset
|
955 datapath = os.path.dirname(pycompat.sysexecutable) |
22633
92b54547ac5d
util: introduce datapath for getting the location of supporting data files
Mads Kiilerich <madski@unity3d.com>
parents:
22632
diff
changeset
|
956 else: |
31074
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30988
diff
changeset
|
957 datapath = os.path.dirname(pycompat.fsencode(__file__)) |
30301
8321b083a83d
py3: make util.datapath a bytes variable
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30265
diff
changeset
|
958 |
22638
0d0350cfc7ab
i18n: use datapath for i18n like for templates and help
Mads Kiilerich <madski@unity3d.com>
parents:
22633
diff
changeset
|
959 i18n.setdatapath(datapath) |
0d0350cfc7ab
i18n: use datapath for i18n like for templates and help
Mads Kiilerich <madski@unity3d.com>
parents:
22633
diff
changeset
|
960 |
22632
db15bb2d6323
util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents:
22245
diff
changeset
|
961 _hgexecutable = None |
db15bb2d6323
util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents:
22245
diff
changeset
|
962 |
5062
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
963 def hgexecutable(): |
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
964 """return location of the 'hg' executable. |
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
965 |
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
966 Defaults to $HG or 'hg' in the search path. |
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
967 """ |
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
968 if _hgexecutable is None: |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30625
diff
changeset
|
969 hg = encoding.environ.get('HG') |
31533
28f00d07e2ee
util: reference __main__ in sys.modules as a sysstr
Augie Fackler <augie@google.com>
parents:
31496
diff
changeset
|
970 mainmod = sys.modules[pycompat.sysstr('__main__')] |
6500 | 971 if hg: |
14229
85fd8402cbc4
rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents:
14228
diff
changeset
|
972 _sethgexecutable(hg) |
14228
116de1da2154
rename util.main_is_frozen to mainfrozen
Adrian Buehlmann <adrian@cadifra.com>
parents:
14167
diff
changeset
|
973 elif mainfrozen(): |
27765
f1fb93eebb1d
util: adjust hgexecutable() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents:
27764
diff
changeset
|
974 if getattr(sys, 'frozen', None) == 'macosx_app': |
f1fb93eebb1d
util: adjust hgexecutable() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents:
27764
diff
changeset
|
975 # Env variable set by py2app |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30625
diff
changeset
|
976 _sethgexecutable(encoding.environ['EXECUTABLEPATH']) |
27765
f1fb93eebb1d
util: adjust hgexecutable() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents:
27764
diff
changeset
|
977 else: |
30669
10b17ed9b591
py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30642
diff
changeset
|
978 _sethgexecutable(pycompat.sysexecutable) |
31074
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30988
diff
changeset
|
979 elif (os.path.basename( |
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30988
diff
changeset
|
980 pycompat.fsencode(getattr(mainmod, '__file__', ''))) == 'hg'): |
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30988
diff
changeset
|
981 _sethgexecutable(pycompat.fsencode(mainmod.__file__)) |
6499
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
982 else: |
14271
4030630fb59c
rename util.find_exe to findexe
Adrian Buehlmann <adrian@cadifra.com>
parents:
14262
diff
changeset
|
983 exe = findexe('hg') or os.path.basename(sys.argv[0]) |
14229
85fd8402cbc4
rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents:
14228
diff
changeset
|
984 _sethgexecutable(exe) |
5062
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
985 return _hgexecutable |
4686
849f011dbf79
Remember path to 'hg' executable and pass to external tools and hooks as $HG.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4673
diff
changeset
|
986 |
14229
85fd8402cbc4
rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents:
14228
diff
changeset
|
987 def _sethgexecutable(path): |
5062
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
988 """set location of the 'hg' executable""" |
4686
849f011dbf79
Remember path to 'hg' executable and pass to external tools and hooks as $HG.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4673
diff
changeset
|
989 global _hgexecutable |
5062
3d35c8cb5eb4
Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4832
diff
changeset
|
990 _hgexecutable = path |
4686
849f011dbf79
Remember path to 'hg' executable and pass to external tools and hooks as $HG.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4673
diff
changeset
|
991 |
26450
1138e1d05207
util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents:
26392
diff
changeset
|
992 def _isstdout(f): |
1138e1d05207
util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents:
26392
diff
changeset
|
993 fileno = getattr(f, 'fileno', None) |
1138e1d05207
util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents:
26392
diff
changeset
|
994 return fileno and fileno() == sys.__stdout__.fileno() |
1138e1d05207
util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents:
26392
diff
changeset
|
995 |
30736
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
996 def shellenviron(environ=None): |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
997 """return environ with optional override, useful for shelling out""" |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
998 def py2shell(val): |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
999 'convert python object into string that is useful to shell' |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1000 if val is None or val is False: |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1001 return '0' |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1002 if val is True: |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1003 return '1' |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1004 return str(val) |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1005 env = dict(encoding.environ) |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1006 if environ: |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1007 env.update((k, py2shell(v)) for k, v in environ.iteritems()) |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1008 env['HG'] = hgexecutable() |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1009 return env |
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1010 |
31108
3f8f53190d6a
chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents:
31074
diff
changeset
|
1011 def system(cmd, environ=None, cwd=None, out=None): |
1882
c0320567931f
merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1880
diff
changeset
|
1012 '''enhanced shell command execution. |
c0320567931f
merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1880
diff
changeset
|
1013 run with environment maybe modified, maybe in different dir. |
508 | 1014 |
11469
c37f35d7f2f5
http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents:
11297
diff
changeset
|
1015 if out is specified, it is assumed to be a file-like object that has a |
c37f35d7f2f5
http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents:
11297
diff
changeset
|
1016 write() method. stdout and stderr will be redirected to out.''' |
13439
d724a69309e0
util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents:
13400
diff
changeset
|
1017 try: |
30473
39d13b8c101d
py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents:
30472
diff
changeset
|
1018 stdout.flush() |
13439
d724a69309e0
util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents:
13400
diff
changeset
|
1019 except Exception: |
d724a69309e0
util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents:
13400
diff
changeset
|
1020 pass |
13188
6c9345f9edca
util: concentrate quoting knowledge to windows.py quotecommand()
Steve Borho <steve@borho.org>
parents:
13128
diff
changeset
|
1021 cmd = quotecommand(cmd) |
30642
e995f00a9e9a
py3: replace sys.platform with pycompat.sysplatform (part 2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30639
diff
changeset
|
1022 if pycompat.sysplatform == 'plan9' and (sys.version_info[0] == 2 |
19729
dfefb719eb92
plan9: update util.py for cpython 2.7 build
Jeff Sickel <jas@corpus-callosum.com>
parents:
19710
diff
changeset
|
1023 and sys.version_info[1] < 7): |
16383
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1024 # subprocess kludge to work around issues in half-baked Python |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1025 # ports, notably bichued/python: |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1026 if not cwd is None: |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1027 os.chdir(cwd) |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1028 rc = os.system(cmd) |
11469
c37f35d7f2f5
http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents:
11297
diff
changeset
|
1029 else: |
30736
d9e5b0aeeb90
util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents:
30669
diff
changeset
|
1030 env = shellenviron(environ) |
26450
1138e1d05207
util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents:
26392
diff
changeset
|
1031 if out is None or _isstdout(out): |
16383
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1032 rc = subprocess.call(cmd, shell=True, close_fds=closefds, |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1033 env=env, cwd=cwd) |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1034 else: |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1035 proc = subprocess.Popen(cmd, shell=True, close_fds=closefds, |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1036 env=env, cwd=cwd, stdout=subprocess.PIPE, |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1037 stderr=subprocess.STDOUT) |
29730
4d23cd6e2219
util: use `iter(callable, sentinel)` instead of while True
Augie Fackler <augie@google.com>
parents:
29638
diff
changeset
|
1038 for line in iter(proc.stdout.readline, ''): |
16383
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1039 out.write(line) |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1040 proc.wait() |
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1041 rc = proc.returncode |
30642
e995f00a9e9a
py3: replace sys.platform with pycompat.sysplatform (part 2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30639
diff
changeset
|
1042 if pycompat.sysplatform == 'OpenVMS' and rc & 1: |
16383
f5dd179bfa4a
plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
16360
diff
changeset
|
1043 rc = 0 |
9517
4368f582c806
util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents:
9508
diff
changeset
|
1044 return rc |
1880
05c7d75be925
fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1877
diff
changeset
|
1045 |
7388
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1046 def checksignature(func): |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1047 '''wrap a function with code to check for calling errors''' |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1048 def check(*args, **kwargs): |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1049 try: |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1050 return func(*args, **kwargs) |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1051 except TypeError: |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1052 if len(traceback.extract_tb(sys.exc_info()[2])) == 1: |
7646 | 1053 raise error.SignatureError |
7388
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1054 raise |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1055 |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1056 return check |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7301
diff
changeset
|
1057 |
31575
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1058 # a whilelist of known filesystems where hardlink works reliably |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1059 _hardlinkfswhitelist = set([ |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1060 'btrfs', |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1061 'ext2', |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1062 'ext3', |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1063 'ext4', |
31598
32f09ead059b
util: enable hardlink for some BSD-family filesystems
Jun Wu <quark@fb.com>
parents:
31594
diff
changeset
|
1064 'hfs', |
31575
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1065 'jfs', |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1066 'reiserfs', |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1067 'tmpfs', |
31598
32f09ead059b
util: enable hardlink for some BSD-family filesystems
Jun Wu <quark@fb.com>
parents:
31594
diff
changeset
|
1068 'ufs', |
31575
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1069 'xfs', |
31598
32f09ead059b
util: enable hardlink for some BSD-family filesystems
Jun Wu <quark@fb.com>
parents:
31594
diff
changeset
|
1070 'zfs', |
31575
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1071 ]) |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1072 |
29204
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1073 def copyfile(src, dest, hardlink=False, copystat=False, checkambig=False): |
27369
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1074 '''copy a file, preserving mode and optionally other stat info like |
29367
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1075 atime/mtime |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1076 |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1077 checkambig argument is used with filestat, and is useful only if |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1078 destination file is guarded by any lock (e.g. repo.lock or |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1079 repo.wlock). |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1080 |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1081 copystat and checkambig should be exclusive. |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1082 ''' |
29204
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1083 assert not (copystat and checkambig) |
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1084 oldstat = None |
18326
614f769e6aa7
util: copyfile: remove dest before copying
Mads Kiilerich <mads@kiilerich.com>
parents:
18026
diff
changeset
|
1085 if os.path.lexists(dest): |
29204
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1086 if checkambig: |
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1087 oldstat = checkambig and filestat(dest) |
18326
614f769e6aa7
util: copyfile: remove dest before copying
Mads Kiilerich <mads@kiilerich.com>
parents:
18026
diff
changeset
|
1088 unlink(dest) |
31575
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1089 if hardlink: |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1090 # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1091 # unless we are confident that dest is on a whitelisted filesystem. |
31678
1ed57a7dd904
statfs: make getfstype() raise OSError
Yuya Nishihara <yuya@tcha.org>
parents:
31662
diff
changeset
|
1092 try: |
1ed57a7dd904
statfs: make getfstype() raise OSError
Yuya Nishihara <yuya@tcha.org>
parents:
31662
diff
changeset
|
1093 fstype = getfstype(os.path.dirname(dest)) |
1ed57a7dd904
statfs: make getfstype() raise OSError
Yuya Nishihara <yuya@tcha.org>
parents:
31662
diff
changeset
|
1094 except OSError: |
1ed57a7dd904
statfs: make getfstype() raise OSError
Yuya Nishihara <yuya@tcha.org>
parents:
31662
diff
changeset
|
1095 fstype = None |
31575
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1096 if fstype not in _hardlinkfswhitelist: |
e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Jun Wu <quark@fb.com>
parents:
31573
diff
changeset
|
1097 hardlink = False |
31577 | 1098 if hardlink: |
23899
4e451d1359de
copyfile: allow optional hardlinking
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23864
diff
changeset
|
1099 try: |
4e451d1359de
copyfile: allow optional hardlinking
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23864
diff
changeset
|
1100 oslink(src, dest) |
4e451d1359de
copyfile: allow optional hardlinking
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23864
diff
changeset
|
1101 return |
4e451d1359de
copyfile: allow optional hardlinking
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23864
diff
changeset
|
1102 except (IOError, OSError): |
4e451d1359de
copyfile: allow optional hardlinking
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23864
diff
changeset
|
1103 pass # fall back to normal copy |
4271
1eaa8d90c689
fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents:
4256
diff
changeset
|
1104 if os.path.islink(src): |
1eaa8d90c689
fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents:
4256
diff
changeset
|
1105 os.symlink(os.readlink(src), dest) |
27369
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1106 # copytime is ignored for symlinks, but in general copytime isn't needed |
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1107 # for them anyway |
4271
1eaa8d90c689
fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents:
4256
diff
changeset
|
1108 else: |
1eaa8d90c689
fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents:
4256
diff
changeset
|
1109 try: |
1eaa8d90c689
fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents:
4256
diff
changeset
|
1110 shutil.copyfile(src, dest) |
27369
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1111 if copystat: |
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1112 # copystat also copies mode |
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1113 shutil.copystat(src, dest) |
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1114 else: |
c48ecc0b5bc9
copyfile: add an optional parameter to copy other stat data
Siddharth Agarwal <sid0@fb.com>
parents:
26665
diff
changeset
|
1115 shutil.copymode(src, dest) |
29204
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1116 if oldstat and oldstat.stat: |
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1117 newstat = filestat(dest) |
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1118 if newstat.isambig(oldstat): |
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1119 # stat of copied file is ambiguous to original one |
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1120 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff |
ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29201
diff
changeset
|
1121 os.utime(dest, (advanced, advanced)) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25420
diff
changeset
|
1122 except shutil.Error as inst: |
4271
1eaa8d90c689
fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents:
4256
diff
changeset
|
1123 raise Abort(str(inst)) |
3629
4cfb72bcb978
util: add copyfile function
Matt Mackall <mpm@selenic.com>
parents:
3568
diff
changeset
|
1124 |
24439
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1125 def copyfiles(src, dst, hardlink=None, progress=lambda t, pos: None): |
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1126 """Copy a directory tree using hardlinks if possible.""" |
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1127 num = 0 |
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
1128 |
31718
bf64449b2779
hardlink: extract topic text logic of copyfiles
Jun Wu <quark@fb.com>
parents:
31678
diff
changeset
|
1129 gettopic = lambda: hardlink and _('linking') or _('copying') |
698
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
1130 |
1207 | 1131 if os.path.isdir(src): |
31719
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1132 if hardlink is None: |
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1133 hardlink = (os.stat(src).st_dev == |
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1134 os.stat(os.path.dirname(dst)).st_dev) |
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1135 topic = gettopic() |
1207 | 1136 os.mkdir(dst) |
5396
5105b119edd2
Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
5360
diff
changeset
|
1137 for name, kind in osutil.listdir(src): |
1207 | 1138 srcname = os.path.join(src, name) |
1139 dstname = os.path.join(dst, name) | |
24439
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1140 def nprog(t, pos): |
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1141 if pos is not None: |
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1142 return progress(t, pos + num) |
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1143 hardlink, n = copyfiles(srcname, dstname, hardlink, progress=nprog) |
11251
c61442f6d106
clone: print number of linked/copied files on --debug
Adrian Buehlmann <adrian@cadifra.com>
parents:
11232
diff
changeset
|
1144 num += n |
1207 | 1145 else: |
31719
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1146 if hardlink is None: |
31720
dea2a17cbfd0
hardlink: check directory's st_dev when copying files
Jun Wu <quark@fb.com>
parents:
31719
diff
changeset
|
1147 hardlink = (os.stat(os.path.dirname(src)).st_dev == |
31719
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1148 os.stat(os.path.dirname(dst)).st_dev) |
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1149 topic = gettopic() |
456efd1b51fd
hardlink: duplicate hardlink detection for copying files and directories
Jun Wu <quark@fb.com>
parents:
31718
diff
changeset
|
1150 |
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
1151 if hardlink: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
1152 try: |
14235
b9e1b041744f
rename util.os_link to oslink
Adrian Buehlmann <adrian@cadifra.com>
parents:
14234
diff
changeset
|
1153 oslink(src, dst) |
2050
e49d0fa38176
util.copyfiles: only switch to copy if hardlink raises IOError or OSError.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2026
diff
changeset
|
1154 except (IOError, OSError): |
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
1155 hardlink = False |
1591
5a3229cf1492
do not copy atime and mtime in util.copyfiles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1585
diff
changeset
|
1156 shutil.copy(src, dst) |
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
1157 else: |
1591
5a3229cf1492
do not copy atime and mtime in util.copyfiles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1585
diff
changeset
|
1158 shutil.copy(src, dst) |
11251
c61442f6d106
clone: print number of linked/copied files on --debug
Adrian Buehlmann <adrian@cadifra.com>
parents:
11232
diff
changeset
|
1159 num += 1 |
24439
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1160 progress(topic, num) |
2ddfac2f163e
util: add progress callback support to copyfiles
Augie Fackler <augie@google.com>
parents:
24236
diff
changeset
|
1161 progress(topic, None) |
698
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
1162 |
11251
c61442f6d106
clone: print number of linked/copied files on --debug
Adrian Buehlmann <adrian@cadifra.com>
parents:
11232
diff
changeset
|
1163 return hardlink, num |
11254
640d419725d0
util.copyfiles: don't try os_link() again if it failed before
Adrian Buehlmann <adrian@cadifra.com>
parents:
11010
diff
changeset
|
1164 |
14262
23cd7eeff678
util: rename _windows_reserved_filenames and _windows_reserved_chars
Adrian Buehlmann <adrian@cadifra.com>
parents:
14250
diff
changeset
|
1165 _winreservednames = '''con prn aux nul |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1166 com1 com2 com3 com4 com5 com6 com7 com8 com9 |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1167 lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split() |
14262
23cd7eeff678
util: rename _windows_reserved_filenames and _windows_reserved_chars
Adrian Buehlmann <adrian@cadifra.com>
parents:
14250
diff
changeset
|
1168 _winreservedchars = ':*?"<>|' |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1169 def checkwinfilename(path): |
20000
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1170 r'''Check that the base-relative path is a valid filename on Windows. |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1171 Returns None if the path is ok, or a UI string describing the problem. |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1172 |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1173 >>> checkwinfilename("just/a/normal/path") |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1174 >>> checkwinfilename("foo/bar/con.xml") |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1175 "filename contains 'con', which is reserved on Windows" |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1176 >>> checkwinfilename("foo/con.xml/bar") |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1177 "filename contains 'con', which is reserved on Windows" |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1178 >>> checkwinfilename("foo/bar/xml.con") |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1179 >>> checkwinfilename("foo/bar/AUX/bla.txt") |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1180 "filename contains 'AUX', which is reserved on Windows" |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1181 >>> checkwinfilename("foo/bar/bla:.txt") |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1182 "filename contains ':', which is reserved on Windows" |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1183 >>> checkwinfilename("foo/bar/b\07la.txt") |
20000
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1184 "filename contains '\\x07', which is invalid on Windows" |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1185 >>> checkwinfilename("foo/bar/bla ") |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1186 "filename ends with ' ', which is not allowed on Windows" |
15358
a347b3614bae
util: don't complain about '..' in path components not working on Windows
Matt Mackall <mpm@selenic.com>
parents:
15159
diff
changeset
|
1187 >>> checkwinfilename("../bar") |
20000
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1188 >>> checkwinfilename("foo\\") |
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1189 "filename ends with '\\', which is invalid on Windows" |
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1190 >>> checkwinfilename("foo\\/bar") |
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1191 "directory name ends with '\\', which is invalid on Windows" |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1192 ''' |
20000
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1193 if path.endswith('\\'): |
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1194 return _("filename ends with '\\', which is invalid on Windows") |
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1195 if '\\/' in path: |
0849d280663e
util: warn when adding paths ending with \
Mads Kiilerich <madski@unity3d.com>
parents:
19951
diff
changeset
|
1196 return _("directory name ends with '\\', which is invalid on Windows") |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1197 for n in path.replace('\\', '/').split('/'): |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1198 if not n: |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1199 continue |
31495
d1937bdcee8c
util: use pycompat.bytestr in checkwinfilename
Augie Fackler <augie@google.com>
parents:
31485
diff
changeset
|
1200 for c in pycompat.bytestr(n): |
14262
23cd7eeff678
util: rename _windows_reserved_filenames and _windows_reserved_chars
Adrian Buehlmann <adrian@cadifra.com>
parents:
14250
diff
changeset
|
1201 if c in _winreservedchars: |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1202 return _("filename contains '%s', which is reserved " |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1203 "on Windows") % c |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1204 if ord(c) <= 31: |
13947
d2d1ef6a5238
checkwinfilename: use %r in format string
Adrian Buehlmann <adrian@cadifra.com>
parents:
13944
diff
changeset
|
1205 return _("filename contains %r, which is invalid " |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1206 "on Windows") % c |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1207 base = n.split('.')[0] |
14262
23cd7eeff678
util: rename _windows_reserved_filenames and _windows_reserved_chars
Adrian Buehlmann <adrian@cadifra.com>
parents:
14250
diff
changeset
|
1208 if base and base.lower() in _winreservednames: |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1209 return _("filename contains '%s', which is reserved " |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1210 "on Windows") % base |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1211 t = n[-1] |
15358
a347b3614bae
util: don't complain about '..' in path components not working on Windows
Matt Mackall <mpm@selenic.com>
parents:
15159
diff
changeset
|
1212 if t in '. ' and n not in '..': |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1213 return _("filename ends with '%s', which is not allowed " |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1214 "on Windows") % t |
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1215 |
30639
d524c88511a7
py3: replace os.name with pycompat.osname (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30637
diff
changeset
|
1216 if pycompat.osname == 'nt': |
13916
98ee3dd5bab4
path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13910
diff
changeset
|
1217 checkosfilename = checkwinfilename |
30974
ae5d60bb70c9
util: introduce timer()
Simon Farnsworth <simonfar@fb.com>
parents:
30925
diff
changeset
|
1218 timer = time.clock |
7890
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1219 else: |
14926
4e7e63fc685a
util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents:
14918
diff
changeset
|
1220 checkosfilename = platform.checkosfilename |
30974
ae5d60bb70c9
util: introduce timer()
Simon Farnsworth <simonfar@fb.com>
parents:
30925
diff
changeset
|
1221 timer = time.time |
ae5d60bb70c9
util: introduce timer()
Simon Farnsworth <simonfar@fb.com>
parents:
30925
diff
changeset
|
1222 |
ae5d60bb70c9
util: introduce timer()
Simon Farnsworth <simonfar@fb.com>
parents:
30925
diff
changeset
|
1223 if safehasattr(time, "perf_counter"): |
ae5d60bb70c9
util: introduce timer()
Simon Farnsworth <simonfar@fb.com>
parents:
30925
diff
changeset
|
1224 timer = time.perf_counter |
7890
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1225 |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1226 def makelock(info, pathname): |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1227 try: |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1228 return os.symlink(info, pathname) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25420
diff
changeset
|
1229 except OSError as why: |
7890
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1230 if why.errno == errno.EEXIST: |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1231 raise |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1232 except AttributeError: # no symlink in os |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1233 pass |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1234 |
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
1235 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
1236 os.write(ld, info) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
1237 os.close(ld) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
1238 |
7890
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1239 def readlock(pathname): |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1240 try: |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1241 return os.readlink(pathname) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25420
diff
changeset
|
1242 except OSError as why: |
7890
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1243 if why.errno not in (errno.EINVAL, errno.ENOSYS): |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1244 raise |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1245 except AttributeError: # no symlink in os |
e710f0f592b2
util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
7879
diff
changeset
|
1246 pass |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13392
diff
changeset
|
1247 fp = posixfile(pathname) |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13392
diff
changeset
|
1248 r = fp.read() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13392
diff
changeset
|
1249 fp.close() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13392
diff
changeset
|
1250 return r |
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
1251 |
2176
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1252 def fstat(fp): |
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1253 '''stat file object that may not have fileno method.''' |
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1254 try: |
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1255 return os.fstat(fp.fileno()) |
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1256 except AttributeError: |
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1257 return os.stat(fp.name) |
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1258 |
3784 | 1259 # File system features |
1260 | |
29889
6f447b9ec263
util: rename checkcase() to fscasesensitive() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
29832
diff
changeset
|
1261 def fscasesensitive(path): |
3784 | 1262 """ |
18911
451eb1c27c1b
util: improve doc for checkcase
Mads Kiilerich <mads@kiilerich.com>
parents:
18868
diff
changeset
|
1263 Return true if the given path is on a case-sensitive filesystem |
3784 | 1264 |
1265 Requires a path (like /foo/.hg) ending with a foldable final | |
1266 directory component. | |
1267 """ | |
24902
986a5c23b1c1
util.checkcase: don't abort on broken symlinks
Siddharth Agarwal <sid0@fb.com>
parents:
24692
diff
changeset
|
1268 s1 = os.lstat(path) |
3784 | 1269 d, b = os.path.split(path) |
15667
eacfd851cb9e
icasefs: consider as case sensitive if there is no counterevidence, for safety
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15609
diff
changeset
|
1270 b2 = b.upper() |
eacfd851cb9e
icasefs: consider as case sensitive if there is no counterevidence, for safety
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15609
diff
changeset
|
1271 if b == b2: |
eacfd851cb9e
icasefs: consider as case sensitive if there is no counterevidence, for safety
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15609
diff
changeset
|
1272 b2 = b.lower() |
eacfd851cb9e
icasefs: consider as case sensitive if there is no counterevidence, for safety
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15609
diff
changeset
|
1273 if b == b2: |
eacfd851cb9e
icasefs: consider as case sensitive if there is no counterevidence, for safety
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15609
diff
changeset
|
1274 return True # no evidence against case sensitivity |
eacfd851cb9e
icasefs: consider as case sensitive if there is no counterevidence, for safety
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15609
diff
changeset
|
1275 p2 = os.path.join(d, b2) |
3784 | 1276 try: |
24902
986a5c23b1c1
util.checkcase: don't abort on broken symlinks
Siddharth Agarwal <sid0@fb.com>
parents:
24692
diff
changeset
|
1277 s2 = os.lstat(p2) |
3784 | 1278 if s2 == s1: |
1279 return False | |
1280 return True | |
14004
97ed99d1f419
eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents:
13985
diff
changeset
|
1281 except OSError: |
3784 | 1282 return True |
1283 | |
16943
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1284 try: |
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1285 import re2 |
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1286 _re2 = None |
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1287 except ImportError: |
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1288 _re2 = False |
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1289 |
21908
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1290 class _re(object): |
21913
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1291 def _checkre2(self): |
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1292 global _re2 |
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1293 try: |
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1294 # check if match works, see issue3964 |
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1295 _re2 = bool(re2.match(r'\[([^\[]+)\]', '[ui]')) |
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1296 except ImportError: |
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1297 _re2 = False |
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1298 |
21908
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1299 def compile(self, pat, flags=0): |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1300 '''Compile a regular expression, using re2 if possible |
16943
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1301 |
21908
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1302 For best performance, use only re2-compatible regexp features. The |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1303 only flags from the re module that are re2-compatible are |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1304 IGNORECASE and MULTILINE.''' |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1305 if _re2 is None: |
21913
50aad4609224
util.re: move check for re2 into a separate method
Siddharth Agarwal <sid0@fb.com>
parents:
21912
diff
changeset
|
1306 self._checkre2() |
21908
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1307 if _re2 and (flags & ~(remod.IGNORECASE | remod.MULTILINE)) == 0: |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1308 if flags & remod.IGNORECASE: |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1309 pat = '(?i)' + pat |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1310 if flags & remod.MULTILINE: |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1311 pat = '(?m)' + pat |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1312 try: |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1313 return re2.compile(pat) |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1314 except re2.error: |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1315 pass |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1316 return remod.compile(pat, flags) |
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1317 |
21914
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1318 @propertycache |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1319 def escape(self): |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1320 '''Return the version of escape corresponding to self.compile. |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1321 |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1322 This is imperfect because whether re2 or re is used for a particular |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1323 function depends on the flags, etc, but it's the best we can do. |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1324 ''' |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1325 global _re2 |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1326 if _re2 is None: |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1327 self._checkre2() |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1328 if _re2: |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1329 return re2.escape |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1330 else: |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1331 return remod.escape |
10e99839a7a4
util.re: add an escape method
Siddharth Agarwal <sid0@fb.com>
parents:
21913
diff
changeset
|
1332 |
21908
cad9dadc9d26
util: move compilere to a class
Siddharth Agarwal <sid0@fb.com>
parents:
21907
diff
changeset
|
1333 re = _re() |
16943
8d08a28aa63e
matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents:
16873
diff
changeset
|
1334 |
6676
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1335 _fspathcache = {} |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1336 def fspath(name, root): |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1337 '''Get name in the case stored in the filesystem |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1338 |
15710
f63e40047372
icasefs: avoid path-absoluteness/existance check in util.fspath() for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15709
diff
changeset
|
1339 The name should be relative to root, and be normcase-ed for efficiency. |
f63e40047372
icasefs: avoid path-absoluteness/existance check in util.fspath() for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15709
diff
changeset
|
1340 |
f63e40047372
icasefs: avoid path-absoluteness/existance check in util.fspath() for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15709
diff
changeset
|
1341 Note that this function is unnecessary, and should not be |
6676
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1342 called, for case-sensitive filesystems (simply because it's expensive). |
15670
d6c19cfa03ce
icasefs: avoid normcase()-ing in util.fspath() for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15669
diff
changeset
|
1343 |
15710
f63e40047372
icasefs: avoid path-absoluteness/existance check in util.fspath() for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15709
diff
changeset
|
1344 The root should be normcase-ed, too. |
6676
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1345 ''' |
23097
30124c40d11f
util.fspath: use a dict rather than a linear scan for lookups
Siddharth Agarwal <sid0@fb.com>
parents:
23076
diff
changeset
|
1346 def _makefspathcacheentry(dir): |
30124c40d11f
util.fspath: use a dict rather than a linear scan for lookups
Siddharth Agarwal <sid0@fb.com>
parents:
23076
diff
changeset
|
1347 return dict((normcase(n), n) for n in os.listdir(dir)) |
15709
a1f4bd47d18e
icasefs: retry directory scan once for already invalidated cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15674
diff
changeset
|
1348 |
30613
1112ff99d965
py3: replace os.sep with pycompat.ossep (part 1 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30536
diff
changeset
|
1349 seps = pycompat.ossep |
30625
bcf4a975f93d
py3: replace os.altsep with pycompat.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30613
diff
changeset
|
1350 if pycompat.osaltsep: |
bcf4a975f93d
py3: replace os.altsep with pycompat.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30613
diff
changeset
|
1351 seps = seps + pycompat.osaltsep |
6676
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1352 # Protect backslashes. This gets silly very quickly. |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1353 seps.replace('\\','\\\\') |
31496
670166e0fcaa
util: use bytes re on bytes input in fspath
Augie Fackler <augie@google.com>
parents:
31495
diff
changeset
|
1354 pattern = remod.compile(br'([^%s]+)|([%s]+)' % (seps, seps)) |
15669
390bcd01775a
icasefs: use util.normcase() instead of lower() or os.path.normcase in fspath
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15667
diff
changeset
|
1355 dir = os.path.normpath(root) |
6676
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1356 result = [] |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1357 for part, sep in pattern.findall(name): |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1358 if sep: |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1359 result.append(sep) |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1360 continue |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1361 |
15719
1dd60426b061
icasefs: follow standard cache look up pattern
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15718
diff
changeset
|
1362 if dir not in _fspathcache: |
23097
30124c40d11f
util.fspath: use a dict rather than a linear scan for lookups
Siddharth Agarwal <sid0@fb.com>
parents:
23076
diff
changeset
|
1363 _fspathcache[dir] = _makefspathcacheentry(dir) |
15719
1dd60426b061
icasefs: follow standard cache look up pattern
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15718
diff
changeset
|
1364 contents = _fspathcache[dir] |
6676
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1365 |
23097
30124c40d11f
util.fspath: use a dict rather than a linear scan for lookups
Siddharth Agarwal <sid0@fb.com>
parents:
23076
diff
changeset
|
1366 found = contents.get(part) |
15709
a1f4bd47d18e
icasefs: retry directory scan once for already invalidated cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15674
diff
changeset
|
1367 if not found: |
15720
3bcfea777efc
icasefs: rewrite comment to explain situtation precisely
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15719
diff
changeset
|
1368 # retry "once per directory" per "dirstate.walk" which |
3bcfea777efc
icasefs: rewrite comment to explain situtation precisely
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15719
diff
changeset
|
1369 # may take place for each patches of "hg qpush", for example |
23097
30124c40d11f
util.fspath: use a dict rather than a linear scan for lookups
Siddharth Agarwal <sid0@fb.com>
parents:
23076
diff
changeset
|
1370 _fspathcache[dir] = contents = _makefspathcacheentry(dir) |
30124c40d11f
util.fspath: use a dict rather than a linear scan for lookups
Siddharth Agarwal <sid0@fb.com>
parents:
23076
diff
changeset
|
1371 found = contents.get(part) |
15709
a1f4bd47d18e
icasefs: retry directory scan once for already invalidated cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15674
diff
changeset
|
1372 |
a1f4bd47d18e
icasefs: retry directory scan once for already invalidated cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15674
diff
changeset
|
1373 result.append(found or part) |
15669
390bcd01775a
icasefs: use util.normcase() instead of lower() or os.path.normcase in fspath
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15667
diff
changeset
|
1374 dir = os.path.join(dir, part) |
6676
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1375 |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1376 return ''.join(result) |
33045179d079
Add a new function, fspath
Paul Moore <p.f.moore@gmail.com>
parents:
6595
diff
changeset
|
1377 |
31593 | 1378 def getfstype(dirpath): |
1379 '''Get the filesystem type name from a directory (best-effort) | |
1380 | |
31678
1ed57a7dd904
statfs: make getfstype() raise OSError
Yuya Nishihara <yuya@tcha.org>
parents:
31662
diff
changeset
|
1381 Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc. |
31593 | 1382 ''' |
1383 return getattr(osutil, 'getfstype', lambda x: None)(dirpath) | |
1384 | |
12938
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1385 def checknlink(testfile): |
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1386 '''check whether hardlink count reporting works properly''' |
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1387 |
13204
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1388 # testfile may be open, so we need a separate file for checking to |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1389 # work around issue2543 (or testfile may get lost on Samba shares) |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1390 f1 = testfile + ".hgtmp1" |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1391 if os.path.lexists(f1): |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1392 return False |
12938
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1393 try: |
13204
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1394 posixfile(f1, 'w').close() |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1395 except IOError: |
29832
bac1829ec31f
util: checknlink should remove file it creates if an exception occurs
Tony Tung <tonytung@merly.org>
parents:
29828
diff
changeset
|
1396 try: |
bac1829ec31f
util: checknlink should remove file it creates if an exception occurs
Tony Tung <tonytung@merly.org>
parents:
29828
diff
changeset
|
1397 os.unlink(f1) |
bac1829ec31f
util: checknlink should remove file it creates if an exception occurs
Tony Tung <tonytung@merly.org>
parents:
29828
diff
changeset
|
1398 except OSError: |
bac1829ec31f
util: checknlink should remove file it creates if an exception occurs
Tony Tung <tonytung@merly.org>
parents:
29828
diff
changeset
|
1399 pass |
12938
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1400 return False |
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1401 |
13204
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1402 f2 = testfile + ".hgtmp2" |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1403 fd = None |
12938
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1404 try: |
25088
754df8e932d3
util: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24902
diff
changeset
|
1405 oslink(f1, f2) |
12938
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1406 # nlinks() may behave differently for files on Windows shares if |
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1407 # the file is open. |
13342
2dc7a2a96cfd
opener: use posixfile to hold file open when calling nlinks()
Adrian Buehlmann <adrian@cadifra.com>
parents:
13316
diff
changeset
|
1408 fd = posixfile(f2) |
13204
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1409 return nlinks(f2) > 1 |
25088
754df8e932d3
util: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24902
diff
changeset
|
1410 except OSError: |
754df8e932d3
util: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24902
diff
changeset
|
1411 return False |
12938
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1412 finally: |
13204
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1413 if fd is not None: |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1414 fd.close() |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1415 for f in (f1, f2): |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1416 try: |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1417 os.unlink(f) |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1418 except OSError: |
5b83ab614dab
checknlink: use two testfiles (issue2543)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13188
diff
changeset
|
1419 pass |
12938
bf826c0b9537
opener: check hardlink count reporting (issue1866)
Adrian Buehlmann <adrian@cadifra.com>
parents:
12927
diff
changeset
|
1420 |
5843
83c354c4d529
Add endswithsep() and use it instead of using os.sep and os.altsep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5802
diff
changeset
|
1421 def endswithsep(path): |
83c354c4d529
Add endswithsep() and use it instead of using os.sep and os.altsep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5802
diff
changeset
|
1422 '''Check path ends with os.sep or os.altsep.''' |
30613
1112ff99d965
py3: replace os.sep with pycompat.ossep (part 1 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30536
diff
changeset
|
1423 return (path.endswith(pycompat.ossep) |
30625
bcf4a975f93d
py3: replace os.altsep with pycompat.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30613
diff
changeset
|
1424 or pycompat.osaltsep and path.endswith(pycompat.osaltsep)) |
5843
83c354c4d529
Add endswithsep() and use it instead of using os.sep and os.altsep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5802
diff
changeset
|
1425 |
5844
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
1426 def splitpath(path): |
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
1427 '''Split path by os.sep. |
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
1428 Note that this function does not use os.altsep because this is |
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
1429 an alternative of simple "xxx.split(os.sep)". |
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
1430 It is recommended to use os.path.normpath() before using this |
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
1431 function if need.''' |
30613
1112ff99d965
py3: replace os.sep with pycompat.ossep (part 1 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30536
diff
changeset
|
1432 return path.split(pycompat.ossep) |
5844
07d8eb78dd68
Add util.splitpath() and use it instead of using os.sep directly.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
5843
diff
changeset
|
1433 |
6007
090b1a665901
filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents:
6006
diff
changeset
|
1434 def gui(): |
090b1a665901
filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents:
6006
diff
changeset
|
1435 '''Are we running in a GUI?''' |
30642
e995f00a9e9a
py3: replace sys.platform with pycompat.sysplatform (part 2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30639
diff
changeset
|
1436 if pycompat.sysplatform == 'darwin': |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30625
diff
changeset
|
1437 if 'SSH_CONNECTION' in encoding.environ: |
13734
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1438 # handle SSH access to a box where the user is logged in |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1439 return False |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1440 elif getattr(osutil, 'isgui', None): |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1441 # check if a CoreGraphics session is available |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1442 return osutil.isgui() |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1443 else: |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1444 # pure build; use a safe default |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1445 return True |
16118b4859a1
util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13439
diff
changeset
|
1446 else: |
30639
d524c88511a7
py3: replace os.name with pycompat.osname (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30637
diff
changeset
|
1447 return pycompat.osname == "nt" or encoding.environ.get("DISPLAY") |
6007
090b1a665901
filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents:
6006
diff
changeset
|
1448 |
6062
3c3b126e5619
Make files in .hg inherit the permissions from .hg/store
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
6007
diff
changeset
|
1449 def mktempcopy(name, emptyok=False, createmode=None): |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1450 """Create a temporary file with the same contents from name |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1451 |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1452 The permission bits are copied from the original file. |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1453 |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1454 If the temporary file is going to be truncated immediately, you |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1455 can use emptyok=True as an optimization. |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1456 |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1457 Returns the name of the temporary file. |
2176
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1458 """ |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1459 d, fn = os.path.split(name) |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1460 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d) |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1461 os.close(fd) |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1462 # Temporary files are created with mode 0600, which is usually not |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1463 # what we want. If the original file already exists, just copy |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1464 # its mode. Otherwise, manually obey umask. |
15010
c3114acd8ea2
util: factor new function copymode out of mktempcopy
Adrian Buehlmann <adrian@cadifra.com>
parents:
14999
diff
changeset
|
1465 copymode(name, temp, createmode) |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1466 if emptyok: |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1467 return temp |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1468 try: |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1469 try: |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1470 ifp = posixfile(name, "rb") |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25420
diff
changeset
|
1471 except IOError as inst: |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1472 if inst.errno == errno.ENOENT: |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1473 return temp |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1474 if not getattr(inst, 'filename', None): |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1475 inst.filename = name |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1476 raise |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1477 ofp = posixfile(temp, "wb") |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1478 for chunk in filechunkiter(ifp): |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1479 ofp.write(chunk) |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1480 ifp.close() |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1481 ofp.close() |
16705
c2d9ef43ff6c
check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents:
16703
diff
changeset
|
1482 except: # re-raises |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1483 try: os.unlink(temp) |
16703
7292a4618f46
cleanup: replace more naked excepts with more specific ones
Brodie Rao <brodie@sf.io>
parents:
16688
diff
changeset
|
1484 except OSError: pass |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1485 raise |
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1486 return temp |
2176
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2117
diff
changeset
|
1487 |
29200
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1488 class filestat(object): |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1489 """help to exactly detect change of a file |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1490 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1491 'stat' attribute is result of 'os.stat()' if specified 'path' |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1492 exists. Otherwise, it is None. This can avoid preparative |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1493 'exists()' examination on client side of this class. |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1494 """ |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1495 def __init__(self, path): |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1496 try: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1497 self.stat = os.stat(path) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1498 except OSError as err: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1499 if err.errno != errno.ENOENT: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1500 raise |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1501 self.stat = None |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1502 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1503 __hash__ = object.__hash__ |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1504 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1505 def __eq__(self, old): |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1506 try: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1507 # if ambiguity between stat of new and old file is |
30332
318a24b52eeb
spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents:
30329
diff
changeset
|
1508 # avoided, comparison of size, ctime and mtime is enough |
29200
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1509 # to exactly detect change of a file regardless of platform |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1510 return (self.stat.st_size == old.stat.st_size and |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1511 self.stat.st_ctime == old.stat.st_ctime and |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1512 self.stat.st_mtime == old.stat.st_mtime) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1513 except AttributeError: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1514 return False |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1515 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1516 def isambig(self, old): |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1517 """Examine whether new (= self) stat is ambiguous against old one |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1518 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1519 "S[N]" below means stat of a file at N-th change: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1520 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1521 - S[n-1].ctime < S[n].ctime: can detect change of a file |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1522 - S[n-1].ctime == S[n].ctime |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1523 - S[n-1].ctime < S[n].mtime: means natural advancing (*1) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1524 - S[n-1].ctime == S[n].mtime: is ambiguous (*2) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1525 - S[n-1].ctime > S[n].mtime: never occurs naturally (don't care) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1526 - S[n-1].ctime > S[n].ctime: never occurs naturally (don't care) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1527 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1528 Case (*2) above means that a file was changed twice or more at |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1529 same time in sec (= S[n-1].ctime), and comparison of timestamp |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1530 is ambiguous. |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1531 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1532 Base idea to avoid such ambiguity is "advance mtime 1 sec, if |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1533 timestamp is ambiguous". |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1534 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1535 But advancing mtime only in case (*2) doesn't work as |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1536 expected, because naturally advanced S[n].mtime in case (*1) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1537 might be equal to manually advanced S[n-1 or earlier].mtime. |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1538 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1539 Therefore, all "S[n-1].ctime == S[n].ctime" cases should be |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1540 treated as ambiguous regardless of mtime, to avoid overlooking |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1541 by confliction between such mtime. |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1542 |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1543 Advancing mtime "if isambig(oldstat)" ensures "S[n-1].mtime != |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1544 S[n].mtime", even if size of a file isn't changed. |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1545 """ |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1546 try: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1547 return (self.stat.st_ctime == old.stat.st_ctime) |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1548 except AttributeError: |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1549 return False |
ca4065028e00
util: add filestat class to detect ambiguity of file stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29017
diff
changeset
|
1550 |
30319
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1551 def avoidambig(self, path, old): |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1552 """Change file stat of specified path to avoid ambiguity |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1553 |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1554 'old' should be previous filestat of 'path'. |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1555 |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1556 This skips avoiding ambiguity, if a process doesn't have |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1557 appropriate privileges for 'path'. |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1558 """ |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1559 advanced = (old.stat.st_mtime + 1) & 0x7fffffff |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1560 try: |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1561 os.utime(path, (advanced, advanced)) |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1562 except OSError as inst: |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1563 if inst.errno == errno.EPERM: |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1564 # utime() on the file created by another user causes EPERM, |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1565 # if a process doesn't have appropriate privileges |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1566 return |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1567 raise |
b496a464399c
util: add utility function to skip avoiding file stat ambiguity if EPERM
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
30181
diff
changeset
|
1568 |
29298
82f6193ff2bc
util: add __ne__ to filestat class for consistency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29261
diff
changeset
|
1569 def __ne__(self, other): |
82f6193ff2bc
util: add __ne__ to filestat class for consistency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29261
diff
changeset
|
1570 return not self == other |
82f6193ff2bc
util: add __ne__ to filestat class for consistency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29261
diff
changeset
|
1571 |
8778
c5f36402daad
use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8631
diff
changeset
|
1572 class atomictempfile(object): |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
17391
diff
changeset
|
1573 '''writable file object that atomically updates a file |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1574 |
14008
da65edcac72a
atomictempfile: rewrite docstring to clarify rename() vs. close().
Greg Ward <greg@gerg.ca>
parents:
14007
diff
changeset
|
1575 All writes will go to a temporary copy of the original file. Call |
15057
774da7121fc9
atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents:
15050
diff
changeset
|
1576 close() when you are done writing, and atomictempfile will rename |
774da7121fc9
atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents:
15050
diff
changeset
|
1577 the temporary copy to the original name, making the changes |
774da7121fc9
atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents:
15050
diff
changeset
|
1578 visible. If the object is destroyed without being closed, all your |
774da7121fc9
atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents:
15050
diff
changeset
|
1579 writes are discarded. |
29367
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1580 |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1581 checkambig argument of constructor is used with filestat, and is |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1582 useful only if target file is guarded by any lock (e.g. repo.lock |
4e6e280e238f
doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29342
diff
changeset
|
1583 or repo.wlock). |
14008
da65edcac72a
atomictempfile: rewrite docstring to clarify rename() vs. close().
Greg Ward <greg@gerg.ca>
parents:
14007
diff
changeset
|
1584 ''' |
29201
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1585 def __init__(self, name, mode='w+b', createmode=None, checkambig=False): |
14007
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1586 self.__name = name # permanent name |
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1587 self._tempname = mktempcopy(name, emptyok=('w' in mode), |
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1588 createmode=createmode) |
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1589 self._fp = posixfile(self._tempname, mode) |
29201
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1590 self._checkambig = checkambig |
8327
aa25be1c2889
atomictempfile: delegate to posixfile instead of inheriting from it
Bryan O'Sullivan <bos@serpentine.com>
parents:
8312
diff
changeset
|
1591 |
14007
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1592 # delegated methods |
29393
50269a4dce61
atomictempfile: add read to the supported file operations
Martijn Pieters <mjpieters@fb.com>
parents:
29367
diff
changeset
|
1593 self.read = self._fp.read |
14007
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1594 self.write = self._fp.write |
17237
e73128535105
util: delegate seek and tell methods of atomictempfile
Bryan O'Sullivan <bryano@fb.com>
parents:
17203
diff
changeset
|
1595 self.seek = self._fp.seek |
e73128535105
util: delegate seek and tell methods of atomictempfile
Bryan O'Sullivan <bryano@fb.com>
parents:
17203
diff
changeset
|
1596 self.tell = self._fp.tell |
14007
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1597 self.fileno = self._fp.fileno |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1598 |
15057
774da7121fc9
atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents:
15050
diff
changeset
|
1599 def close(self): |
8785
7a9151bc5b37
atomictempfile: fix exception in __del__ if mktempcopy fails (self._fp is None)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8778
diff
changeset
|
1600 if not self._fp.closed: |
8327
aa25be1c2889
atomictempfile: delegate to posixfile instead of inheriting from it
Bryan O'Sullivan <bos@serpentine.com>
parents:
8312
diff
changeset
|
1601 self._fp.close() |
29201
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1602 filename = localpath(self.__name) |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1603 oldstat = self._checkambig and filestat(filename) |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1604 if oldstat and oldstat.stat: |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1605 rename(self._tempname, filename) |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1606 newstat = filestat(filename) |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1607 if newstat.isambig(oldstat): |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1608 # stat of changed file is ambiguous to original one |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1609 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1610 os.utime(filename, (advanced, advanced)) |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1611 else: |
a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29200
diff
changeset
|
1612 rename(self._tempname, filename) |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1613 |
15057
774da7121fc9
atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents:
15050
diff
changeset
|
1614 def discard(self): |
8785
7a9151bc5b37
atomictempfile: fix exception in __del__ if mktempcopy fails (self._fp is None)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8778
diff
changeset
|
1615 if not self._fp.closed: |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1616 try: |
14007
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1617 os.unlink(self._tempname) |
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1618 except OSError: |
d764463b433e
atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
14004
diff
changeset
|
1619 pass |
8327
aa25be1c2889
atomictempfile: delegate to posixfile instead of inheriting from it
Bryan O'Sullivan <bos@serpentine.com>
parents:
8312
diff
changeset
|
1620 self._fp.close() |
4827
89defeae88f3
turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4803
diff
changeset
|
1621 |
13098
f7d6750dcd01
util: make atomicfiles closable
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13072
diff
changeset
|
1622 def __del__(self): |
14968
b7dbe957585c
util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14942
diff
changeset
|
1623 if safehasattr(self, '_fp'): # constructor actually did something |
15057
774da7121fc9
atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents:
15050
diff
changeset
|
1624 self.discard() |
13098
f7d6750dcd01
util: make atomicfiles closable
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13072
diff
changeset
|
1625 |
29394
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1626 def __enter__(self): |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1627 return self |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1628 |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1629 def __exit__(self, exctype, excvalue, traceback): |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1630 if exctype is not None: |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1631 self.discard() |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1632 else: |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1633 self.close() |
6d96658a22b0
atomictempfile: add context manager support
Martijn Pieters <mjpieters@fb.com>
parents:
29393
diff
changeset
|
1634 |
31539 | 1635 def unlinkpath(f, ignoremissing=False): |
1636 """unlink and remove the directory if it is empty""" | |
31541
bd9daafbf87c
util: use tryunlink in unlinkpath
Ryan McElroy <rmcelroy@fb.com>
parents:
31540
diff
changeset
|
1637 if ignoremissing: |
bd9daafbf87c
util: use tryunlink in unlinkpath
Ryan McElroy <rmcelroy@fb.com>
parents:
31540
diff
changeset
|
1638 tryunlink(f) |
bd9daafbf87c
util: use tryunlink in unlinkpath
Ryan McElroy <rmcelroy@fb.com>
parents:
31540
diff
changeset
|
1639 else: |
31539 | 1640 unlink(f) |
1641 # try removing directories that might now be empty | |
1642 try: | |
1643 removedirs(os.path.dirname(f)) | |
1644 except OSError: | |
1645 pass | |
1646 | |
31540
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1647 def tryunlink(f): |
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1648 """Attempt to remove a file, ignoring ENOENT errors.""" |
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1649 try: |
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1650 unlink(f) |
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1651 except OSError as e: |
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1652 if e.errno != errno.ENOENT: |
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1653 raise |
6d5b77abf306
util: add tryunlink function
Ryan McElroy <rmcelroy@fb.com>
parents:
31539
diff
changeset
|
1654 |
18938
e22107cff6bf
util: add notindexed optional parameter to makedirs function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
18930
diff
changeset
|
1655 def makedirs(name, mode=None, notindexed=False): |
29017
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1656 """recursive directory creation with parent mode inheritance |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1657 |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1658 Newly created directories are marked as "not to be indexed by |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1659 the content indexing service", if ``notindexed`` is specified |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1660 for "write" mode access. |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1661 """ |
6062
3c3b126e5619
Make files in .hg inherit the permissions from .hg/store
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
6007
diff
changeset
|
1662 try: |
18938
e22107cff6bf
util: add notindexed optional parameter to makedirs function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
18930
diff
changeset
|
1663 makedir(name, notindexed) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25420
diff
changeset
|
1664 except OSError as err: |
6062
3c3b126e5619
Make files in .hg inherit the permissions from .hg/store
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
6007
diff
changeset
|
1665 if err.errno == errno.EEXIST: |
3c3b126e5619
Make files in .hg inherit the permissions from .hg/store
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
6007
diff
changeset
|
1666 return |
15058
81f33be0ea79
util: postpone and reorder parent calculation in makedirs
Adrian Buehlmann <adrian@cadifra.com>
parents:
15057
diff
changeset
|
1667 if err.errno != errno.ENOENT or not name: |
81f33be0ea79
util: postpone and reorder parent calculation in makedirs
Adrian Buehlmann <adrian@cadifra.com>
parents:
15057
diff
changeset
|
1668 raise |
81f33be0ea79
util: postpone and reorder parent calculation in makedirs
Adrian Buehlmann <adrian@cadifra.com>
parents:
15057
diff
changeset
|
1669 parent = os.path.dirname(os.path.abspath(name)) |
81f33be0ea79
util: postpone and reorder parent calculation in makedirs
Adrian Buehlmann <adrian@cadifra.com>
parents:
15057
diff
changeset
|
1670 if parent == name: |
6062
3c3b126e5619
Make files in .hg inherit the permissions from .hg/store
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
6007
diff
changeset
|
1671 raise |
18938
e22107cff6bf
util: add notindexed optional parameter to makedirs function
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
18930
diff
changeset
|
1672 makedirs(parent, mode, notindexed) |
29017
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1673 try: |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1674 makedir(name, notindexed) |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1675 except OSError as err: |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1676 # Catch EEXIST to handle races |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1677 if err.errno == errno.EEXIST: |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1678 return |
07be86828e79
util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents:
28883
diff
changeset
|
1679 raise |
18678
423eee0b0b14
util: make ensuredirs safer against races
Bryan O'Sullivan <bryano@fb.com>
parents:
18668
diff
changeset
|
1680 if mode is not None: |
423eee0b0b14
util: make ensuredirs safer against races
Bryan O'Sullivan <bryano@fb.com>
parents:
18668
diff
changeset
|
1681 os.chmod(name, mode) |
18668
4034b8d551b1
scmutil: create directories in a race-safe way during update
Bryan O'Sullivan <bryano@fb.com>
parents:
18614
diff
changeset
|
1682 |
14099
0824a0a3cefc
util: add readfile() & writefile() helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14077
diff
changeset
|
1683 def readfile(path): |
27778
4d10600c3f08
util: simplify file I/O functions using context managers
Bryan O'Sullivan <bryano@fb.com>
parents:
27768
diff
changeset
|
1684 with open(path, 'rb') as fp: |
14100
3e9e02a41dfb
util: really drop size from readfile
Matt Mackall <mpm@selenic.com>
parents:
14099
diff
changeset
|
1685 return fp.read() |
14099
0824a0a3cefc
util: add readfile() & writefile() helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14077
diff
changeset
|
1686 |
14167
0e4753807c93
util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14147
diff
changeset
|
1687 def writefile(path, text): |
27778
4d10600c3f08
util: simplify file I/O functions using context managers
Bryan O'Sullivan <bryano@fb.com>
parents:
27768
diff
changeset
|
1688 with open(path, 'wb') as fp: |
14167
0e4753807c93
util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14147
diff
changeset
|
1689 fp.write(text) |
0e4753807c93
util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14147
diff
changeset
|
1690 |
0e4753807c93
util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14147
diff
changeset
|
1691 def appendfile(path, text): |
27778
4d10600c3f08
util: simplify file I/O functions using context managers
Bryan O'Sullivan <bryano@fb.com>
parents:
27768
diff
changeset
|
1692 with open(path, 'ab') as fp: |
14099
0824a0a3cefc
util: add readfile() & writefile() helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14077
diff
changeset
|
1693 fp.write(text) |
0824a0a3cefc
util: add readfile() & writefile() helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
14077
diff
changeset
|
1694 |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
1695 class chunkbuffer(object): |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
1696 """Allow arbitrary sized chunks of data to be efficiently read from an |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
1697 iterator over chunks of arbitrary size.""" |
1200 | 1698 |
5446
fa836e050c50
chunkbuffer: removed unused method and arg
Matt Mackall <mpm@selenic.com>
parents:
5420
diff
changeset
|
1699 def __init__(self, in_iter): |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
1700 """in_iter is the iterator that's iterating over the input chunks. |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
1701 targetsize is how big a buffer to try to maintain.""" |
11670
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1702 def splitbig(chunks): |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1703 for chunk in chunks: |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1704 if len(chunk) > 2**20: |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1705 pos = 0 |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1706 while pos < len(chunk): |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1707 end = pos + 2 ** 18 |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1708 yield chunk[pos:end] |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1709 pos = end |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1710 else: |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1711 yield chunk |
1b3b843e1100
chunkbuffer: split big strings directly in chunkbuffer
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
11668
diff
changeset
|
1712 self.iter = splitbig(in_iter) |
25113
0ca8410ea345
util: drop alias for collections.deque
Martin von Zweigbergk <martinvonz@google.com>
parents:
25112
diff
changeset
|
1713 self._queue = collections.deque() |
26480
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1714 self._chunkoffset = 0 |
1200 | 1715 |
21018
c848bfd02366
util: support None size in chunkbuffer.read()
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20835
diff
changeset
|
1716 def read(self, l=None): |
1200 | 1717 """Read L bytes of data from the iterator of chunks of data. |
21018
c848bfd02366
util: support None size in chunkbuffer.read()
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20835
diff
changeset
|
1718 Returns less than L bytes if the iterator runs dry. |
c848bfd02366
util: support None size in chunkbuffer.read()
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20835
diff
changeset
|
1719 |
23139
e53f6b72a0e4
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23097
diff
changeset
|
1720 If size parameter is omitted, read everything""" |
26478
a3f7e5461dbd
util.chunkbuffer: special case reading everything
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26450
diff
changeset
|
1721 if l is None: |
a3f7e5461dbd
util.chunkbuffer: special case reading everything
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26450
diff
changeset
|
1722 return ''.join(self.iter) |
a3f7e5461dbd
util.chunkbuffer: special case reading everything
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26450
diff
changeset
|
1723 |
11758
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1724 left = l |
17962
4c29668ca316
util: make chunkbuffer non-quadratic on Windows
Matt Mackall <mpm@selenic.com>
parents:
17560
diff
changeset
|
1725 buf = [] |
16873
37e081609828
util: simplify queue management in chunkbuffer
Bryan O'Sullivan <bryano@fb.com>
parents:
16834
diff
changeset
|
1726 queue = self._queue |
26478
a3f7e5461dbd
util.chunkbuffer: special case reading everything
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26450
diff
changeset
|
1727 while left > 0: |
11758
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1728 # refill the queue |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1729 if not queue: |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1730 target = 2**18 |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1731 for chunk in self.iter: |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1732 queue.append(chunk) |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1733 target -= len(chunk) |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1734 if target <= 0: |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1735 break |
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1736 if not queue: |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
1737 break |
11758
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1738 |
26480
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1739 # The easy way to do this would be to queue.popleft(), modify the |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1740 # chunk (if necessary), then queue.appendleft(). However, for cases |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1741 # where we read partial chunk content, this incurs 2 dequeue |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1742 # mutations and creates a new str for the remaining chunk in the |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1743 # queue. Our code below avoids this overhead. |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1744 |
26479
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1745 chunk = queue[0] |
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1746 chunkl = len(chunk) |
26480
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1747 offset = self._chunkoffset |
26479
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1748 |
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1749 # Use full chunk. |
26480
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1750 if offset == 0 and left >= chunkl: |
26479
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1751 left -= chunkl |
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1752 queue.popleft() |
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1753 buf.append(chunk) |
26480
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1754 # self._chunkoffset remains at 0. |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1755 continue |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1756 |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1757 chunkremaining = chunkl - offset |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1758 |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1759 # Use all of unconsumed part of chunk. |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1760 if left >= chunkremaining: |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1761 left -= chunkremaining |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1762 queue.popleft() |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1763 # offset == 0 is enabled by block above, so this won't merely |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1764 # copy via ``chunk[0:]``. |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1765 buf.append(chunk[offset:]) |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1766 self._chunkoffset = 0 |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1767 |
26479
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1768 # Partial chunk needed. |
46143f31290e
util.chunkbuffer: refactor chunk handling logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26478
diff
changeset
|
1769 else: |
26480
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1770 buf.append(chunk[offset:offset + left]) |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1771 self._chunkoffset += left |
6ae14d1ca3aa
util.chunkbuffer: avoid extra mutations when reading partial chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26479
diff
changeset
|
1772 left -= chunkremaining |
11758
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1773 |
17962
4c29668ca316
util: make chunkbuffer non-quadratic on Windows
Matt Mackall <mpm@selenic.com>
parents:
17560
diff
changeset
|
1774 return ''.join(buf) |
11758
a79214972da2
chunkbuffer: use += rather than cStringIO to reduce memory footprint
Matt Mackall <mpm@selenic.com>
parents:
11469
diff
changeset
|
1775 |
30181
7356e6b1f5b8
util: increase filechunkiter size to 128k
Mads Kiilerich <madski@unity3d.com>
parents:
30087
diff
changeset
|
1776 def filechunkiter(f, size=131072, limit=None): |
2462
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1777 """Create a generator that produces the data in the file size |
30181
7356e6b1f5b8
util: increase filechunkiter size to 128k
Mads Kiilerich <madski@unity3d.com>
parents:
30087
diff
changeset
|
1778 (default 131072) bytes at a time, up to optional limit (default is |
2462
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1779 to read all data). Chunks may be less than size bytes if the |
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1780 chunk is the last chunk in the file, or the file is a socket or |
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1781 some other type of file that sometimes reads less data than is |
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1782 requested.""" |
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1783 assert size >= 0 |
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1784 assert limit is None or limit >= 0 |
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1785 while True: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1786 if limit is None: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1787 nbytes = size |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1788 else: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1789 nbytes = min(limit, size) |
2462
d610bcfd66a8
util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2448
diff
changeset
|
1790 s = nbytes and f.read(nbytes) |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1791 if not s: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1792 break |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1793 if limit: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1794 limit -= len(s) |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
1795 yield s |
1320
5f277e73778f
Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1312
diff
changeset
|
1796 |
19287
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
1797 def makedate(timestamp=None): |
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
1798 '''Return a unix timestamp (or the current time) as a (unixtime, |
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
1799 offset) tuple based off the local timezone.''' |
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
1800 if timestamp is None: |
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
1801 timestamp = time.time() |
19286
78501209488a
util: rename ct variable in makedate to timestamp
Bryan O'Sullivan <bryano@fb.com>
parents:
19211
diff
changeset
|
1802 if timestamp < 0: |
13063
e98581d44f0b
makedate: abort on negative timestamps (issue2513)
Adrian Buehlmann <adrian@cadifra.com>
parents:
13062
diff
changeset
|
1803 hint = _("check your clock") |
19286
78501209488a
util: rename ct variable in makedate to timestamp
Bryan O'Sullivan <bryano@fb.com>
parents:
19211
diff
changeset
|
1804 raise Abort(_("negative timestamp: %d") % timestamp, hint=hint) |
78501209488a
util: rename ct variable in makedate to timestamp
Bryan O'Sullivan <bryano@fb.com>
parents:
19211
diff
changeset
|
1805 delta = (datetime.datetime.utcfromtimestamp(timestamp) - |
78501209488a
util: rename ct variable in makedate to timestamp
Bryan O'Sullivan <bryano@fb.com>
parents:
19211
diff
changeset
|
1806 datetime.datetime.fromtimestamp(timestamp)) |
15505
ae04af1ce78d
makedate: wrong timezone offset if DST rules changed this year (issue2511)
Dmitry Panov <dop@itoolabs.com>
parents:
15496
diff
changeset
|
1807 tz = delta.days * 86400 + delta.seconds |
19286
78501209488a
util: rename ct variable in makedate to timestamp
Bryan O'Sullivan <bryano@fb.com>
parents:
19211
diff
changeset
|
1808 return timestamp, tz |
1329
8f06817bf266
Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1321
diff
changeset
|
1809 |
6229
c3182eeb70ea
dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents:
6224
diff
changeset
|
1810 def datestr(date=None, format='%a %b %d %H:%M:%S %Y %1%2'): |
1321
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
1811 """represent a (unixtime, offset) tuple as a localized time. |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
1812 unixtime is seconds since the epoch, and offset is the time zone's |
28865
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1813 number of seconds away from UTC. |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1814 |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1815 >>> datestr((0, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1816 'Thu Jan 01 00:00:00 1970 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1817 >>> datestr((42, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1818 'Thu Jan 01 00:00:42 1970 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1819 >>> datestr((-42, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1820 'Wed Dec 31 23:59:18 1969 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1821 >>> datestr((0x7fffffff, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1822 'Tue Jan 19 03:14:07 2038 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1823 >>> datestr((-0x80000000, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1824 'Fri Dec 13 20:45:52 1901 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
1825 """ |
1321
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
1826 t, tz = date or makedate() |
19989
c38c3fdc8b93
date: allow %z in format (issue4040)
Matt Mackall <mpm@selenic.com>
parents:
19951
diff
changeset
|
1827 if "%1" in format or "%2" in format or "%z" in format: |
6229
c3182eeb70ea
dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents:
6224
diff
changeset
|
1828 sign = (tz > 0) and "-" or "+" |
9029
0001e49f1c11
compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents:
8938
diff
changeset
|
1829 minutes = abs(tz) // 60 |
27066
6f1f8e88f036
util.datestr: use divmod()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27016
diff
changeset
|
1830 q, r = divmod(minutes, 60) |
19989
c38c3fdc8b93
date: allow %z in format (issue4040)
Matt Mackall <mpm@selenic.com>
parents:
19951
diff
changeset
|
1831 format = format.replace("%z", "%1%2") |
27066
6f1f8e88f036
util.datestr: use divmod()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27016
diff
changeset
|
1832 format = format.replace("%1", "%c%02d" % (sign, q)) |
6f1f8e88f036
util.datestr: use divmod()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27016
diff
changeset
|
1833 format = format.replace("%2", "%02d" % r) |
28825
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
1834 d = t - tz |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
1835 if d > 0x7fffffff: |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
1836 d = 0x7fffffff |
28864
b0811a9fe67c
date: fix boundary check of negative integer
Florent Gallaire <fgallaire@gmail.com>
parents:
28835
diff
changeset
|
1837 elif d < -0x80000000: |
b0811a9fe67c
date: fix boundary check of negative integer
Florent Gallaire <fgallaire@gmail.com>
parents:
28835
diff
changeset
|
1838 d = -0x80000000 |
28825
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
1839 # Never use time.gmtime() and datetime.datetime.fromtimestamp() |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
1840 # because they use the gmtime() system call which is buggy on Windows |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
1841 # for negative values. |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
1842 t = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=d) |
31449
756175623f2e
py3: call strftime() with native str type
Yuya Nishihara <yuya@tcha.org>
parents:
31448
diff
changeset
|
1843 s = encoding.strtolocal(t.strftime(encoding.strfromlocal(format))) |
1987
04c17fc39c84
add changelog style to command line template.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1976
diff
changeset
|
1844 return s |
1829
b0f6af327fd4
hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
1845 |
6134
7b937b26adf7
Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6111
diff
changeset
|
1846 def shortdate(date=None): |
7b937b26adf7
Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6111
diff
changeset
|
1847 """turn (timestamp, tzoff) tuple into iso 8631 date.""" |
6229
c3182eeb70ea
dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents:
6224
diff
changeset
|
1848 return datestr(date, format='%Y-%m-%d') |
6134
7b937b26adf7
Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6111
diff
changeset
|
1849 |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1850 def parsetimezone(s): |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1851 """find a trailing timezone, if any, in string, and return a |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1852 (offset, remainder) pair""" |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1853 |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1854 if s.endswith("GMT") or s.endswith("UTC"): |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1855 return 0, s[:-3].rstrip() |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1856 |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1857 # Unix-style timezones [+-]hhmm |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1858 if len(s) >= 5 and s[-5] in "+-" and s[-4:].isdigit(): |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1859 sign = (s[-5] == "+") and 1 or -1 |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1860 hours = int(s[-4:-2]) |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1861 minutes = int(s[-2:]) |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1862 return -sign * (hours * 60 + minutes) * 60, s[:-5].rstrip() |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1863 |
29637
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1864 # ISO8601 trailing Z |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1865 if s.endswith("Z") and s[-2:-1].isdigit(): |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1866 return 0, s[:-1] |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1867 |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1868 # ISO8601-style [+-]hh:mm |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1869 if (len(s) >= 6 and s[-6] in "+-" and s[-3] == ":" and |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1870 s[-5:-3].isdigit() and s[-2:].isdigit()): |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1871 sign = (s[-6] == "+") and 1 or -1 |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1872 hours = int(s[-5:-3]) |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1873 minutes = int(s[-2:]) |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1874 return -sign * (hours * 60 + minutes) * 60, s[:-6] |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
1875 |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1876 return None, s |
26126
7b625baed995
util: extract function that parses timezone string
Yuya Nishihara <yuya@tcha.org>
parents:
26098
diff
changeset
|
1877 |
31393
8b6927eb7efd
util: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31368
diff
changeset
|
1878 def strdate(string, format, defaults=None): |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
1879 """parse a localized time string and return a (unixtime, offset) tuple. |
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
1880 if the string cannot be parsed, ValueError is raised.""" |
31465
da83f12d7a88
util: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31453
diff
changeset
|
1881 if defaults is None: |
da83f12d7a88
util: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31453
diff
changeset
|
1882 defaults = {} |
31393
8b6927eb7efd
util: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31368
diff
changeset
|
1883 |
3255
e96d2956eb4a
util.strdate: compute timestamp using UTC, not local timezone
Jose M. Prieto <jmprieto@gmx.net>
parents:
3176
diff
changeset
|
1884 # NOTE: unixtime = localunixtime + offset |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
1885 offset, date = parsetimezone(string) |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
1886 |
3812 | 1887 # add missing elements from defaults |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1888 usenow = False # default to using biased defaults |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1889 for part in ("S", "M", "HI", "d", "mb", "yY"): # decreasing specificity |
3812 | 1890 found = [True for p in part if ("%"+p) in format] |
1891 if not found: | |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1892 date += "@" + defaults[part][usenow] |
3812 | 1893 format += "@%" + part[0] |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1894 else: |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1895 # We've found a specific time element, less specific time |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1896 # elements are relative to today |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1897 usenow = True |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
1898 |
3256
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1899 timetuple = time.strptime(date, format) |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1900 localunixtime = int(calendar.timegm(timetuple)) |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1901 if offset is None: |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1902 # local timezone |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1903 unixtime = int(time.mktime(timetuple)) |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1904 offset = unixtime - localunixtime |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1905 else: |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
1906 unixtime = localunixtime + offset |
3255
e96d2956eb4a
util.strdate: compute timestamp using UTC, not local timezone
Jose M. Prieto <jmprieto@gmx.net>
parents:
3176
diff
changeset
|
1907 return unixtime, offset |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
1908 |
26311
60dd8e3977f0
util: avoid mutable default arguments
Siddharth Agarwal <sid0@fb.com>
parents:
26267
diff
changeset
|
1909 def parsedate(date, formats=None, bias=None): |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1910 """parse a localized date/time and return a (unixtime, offset) tuple. |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1911 |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
1912 The date may be a "unixtime offset" string or in one of the specified |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1913 formats. If the date already is a (unixtime, offset) tuple, it is returned. |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1914 |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1915 >>> parsedate(' today ') == parsedate(\ |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1916 datetime.date.today().strftime('%b %d')) |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1917 True |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1918 >>> parsedate( 'yesterday ') == parsedate((datetime.date.today() -\ |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1919 datetime.timedelta(days=1)\ |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1920 ).strftime('%b %d')) |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1921 True |
18614
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
1922 >>> now, tz = makedate() |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
1923 >>> strnow, strtz = parsedate('now') |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
1924 >>> (strnow - now) < 1 |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
1925 True |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
1926 >>> tz == strtz |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
1927 True |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1928 """ |
26311
60dd8e3977f0
util: avoid mutable default arguments
Siddharth Agarwal <sid0@fb.com>
parents:
26267
diff
changeset
|
1929 if bias is None: |
60dd8e3977f0
util: avoid mutable default arguments
Siddharth Agarwal <sid0@fb.com>
parents:
26267
diff
changeset
|
1930 bias = {} |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1931 if not date: |
3807
e43b48f0f718
parsedate: allow '' for epoch
Matt Mackall <mpm@selenic.com>
parents:
3806
diff
changeset
|
1932 return 0, 0 |
6230
c7253d1a774e
dates: Fix bare times to be relative to "today"
Matt Mackall <mpm@selenic.com>
parents:
6229
diff
changeset
|
1933 if isinstance(date, tuple) and len(date) == 2: |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1934 return date |
2609
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
1935 if not formats: |
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
1936 formats = defaultdateformats |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1937 date = date.strip() |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1938 |
24188
5a7920c4d2ea
util: accept "now, today, yesterday" for dates even the locale is not english
Andr? Klitzing <aklitzing@gmail.com>
parents:
24164
diff
changeset
|
1939 if date == 'now' or date == _('now'): |
18614
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
1940 return makedate() |
24188
5a7920c4d2ea
util: accept "now, today, yesterday" for dates even the locale is not english
Andr? Klitzing <aklitzing@gmail.com>
parents:
24164
diff
changeset
|
1941 if date == 'today' or date == _('today'): |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1942 date = datetime.date.today().strftime('%b %d') |
24188
5a7920c4d2ea
util: accept "now, today, yesterday" for dates even the locale is not english
Andr? Klitzing <aklitzing@gmail.com>
parents:
24164
diff
changeset
|
1943 elif date == 'yesterday' or date == _('yesterday'): |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1944 date = (datetime.date.today() - |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1945 datetime.timedelta(days=1)).strftime('%b %d') |
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
1946 |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
1947 try: |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1948 when, offset = map(int, date.split(' ')) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1949 except ValueError: |
3812 | 1950 # fill out defaults |
1951 now = makedate() | |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1952 defaults = {} |
13200
6f011cf52f9a
avoid .split() in for loops and use tuples instead
David Soria Parra <dsp@php.net>
parents:
13197
diff
changeset
|
1953 for part in ("d", "mb", "yY", "HI", "M", "S"): |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1954 # this piece is for rounding the specific end of unknowns |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1955 b = bias.get(part) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1956 if b is None: |
3812 | 1957 if part[0] in "HMS": |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1958 b = "00" |
3812 | 1959 else: |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1960 b = "0" |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1961 |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1962 # this piece is for matching the generic end to today's date |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1963 n = datestr(now, "%" + part[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1964 |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1965 defaults[part] = (b, n) |
3812 | 1966 |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1967 for format in formats: |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1968 try: |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
1969 when, offset = strdate(date, format, defaults) |
6087
12856a1742dc
better handle errors with date parsing (issue983)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5917
diff
changeset
|
1970 except (ValueError, OverflowError): |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1971 pass |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1972 else: |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1973 break |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1974 else: |
12105
6f58430dfdd0
util: get rid of extra trailing whitespace in parsedate abort message
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
12088
diff
changeset
|
1975 raise Abort(_('invalid date: %r') % date) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1976 # validate explicit (probably user-specified) date and |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1977 # time zone offset. values must fit in signed 32 bits for |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1978 # current 32-bit linux runtimes. timezones go from UTC-12 |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1979 # to UTC+14 |
28864
b0811a9fe67c
date: fix boundary check of negative integer
Florent Gallaire <fgallaire@gmail.com>
parents:
28835
diff
changeset
|
1980 if when < -0x80000000 or when > 0x7fffffff: |
3806
92a3532a01d9
parsedate: use Abort rather than ValueError
Matt Mackall <mpm@selenic.com>
parents:
3784
diff
changeset
|
1981 raise Abort(_('date exceeds 32 bits: %d') % when) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1982 if offset < -50400 or offset > 43200: |
3806
92a3532a01d9
parsedate: use Abort rather than ValueError
Matt Mackall <mpm@selenic.com>
parents:
3784
diff
changeset
|
1983 raise Abort(_('impossible time zone offset: %d') % offset) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
1984 return when, offset |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
1985 |
3812 | 1986 def matchdate(date): |
1987 """Return a function that matches a given date match specifier | |
1988 | |
1989 Formats include: | |
1990 | |
1991 '{date}' match a given date to the accuracy provided | |
1992 | |
1993 '<{date}' on or before a given date | |
1994 | |
1995 '>{date}' on or after a given date | |
1996 | |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1997 >>> p1 = parsedate("10:29:59") |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1998 >>> p2 = parsedate("10:30:00") |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
1999 >>> p3 = parsedate("10:30:59") |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2000 >>> p4 = parsedate("10:31:00") |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2001 >>> p5 = parsedate("Sep 15 10:30:00 1999") |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2002 >>> f = matchdate("10:30") |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2003 >>> f(p1[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2004 False |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2005 >>> f(p2[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2006 True |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2007 >>> f(p3[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2008 True |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2009 >>> f(p4[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2010 False |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2011 >>> f(p5[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
2012 False |
3812 | 2013 """ |
2014 | |
2015 def lower(date): | |
20679
0916f829eb8d
util: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents:
20542
diff
changeset
|
2016 d = {'mb': "1", 'd': "1"} |
6230
c7253d1a774e
dates: Fix bare times to be relative to "today"
Matt Mackall <mpm@selenic.com>
parents:
6229
diff
changeset
|
2017 return parsedate(date, extendeddateformats, d)[0] |
3812 | 2018 |
2019 def upper(date): | |
20679
0916f829eb8d
util: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents:
20542
diff
changeset
|
2020 d = {'mb': "12", 'HI': "23", 'M': "59", 'S': "59"} |
13200
6f011cf52f9a
avoid .split() in for loops and use tuples instead
David Soria Parra <dsp@php.net>
parents:
13197
diff
changeset
|
2021 for days in ("31", "30", "29"): |
3812 | 2022 try: |
2023 d["d"] = days | |
2024 return parsedate(date, extendeddateformats, d)[0] | |
16688
cfb6682961b8
cleanup: replace naked excepts with more specific ones
Brodie Rao <brodie@sf.io>
parents:
16397
diff
changeset
|
2025 except Abort: |
3812 | 2026 pass |
2027 d["d"] = "28" | |
2028 return parsedate(date, extendeddateformats, d)[0] | |
2029 | |
7953
8c6f823efcc9
Correct a bug on date formats with '>' or '<' accompanied by space characters.
Justin Peng <justin.peng.sw@gmail.com>
parents:
7948
diff
changeset
|
2030 date = date.strip() |
13780
bc7b5d1c1999
util: dates cannot consist entirely of whitespace (issue2732)
Idan Kamara <idankk86@gmail.com>
parents:
13734
diff
changeset
|
2031 |
bc7b5d1c1999
util: dates cannot consist entirely of whitespace (issue2732)
Idan Kamara <idankk86@gmail.com>
parents:
13734
diff
changeset
|
2032 if not date: |
bc7b5d1c1999
util: dates cannot consist entirely of whitespace (issue2732)
Idan Kamara <idankk86@gmail.com>
parents:
13734
diff
changeset
|
2033 raise Abort(_("dates cannot consist entirely of whitespace")) |
bc7b5d1c1999
util: dates cannot consist entirely of whitespace (issue2732)
Idan Kamara <idankk86@gmail.com>
parents:
13734
diff
changeset
|
2034 elif date[0] == "<": |
13869
b470894c33f8
date: fixup breakage from ">" fix
Matt Mackall <mpm@selenic.com>
parents:
13867
diff
changeset
|
2035 if not date[1:]: |
13886
fe48c57390f2
help/dates: use DATE as place-holder in help and abort texts
Martin Geisler <mg@aragost.com>
parents:
13879
diff
changeset
|
2036 raise Abort(_("invalid day spec, use '<DATE'")) |
3812 | 2037 when = upper(date[1:]) |
2038 return lambda x: x <= when | |
2039 elif date[0] == ">": | |
13869
b470894c33f8
date: fixup breakage from ">" fix
Matt Mackall <mpm@selenic.com>
parents:
13867
diff
changeset
|
2040 if not date[1:]: |
13886
fe48c57390f2
help/dates: use DATE as place-holder in help and abort texts
Martin Geisler <mg@aragost.com>
parents:
13879
diff
changeset
|
2041 raise Abort(_("invalid day spec, use '>DATE'")) |
3812 | 2042 when = lower(date[1:]) |
2043 return lambda x: x >= when | |
2044 elif date[0] == "-": | |
2045 try: | |
2046 days = int(date[1:]) | |
2047 except ValueError: | |
2048 raise Abort(_("invalid day spec: %s") % date[1:]) | |
13889
9a96efc4af8a
util: make 'hg log -d --2' abort (issue2734)
Yun Lee <yunlee.bj@gmail.com>
parents:
13886
diff
changeset
|
2049 if days < 0: |
29977
73b1c328a7da
util: use single quotes in use warning
timeless <timeless@mozdev.org>
parents:
29889
diff
changeset
|
2050 raise Abort(_("%s must be nonnegative (see 'hg help dates')") |
13889
9a96efc4af8a
util: make 'hg log -d --2' abort (issue2734)
Yun Lee <yunlee.bj@gmail.com>
parents:
13886
diff
changeset
|
2051 % date[1:]) |
3812 | 2052 when = makedate()[0] - days * 3600 * 24 |
3813 | 2053 return lambda x: x >= when |
3812 | 2054 elif " to " in date: |
2055 a, b = date.split(" to ") | |
2056 start, stop = lower(a), upper(b) | |
2057 return lambda x: x >= start and x <= stop | |
2058 else: | |
2059 start, stop = lower(date), upper(date) | |
2060 return lambda x: x >= start and x <= stop | |
2061 | |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2062 def stringmatcher(pattern, casesensitive=True): |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2063 """ |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2064 accepts a string, possibly starting with 're:' or 'literal:' prefix. |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2065 returns the matcher name, pattern, and matcher function. |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2066 missing or unknown prefixes are treated as literal matches. |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2067 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2068 helper for tests: |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2069 >>> def test(pattern, *tests): |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2070 ... kind, pattern, matcher = stringmatcher(pattern) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2071 ... return (kind, pattern, [bool(matcher(t)) for t in tests]) |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2072 >>> def itest(pattern, *tests): |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2073 ... kind, pattern, matcher = stringmatcher(pattern, casesensitive=False) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2074 ... return (kind, pattern, [bool(matcher(t)) for t in tests]) |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2075 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2076 exact matching (no prefix): |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2077 >>> test('abcdefg', 'abc', 'def', 'abcdefg') |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2078 ('literal', 'abcdefg', [False, False, True]) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2079 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2080 regex matching ('re:' prefix) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2081 >>> test('re:a.+b', 'nomatch', 'fooadef', 'fooadefbar') |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2082 ('re', 'a.+b', [False, False, True]) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2083 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2084 force exact matches ('literal:' prefix) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2085 >>> test('literal:re:foobar', 'foobar', 're:foobar') |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2086 ('literal', 're:foobar', [False, True]) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2087 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2088 unknown prefixes are ignored and treated as literals |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2089 >>> test('foo:bar', 'foo', 'bar', 'foo:bar') |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2090 ('literal', 'foo:bar', [False, False, True]) |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2091 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2092 case insensitive regex matches |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2093 >>> itest('re:A.+b', 'nomatch', 'fooadef', 'fooadefBar') |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2094 ('re', 'A.+b', [False, False, True]) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2095 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2096 case insensitive literal matches |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2097 >>> itest('ABCDEFG', 'abc', 'def', 'abcdefg') |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2098 ('literal', 'ABCDEFG', [False, False, True]) |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2099 """ |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2100 if pattern.startswith('re:'): |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2101 pattern = pattern[3:] |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2102 try: |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2103 flags = 0 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2104 if not casesensitive: |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2105 flags = remod.I |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2106 regex = remod.compile(pattern, flags) |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2107 except remod.error as e: |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2108 raise error.ParseError(_('invalid regular expression: %s') |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2109 % e) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2110 return 're', pattern, regex.search |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2111 elif pattern.startswith('literal:'): |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2112 pattern = pattern[8:] |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2113 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2114 match = pattern.__eq__ |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2115 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2116 if not casesensitive: |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2117 ipat = encoding.lower(pattern) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2118 match = lambda s: ipat == encoding.lower(s) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
2119 return 'literal', pattern, match |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
2120 |
1903
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2121 def shortuser(user): |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2122 """Return a short representation of a user name or email address.""" |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2123 f = user.find('@') |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2124 if f >= 0: |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2125 user = user[:f] |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2126 f = user.find('<') |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2127 if f >= 0: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
2128 user = user[f + 1:] |
3176
7492b33bdd9f
shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3147
diff
changeset
|
2129 f = user.find(' ') |
7492b33bdd9f
shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3147
diff
changeset
|
2130 if f >= 0: |
7492b33bdd9f
shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3147
diff
changeset
|
2131 user = user[:f] |
3533
bb44489b901f
shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents:
3466
diff
changeset
|
2132 f = user.find('.') |
bb44489b901f
shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents:
3466
diff
changeset
|
2133 if f >= 0: |
bb44489b901f
shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents:
3466
diff
changeset
|
2134 user = user[:f] |
1903
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
2135 return user |
1920 | 2136 |
16360
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2137 def emailuser(user): |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2138 """Return the user portion of an email address.""" |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2139 f = user.find('@') |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2140 if f >= 0: |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2141 user = user[:f] |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2142 f = user.find('<') |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2143 if f >= 0: |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2144 user = user[f + 1:] |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2145 return user |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
2146 |
5975
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
2147 def email(author): |
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
2148 '''get email of author.''' |
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
2149 r = author.find('>') |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
2150 if r == -1: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
2151 r = None |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
2152 return author[author.find('<') + 1:r] |
5975
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
2153 |
3767
1861fa38a6a7
Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3721
diff
changeset
|
2154 def ellipsis(text, maxlength=400): |
21857
86c2d792a4b7
util: replace 'ellipsis' implementation by 'encoding.trim'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21813
diff
changeset
|
2155 """Trim string to at most maxlength (default: 400) columns in display.""" |
86c2d792a4b7
util: replace 'ellipsis' implementation by 'encoding.trim'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21813
diff
changeset
|
2156 return encoding.trim(text, maxlength, ellipsis='...') |
3767
1861fa38a6a7
Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3721
diff
changeset
|
2157 |
18735
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2158 def unitcountfn(*unittable): |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2159 '''return a function that renders a readable count of some quantity''' |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2160 |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2161 def go(count): |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2162 for multiplier, divisor, format in unittable: |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2163 if count >= divisor * multiplier: |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2164 return format % (count / float(divisor)) |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2165 return unittable[-1][2] % count |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2166 |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2167 return go |
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2168 |
31662
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2169 def processlinerange(fromline, toline): |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2170 """Check that linerange <fromline>:<toline> makes sense and return a |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2171 0-based range. |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2172 |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2173 >>> processlinerange(10, 20) |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2174 (9, 20) |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2175 >>> processlinerange(2, 1) |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2176 Traceback (most recent call last): |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2177 ... |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2178 ParseError: line range must be positive |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2179 >>> processlinerange(0, 5) |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2180 Traceback (most recent call last): |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2181 ... |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2182 ParseError: fromline must be strictly positive |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2183 """ |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2184 if toline - fromline < 0: |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2185 raise error.ParseError(_("line range must be positive")) |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2186 if fromline < 1: |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2187 raise error.ParseError(_("fromline must be strictly positive")) |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2188 return fromline - 1, toline |
080734cd2440
revset: factor out linerange processing into a utility function
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
31598
diff
changeset
|
2189 |
18735
716cad930691
util: generalize bytecount to unitcountfn
Bryan O'Sullivan <bryano@fb.com>
parents:
18678
diff
changeset
|
2190 bytecount = unitcountfn( |
16397
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2191 (100, 1 << 30, _('%.0f GB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2192 (10, 1 << 30, _('%.1f GB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2193 (1, 1 << 30, _('%.2f GB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2194 (100, 1 << 20, _('%.0f MB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2195 (10, 1 << 20, _('%.1f MB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2196 (1, 1 << 20, _('%.2f MB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2197 (100, 1 << 10, _('%.0f KB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2198 (10, 1 << 10, _('%.1f KB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2199 (1, 1 << 10, _('%.2f KB')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2200 (1, 1, _('%.0f bytes')), |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2201 ) |
f0f7f3fab315
util: create bytecount array just once
Matt Mackall <mpm@selenic.com>
parents:
16383
diff
changeset
|
2202 |
31451
53865692a354
util: wrap s.encode('string_escape') call for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31449
diff
changeset
|
2203 def escapestr(s): |
31453
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31451
diff
changeset
|
2204 # call underlying function of s.encode('string_escape') directly for |
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31451
diff
changeset
|
2205 # Python 3 compatibility |
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31451
diff
changeset
|
2206 return codecs.escape_encode(s)[0] |
31451
53865692a354
util: wrap s.encode('string_escape') call for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31449
diff
changeset
|
2207 |
31484
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31465
diff
changeset
|
2208 def unescapestr(s): |
31485
cad95575dc46
py3: call codecs.escape_decode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
2209 return codecs.escape_decode(s)[0] |
31484
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31465
diff
changeset
|
2210 |
5291
23651848d638
extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents:
5213
diff
changeset
|
2211 def uirepr(s): |
23651848d638
extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents:
5213
diff
changeset
|
2212 # Avoid double backslash in Windows path repr() |
23651848d638
extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents:
5213
diff
changeset
|
2213 return repr(s).replace('\\\\', '\\') |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7537
diff
changeset
|
2214 |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2215 # delay import of textwrap |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2216 def MBTextWrapper(**kwargs): |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2217 class tw(textwrap.TextWrapper): |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2218 """ |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2219 Extend TextWrapper for width-awareness. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2220 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2221 Neither number of 'bytes' in any encoding nor 'characters' is |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2222 appropriate to calculate terminal columns for specified string. |
12957
9f2ac318b92e
util: clarify purpose of MBTextWrapper class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
12938
diff
changeset
|
2223 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2224 Original TextWrapper implementation uses built-in 'len()' directly, |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2225 so overriding is needed to use width information of each characters. |
12957
9f2ac318b92e
util: clarify purpose of MBTextWrapper class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
12938
diff
changeset
|
2226 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2227 In addition, characters classified into 'ambiguous' width are |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
17391
diff
changeset
|
2228 treated as wide in East Asian area, but as narrow in other. |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2229 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2230 This requires use decision to determine width of such characters. |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2231 """ |
15065
24a6c3f903bb
util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents:
15024
diff
changeset
|
2232 def _cutdown(self, ucstr, space_left): |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2233 l = 0 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2234 colwidth = encoding.ucolwidth |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2235 for i in xrange(len(ucstr)): |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2236 l += colwidth(ucstr[i]) |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2237 if space_left < l: |
15065
24a6c3f903bb
util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents:
15024
diff
changeset
|
2238 return (ucstr[:i], ucstr[i:]) |
24a6c3f903bb
util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents:
15024
diff
changeset
|
2239 return ucstr, '' |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2240 |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2241 # overriding of base class |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2242 def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2243 space_left = max(width - cur_len, 1) |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2244 |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2245 if self.break_long_words: |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2246 cut, res = self._cutdown(reversed_chunks[-1], space_left) |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2247 cur_line.append(cut) |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2248 reversed_chunks[-1] = res |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2249 elif not cur_line: |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2250 cur_line.append(reversed_chunks.pop()) |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2251 |
26201
c5b2074ae8c0
util: capitalize Python in MBTextWrapper._wrap_chunks comment
timeless@mozdev.org
parents:
26126
diff
changeset
|
2252 # this overriding code is imported from TextWrapper of Python 2.6 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2253 # to calculate columns of string by 'encoding.ucolwidth()' |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2254 def _wrap_chunks(self, chunks): |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2255 colwidth = encoding.ucolwidth |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2256 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2257 lines = [] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2258 if self.width <= 0: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2259 raise ValueError("invalid width %r (must be > 0)" % self.width) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2260 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2261 # Arrange in reverse order so items can be efficiently popped |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2262 # from a stack of chucks. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2263 chunks.reverse() |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2264 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2265 while chunks: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2266 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2267 # Start the list of chunks that will make up the current line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2268 # cur_len is just the length of all the chunks in cur_line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2269 cur_line = [] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2270 cur_len = 0 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2271 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2272 # Figure out which static string will prefix this line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2273 if lines: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2274 indent = self.subsequent_indent |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2275 else: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2276 indent = self.initial_indent |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2277 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2278 # Maximum width for this line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2279 width = self.width - len(indent) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2280 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2281 # First chunk on line is whitespace -- drop it, unless this |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
17391
diff
changeset
|
2282 # is the very beginning of the text (i.e. no lines started yet). |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2283 if self.drop_whitespace and chunks[-1].strip() == '' and lines: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2284 del chunks[-1] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2285 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2286 while chunks: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2287 l = colwidth(chunks[-1]) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2288 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2289 # Can at least squeeze this chunk onto the current line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2290 if cur_len + l <= width: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2291 cur_line.append(chunks.pop()) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2292 cur_len += l |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2293 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2294 # Nope, this line is full. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2295 else: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2296 break |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2297 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2298 # The current line is full, and the next chunk is too big to |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2299 # fit on *any* line (not just this one). |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2300 if chunks and colwidth(chunks[-1]) > width: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2301 self._handle_long_word(chunks, cur_line, cur_len, width) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2302 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2303 # If the last chunk on this line is all whitespace, drop it. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2304 if (self.drop_whitespace and |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2305 cur_line and cur_line[-1].strip() == ''): |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2306 del cur_line[-1] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2307 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2308 # Convert current line back to a string and store it in list |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2309 # of all lines (return value). |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2310 if cur_line: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2311 lines.append(indent + ''.join(cur_line)) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2312 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2313 return lines |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
2314 |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2315 global MBTextWrapper |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2316 MBTextWrapper = tw |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
2317 return tw(**kwargs) |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2318 |
12698
7aef77e74cf3
util: make wrap() require a width argument
Matt Mackall <mpm@selenic.com>
parents:
12689
diff
changeset
|
2319 def wrap(line, width, initindent='', hangindent=''): |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2320 maxindent = max(len(hangindent), len(initindent)) |
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2321 if width <= maxindent: |
9417
4c3fb45123e5
util, minirst: do not crash with COLUMNS=0
Martin Geisler <mg@lazybytes.net>
parents:
9397
diff
changeset
|
2322 # adjust for weird terminal size |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2323 width = max(78, maxindent + 1) |
31338
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31315
diff
changeset
|
2324 line = line.decode(pycompat.sysstr(encoding.encoding), |
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31315
diff
changeset
|
2325 pycompat.sysstr(encoding.encodingmode)) |
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31315
diff
changeset
|
2326 initindent = initindent.decode(pycompat.sysstr(encoding.encoding), |
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31315
diff
changeset
|
2327 pycompat.sysstr(encoding.encodingmode)) |
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31315
diff
changeset
|
2328 hangindent = hangindent.decode(pycompat.sysstr(encoding.encoding), |
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31315
diff
changeset
|
2329 pycompat.sysstr(encoding.encodingmode)) |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2330 wrapper = MBTextWrapper(width=width, |
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2331 initial_indent=initindent, |
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
2332 subsequent_indent=hangindent) |
31338
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31315
diff
changeset
|
2333 return wrapper.fill(line).encode(pycompat.sysstr(encoding.encoding)) |
8938
9b8c9266c59d
commands: wrap short descriptions in 'hg help'
Martin Geisler <mg@lazybytes.net>
parents:
8785
diff
changeset
|
2334 |
30418
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2335 if (pyplatform.python_implementation() == 'CPython' and |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2336 sys.version_info < (3, 0)): |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2337 # There is an issue in CPython that some IO methods do not handle EINTR |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2338 # correctly. The following table shows what CPython version (and functions) |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2339 # are affected (buggy: has the EINTR bug, okay: otherwise): |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2340 # |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2341 # | < 2.7.4 | 2.7.4 to 2.7.12 | >= 3.0 |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2342 # -------------------------------------------------- |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2343 # fp.__iter__ | buggy | buggy | okay |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2344 # fp.read* | buggy | okay [1] | okay |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2345 # |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2346 # [1]: fixed by changeset 67dc99a989cd in the cpython hg repo. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2347 # |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2348 # Here we workaround the EINTR issue for fileobj.__iter__. Other methods |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2349 # like "read*" are ignored for now, as Python < 2.7.4 is a minority. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2350 # |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2351 # Although we can workaround the EINTR issue for fp.__iter__, it is slower: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2352 # "for x in fp" is 4x faster than "for x in iter(fp.readline, '')" in |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2353 # CPython 2, because CPython 2 maintains an internal readahead buffer for |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2354 # fp.__iter__ but not other fp.read* methods. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2355 # |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2356 # On modern systems like Linux, the "read" syscall cannot be interrupted |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2357 # when reading "fast" files like on-disk files. So the EINTR issue only |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2358 # affects things like pipes, sockets, ttys etc. We treat "normal" (S_ISREG) |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2359 # files approximately as "fast" files and use the fast (unsafe) code path, |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2360 # to minimize the performance impact. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2361 if sys.version_info >= (2, 7, 4): |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2362 # fp.readline deals with EINTR correctly, use it as a workaround. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2363 def _safeiterfile(fp): |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2364 return iter(fp.readline, '') |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2365 else: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2366 # fp.read* are broken too, manually deal with EINTR in a stupid way. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2367 # note: this may block longer than necessary because of bufsize. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2368 def _safeiterfile(fp, bufsize=4096): |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2369 fd = fp.fileno() |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2370 line = '' |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2371 while True: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2372 try: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2373 buf = os.read(fd, bufsize) |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2374 except OSError as ex: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2375 # os.read only raises EINTR before any data is read |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2376 if ex.errno == errno.EINTR: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2377 continue |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2378 else: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2379 raise |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2380 line += buf |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2381 if '\n' in buf: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2382 splitted = line.splitlines(True) |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2383 line = '' |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2384 for l in splitted: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2385 if l[-1] == '\n': |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2386 yield l |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2387 else: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2388 line = l |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2389 if not buf: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2390 break |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2391 if line: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2392 yield line |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2393 |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2394 def iterfile(fp): |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2395 fastpath = True |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2396 if type(fp) is file: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2397 fastpath = stat.S_ISREG(os.fstat(fp.fileno()).st_mode) |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2398 if fastpath: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2399 return fp |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2400 else: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2401 return _safeiterfile(fp) |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2402 else: |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2403 # PyPy and CPython 3 do not have the EINTR issue thus no workaround needed. |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2404 def iterfile(fp): |
1156ec81f709
util: improve iterfile so it chooses code path wisely
Jun Wu <quark@fb.com>
parents:
30417
diff
changeset
|
2405 return fp |
30395
10514a92860e
util: add iterfile to workaround a fileobj.__iter__ issue with EINTR
Jun Wu <quark@fb.com>
parents:
30359
diff
changeset
|
2406 |
7879
5c4026a289a4
templater: ability to display diffstat for log-like commands
Alexander Solovyov <piranha at piranha.org.ua>
parents:
7875
diff
changeset
|
2407 def iterlines(iterator): |
5c4026a289a4
templater: ability to display diffstat for log-like commands
Alexander Solovyov <piranha at piranha.org.ua>
parents:
7875
diff
changeset
|
2408 for chunk in iterator: |
5c4026a289a4
templater: ability to display diffstat for log-like commands
Alexander Solovyov <piranha at piranha.org.ua>
parents:
7875
diff
changeset
|
2409 for line in chunk.splitlines(): |
5c4026a289a4
templater: ability to display diffstat for log-like commands
Alexander Solovyov <piranha at piranha.org.ua>
parents:
7875
diff
changeset
|
2410 yield line |
9610
d78fe60f6bda
make path expanding more consistent
Alexander Solovyov <piranha@piranha.org.ua>
parents:
9569
diff
changeset
|
2411 |
d78fe60f6bda
make path expanding more consistent
Alexander Solovyov <piranha@piranha.org.ua>
parents:
9569
diff
changeset
|
2412 def expandpath(path): |
d78fe60f6bda
make path expanding more consistent
Alexander Solovyov <piranha@piranha.org.ua>
parents:
9569
diff
changeset
|
2413 return os.path.expanduser(os.path.expandvars(path)) |
10239
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2414 |
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2415 def hgcmd(): |
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2416 """Return the command used to execute current hg |
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2417 |
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2418 This is different from hgexecutable() because on Windows we want |
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2419 to avoid things opening new shell windows like batch files, so we |
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2420 get either the python call or current executable. |
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2421 """ |
14228
116de1da2154
rename util.main_is_frozen to mainfrozen
Adrian Buehlmann <adrian@cadifra.com>
parents:
14167
diff
changeset
|
2422 if mainfrozen(): |
27766
198f78a52a2f
util: adjust hgcmd() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents:
27765
diff
changeset
|
2423 if getattr(sys, 'frozen', None) == 'macosx_app': |
198f78a52a2f
util: adjust hgcmd() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents:
27765
diff
changeset
|
2424 # Env variable set by py2app |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30625
diff
changeset
|
2425 return [encoding.environ['EXECUTABLEPATH']] |
27766
198f78a52a2f
util: adjust hgcmd() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents:
27765
diff
changeset
|
2426 else: |
30669
10b17ed9b591
py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30642
diff
changeset
|
2427 return [pycompat.sysexecutable] |
10239
8e4be44a676f
Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents:
10199
diff
changeset
|
2428 return gethgcmd() |
10344
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2429 |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2430 def rundetached(args, condfn): |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2431 """Execute the argument list in a detached process. |
10422
600142e7a028
util: fix trailing whitespace found by check-code
Augie Fackler <durin42@gmail.com>
parents:
10344
diff
changeset
|
2432 |
10344
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2433 condfn is a callable which is called repeatedly and should return |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2434 True once the child process is known to have started successfully. |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2435 At this point, the child process PID is returned. If the child |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2436 process fails to start or finishes before condfn() evaluates to |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2437 True, return -1. |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2438 """ |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2439 # Windows case is easier because the child process is either |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2440 # successfully starting and validating the condition or exiting |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2441 # on failure. We just poll on its PID. On Unix, if the child |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2442 # process fails to start, it will be left in a zombie state until |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2443 # the parent wait on it, which we cannot do since we expect a long |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2444 # running process on success. Instead we listen for SIGCHLD telling |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2445 # us our child process terminated. |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2446 terminated = set() |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2447 def handler(signum, frame): |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2448 terminated.add(os.wait()) |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2449 prevhandler = None |
14968
b7dbe957585c
util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14942
diff
changeset
|
2450 SIGCHLD = getattr(signal, 'SIGCHLD', None) |
b7dbe957585c
util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14942
diff
changeset
|
2451 if SIGCHLD is not None: |
b7dbe957585c
util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14942
diff
changeset
|
2452 prevhandler = signal.signal(SIGCHLD, handler) |
10344
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2453 try: |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2454 pid = spawndetached(args) |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2455 while not condfn(): |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2456 if ((pid in terminated or not testpid(pid)) |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2457 and not condfn()): |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2458 return -1 |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2459 time.sleep(0.1) |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2460 return pid |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2461 finally: |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2462 if prevhandler is not None: |
9501cde4c034
util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents:
10282
diff
changeset
|
2463 signal.signal(signal.SIGCHLD, prevhandler) |
10438
e6dc44147234
util: add any() and all() functions for Python 2.4 compatibility
Steve Losh <steve@stevelosh.com>
parents:
10422
diff
changeset
|
2464 |
13392
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2465 def interpolate(prefix, mapping, s, fn=None, escape_prefix=False): |
11988
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2466 """Return the result of interpolating items in the mapping into string s. |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2467 |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2468 prefix is a single character string, or a two character string with |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2469 a backslash as the first character if the prefix needs to be escaped in |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2470 a regular expression. |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2471 |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2472 fn is an optional function that will be applied to the replacement text |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2473 just before replacement. |
13392
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2474 |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2475 escape_prefix is an optional flag that allows using doubled prefix for |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2476 its escaping. |
11988
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2477 """ |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2478 fn = fn or (lambda s: s) |
13392
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2479 patterns = '|'.join(mapping.keys()) |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2480 if escape_prefix: |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2481 patterns += '|' + prefix |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2482 if len(prefix) > 1: |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2483 prefix_char = prefix[1:] |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2484 else: |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2485 prefix_char = prefix |
777cef34a890
dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents:
13375
diff
changeset
|
2486 mapping[prefix_char] = prefix_char |
21907
7e5dfa00e3c2
util: rename 're' to 'remod'
Siddharth Agarwal <sid0@fb.com>
parents:
21857
diff
changeset
|
2487 r = remod.compile(r'%s(%s)' % (prefix, patterns)) |
11988
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2488 return r.sub(lambda x: fn(mapping[x.group()[1:]]), s) |
8380ed691df8
util: add an interpolate() function to for replacing multiple values
Steve Losh <steve@stevelosh.com>
parents:
11946
diff
changeset
|
2489 |
12076
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2490 def getport(port): |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2491 """Return the port for a given network service. |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2492 |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2493 If port is an integer, it's returned as is. If it's a string, it's |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2494 looked up using socket.getservbyname(). If there's no matching |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26493
diff
changeset
|
2495 service, error.Abort is raised. |
12076
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2496 """ |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2497 try: |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2498 return int(port) |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2499 except ValueError: |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2500 pass |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2501 |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2502 try: |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2503 return socket.getservbyname(port) |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2504 except socket.error: |
49463314c24f
mail/hgweb: support service names for ports (issue2350)
Brodie Rao <brodie@bitheap.org>
parents:
12054
diff
changeset
|
2505 raise Abort(_("no port number associated with service '%s'") % port) |
12087
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2506 |
12088
1f71dffabc53
parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents:
12087
diff
changeset
|
2507 _booleans = {'1': True, 'yes': True, 'true': True, 'on': True, 'always': True, |
1f71dffabc53
parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents:
12087
diff
changeset
|
2508 '0': False, 'no': False, 'false': False, 'off': False, |
1f71dffabc53
parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents:
12087
diff
changeset
|
2509 'never': False} |
12087
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2510 |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2511 def parsebool(s): |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2512 """Parse s into a boolean. |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2513 |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2514 If s is not a valid boolean, returns None. |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2515 """ |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
2516 return _booleans.get(s.lower(), None) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2517 |
14077
c285bdb0572a
util.url: copy urllib.unquote() into util to improve startup times
Brodie Rao <brodie@bitheap.org>
parents:
14076
diff
changeset
|
2518 _hextochr = dict((a + b, chr(int(a + b, 16))) |
30054
8b89521a69ba
util: use string.hexdigits instead of defining it ourselves
Augie Fackler <augie@google.com>
parents:
30053
diff
changeset
|
2519 for a in string.hexdigits for b in string.hexdigits) |
14077
c285bdb0572a
util.url: copy urllib.unquote() into util to improve startup times
Brodie Rao <brodie@bitheap.org>
parents:
14076
diff
changeset
|
2520 |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2521 class url(object): |
14146
1618c4f6f15b
tests: use raw string for url tests of '\' handling
Mads Kiilerich <mads@kiilerich.com>
parents:
14100
diff
changeset
|
2522 r"""Reliable URL parser. |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2523 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2524 This parses URLs and provides attributes for the following |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2525 components: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2526 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2527 <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment> |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2528 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2529 Missing components are set to None. The only exception is |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2530 fragment, which is set to '' if present but empty. |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2531 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2532 If parsefragment is False, fragment is included in query. If |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2533 parsequery is False, query is included in path. If both are |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2534 False, both fragment and query are included in path. |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2535 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2536 See http://www.ietf.org/rfc/rfc2396.txt for more information. |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2537 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2538 Note that for backward compatibility reasons, bundle URLs do not |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2539 take host names. That means 'bundle://../' has a path of '../'. |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2540 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2541 Examples: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2542 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2543 >>> url('http://www.ietf.org/rfc/rfc2396.txt') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2544 <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'> |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2545 >>> url('ssh://[::1]:2200//home/joe/repo') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2546 <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'> |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2547 >>> url('file:///home/joe/repo') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2548 <url scheme: 'file', path: '/home/joe/repo'> |
14915
28edd65000d9
url: handle urls of the form file:///c:/foo/bar/ correctly
Matt Mackall <mpm@selenic.com>
parents:
14825
diff
changeset
|
2549 >>> url('file:///c:/temp/foo/') |
28edd65000d9
url: handle urls of the form file:///c:/foo/bar/ correctly
Matt Mackall <mpm@selenic.com>
parents:
14825
diff
changeset
|
2550 <url scheme: 'file', path: 'c:/temp/foo/'> |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2551 >>> url('bundle:foo') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2552 <url scheme: 'bundle', path: 'foo'> |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2553 >>> url('bundle://../foo') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2554 <url scheme: 'bundle', path: '../foo'> |
14146
1618c4f6f15b
tests: use raw string for url tests of '\' handling
Mads Kiilerich <mads@kiilerich.com>
parents:
14100
diff
changeset
|
2555 >>> url(r'c:\foo\bar') |
1618c4f6f15b
tests: use raw string for url tests of '\' handling
Mads Kiilerich <mads@kiilerich.com>
parents:
14100
diff
changeset
|
2556 <url path: 'c:\\foo\\bar'> |
14699
388af80c058b
url: catch UNC paths as yet another Windows special case (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14640
diff
changeset
|
2557 >>> url(r'\\blah\blah\blah') |
388af80c058b
url: catch UNC paths as yet another Windows special case (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14640
diff
changeset
|
2558 <url path: '\\\\blah\\blah\\blah'> |
15074
64fbd0de9773
url: parse fragments first (issue2997)
Matt Mackall <mpm@selenic.com>
parents:
15066
diff
changeset
|
2559 >>> url(r'\\blah\blah\blah#baz') |
64fbd0de9773
url: parse fragments first (issue2997)
Matt Mackall <mpm@selenic.com>
parents:
15066
diff
changeset
|
2560 <url path: '\\\\blah\\blah\\blah', fragment: 'baz'> |
20106
c33d9217e99d
util: url keeps backslash in paths
Simon Heimberg <simohe@besonet.ch>
parents:
20000
diff
changeset
|
2561 >>> url(r'file:///C:\users\me') |
c33d9217e99d
util: url keeps backslash in paths
Simon Heimberg <simohe@besonet.ch>
parents:
20000
diff
changeset
|
2562 <url scheme: 'file', path: 'C:\\users\\me'> |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2563 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2564 Authentication credentials: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2565 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2566 >>> url('ssh://joe:xyz@x/repo') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2567 <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'> |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2568 >>> url('ssh://joe@x/repo') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2569 <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'> |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2570 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2571 Query strings and fragments: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2572 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2573 >>> url('http://host/a?b#c') |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2574 <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'> |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2575 >>> url('http://host/a?b#c', parsequery=False, parsefragment=False) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2576 <url scheme: 'http', host: 'host', path: 'a?b#c'> |
30036
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2577 |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2578 Empty path: |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2579 |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2580 >>> url('') |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2581 <url path: ''> |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2582 >>> url('#a') |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2583 <url path: '', fragment: 'a'> |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2584 >>> url('http://host/') |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2585 <url scheme: 'http', host: 'host', path: ''> |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2586 >>> url('http://host/#a') |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2587 <url scheme: 'http', host: 'host', path: '', fragment: 'a'> |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2588 |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2589 Only scheme: |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2590 |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2591 >>> url('http:') |
3f4e1c033f40
url: fix crash by empty path with #fragments
Yuya Nishihara <yuya@tcha.org>
parents:
30030
diff
changeset
|
2592 <url scheme: 'http'> |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2593 """ |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2594 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2595 _safechars = "!~*'()+" |
20106
c33d9217e99d
util: url keeps backslash in paths
Simon Heimberg <simohe@besonet.ch>
parents:
20000
diff
changeset
|
2596 _safepchars = "/!~*'()+:\\" |
30329
dadb00a0ec0f
util: use '\\' rather than using r'\'
Augie Fackler <augie@google.com>
parents:
30328
diff
changeset
|
2597 _matchscheme = remod.compile('^[a-zA-Z0-9+.\\-]+:').match |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2598 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2599 def __init__(self, path, parsequery=True, parsefragment=True): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2600 # We slowly chomp away at path until we have only the path left |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2601 self.scheme = self.user = self.passwd = self.host = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2602 self.port = self.path = self.query = self.fragment = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2603 self._localpath = True |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2604 self._hostport = '' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2605 self._origpath = path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2606 |
15074
64fbd0de9773
url: parse fragments first (issue2997)
Matt Mackall <mpm@selenic.com>
parents:
15066
diff
changeset
|
2607 if parsefragment and '#' in path: |
64fbd0de9773
url: parse fragments first (issue2997)
Matt Mackall <mpm@selenic.com>
parents:
15066
diff
changeset
|
2608 path, self.fragment = path.split('#', 1) |
64fbd0de9773
url: parse fragments first (issue2997)
Matt Mackall <mpm@selenic.com>
parents:
15066
diff
changeset
|
2609 |
14699
388af80c058b
url: catch UNC paths as yet another Windows special case (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14640
diff
changeset
|
2610 # special case for Windows drive letters and UNC paths |
30329
dadb00a0ec0f
util: use '\\' rather than using r'\'
Augie Fackler <augie@google.com>
parents:
30328
diff
changeset
|
2611 if hasdriveletter(path) or path.startswith('\\\\'): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2612 self.path = path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2613 return |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2614 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2615 # For compatibility reasons, we can't handle bundle paths as |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2616 # normal URLS |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2617 if path.startswith('bundle:'): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2618 self.scheme = 'bundle' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2619 path = path[7:] |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2620 if path.startswith('//'): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2621 path = path[2:] |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2622 self.path = path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2623 return |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2624 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2625 if self._matchscheme(path): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2626 parts = path.split(':', 1) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2627 if parts[0]: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2628 self.scheme, path = parts |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2629 self._localpath = False |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2630 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2631 if not path: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2632 path = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2633 if self._localpath: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2634 self.path = '' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2635 return |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2636 else: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2637 if self._localpath: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2638 self.path = path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2639 return |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2640 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2641 if parsequery and '?' in path: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2642 path, self.query = path.split('?', 1) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2643 if not path: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2644 path = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2645 if not self.query: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2646 self.query = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2647 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2648 # // is required to specify a host/authority |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2649 if path and path.startswith('//'): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2650 parts = path[2:].split('/', 1) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2651 if len(parts) > 1: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2652 self.host, path = parts |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2653 else: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2654 self.host = parts[0] |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2655 path = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2656 if not self.host: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2657 self.host = None |
15018
e89f62dcd723
url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents:
14988
diff
changeset
|
2658 # path of file:///d is /d |
e89f62dcd723
url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents:
14988
diff
changeset
|
2659 # path of file:///d:/ is d:/, not /d:/ |
14915
28edd65000d9
url: handle urls of the form file:///c:/foo/bar/ correctly
Matt Mackall <mpm@selenic.com>
parents:
14825
diff
changeset
|
2660 if path and not hasdriveletter(path): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2661 path = '/' + path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2662 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2663 if self.host and '@' in self.host: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2664 self.user, self.host = self.host.rsplit('@', 1) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2665 if ':' in self.user: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2666 self.user, self.passwd = self.user.split(':', 1) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2667 if not self.host: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2668 self.host = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2669 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2670 # Don't split on colons in IPv6 addresses without ports |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2671 if (self.host and ':' in self.host and |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2672 not (self.host.startswith('[') and self.host.endswith(']'))): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2673 self._hostport = self.host |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2674 self.host, self.port = self.host.rsplit(':', 1) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2675 if not self.host: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2676 self.host = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2677 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2678 if (self.host and self.scheme == 'file' and |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2679 self.host not in ('localhost', '127.0.0.1', '[::1]')): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2680 raise Abort(_('file:// URLs can only refer to localhost')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2681 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2682 self.path = path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2683 |
14988
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2684 # leave the query string escaped |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2685 for a in ('user', 'passwd', 'host', 'port', |
14988
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2686 'path', 'fragment'): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2687 v = getattr(self, a) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2688 if v is not None: |
31567
4ebecf331d7d
util: use urlreq.unquote
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31541
diff
changeset
|
2689 setattr(self, a, urlreq.unquote(v)) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2690 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2691 def __repr__(self): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2692 attrs = [] |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2693 for a in ('scheme', 'user', 'passwd', 'host', 'port', 'path', |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2694 'query', 'fragment'): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2695 v = getattr(self, a) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2696 if v is not None: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2697 attrs.append('%s: %r' % (a, v)) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2698 return '<url %s>' % ', '.join(attrs) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2699 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2700 def __str__(self): |
14147
617483af1cc0
test: test that backslash is preserved by the url class
Mads Kiilerich <mads@kiilerich.com>
parents:
14146
diff
changeset
|
2701 r"""Join the URL's components back into a URL string. |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2702 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2703 Examples: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2704 |
15452
de7e2fba4326
util: don't encode ':' in url paths
Mads Kiilerich <mads@kiilerich.com>
parents:
15392
diff
changeset
|
2705 >>> str(url('http://user:pw@host:80/c:/bob?fo:oo#ba:ar')) |
de7e2fba4326
util: don't encode ':' in url paths
Mads Kiilerich <mads@kiilerich.com>
parents:
15392
diff
changeset
|
2706 'http://user:pw@host:80/c:/bob?fo:oo#ba:ar' |
14988
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2707 >>> str(url('http://user:pw@host:80/?foo=bar&baz=42')) |
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2708 'http://user:pw@host:80/?foo=bar&baz=42' |
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2709 >>> str(url('http://user:pw@host:80/?foo=bar%3dbaz')) |
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2710 'http://user:pw@host:80/?foo=bar%3dbaz' |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2711 >>> str(url('ssh://user:pw@[::1]:2200//home/joe#')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2712 'ssh://user:pw@[::1]:2200//home/joe#' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2713 >>> str(url('http://localhost:80//')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2714 'http://localhost:80//' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2715 >>> str(url('http://localhost:80/')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2716 'http://localhost:80/' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2717 >>> str(url('http://localhost:80')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2718 'http://localhost:80/' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2719 >>> str(url('bundle:foo')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2720 'bundle:foo' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2721 >>> str(url('bundle://../foo')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2722 'bundle:../foo' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2723 >>> str(url('path')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2724 'path' |
14313
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14271
diff
changeset
|
2725 >>> str(url('file:///tmp/foo/bar')) |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14271
diff
changeset
|
2726 'file:///tmp/foo/bar' |
15609
8f4bad72d8b1
util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents:
15505
diff
changeset
|
2727 >>> str(url('file:///c:/tmp/foo/bar')) |
15611 | 2728 'file:///c:/tmp/foo/bar' |
14147
617483af1cc0
test: test that backslash is preserved by the url class
Mads Kiilerich <mads@kiilerich.com>
parents:
14146
diff
changeset
|
2729 >>> print url(r'bundle:foo\bar') |
617483af1cc0
test: test that backslash is preserved by the url class
Mads Kiilerich <mads@kiilerich.com>
parents:
14146
diff
changeset
|
2730 bundle:foo\bar |
20106
c33d9217e99d
util: url keeps backslash in paths
Simon Heimberg <simohe@besonet.ch>
parents:
20000
diff
changeset
|
2731 >>> print url(r'file:///D:\data\hg') |
c33d9217e99d
util: url keeps backslash in paths
Simon Heimberg <simohe@besonet.ch>
parents:
20000
diff
changeset
|
2732 file:///D:\data\hg |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2733 """ |
31448
6419cd243017
encoding: add converter between native str and byte string
Yuya Nishihara <yuya@tcha.org>
parents:
31447
diff
changeset
|
2734 return encoding.strfromlocal(self.__bytes__()) |
31368
6e59397b08d8
util: teach url object about __bytes__
Augie Fackler <augie@google.com>
parents:
31338
diff
changeset
|
2735 |
6e59397b08d8
util: teach url object about __bytes__
Augie Fackler <augie@google.com>
parents:
31338
diff
changeset
|
2736 def __bytes__(self): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2737 if self._localpath: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2738 s = self.path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2739 if self.scheme == 'bundle': |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2740 s = 'bundle:' + s |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2741 if self.fragment: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2742 s += '#' + self.fragment |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2743 return s |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2744 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2745 s = self.scheme + ':' |
14313
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14271
diff
changeset
|
2746 if self.user or self.passwd or self.host: |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14271
diff
changeset
|
2747 s += '//' |
15609
8f4bad72d8b1
util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents:
15505
diff
changeset
|
2748 elif self.scheme and (not self.path or self.path.startswith('/') |
8f4bad72d8b1
util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents:
15505
diff
changeset
|
2749 or hasdriveletter(self.path)): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2750 s += '//' |
15609
8f4bad72d8b1
util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents:
15505
diff
changeset
|
2751 if hasdriveletter(self.path): |
8f4bad72d8b1
util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents:
15505
diff
changeset
|
2752 s += '/' |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2753 if self.user: |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
2754 s += urlreq.quote(self.user, safe=self._safechars) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2755 if self.passwd: |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
2756 s += ':' + urlreq.quote(self.passwd, safe=self._safechars) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2757 if self.user or self.passwd: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2758 s += '@' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2759 if self.host: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2760 if not (self.host.startswith('[') and self.host.endswith(']')): |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
2761 s += urlreq.quote(self.host) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2762 else: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2763 s += self.host |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2764 if self.port: |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
2765 s += ':' + urlreq.quote(self.port) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2766 if self.host: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2767 s += '/' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2768 if self.path: |
14988
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2769 # TODO: similar to the query string, we should not unescape the |
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2770 # path when we store it, the path might contain '%2f' = '/', |
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2771 # which we should *not* escape. |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
2772 s += urlreq.quote(self.path, safe=self._safepchars) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2773 if self.query: |
14988
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2774 # we store the query in escaped form. |
e6730f9e13bc
url: store and assume the query part of an url is in escaped form (issue2921)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
14915
diff
changeset
|
2775 s += '?' + self.query |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2776 if self.fragment is not None: |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28882
diff
changeset
|
2777 s += '#' + urlreq.quote(self.fragment, safe=self._safepchars) |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2778 return s |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2779 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2780 def authinfo(self): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2781 user, passwd = self.user, self.passwd |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2782 try: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2783 self.user, self.passwd = None, None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2784 s = str(self) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2785 finally: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2786 self.user, self.passwd = user, passwd |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2787 if not self.user: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2788 return (s, None) |
15028
eb97a3e38656
http: explain why the host is passed to urllib2 password manager
Patrick Mezard <pmezard@gmail.com>
parents:
15027
diff
changeset
|
2789 # authinfo[1] is passed to urllib2 password manager, and its |
eb97a3e38656
http: explain why the host is passed to urllib2 password manager
Patrick Mezard <pmezard@gmail.com>
parents:
15027
diff
changeset
|
2790 # URIs must not contain credentials. The host is passed in the |
eb97a3e38656
http: explain why the host is passed to urllib2 password manager
Patrick Mezard <pmezard@gmail.com>
parents:
15027
diff
changeset
|
2791 # URIs list because Python < 2.4.3 uses only that to search for |
eb97a3e38656
http: explain why the host is passed to urllib2 password manager
Patrick Mezard <pmezard@gmail.com>
parents:
15027
diff
changeset
|
2792 # a password. |
15024
0f1311e829c9
http: strip credentials from urllib2 manager URIs (issue2885)
Patrick Mezard <pmezard@gmail.com>
parents:
15018
diff
changeset
|
2793 return (s, (None, (s, self.host), |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2794 self.user, self.passwd or '')) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2795 |
14766
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2796 def isabs(self): |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2797 if self.scheme and self.scheme != 'file': |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2798 return True # remote URL |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2799 if hasdriveletter(self.path): |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2800 return True # absolute for our purposes - can't be joined() |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2801 if self.path.startswith(r'\\'): |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2802 return True # Windows UNC path |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2803 if self.path.startswith('/'): |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2804 return True # POSIX-style |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2805 return False |
4f56b7530eab
subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents:
14699
diff
changeset
|
2806 |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2807 def localpath(self): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2808 if self.scheme == 'file' or self.scheme == 'bundle': |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2809 path = self.path or '/' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2810 # For Windows, we need to promote hosts containing drive |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2811 # letters to paths with drive letters. |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2812 if hasdriveletter(self._hostport): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2813 path = self._hostport + '/' + self.path |
15496
396e83d635a6
url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents:
15488
diff
changeset
|
2814 elif (self.host is not None and self.path |
396e83d635a6
url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents:
15488
diff
changeset
|
2815 and not hasdriveletter(path)): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2816 path = '/' + path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2817 return path |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2818 return self._origpath |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2819 |
20353
0889585b44f1
util.url: add an 'islocal' method
Siddharth Agarwal <sid0@fb.com>
parents:
20244
diff
changeset
|
2820 def islocal(self): |
0889585b44f1
util.url: add an 'islocal' method
Siddharth Agarwal <sid0@fb.com>
parents:
20244
diff
changeset
|
2821 '''whether localpath will return something that posixfile can open''' |
0889585b44f1
util.url: add an 'islocal' method
Siddharth Agarwal <sid0@fb.com>
parents:
20244
diff
changeset
|
2822 return (not self.scheme or self.scheme == 'file' |
0889585b44f1
util.url: add an 'islocal' method
Siddharth Agarwal <sid0@fb.com>
parents:
20244
diff
changeset
|
2823 or self.scheme == 'bundle') |
0889585b44f1
util.url: add an 'islocal' method
Siddharth Agarwal <sid0@fb.com>
parents:
20244
diff
changeset
|
2824 |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2825 def hasscheme(path): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2826 return bool(url(path).scheme) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2827 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2828 def hasdriveletter(path): |
15609
8f4bad72d8b1
util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents:
15505
diff
changeset
|
2829 return path and path[1:2] == ':' and path[0:1].isalpha() |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2830 |
14825
de9eb6b1da4f
util: rename the util.localpath that uses url to urllocalpath (issue2875)
Mads Kiilerich <mads@kiilerich.com>
parents:
14766
diff
changeset
|
2831 def urllocalpath(path): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2832 return url(path, parsequery=False, parsefragment=False).localpath() |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2833 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2834 def hidepassword(u): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2835 '''hide user credential in a url string''' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2836 u = url(u) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2837 if u.passwd: |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2838 u.passwd = '***' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2839 return str(u) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2840 |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2841 def removeauth(u): |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2842 '''remove all authentication information from a url string''' |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2843 u = url(u) |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2844 u.user = u.passwd = None |
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14064
diff
changeset
|
2845 return str(u) |
14515
76f295eaed86
util: add helper function isatty(fd) to check for tty-ness
Idan Kamara <idankk86@gmail.com>
parents:
14313
diff
changeset
|
2846 |
18736
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2847 timecount = unitcountfn( |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2848 (1, 1e3, _('%.0f s')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2849 (100, 1, _('%.1f s')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2850 (10, 1, _('%.2f s')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2851 (1, 1, _('%.3f s')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2852 (100, 0.001, _('%.1f ms')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2853 (10, 0.001, _('%.2f ms')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2854 (1, 0.001, _('%.3f ms')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2855 (100, 0.000001, _('%.1f us')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2856 (10, 0.000001, _('%.2f us')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2857 (1, 0.000001, _('%.3f us')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2858 (100, 0.000000001, _('%.1f ns')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2859 (10, 0.000000001, _('%.2f ns')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2860 (1, 0.000000001, _('%.3f ns')), |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2861 ) |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2862 |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2863 _timenesting = [0] |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2864 |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2865 def timed(func): |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2866 '''Report the execution time of a function call to stderr. |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2867 |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2868 During development, use as a decorator when you need to measure |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2869 the cost of a function, e.g. as follows: |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2870 |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2871 @util.timed |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2872 def foo(a, b, c): |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2873 pass |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2874 ''' |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2875 |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2876 def wrapper(*args, **kwargs): |
30975
22fbca1d11ed
mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents:
30974
diff
changeset
|
2877 start = timer() |
18736
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2878 indent = 2 |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2879 _timenesting[0] += indent |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2880 try: |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2881 return func(*args, **kwargs) |
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2882 finally: |
30975
22fbca1d11ed
mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents:
30974
diff
changeset
|
2883 elapsed = timer() - start |
18736
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2884 _timenesting[0] -= indent |
30473
39d13b8c101d
py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents:
30472
diff
changeset
|
2885 stderr.write('%s%s: %s\n' % |
39d13b8c101d
py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents:
30472
diff
changeset
|
2886 (' ' * _timenesting[0], func.__name__, |
39d13b8c101d
py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents:
30472
diff
changeset
|
2887 timecount(elapsed))) |
18736
af9ddea2cb99
util: add a timed function for use during development
Bryan O'Sullivan <bryano@fb.com>
parents:
18735
diff
changeset
|
2888 return wrapper |
19194
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2889 |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2890 _sizeunits = (('m', 2**20), ('k', 2**10), ('g', 2**30), |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2891 ('kb', 2**10), ('mb', 2**20), ('gb', 2**30), ('b', 1)) |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2892 |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2893 def sizetoint(s): |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2894 '''Convert a space specifier to a byte count. |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2895 |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2896 >>> sizetoint('30') |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2897 30 |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2898 >>> sizetoint('2.2kb') |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2899 2252 |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2900 >>> sizetoint('6M') |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2901 6291456 |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2902 ''' |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2903 t = s.strip().lower() |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2904 try: |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2905 for k, u in _sizeunits: |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2906 if t.endswith(k): |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2907 return int(float(t[:-len(k)]) * u) |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2908 return int(t) |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2909 except ValueError: |
1d08df65cd3c
util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents:
18938
diff
changeset
|
2910 raise error.ParseError(_("couldn't parse size: %s") % s) |
19211
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2911 |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2912 class hooks(object): |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2913 '''A collection of hook functions that can be used to extend a |
26098 | 2914 function's behavior. Hooks are called in lexicographic order, |
19211
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2915 based on the names of their sources.''' |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2916 |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2917 def __init__(self): |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2918 self._hooks = [] |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2919 |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2920 def add(self, source, hook): |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2921 self._hooks.append((source, hook)) |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2922 |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2923 def __call__(self, *args): |
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2924 self._hooks.sort(key=lambda x: x[0]) |
21046
cc13addbd62b
util: enable "hooks" to return list of the values returned from each hooks
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21018
diff
changeset
|
2925 results = [] |
19211
3bfd7f1e7485
summary: augment output with info from extensions
Bryan O'Sullivan <bryano@fb.com>
parents:
19194
diff
changeset
|
2926 for source, hook in self._hooks: |
21046
cc13addbd62b
util: enable "hooks" to return list of the values returned from each hooks
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21018
diff
changeset
|
2927 results.append(hook(*args)) |
cc13addbd62b
util: enable "hooks" to return list of the values returned from each hooks
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21018
diff
changeset
|
2928 return results |
20244
47d0843647d1
util: introduce util.debugstacktrace for showing a stack trace without crashing
Mads Kiilerich <madski@unity3d.com>
parents:
20202
diff
changeset
|
2929 |
31315
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2930 def getstackframes(skip=0, line=' %-*s in %s\n', fileline='%s:%s', depth=0): |
28497
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2931 '''Yields lines for a nicely formatted stacktrace. |
31315
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2932 Skips the 'skip' last entries, then return the last 'depth' entries. |
28497
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2933 Each file+linenumber is formatted according to fileline. |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2934 Each line is formatted according to line. |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2935 If line is None, it yields: |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2936 length of longest filepath+line number, |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2937 filepath+linenumber, |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2938 function |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2939 |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2940 Not be used in production code but very convenient while developing. |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2941 ''' |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2942 entries = [(fileline % (fn, ln), func) |
31315
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2943 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1] |
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2944 ][-depth:] |
28497
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2945 if entries: |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2946 fnmax = max(len(entry[0]) for entry in entries) |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2947 for fnln, func in entries: |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2948 if line is None: |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2949 yield (fnmax, fnln, func) |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2950 else: |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2951 yield line % (fnmax, fnln, func) |
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2952 |
31315
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2953 def debugstacktrace(msg='stacktrace', skip=0, |
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2954 f=stderr, otherf=stdout, depth=0): |
20244
47d0843647d1
util: introduce util.debugstacktrace for showing a stack trace without crashing
Mads Kiilerich <madski@unity3d.com>
parents:
20202
diff
changeset
|
2955 '''Writes a message to f (stderr) with a nicely formatted stacktrace. |
31315
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2956 Skips the 'skip' entries closest to the call, then show 'depth' entries. |
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2957 By default it will flush stdout first. |
28496
b592564a803c
util: reword debugstacktrace comment
timeless <timeless@mozdev.org>
parents:
28027
diff
changeset
|
2958 It can be used everywhere and intentionally does not require an ui object. |
20244
47d0843647d1
util: introduce util.debugstacktrace for showing a stack trace without crashing
Mads Kiilerich <madski@unity3d.com>
parents:
20202
diff
changeset
|
2959 Not be used in production code but very convenient while developing. |
47d0843647d1
util: introduce util.debugstacktrace for showing a stack trace without crashing
Mads Kiilerich <madski@unity3d.com>
parents:
20202
diff
changeset
|
2960 ''' |
20542
be27652675ce
util: debugstacktrace, flush before and after writing
Mads Kiilerich <madski@unity3d.com>
parents:
20353
diff
changeset
|
2961 if otherf: |
be27652675ce
util: debugstacktrace, flush before and after writing
Mads Kiilerich <madski@unity3d.com>
parents:
20353
diff
changeset
|
2962 otherf.flush() |
31314
7c877cbf30d6
util: strip trailing newline from debugstacktrace message
Mads Kiilerich <madski@unity3d.com>
parents:
31141
diff
changeset
|
2963 f.write('%s at:\n' % msg.rstrip()) |
31315
78ac7061f840
util: add debugstacktrace depth limit
Mads Kiilerich <madski@unity3d.com>
parents:
31314
diff
changeset
|
2964 for line in getstackframes(skip + 1, depth=depth): |
28497
906fece80cfa
util: refactor getstackframes
timeless <timeless@mozdev.org>
parents:
28496
diff
changeset
|
2965 f.write(line) |
20542
be27652675ce
util: debugstacktrace, flush before and after writing
Mads Kiilerich <madski@unity3d.com>
parents:
20353
diff
changeset
|
2966 f.flush() |
20244
47d0843647d1
util: introduce util.debugstacktrace for showing a stack trace without crashing
Mads Kiilerich <madski@unity3d.com>
parents:
20202
diff
changeset
|
2967 |
24635
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2968 class dirs(object): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2969 '''a multiset of directory names from a dirstate or manifest''' |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2970 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2971 def __init__(self, map, skip=None): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2972 self._dirs = {} |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2973 addpath = self.addpath |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2974 if safehasattr(map, 'iteritems') and skip is not None: |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2975 for f, s in map.iteritems(): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2976 if s[0] != skip: |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2977 addpath(f) |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2978 else: |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2979 for f in map: |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2980 addpath(f) |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2981 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2982 def addpath(self, path): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2983 dirs = self._dirs |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2984 for base in finddirs(path): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2985 if base in dirs: |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2986 dirs[base] += 1 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2987 return |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2988 dirs[base] = 1 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2989 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2990 def delpath(self, path): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2991 dirs = self._dirs |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2992 for base in finddirs(path): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2993 if dirs[base] > 1: |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2994 dirs[base] -= 1 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2995 return |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2996 del dirs[base] |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2997 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
2998 def __iter__(self): |
31430
807387581d89
py3: use iter() instead of iterkeys()
Rishabh Madan <rishabhmadan96@gmail.com>
parents:
31404
diff
changeset
|
2999 return iter(self._dirs) |
24635
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3000 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3001 def __contains__(self, d): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3002 return d in self._dirs |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3003 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3004 if safehasattr(parsers, 'dirs'): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3005 dirs = parsers.dirs |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3006 |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3007 def finddirs(path): |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3008 pos = path.rfind('/') |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3009 while pos != -1: |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3010 yield path[:pos] |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3011 pos = path.rfind('/', 0, pos) |
21e1ece30f8c
util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents:
24605
diff
changeset
|
3012 |
27703
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3013 class ctxmanager(object): |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3014 '''A context manager for use in 'with' blocks to allow multiple |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3015 contexts to be entered at once. This is both safer and more |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3016 flexible than contextlib.nested. |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3017 |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3018 Once Mercurial supports Python 2.7+, this will become mostly |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3019 unnecessary. |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3020 ''' |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3021 |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3022 def __init__(self, *args): |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3023 '''Accepts a list of no-argument functions that return context |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3024 managers. These will be invoked at __call__ time.''' |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3025 self._pending = args |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3026 self._atexit = [] |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3027 |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3028 def __enter__(self): |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3029 return self |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3030 |
27785
ba427b51f1d8
util: rename ctxmanager's __call__ method to enter
Bryan O'Sullivan <bryano@fb.com>
parents:
27778
diff
changeset
|
3031 def enter(self): |
27703
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3032 '''Create and enter context managers in the order in which they were |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3033 passed to the constructor.''' |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3034 values = [] |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3035 for func in self._pending: |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3036 obj = func() |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3037 values.append(obj.__enter__()) |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3038 self._atexit.append(obj.__exit__) |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3039 del self._pending |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3040 return values |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3041 |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3042 def atexit(self, func, *args, **kwargs): |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3043 '''Add a function to call when this context manager exits. The |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3044 ordering of multiple atexit calls is unspecified, save that |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3045 they will happen before any __exit__ functions.''' |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3046 def wrapper(exc_type, exc_val, exc_tb): |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3047 func(*args, **kwargs) |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3048 self._atexit.append(wrapper) |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3049 return func |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3050 |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3051 def __exit__(self, exc_type, exc_val, exc_tb): |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3052 '''Context managers are exited in the reverse order from which |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3053 they were created.''' |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3054 received = exc_type is not None |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3055 suppressed = False |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3056 pending = None |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3057 self._atexit.reverse() |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3058 for exitfunc in self._atexit: |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3059 try: |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3060 if exitfunc(exc_type, exc_val, exc_tb): |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3061 suppressed = True |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3062 exc_type = None |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3063 exc_val = None |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3064 exc_tb = None |
27755
50c5192e4a5e
util: don't capture exception with a name since we don't use it
Augie Fackler <augie@google.com>
parents:
27703
diff
changeset
|
3065 except BaseException: |
27703
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3066 pending = sys.exc_info() |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3067 exc_type, exc_val, exc_tb = pending = sys.exc_info() |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3068 del self._atexit |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3069 if pending: |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3070 raise exc_val |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3071 return received and suppressed |
4e27c0a70574
util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
27667
diff
changeset
|
3072 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3073 # compression code |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3074 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3075 SERVERROLE = 'server' |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3076 CLIENTROLE = 'client' |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3077 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3078 compewireprotosupport = collections.namedtuple(u'compenginewireprotosupport', |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3079 (u'name', u'serverpriority', |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3080 u'clientpriority')) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3081 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3082 class compressormanager(object): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3083 """Holds registrations of various compression engines. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3084 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3085 This class essentially abstracts the differences between compression |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3086 engines to allow new compression formats to be added easily, possibly from |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3087 extensions. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3088 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3089 Compressors are registered against the global instance by calling its |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3090 ``register()`` method. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3091 """ |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3092 def __init__(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3093 self._engines = {} |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3094 # Bundle spec human name to engine name. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3095 self._bundlenames = {} |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3096 # Internal bundle identifier to engine name. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3097 self._bundletypes = {} |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3098 # Revlog header to engine name. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3099 self._revlogheaders = {} |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3100 # Wire proto identifier to engine name. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3101 self._wiretypes = {} |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3102 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3103 def __getitem__(self, key): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3104 return self._engines[key] |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3105 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3106 def __contains__(self, key): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3107 return key in self._engines |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3108 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3109 def __iter__(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3110 return iter(self._engines.keys()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3111 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3112 def register(self, engine): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3113 """Register a compression engine with the manager. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3114 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3115 The argument must be a ``compressionengine`` instance. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3116 """ |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3117 if not isinstance(engine, compressionengine): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3118 raise ValueError(_('argument must be a compressionengine')) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3119 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3120 name = engine.name() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3121 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3122 if name in self._engines: |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3123 raise error.Abort(_('compression engine %s already registered') % |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3124 name) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3125 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3126 bundleinfo = engine.bundletype() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3127 if bundleinfo: |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3128 bundlename, bundletype = bundleinfo |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3129 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3130 if bundlename in self._bundlenames: |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3131 raise error.Abort(_('bundle name %s already registered') % |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3132 bundlename) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3133 if bundletype in self._bundletypes: |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3134 raise error.Abort(_('bundle type %s already registered by %s') % |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3135 (bundletype, self._bundletypes[bundletype])) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3136 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3137 # No external facing name declared. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3138 if bundlename: |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3139 self._bundlenames[bundlename] = name |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3140 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3141 self._bundletypes[bundletype] = name |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3142 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3143 wiresupport = engine.wireprotosupport() |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3144 if wiresupport: |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3145 wiretype = wiresupport.name |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3146 if wiretype in self._wiretypes: |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3147 raise error.Abort(_('wire protocol compression %s already ' |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3148 'registered by %s') % |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3149 (wiretype, self._wiretypes[wiretype])) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3150 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3151 self._wiretypes[wiretype] = name |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3152 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3153 revlogheader = engine.revlogheader() |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3154 if revlogheader and revlogheader in self._revlogheaders: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3155 raise error.Abort(_('revlog header %s already registered by %s') % |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3156 (revlogheader, self._revlogheaders[revlogheader])) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3157 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3158 if revlogheader: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3159 self._revlogheaders[revlogheader] = name |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3160 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3161 self._engines[name] = engine |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3162 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3163 @property |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3164 def supportedbundlenames(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3165 return set(self._bundlenames.keys()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3166 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3167 @property |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3168 def supportedbundletypes(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3169 return set(self._bundletypes.keys()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3170 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3171 def forbundlename(self, bundlename): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3172 """Obtain a compression engine registered to a bundle name. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3173 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3174 Will raise KeyError if the bundle type isn't registered. |
30438
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3175 |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3176 Will abort if the engine is known but not available. |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3177 """ |
30438
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3178 engine = self._engines[self._bundlenames[bundlename]] |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3179 if not engine.available(): |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3180 raise error.Abort(_('compression engine %s could not be loaded') % |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3181 engine.name()) |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3182 return engine |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3183 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3184 def forbundletype(self, bundletype): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3185 """Obtain a compression engine registered to a bundle type. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3186 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3187 Will raise KeyError if the bundle type isn't registered. |
30438
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3188 |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3189 Will abort if the engine is known but not available. |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3190 """ |
30438
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3191 engine = self._engines[self._bundletypes[bundletype]] |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3192 if not engine.available(): |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3193 raise error.Abort(_('compression engine %s could not be loaded') % |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3194 engine.name()) |
90933e4e44fd
util: check for compression engine availability before returning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30437
diff
changeset
|
3195 return engine |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3196 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3197 def supportedwireengines(self, role, onlyavailable=True): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3198 """Obtain compression engines that support the wire protocol. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3199 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3200 Returns a list of engines in prioritized order, most desired first. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3201 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3202 If ``onlyavailable`` is set, filter out engines that can't be |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3203 loaded. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3204 """ |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3205 assert role in (SERVERROLE, CLIENTROLE) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3206 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3207 attr = 'serverpriority' if role == SERVERROLE else 'clientpriority' |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3208 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3209 engines = [self._engines[e] for e in self._wiretypes.values()] |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3210 if onlyavailable: |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3211 engines = [e for e in engines if e.available()] |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3212 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3213 def getkey(e): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3214 # Sort first by priority, highest first. In case of tie, sort |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3215 # alphabetically. This is arbitrary, but ensures output is |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3216 # stable. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3217 w = e.wireprotosupport() |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3218 return -1 * getattr(w, attr), w.name |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3219 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3220 return list(sorted(engines, key=getkey)) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3221 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3222 def forwiretype(self, wiretype): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3223 engine = self._engines[self._wiretypes[wiretype]] |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3224 if not engine.available(): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3225 raise error.Abort(_('compression engine %s could not be loaded') % |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3226 engine.name()) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3227 return engine |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3228 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3229 def forrevlogheader(self, header): |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3230 """Obtain a compression engine registered to a revlog header. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3231 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3232 Will raise KeyError if the revlog header value isn't registered. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3233 """ |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3234 return self._engines[self._revlogheaders[header]] |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3235 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3236 compengines = compressormanager() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3237 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3238 class compressionengine(object): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3239 """Base class for compression engines. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3240 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3241 Compression engines must implement the interface defined by this class. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3242 """ |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3243 def name(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3244 """Returns the name of the compression engine. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3245 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3246 This is the key the engine is registered under. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3247 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3248 This method must be implemented. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3249 """ |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3250 raise NotImplementedError() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3251 |
30437
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3252 def available(self): |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3253 """Whether the compression engine is available. |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3254 |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3255 The intent of this method is to allow optional compression engines |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3256 that may not be available in all installations (such as engines relying |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3257 on C extensions that may not be present). |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3258 """ |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3259 return True |
64d7275445d0
util: expose an "available" API on compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30418
diff
changeset
|
3260 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3261 def bundletype(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3262 """Describes bundle identifiers for this engine. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3263 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3264 If this compression engine isn't supported for bundles, returns None. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3265 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3266 If this engine can be used for bundles, returns a 2-tuple of strings of |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3267 the user-facing "bundle spec" compression name and an internal |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3268 identifier used to denote the compression format within bundles. To |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3269 exclude the name from external usage, set the first element to ``None``. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3270 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3271 If bundle compression is supported, the class must also implement |
30359
673f0fdc1046
util: remove compressorobj API from compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30356
diff
changeset
|
3272 ``compressstream`` and `decompressorreader``. |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3273 """ |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3274 return None |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3275 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3276 def wireprotosupport(self): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3277 """Declare support for this compression format on the wire protocol. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3278 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3279 If this compression engine isn't supported for compressing wire |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3280 protocol payloads, returns None. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3281 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3282 Otherwise, returns ``compenginewireprotosupport`` with the following |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3283 fields: |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3284 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3285 * String format identifier |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3286 * Integer priority for the server |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3287 * Integer priority for the client |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3288 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3289 The integer priorities are used to order the advertisement of format |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3290 support by server and client. The highest integer is advertised |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3291 first. Integers with non-positive values aren't advertised. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3292 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3293 The priority values are somewhat arbitrary and only used for default |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3294 ordering. The relative order can be changed via config options. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3295 |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3296 If wire protocol compression is supported, the class must also implement |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3297 ``compressstream`` and ``decompressorreader``. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3298 """ |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3299 return None |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3300 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3301 def revlogheader(self): |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3302 """Header added to revlog chunks that identifies this engine. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3303 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3304 If this engine can be used to compress revlogs, this method should |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3305 return the bytes used to identify chunks compressed with this engine. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3306 Else, the method should return ``None`` to indicate it does not |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3307 participate in revlog compression. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3308 """ |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3309 return None |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3310 |
30356
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3311 def compressstream(self, it, opts=None): |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3312 """Compress an iterator of chunks. |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3313 |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3314 The method receives an iterator (ideally a generator) of chunks of |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3315 bytes to be compressed. It returns an iterator (ideally a generator) |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3316 of bytes of chunks representing the compressed output. |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3317 |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3318 Optionally accepts an argument defining how to perform compression. |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3319 Each engine treats this argument differently. |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3320 """ |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3321 raise NotImplementedError() |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3322 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3323 def decompressorreader(self, fh): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3324 """Perform decompression on a file object. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3325 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3326 Argument is an object with a ``read(size)`` method that returns |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3327 compressed data. Return value is an object with a ``read(size)`` that |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3328 returns uncompressed data. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3329 """ |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3330 raise NotImplementedError() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3331 |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3332 def revlogcompressor(self, opts=None): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3333 """Obtain an object that can be used to compress revlog entries. |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3334 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3335 The object has a ``compress(data)`` method that compresses binary |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3336 data. This method returns compressed binary data or ``None`` if |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3337 the data could not be compressed (too small, not compressible, etc). |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3338 The returned data should have a header uniquely identifying this |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3339 compression format so decompression can be routed to this engine. |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3340 This header should be identified by the ``revlogheader()`` return |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3341 value. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3342 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3343 The object has a ``decompress(data)`` method that decompresses |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3344 data. The method will only be called if ``data`` begins with |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3345 ``revlogheader()``. The method should return the raw, uncompressed |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3346 data or raise a ``RevlogError``. |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3347 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3348 The object is reusable but is not thread safe. |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3349 """ |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3350 raise NotImplementedError() |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3351 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3352 class _zlibengine(compressionengine): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3353 def name(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3354 return 'zlib' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3355 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3356 def bundletype(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3357 return 'gzip', 'GZ' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3358 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3359 def wireprotosupport(self): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3360 return compewireprotosupport('zlib', 20, 20) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3361 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3362 def revlogheader(self): |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3363 return 'x' |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3364 |
30356
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3365 def compressstream(self, it, opts=None): |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3366 opts = opts or {} |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3367 |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3368 z = zlib.compressobj(opts.get('level', -1)) |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3369 for chunk in it: |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3370 data = z.compress(chunk) |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3371 # Not all calls to compress emit data. It is cheaper to inspect |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3372 # here than to feed empty chunks through generator. |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3373 if data: |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3374 yield data |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3375 |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3376 yield z.flush() |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3377 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3378 def decompressorreader(self, fh): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3379 def gen(): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3380 d = zlib.decompressobj() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3381 for chunk in filechunkiter(fh): |
30536
98d7636c4729
util: limit output chunk size in zlib decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30473
diff
changeset
|
3382 while chunk: |
98d7636c4729
util: limit output chunk size in zlib decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30473
diff
changeset
|
3383 # Limit output size to limit memory. |
98d7636c4729
util: limit output chunk size in zlib decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30473
diff
changeset
|
3384 yield d.decompress(chunk, 2 ** 18) |
98d7636c4729
util: limit output chunk size in zlib decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30473
diff
changeset
|
3385 chunk = d.unconsumed_tail |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3386 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3387 return chunkbuffer(gen()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3388 |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3389 class zlibrevlogcompressor(object): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3390 def compress(self, data): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3391 insize = len(data) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3392 # Caller handles empty input case. |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3393 assert insize > 0 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3394 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3395 if insize < 44: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3396 return None |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3397 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3398 elif insize <= 1000000: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3399 compressed = zlib.compress(data) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3400 if len(compressed) < insize: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3401 return compressed |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3402 return None |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3403 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3404 # zlib makes an internal copy of the input buffer, doubling |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3405 # memory usage for large inputs. So do streaming compression |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3406 # on large inputs. |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3407 else: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3408 z = zlib.compressobj() |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3409 parts = [] |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3410 pos = 0 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3411 while pos < insize: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3412 pos2 = pos + 2**20 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3413 parts.append(z.compress(data[pos:pos2])) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3414 pos = pos2 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3415 parts.append(z.flush()) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3416 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3417 if sum(map(len, parts)) < insize: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3418 return ''.join(parts) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3419 return None |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3420 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3421 def decompress(self, data): |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3422 try: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3423 return zlib.decompress(data) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3424 except zlib.error as e: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3425 raise error.RevlogError(_('revlog decompress error: %s') % |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3426 str(e)) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3427 |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3428 def revlogcompressor(self, opts=None): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3429 return self.zlibrevlogcompressor() |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3430 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3431 compengines.register(_zlibengine()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3432 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3433 class _bz2engine(compressionengine): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3434 def name(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3435 return 'bz2' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3436 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3437 def bundletype(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3438 return 'bzip2', 'BZ' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3439 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3440 # We declare a protocol name but don't advertise by default because |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3441 # it is slow. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3442 def wireprotosupport(self): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3443 return compewireprotosupport('bzip2', 0, 0) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3444 |
30356
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3445 def compressstream(self, it, opts=None): |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3446 opts = opts or {} |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3447 z = bz2.BZ2Compressor(opts.get('level', 9)) |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3448 for chunk in it: |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3449 data = z.compress(chunk) |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3450 if data: |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3451 yield data |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3452 |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3453 yield z.flush() |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3454 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3455 def decompressorreader(self, fh): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3456 def gen(): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3457 d = bz2.BZ2Decompressor() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3458 for chunk in filechunkiter(fh): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3459 yield d.decompress(chunk) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3460 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3461 return chunkbuffer(gen()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3462 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3463 compengines.register(_bz2engine()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3464 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3465 class _truncatedbz2engine(compressionengine): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3466 def name(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3467 return 'bz2truncated' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3468 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3469 def bundletype(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3470 return None, '_truncatedBZ' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3471 |
30359
673f0fdc1046
util: remove compressorobj API from compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30356
diff
changeset
|
3472 # We don't implement compressstream because it is hackily handled elsewhere. |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3473 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3474 def decompressorreader(self, fh): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3475 def gen(): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3476 # The input stream doesn't have the 'BZ' header. So add it back. |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3477 d = bz2.BZ2Decompressor() |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3478 d.decompress('BZ') |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3479 for chunk in filechunkiter(fh): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3480 yield d.decompress(chunk) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3481 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3482 return chunkbuffer(gen()) |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3483 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3484 compengines.register(_truncatedbz2engine()) |
30265
6a8aff737a17
util: put compression code next to each other
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30181
diff
changeset
|
3485 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3486 class _noopengine(compressionengine): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3487 def name(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3488 return 'none' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3489 |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3490 def bundletype(self): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3491 return 'none', 'UN' |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3492 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3493 # Clients always support uncompressed payloads. Servers don't because |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3494 # unless you are on a fast network, uncompressed payloads can easily |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3495 # saturate your network pipe. |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3496 def wireprotosupport(self): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3497 return compewireprotosupport('none', 0, 10) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3498 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3499 # We don't implement revlogheader because it is handled specially |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3500 # in the revlog class. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3501 |
30356
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3502 def compressstream(self, it, opts=None): |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3503 return it |
c86109eface7
util: add a stream compression API to compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30355
diff
changeset
|
3504 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3505 def decompressorreader(self, fh): |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3506 return fh |
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3507 |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3508 class nooprevlogcompressor(object): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3509 def compress(self, data): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3510 return None |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3511 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3512 def revlogcompressor(self, opts=None): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3513 return self.nooprevlogcompressor() |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3514 |
30350
358cda0af6ee
util: create new abstraction for compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30332
diff
changeset
|
3515 compengines.register(_noopengine()) |
26266
1e042e31bd0c
changegroup: move all compressions utilities in util
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26201
diff
changeset
|
3516 |
30442
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3517 class _zstdengine(compressionengine): |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3518 def name(self): |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3519 return 'zstd' |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3520 |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3521 @propertycache |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3522 def _module(self): |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3523 # Not all installs have the zstd module available. So defer importing |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3524 # until first access. |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3525 try: |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3526 from . import zstd |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3527 # Force delayed import. |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3528 zstd.__version__ |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3529 return zstd |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3530 except ImportError: |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3531 return None |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3532 |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3533 def available(self): |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3534 return bool(self._module) |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3535 |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3536 def bundletype(self): |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3537 return 'zstd', 'ZS' |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3538 |
30761
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3539 def wireprotosupport(self): |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3540 return compewireprotosupport('zstd', 50, 50) |
7283719e2bfd
util: declare wire protocol support of compression engines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30745
diff
changeset
|
3541 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3542 def revlogheader(self): |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3543 return '\x28' |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3544 |
30442
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3545 def compressstream(self, it, opts=None): |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3546 opts = opts or {} |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3547 # zstd level 3 is almost always significantly faster than zlib |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3548 # while providing no worse compression. It strikes a good balance |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3549 # between speed and compression. |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3550 level = opts.get('level', 3) |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3551 |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3552 zstd = self._module |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3553 z = zstd.ZstdCompressor(level=level).compressobj() |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3554 for chunk in it: |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3555 data = z.compress(chunk) |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3556 if data: |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3557 yield data |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3558 |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3559 yield z.flush() |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3560 |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3561 def decompressorreader(self, fh): |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3562 zstd = self._module |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3563 dctx = zstd.ZstdDecompressor() |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3564 return chunkbuffer(dctx.read_from(fh)) |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3565 |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3566 class zstdrevlogcompressor(object): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3567 def __init__(self, zstd, level=3): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3568 # Writing the content size adds a few bytes to the output. However, |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3569 # it allows decompression to be more optimal since we can |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3570 # pre-allocate a buffer to hold the result. |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3571 self._cctx = zstd.ZstdCompressor(level=level, |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3572 write_content_size=True) |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3573 self._dctx = zstd.ZstdDecompressor() |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3574 self._compinsize = zstd.COMPRESSION_RECOMMENDED_INPUT_SIZE |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3575 self._decompinsize = zstd.DECOMPRESSION_RECOMMENDED_INPUT_SIZE |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3576 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3577 def compress(self, data): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3578 insize = len(data) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3579 # Caller handles empty input case. |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3580 assert insize > 0 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3581 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3582 if insize < 50: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3583 return None |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3584 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3585 elif insize <= 1000000: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3586 compressed = self._cctx.compress(data) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3587 if len(compressed) < insize: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3588 return compressed |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3589 return None |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3590 else: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3591 z = self._cctx.compressobj() |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3592 chunks = [] |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3593 pos = 0 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3594 while pos < insize: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3595 pos2 = pos + self._compinsize |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3596 chunk = z.compress(data[pos:pos2]) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3597 if chunk: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3598 chunks.append(chunk) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3599 pos = pos2 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3600 chunks.append(z.flush()) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3601 |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3602 if sum(map(len, chunks)) < insize: |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3603 return ''.join(chunks) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3604 return None |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3605 |
30798
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3606 def decompress(self, data): |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3607 insize = len(data) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3608 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3609 try: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3610 # This was measured to be faster than other streaming |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3611 # decompressors. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3612 dobj = self._dctx.decompressobj() |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3613 chunks = [] |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3614 pos = 0 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3615 while pos < insize: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3616 pos2 = pos + self._decompinsize |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3617 chunk = dobj.decompress(data[pos:pos2]) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3618 if chunk: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3619 chunks.append(chunk) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3620 pos = pos2 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3621 # Frame should be exhausted, so no finish() API. |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3622 |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3623 return ''.join(chunks) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3624 except Exception as e: |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3625 raise error.RevlogError(_('revlog decompress error: %s') % |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3626 str(e)) |
f50c0db50025
util: compression APIs to support revlog decompression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30794
diff
changeset
|
3627 |
30794
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3628 def revlogcompressor(self, opts=None): |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3629 opts = opts or {} |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3630 return self.zstdrevlogcompressor(self._module, |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3631 level=opts.get('level', 3)) |
31e1f0d4ab44
util: compression APIs to support revlog compression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30773
diff
changeset
|
3632 |
30442
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3633 compengines.register(_zstdengine()) |
41a8106789ca
util: implement zstd compression engine
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30438
diff
changeset
|
3634 |
20244
47d0843647d1
util: introduce util.debugstacktrace for showing a stack trace without crashing
Mads Kiilerich <madski@unity3d.com>
parents:
20202
diff
changeset
|
3635 # convenient shortcut |
47d0843647d1
util: introduce util.debugstacktrace for showing a stack trace without crashing
Mads Kiilerich <madski@unity3d.com>
parents:
20202
diff
changeset
|
3636 dst = debugstacktrace |