mercurial/util.py
author Bryan O'Sullivan <bos@serpentine.com>
Wed, 09 Apr 2008 15:27:57 -0700
changeset 6500 a3175cd7dbec
parent 6499 479847ccabe0
child 6501 4f7feeb6d6ee
permissions -rw-r--r--
Tidy code, fix typo
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     1
"""
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     2
util.py - Mercurial utility functions and platform specfic implementations
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     3
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     4
 Copyright 2005 K. Thananchayan <thananck@yahoo.com>
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4625
diff changeset
     5
 Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2793
diff changeset
     6
 Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     7
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     8
This software may be used and distributed according to the terms
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     9
of the GNU General Public License, incorporated herein by reference.
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
    10
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
    11
This contains helper routines that are independent of the SCM core and hide
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
    12
platform-specific details from the core.
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
    13
"""
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
    14
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
    15
from i18n import _
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
    16
import cStringIO, errno, getpass, popen2, re, shutil, sys, tempfile, strutil
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5360
diff changeset
    17
import os, stat, threading, time, calendar, ConfigParser, locale, glob, osutil
6499
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
    18
import re, urlparse, imp
3769
96095d9ff1f8 Add encoding detection
Matt Mackall <mpm@selenic.com>
parents: 3767
diff changeset
    19
4057
3600b84656d3 Fallback to ascii if getpreferredencoding raises an exception
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4055
diff changeset
    20
try:
4647
7c80e3e6f030 Provide a version independent way to use the set datatype.
Eric Hopper <hopper@omnifarious.org>
parents: 4635
diff changeset
    21
    set = set
7c80e3e6f030 Provide a version independent way to use the set datatype.
Eric Hopper <hopper@omnifarious.org>
parents: 4635
diff changeset
    22
    frozenset = frozenset
7c80e3e6f030 Provide a version independent way to use the set datatype.
Eric Hopper <hopper@omnifarious.org>
parents: 4635
diff changeset
    23
except NameError:
7c80e3e6f030 Provide a version independent way to use the set datatype.
Eric Hopper <hopper@omnifarious.org>
parents: 4635
diff changeset
    24
    from sets import Set as set, ImmutableSet as frozenset
7c80e3e6f030 Provide a version independent way to use the set datatype.
Eric Hopper <hopper@omnifarious.org>
parents: 4635
diff changeset
    25
7c80e3e6f030 Provide a version independent way to use the set datatype.
Eric Hopper <hopper@omnifarious.org>
parents: 4635
diff changeset
    26
try:
4540
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    27
    _encoding = os.environ.get("HGENCODING")
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    28
    if sys.platform == 'darwin' and not _encoding:
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    29
        # On darwin, getpreferredencoding ignores the locale environment and
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    30
        # always returns mac-roman. We override this if the environment is
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    31
        # not C (has been customized by the user).
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    32
        locale.setlocale(locale.LC_CTYPE, '')
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    33
        _encoding = locale.getlocale()[1]
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    34
    if not _encoding:
133a52d70958 Respect locale environment variables on darwin.
Brendan Cully <brendan@kublai.com>
parents: 4533
diff changeset
    35
        _encoding = locale.getpreferredencoding() or 'ascii'
4057
3600b84656d3 Fallback to ascii if getpreferredencoding raises an exception
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4055
diff changeset
    36
except locale.Error:
3600b84656d3 Fallback to ascii if getpreferredencoding raises an exception
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4055
diff changeset
    37
    _encoding = 'ascii'
3770
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    38
_encodingmode = os.environ.get("HGENCODINGMODE", "strict")
3835
d1ce5461beed Allow the user to specify the fallback encoding for the changelog
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3813
diff changeset
    39
_fallbackencoding = 'ISO-8859-1'
3770
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    40
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    41
def tolocal(s):
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    42
    """
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    43
    Convert a string from internal UTF-8 to local encoding
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    44
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    45
    All internal strings should be UTF-8 but some repos before the
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    46
    implementation of locale support may contain latin1 or possibly
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    47
    other character sets. We attempt to decode everything strictly
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    48
    using UTF-8, then Latin-1, and failing that, we use UTF-8 and
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    49
    replace unknown characters.
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    50
    """
3835
d1ce5461beed Allow the user to specify the fallback encoding for the changelog
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3813
diff changeset
    51
    for e in ('UTF-8', _fallbackencoding):
3770
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    52
        try:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    53
            u = s.decode(e) # attempt strict decoding
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    54
            return u.encode(_encoding, "replace")
3843
abaa2cd00d2b make transcoding more robust
Matt Mackall <mpm@selenic.com>
parents: 3835
diff changeset
    55
        except LookupError, k:
abaa2cd00d2b make transcoding more robust
Matt Mackall <mpm@selenic.com>
parents: 3835
diff changeset
    56
            raise Abort(_("%s, please check your locale settings") % k)
3770
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    57
        except UnicodeDecodeError:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    58
            pass
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    59
    u = s.decode("utf-8", "replace") # last ditch
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    60
    return u.encode(_encoding, "replace")
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    61
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    62
def fromlocal(s):
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    63
    """
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    64
    Convert a string from the local character encoding to UTF-8
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    65
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    66
    We attempt to decode strings using the encoding mode set by
4876
001e8a745834 typo fix
Jesse Glick <jesse.glick@sun.com>
parents: 4832
diff changeset
    67
    HGENCODINGMODE, which defaults to 'strict'. In this mode, unknown
3770
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    68
    characters will cause an error message. Other modes include
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    69
    'replace', which replaces unknown characters with a special
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    70
    Unicode character, and 'ignore', which drops the character.
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    71
    """
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    72
    try:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    73
        return s.decode(_encoding, _encodingmode).encode("utf-8")
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    74
    except UnicodeDecodeError, inst:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    75
        sub = s[max(0, inst.start-10):inst.start+10]
3843
abaa2cd00d2b make transcoding more robust
Matt Mackall <mpm@selenic.com>
parents: 3835
diff changeset
    76
        raise Abort("decoding near '%s': %s!" % (sub, inst))
abaa2cd00d2b make transcoding more robust
Matt Mackall <mpm@selenic.com>
parents: 3835
diff changeset
    77
    except LookupError, k:
abaa2cd00d2b make transcoding more robust
Matt Mackall <mpm@selenic.com>
parents: 3835
diff changeset
    78
        raise Abort(_("%s, please check your locale settings") % k)
3770
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    79
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    80
def locallen(s):
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    81
    """Find the length in characters of a local string"""
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    82
    return len(s.decode(_encoding, "replace"))
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    83
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    84
def localsub(s, a, b=None):
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    85
    try:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    86
        u = s.decode(_encoding, _encodingmode)
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    87
        if b is not None:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    88
            u = u[a:b]
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    89
        else:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    90
            u = u[:a]
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    91
        return u.encode(_encoding, _encodingmode)
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    92
    except UnicodeDecodeError, inst:
f96c158ea3a3 Add functions for transcoding and manipulating multibyte strings
Matt Mackall <mpm@selenic.com>
parents: 3769
diff changeset
    93
        sub = s[max(0, inst.start-10), inst.start+10]
4533
36abb07c79d4 Removed trailing \n in calls to util.Abort()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4516
diff changeset
    94
        raise Abort(_("decoding near '%s': %s!") % (sub, inst))
1258
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
    95
2609
6c5b1b5cc160 util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents: 2601
diff changeset
    96
# used by parsedate
3808
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
    97
defaultdateformats = (
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
    98
    '%Y-%m-%d %H:%M:%S',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
    99
    '%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
   100
    '%Y-%m-%d %H:%M',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   101
    '%Y-%m-%d %I:%M%p',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   102
    '%Y-%m-%d',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   103
    '%m-%d',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   104
    '%m/%d',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   105
    '%m/%d/%y',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   106
    '%m/%d/%Y',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   107
    '%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
   108
    '%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
   109
    '%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
   110
    '%b %d %H:%M:%S %Y',
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   111
    '%b %d %I:%M:%S%p %Y',
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   112
    '%b %d %H:%M:%S',
3808
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   113
    '%b %d %I:%M:%S%p',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   114
    '%b %d %H:%M',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   115
    '%b %d %I:%M%p',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   116
    '%b %d %Y',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   117
    '%b %d',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   118
    '%H:%M:%S',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   119
    '%I:%M:%SP',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   120
    '%H:%M',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   121
    '%I:%M%p',
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
   122
)
2609
6c5b1b5cc160 util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents: 2601
diff changeset
   123
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   124
extendeddateformats = defaultdateformats + (
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   125
    "%Y",
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   126
    "%Y-%m",
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   127
    "%b",
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   128
    "%b %Y",
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
   129
    )
2609
6c5b1b5cc160 util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents: 2601
diff changeset
   130
2153
635653cd73ab move SignalInterrupt class into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   131
class SignalInterrupt(Exception):
635653cd73ab move SignalInterrupt class into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   132
    """Exception raised on SIGTERM and SIGHUP."""
635653cd73ab move SignalInterrupt class into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   133
4069
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   134
# differences from SafeConfigParser:
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   135
# - case-sensitive keys
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   136
# - allows values that are not strings (this means that you may not
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   137
#   be able to save the configuration to a file)
3425
ec6f400cff4d Use a case-sensitive version of SafeConfigParser everywhere
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3257
diff changeset
   138
class configparser(ConfigParser.SafeConfigParser):
ec6f400cff4d Use a case-sensitive version of SafeConfigParser everywhere
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3257
diff changeset
   139
    def optionxform(self, optionstr):
ec6f400cff4d Use a case-sensitive version of SafeConfigParser everywhere
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3257
diff changeset
   140
        return optionstr
ec6f400cff4d Use a case-sensitive version of SafeConfigParser everywhere
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3257
diff changeset
   141
4069
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   142
    def set(self, section, option, value):
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   143
        return ConfigParser.ConfigParser.set(self, section, option, value)
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   144
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   145
    def _interpolate(self, section, option, rawval, vars):
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   146
        if not isinstance(rawval, basestring):
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   147
            return rawval
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   148
        return ConfigParser.SafeConfigParser._interpolate(self, section,
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   149
                                                          option, rawval, vars)
3fef134832d8 allow values that aren't strings in util.configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4068
diff changeset
   150
3145
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   151
def cachefunc(func):
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   152
    '''cache the result of function calls'''
3147
97420a49188d add comments in cachefunc
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3145
diff changeset
   153
    # XXX doesn't handle keywords args
3145
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   154
    cache = {}
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   155
    if func.func_code.co_argcount == 1:
3147
97420a49188d add comments in cachefunc
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3145
diff changeset
   156
        # we gain a small amount of time because
97420a49188d add comments in cachefunc
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3145
diff changeset
   157
        # 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
   158
        def f(arg):
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   159
            if arg not in cache:
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   160
                cache[arg] = func(arg)
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   161
            return cache[arg]
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   162
    else:
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   163
        def f(*args):
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   164
            if args not in cache:
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   165
                cache[args] = func(*args)
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   166
            return cache[args]
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   167
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   168
    return f
e4ea47c21480 Add cachefunc to abstract function call cache
Brendan Cully <brendan@kublai.com>
parents: 3131
diff changeset
   169
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   170
def pipefilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   171
    '''filter string S through command CMD, returning its output'''
4625
eaf87cd19337 Work around heisenbug in Popen3.__del__
Brendan Cully <brendan@kublai.com>
parents: 4540
diff changeset
   172
    (pin, pout) = os.popen2(cmd, 'b')
1258
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   173
    def writer():
2096
f5ebe964c6be Ignore EPIPE in pipefilter
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2090
diff changeset
   174
        try:
f5ebe964c6be Ignore EPIPE in pipefilter
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2090
diff changeset
   175
            pin.write(s)
f5ebe964c6be Ignore EPIPE in pipefilter
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2090
diff changeset
   176
            pin.close()
f5ebe964c6be Ignore EPIPE in pipefilter
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2090
diff changeset
   177
        except IOError, inst:
f5ebe964c6be Ignore EPIPE in pipefilter
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2090
diff changeset
   178
            if inst.errno != errno.EPIPE:
f5ebe964c6be Ignore EPIPE in pipefilter
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2090
diff changeset
   179
                raise
1258
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   180
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   181
    # we should use select instead on UNIX, but this will work on most
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   182
    # systems, including Windows
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   183
    w = threading.Thread(target=writer)
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   184
    w.start()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   185
    f = pout.read()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   186
    pout.close()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   187
    w.join()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
   188
    return f
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
   189
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   190
def tempfilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   191
    '''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
   192
    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
   193
    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
   194
    the temporary files generated.'''
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   195
    inname, outname = None, None
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   196
    try:
2165
d821918e3bee Use better names (hg-{usage}-{random}.{suffix}) for temporary files.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2153
diff changeset
   197
        infd, inname = tempfile.mkstemp(prefix='hg-filter-in-')
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   198
        fp = os.fdopen(infd, 'wb')
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   199
        fp.write(s)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   200
        fp.close()
2165
d821918e3bee Use better names (hg-{usage}-{random}.{suffix}) for temporary files.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2153
diff changeset
   201
        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
   202
        os.close(outfd)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   203
        cmd = cmd.replace('INFILE', inname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   204
        cmd = cmd.replace('OUTFILE', outname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   205
        code = os.system(cmd)
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
   206
        if sys.platform == 'OpenVMS' and code & 1:
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
   207
            code = 0
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
   208
        if code: raise Abort(_("command '%s' failed: %s") %
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   209
                             (cmd, explain_exit(code)))
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   210
        return open(outname, 'rb').read()
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   211
    finally:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   212
        try:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   213
            if inname: os.unlink(inname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   214
        except: pass
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   215
        try:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   216
            if outname: os.unlink(outname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   217
        except: pass
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   218
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   219
filtertable = {
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   220
    'tempfile:': tempfilter,
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   221
    'pipe:': pipefilter,
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   222
    }
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   223
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   224
def filter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   225
    "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
   226
    for name, fn in filtertable.iteritems():
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   227
        if cmd.startswith(name):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   228
            return fn(s, cmd[len(name):].lstrip())
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   229
    return pipefilter(s, cmd)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   230
1015
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
   231
def binary(s):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   232
    """return true if a string is binary data using diff's heuristic"""
1015
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
   233
    if s and '\0' in s[:4096]:
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
   234
        return True
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
   235
    return False
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
   236
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
   237
def unique(g):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   238
    """return the uniq elements of iterable g"""
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
   239
    seen = {}
3535
4d97184a06ad Make util.unique return a list
Matt Mackall <mpm@selenic.com>
parents: 3533
diff changeset
   240
    l = []
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
   241
    for f in g:
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
   242
        if f not in seen:
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
   243
            seen[f] = 1
3535
4d97184a06ad Make util.unique return a list
Matt Mackall <mpm@selenic.com>
parents: 3533
diff changeset
   244
            l.append(f)
4d97184a06ad Make util.unique return a list
Matt Mackall <mpm@selenic.com>
parents: 3533
diff changeset
   245
    return l
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
   246
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
   247
class Abort(Exception):
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
   248
    """Raised if a command needs to print an error and exit."""
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
   249
3564
eda9e7c9300d New UnexpectedOutput exception to catch server errors in localrepo.stream_in
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3551
diff changeset
   250
class UnexpectedOutput(Abort):
eda9e7c9300d New UnexpectedOutput exception to catch server errors in localrepo.stream_in
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3551
diff changeset
   251
    """Raised to print an error with part of output and exit."""
eda9e7c9300d New UnexpectedOutput exception to catch server errors in localrepo.stream_in
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3551
diff changeset
   252
724
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   253
def always(fn): return True
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   254
def never(fn): return False
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   255
4054
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   256
def expand_glob(pats):
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   257
    '''On Windows, expand the implicit globs in a list of patterns'''
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   258
    if os.name != 'nt':
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   259
        return list(pats)
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   260
    ret = []
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   261
    for p in pats:
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   262
        kind, name = patkind(p, None)
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   263
        if kind is None:
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   264
            globbed = glob.glob(name)
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   265
            if globbed:
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   266
                ret.extend(globbed)
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   267
                continue
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   268
            # if we couldn't expand the glob, just keep it around
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   269
        ret.append(p)
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   270
    return ret
e6d54283c090 Explicitly expand globs on Windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3905
diff changeset
   271
1563
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
   272
def patkind(name, dflt_pat='glob'):
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
   273
    """Split a string into an optional pattern kind prefix and the
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
   274
    actual pattern."""
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
   275
    for prefix in 're', 'glob', 'path', 'relglob', 'relpath', 'relre':
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
   276
        if name.startswith(prefix + ':'): return name.split(':', 1)
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
   277
    return dflt_pat, name
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
   278
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1031
diff changeset
   279
def globre(pat, head='^', tail='$'):
724
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   280
    "convert a glob pattern into a regexp"
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   281
    i, n = 0, len(pat)
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   282
    res = ''
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   283
    group = False
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   284
    def peek(): return i < n and pat[i]
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   285
    while i < n:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   286
        c = pat[i]
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   287
        i = i+1
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   288
        if c == '*':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   289
            if peek() == '*':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   290
                i += 1
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   291
                res += '.*'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   292
            else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   293
                res += '[^/]*'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   294
        elif c == '?':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   295
            res += '.'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   296
        elif c == '[':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   297
            j = i
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   298
            if j < n and pat[j] in '!]':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   299
                j += 1
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   300
            while j < n and pat[j] != ']':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   301
                j += 1
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   302
            if j >= n:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   303
                res += '\\['
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   304
            else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   305
                stuff = pat[i:j].replace('\\','\\\\')
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   306
                i = j + 1
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   307
                if stuff[0] == '!':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   308
                    stuff = '^' + stuff[1:]
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   309
                elif stuff[0] == '^':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   310
                    stuff = '\\' + stuff
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   311
                res = '%s[%s]' % (res, stuff)
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   312
        elif c == '{':
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   313
            group = True
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   314
            res += '(?:'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   315
        elif c == '}' and group:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   316
            res += ')'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   317
            group = False
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   318
        elif c == ',' and group:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   319
            res += '|'
1990
4b0535c678d6 make it possible to escape characters in a glob expression
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1976
diff changeset
   320
        elif c == '\\':
4b0535c678d6 make it possible to escape characters in a glob expression
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1976
diff changeset
   321
            p = peek()
4b0535c678d6 make it possible to escape characters in a glob expression
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1976
diff changeset
   322
            if p:
4b0535c678d6 make it possible to escape characters in a glob expression
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1976
diff changeset
   323
                i += 1
4b0535c678d6 make it possible to escape characters in a glob expression
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1976
diff changeset
   324
                res += re.escape(p)
4b0535c678d6 make it possible to escape characters in a glob expression
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1976
diff changeset
   325
            else:
4b0535c678d6 make it possible to escape characters in a glob expression
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1976
diff changeset
   326
                res += re.escape(c)
724
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   327
        else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   328
            res += re.escape(c)
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   329
    return head + res + tail
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
   330
812
b65af904d6d7 Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents: 782
diff changeset
   331
_globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
b65af904d6d7 Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents: 782
diff changeset
   332
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
   333
def pathto(root, n1, n2):
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
   334
    '''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
   335
    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
   336
    n1 should use os.sep to separate directories
48768b1ab23c fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3629
diff changeset
   337
    n2 should use "/" to separate directories
48768b1ab23c fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3629
diff changeset
   338
    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
   339
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
   340
    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
   341
    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
   342
    n2 should always be relative to root.
3669
48768b1ab23c fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3629
diff changeset
   343
    '''
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
   344
    if not n1: 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
   345
    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
   346
        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
   347
            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
   348
        n2 = '/'.join((pconvert(root), n2))
3669
48768b1ab23c fix util.pathto
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3629
diff changeset
   349
    a, b = n1.split(os.sep), n2.split('/')
1541
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
   350
    a.reverse()
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
   351
    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
   352
    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
   353
        a.pop()
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
   354
        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
   355
    b.reverse()
087771ebe2e6 Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents: 878
diff changeset
   356
    return os.sep.join((['..'] * len(a)) + b)
087771ebe2e6 Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents: 878
diff changeset
   357
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
   358
def canonpath(root, cwd, myname):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   359
    """return the canonical path of myname, given cwd and root"""
1566
8befbb4e30b2 Handle hg under /
Arun Sharma <arun@sharma-home.net>
parents: 1563
diff changeset
   360
    if root == os.sep:
8befbb4e30b2 Handle hg under /
Arun Sharma <arun@sharma-home.net>
parents: 1563
diff changeset
   361
        rootsep = os.sep
2271
90b122730d32 Make it possible to use the root directory as the root of a repository.
Manpreet Singh <junkblocker@yahoo.com>
parents: 2263
diff changeset
   362
    elif root.endswith(os.sep):
90b122730d32 Make it possible to use the root directory as the root of a repository.
Manpreet Singh <junkblocker@yahoo.com>
parents: 2263
diff changeset
   363
        rootsep = root
1566
8befbb4e30b2 Handle hg under /
Arun Sharma <arun@sharma-home.net>
parents: 1563
diff changeset
   364
    else:
1810
7596611ab3d5 Whitespace, tab and formatting cleanups, mainly in mq.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1635
diff changeset
   365
        rootsep = root + os.sep
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
   366
    name = myname
2090
eb40db373717 fix util.canonpath on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2085
diff changeset
   367
    if not os.path.isabs(name):
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
   368
        name = os.path.join(root, cwd, name)
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
   369
    name = os.path.normpath(name)
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   370
    audit_path = path_auditor(root)
2278
3711e23ab10a Make hg status work for repositories in root directory on windows (issue 228)
Manpreet Singh <junkblocker@yahoo.com>
parents: 2271
diff changeset
   371
    if name != rootsep and name.startswith(rootsep):
1976
df8416346bb7 Enable path validation for copy, rename, debugwalk and other canonpath users.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1958
diff changeset
   372
        name = name[len(rootsep):]
df8416346bb7 Enable path validation for copy, rename, debugwalk and other canonpath users.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1958
diff changeset
   373
        audit_path(name)
df8416346bb7 Enable path validation for copy, rename, debugwalk and other canonpath users.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1958
diff changeset
   374
        return pconvert(name)
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
   375
    elif name == root:
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
   376
        return ''
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
   377
    else:
2115
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   378
        # Determine whether `name' is in the hierarchy at or beneath `root',
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   379
        # by iterating name=dirname(name) until that causes no change (can't
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   380
        # check name == '/', because that doesn't work on windows).  For each
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   381
        # `name', compare dev/inode numbers.  If they match, the list `rel'
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   382
        # holds the reversed list of components making up the relative file
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   383
        # name we want.
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   384
        root_st = os.stat(root)
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   385
        rel = []
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   386
        while True:
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   387
            try:
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   388
                name_st = os.stat(name)
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   389
            except OSError:
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   390
                break
2193
fb28ce04b349 add util.samestat function for windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2177
diff changeset
   391
            if samestat(name_st, root_st):
4086
cc8a52229620 Fix accessing the repo through a symlink.
Jun Inoue <jun.lambda@gmail.com>
parents: 4067
diff changeset
   392
                if not rel:
cc8a52229620 Fix accessing the repo through a symlink.
Jun Inoue <jun.lambda@gmail.com>
parents: 4067
diff changeset
   393
                    # name was actually the same as root (maybe a symlink)
cc8a52229620 Fix accessing the repo through a symlink.
Jun Inoue <jun.lambda@gmail.com>
parents: 4067
diff changeset
   394
                    return ''
2115
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   395
                rel.reverse()
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   396
                name = os.path.join(*rel)
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   397
                audit_path(name)
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   398
                return pconvert(name)
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   399
            dirname, basename = os.path.split(name)
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   400
            rel.append(basename)
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   401
            if dirname == name:
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   402
                break
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   403
            name = dirname
fd77b7ee4aac Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
Jim Meyering <list+hg@meyering.net>
parents: 2096
diff changeset
   404
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
   405
        raise Abort('%s not under root' % myname)
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
   406
4197
492d0d5b6976 remove unused "head" hack from util._matcher
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4195
diff changeset
   407
def matcher(canonroot, cwd='', names=[], inc=[], exc=[], src=None):
492d0d5b6976 remove unused "head" hack from util._matcher
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4195
diff changeset
   408
    return _matcher(canonroot, cwd, names, inc, exc, 'glob', src)
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
   409
4197
492d0d5b6976 remove unused "head" hack from util._matcher
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4195
diff changeset
   410
def cmdmatcher(canonroot, cwd='', names=[], inc=[], exc=[], src=None,
492d0d5b6976 remove unused "head" hack from util._matcher
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4195
diff changeset
   411
               globbed=False, default=None):
4195
e8ee8fdeddb1 change locate to use relglobs by default
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4193
diff changeset
   412
    default = default or 'relpath'
e8ee8fdeddb1 change locate to use relglobs by default
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4193
diff changeset
   413
    if default == 'relpath' and not globbed:
4055
e37786b29bed docopy: deal with globs on windows in a better way
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4054
diff changeset
   414
        names = expand_glob(names)
4197
492d0d5b6976 remove unused "head" hack from util._matcher
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4195
diff changeset
   415
    return _matcher(canonroot, cwd, names, inc, exc, default, src)
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
   416
4197
492d0d5b6976 remove unused "head" hack from util._matcher
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4195
diff changeset
   417
def _matcher(canonroot, cwd, names, inc, exc, dflt_pat, src):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   418
    """build a function to match a set of file patterns
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   419
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   420
    arguments:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   421
    canonroot - the canonical root of the tree you're matching against
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   422
    cwd - the current working directory, if relevant
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   423
    names - patterns to find
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   424
    inc - patterns to include
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   425
    exc - patterns to exclude
4185
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   426
    dflt_pat - if a pattern in names has no explicit type, assume this one
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   427
    src - where these patterns came from (e.g. .hgignore)
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   428
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   429
    a pattern is one of:
4185
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   430
    'glob:<glob>' - a glob relative to cwd
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   431
    're:<regexp>' - a regular expression
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   432
    'path:<path>' - a path relative to canonroot
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   433
    'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   434
    'relpath:<path>' - a path relative to cwd
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   435
    'relre:<regexp>' - a regexp that doesn't have to match the start of a name
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   436
    '<something>' - one of the cases above, selected by the dflt_pat argument
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   437
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   438
    returns:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   439
    a 3-tuple containing
4185
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   440
    - list of roots (places where one should start a recursive walk of the fs);
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   441
      this often matches the explicit non-pattern names passed in, but also
51ee2868a571 util._matcher: update comments
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4183
diff changeset
   442
      includes the initial part of glob: patterns that has no glob characters
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   443
    - a bool match(filename) function
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   444
    - a bool indicating if any patterns were passed in
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   445
    """
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   446
4198
9e3121017fb2 Optimize return value of util._matcher for common command line case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4197
diff changeset
   447
    # a common case: no patterns at all
9e3121017fb2 Optimize return value of util._matcher for common command line case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4197
diff changeset
   448
    if not names and not inc and not exc:
9e3121017fb2 Optimize return value of util._matcher for common command line case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4197
diff changeset
   449
        return [], always, False
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   450
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
   451
    def contains_glob(name):
812
b65af904d6d7 Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents: 782
diff changeset
   452
        for c in name:
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
   453
            if c in _globchars: return True
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
   454
        return False
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   455
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
   456
    def regex(kind, name, tail):
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
   457
        '''convert a pattern into a regular expression'''
4190
769bc4af561d util.*matcher: change default "names" argument
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4189
diff changeset
   458
        if not name:
769bc4af561d util.*matcher: change default "names" argument
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4189
diff changeset
   459
            return ''
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   460
        if kind == 're':
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   461
            return name
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   462
        elif kind == 'path':
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
   463
            return '^' + re.escape(name) + '(?:/|$)'
1270
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
   464
        elif kind == 'relglob':
4307
702f48570eb3 change relglob: patterns to be consistent with glob: patterns
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4306
diff changeset
   465
            return globre(name, '(?:|.*/)', tail)
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
   466
        elif kind == 'relpath':
4197
492d0d5b6976 remove unused "head" hack from util._matcher
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4195
diff changeset
   467
            return re.escape(name) + '(?:/|$)'
1270
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
   468
        elif kind == 'relre':
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
   469
            if name.startswith('^'):
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
   470
                return name
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
   471
            return '.*' + name
4306
6cecaec07cc9 Revert changeset ef1f1a4b2efb; add another test for glob: patterns
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4255
diff changeset
   472
        return globre(name, '', tail)
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
   473
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
   474
    def matchfn(pats, tail):
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
   475
        """build a matching function from a set of patterns"""
1454
f4250806dbeb further fix traceback on invalid .hgignore patterns
Benoit Boissinot <mercurial-bugs@selenic.com>
parents: 1446
diff changeset
   476
        if not pats:
f4250806dbeb further fix traceback on invalid .hgignore patterns
Benoit Boissinot <mercurial-bugs@selenic.com>
parents: 1446
diff changeset
   477
            return
4371
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   478
        try:
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   479
            pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats])
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   480
            return re.compile(pat).match
5201
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   481
        except OverflowError:
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   482
            # We're using a Python with a tiny regex engine and we
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   483
            # made it explode, so we'll divide the pattern list in two
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   484
            # until it works
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   485
            l = len(pats)
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   486
            if l < 2:
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   487
                raise
5454
f2ca8d2c988f explicitely use integer division
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5450
diff changeset
   488
            a, b = matchfn(pats[:l//2], tail), matchfn(pats[l//2:], tail)
5201
0f6a1bdf89fb match: handle large regexes
Matt Mackall <mpm@selenic.com>
parents: 5077
diff changeset
   489
            return lambda s: a(s) or b(s)
4371
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   490
        except re.error:
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   491
            for k, p in pats:
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   492
                try:
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   493
                    re.compile('(?:%s)' % regex(k, p, tail))
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   494
                except re.error:
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   495
                    if src:
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   496
                        raise Abort("%s: invalid pattern (%s): %s" %
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   497
                                    (src, k, p))
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   498
                    else:
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   499
                        raise Abort("invalid pattern (%s): %s" % (k, p))
d7ad1e42a368 util._matcher: speed up regexp matching.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4338
diff changeset
   500
            raise Abort("invalid pattern")
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
   501
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   502
    def globprefix(pat):
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   503
        '''return the non-glob prefix of a path, e.g. foo/* -> foo'''
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   504
        root = []
4183
6f9474044736 small globprefix fix
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4129
diff changeset
   505
        for p in pat.split('/'):
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
   506
            if contains_glob(p): break
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   507
            root.append(p)
4187
01c4ea5e788c A 'glob:foo?bar' pattern determines a root - the tree root
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4185
diff changeset
   508
        return '/'.join(root) or '.'
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   509
4192
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   510
    def normalizepats(names, default):
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   511
        pats = []
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   512
        roots = []
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   513
        anypats = False
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   514
        for kind, name in [patkind(p, default) for p in names]:
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   515
            if kind in ('glob', 'relpath'):
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   516
                name = canonpath(canonroot, cwd, name)
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   517
            elif kind in ('relglob', 'path'):
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   518
                name = normpath(name)
4236
34c4540c04c5 util._matcher: remove superfluous variable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4233
diff changeset
   519
34c4540c04c5 util._matcher: remove superfluous variable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4233
diff changeset
   520
            pats.append((kind, name))
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   521
4192
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   522
            if kind in ('glob', 're', 'relglob', 'relre'):
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   523
                anypats = True
4236
34c4540c04c5 util._matcher: remove superfluous variable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4233
diff changeset
   524
4192
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   525
            if kind == 'glob':
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   526
                root = globprefix(name)
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   527
                roots.append(root)
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   528
            elif kind in ('relpath', 'path'):
4233
03a665f9f913 util._matcher: use "." as the root of empty {rel,}path patterns
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4199
diff changeset
   529
                roots.append(name or '.')
4192
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   530
            elif kind == 'relglob':
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   531
                roots.append('.')
4236
34c4540c04c5 util._matcher: remove superfluous variable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4233
diff changeset
   532
        return roots, pats, anypats
4192
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   533
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   534
    roots, pats, anypats = normalizepats(names, dflt_pat)
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
   535
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
   536
    patmatch = matchfn(pats, '$') or always
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
   537
    incmatch = always
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
   538
    if inc:
4192
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   539
        dummy, inckinds, dummy = normalizepats(inc, 'glob')
2480
519a1011db91 fix -I/-X when relative paths used or in subdir
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2471
diff changeset
   540
        incmatch = matchfn(inckinds, '(?:/|$)')
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
   541
    excmatch = lambda fn: False
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
   542
    if exc:
4192
9814d600011e util._matcher: unify pattern normalization
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4190
diff changeset
   543
        dummy, exckinds, dummy = normalizepats(exc, 'glob')
2480
519a1011db91 fix -I/-X when relative paths used or in subdir
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2471
diff changeset
   544
        excmatch = matchfn(exckinds, '(?:/|$)')
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
   545
4199
ec932167c3a7 Optimize return value of util._matcher for hgignore case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4198
diff changeset
   546
    if not names and inc and not exc:
ec932167c3a7 Optimize return value of util._matcher for hgignore case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4198
diff changeset
   547
        # common case: hgignore patterns
ec932167c3a7 Optimize return value of util._matcher for hgignore case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4198
diff changeset
   548
        match = incmatch
ec932167c3a7 Optimize return value of util._matcher for hgignore case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4198
diff changeset
   549
    else:
ec932167c3a7 Optimize return value of util._matcher for hgignore case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4198
diff changeset
   550
        match = lambda fn: incmatch(fn) and not excmatch(fn) and patmatch(fn)
ec932167c3a7 Optimize return value of util._matcher for hgignore case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4198
diff changeset
   551
ec932167c3a7 Optimize return value of util._matcher for hgignore case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4198
diff changeset
   552
    return (roots, match, (inc or exc or anypats) and True)
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
   553
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   554
_hgexecutable = None
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   555
6499
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   556
def main_is_frozen():
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   557
    """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
   558
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   559
    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
   560
    (portable, not much used).
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   561
    """
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   562
    return (hasattr(sys, "frozen") or # new py2exe
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   563
            hasattr(sys, "importers") or # old py2exe
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   564
            imp.is_frozen("__main__")) # tools/freeze
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   565
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   566
def hgexecutable():
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   567
    """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
   568
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   569
    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
   570
    """
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   571
    if _hgexecutable is None:
6500
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
   572
        hg = os.environ.get('HG')
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
   573
        if hg:
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
   574
            set_hgexecutable(hg)
6499
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   575
        elif main_is_frozen():
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   576
            set_hgexecutable(sys.executable)
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   577
        else:
6500
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
   578
            set_hgexecutable(find_exe('hg', 'hg'))
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   579
    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
   580
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
   581
def set_hgexecutable(path):
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   582
    """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
   583
    global _hgexecutable
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   584
    _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
   585
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   586
def system(cmd, environ={}, cwd=None, onerr=None, errprefix=None):
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   587
    '''enhanced shell command execution.
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   588
    run with environment maybe modified, maybe in different dir.
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
   589
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   590
    if command fails and onerr is None, return status.  if ui object,
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   591
    print error message and return status, else raise onerr object as
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   592
    exception.'''
2601
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   593
    def py2shell(val):
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   594
        'convert python object into string that is useful to shell'
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   595
        if val in (None, False):
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   596
            return '0'
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   597
        if val == True:
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   598
            return '1'
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   599
        return str(val)
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   600
    oldenv = {}
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   601
    for k in environ:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   602
        oldenv[k] = os.environ.get(k)
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   603
    if cwd is not None:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   604
        oldcwd = os.getcwd()
3905
a8c0365b2ace util.system: fix quoting on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3860
diff changeset
   605
    origcmd = cmd
a8c0365b2ace util.system: fix quoting on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3860
diff changeset
   606
    if os.name == 'nt':
a8c0365b2ace util.system: fix quoting on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3860
diff changeset
   607
        cmd = '"%s"' % cmd
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   608
    try:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   609
        for k, v in environ.iteritems():
2601
00fc88b0b256 move most of tag code to localrepository class.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
   610
            os.environ[k] = py2shell(v)
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   611
        os.environ['HG'] = hgexecutable()
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   612
        if cwd is not None and oldcwd != cwd:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   613
            os.chdir(cwd)
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   614
        rc = os.system(cmd)
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
   615
        if sys.platform == 'OpenVMS' and rc & 1:
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
   616
            rc = 0
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   617
        if rc and onerr:
3905
a8c0365b2ace util.system: fix quoting on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3860
diff changeset
   618
            errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]),
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   619
                                explain_exit(rc)[0])
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   620
            if errprefix:
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   621
                errmsg = '%s: %s' % (errprefix, errmsg)
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   622
            try:
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   623
                onerr.warn(errmsg + '\n')
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   624
            except AttributeError:
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   625
                raise onerr(errmsg)
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   626
        return rc
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   627
    finally:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   628
        for k, v in oldenv.iteritems():
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   629
            if v is None:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   630
                del os.environ[k]
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   631
            else:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   632
                os.environ[k] = v
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   633
        if cwd is not None and oldcwd != cwd:
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   634
            os.chdir(oldcwd)
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   635
4281
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   636
# os.path.lexists is not available on python2.3
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   637
def lexists(filename):
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   638
    "test whether a file with this name exists. does not follow symlinks"
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   639
    try:
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   640
        os.lstat(filename)
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   641
    except:
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   642
        return False
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   643
    return True
384672d8080f add util.lexists
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4275
diff changeset
   644
421
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
   645
def rename(src, dst):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   646
    """forcibly rename a file"""
421
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
   647
    try:
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
   648
        os.rename(src, dst)
4956
02b127749dc0 fix unused variables reported by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 4948
diff changeset
   649
    except OSError, err: # FIXME: check err (EEXIST ?)
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   650
        # on windows, rename to existing file is not allowed, so we
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   651
        # must delete destination first. but if file is open, unlink
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   652
        # schedules it for delete but does not delete it. rename
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   653
        # happens immediately even for open files, so we create
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   654
        # temporary file, delete it, rename destination to that name,
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   655
        # then delete that. then rename is safe to do.
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   656
        fd, temp = tempfile.mkstemp(dir=os.path.dirname(dst) or '.')
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   657
        os.close(fd)
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   658
        os.unlink(temp)
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   659
        os.rename(dst, temp)
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   660
        os.unlink(temp)
421
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
   661
        os.rename(src, dst)
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
   662
1415
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
   663
def unlink(f):
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
   664
    """unlink and remove the directory if it is empty"""
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
   665
    os.unlink(f)
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
   666
    # try removing directories that might now be empty
2064
547ede0123a2 util.unlink should only catch OSError.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2054
diff changeset
   667
    try:
547ede0123a2 util.unlink should only catch OSError.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2054
diff changeset
   668
        os.removedirs(os.path.dirname(f))
547ede0123a2 util.unlink should only catch OSError.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2054
diff changeset
   669
    except OSError:
547ede0123a2 util.unlink should only catch OSError.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2054
diff changeset
   670
        pass
1415
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
   671
3629
4cfb72bcb978 util: add copyfile function
Matt Mackall <mpm@selenic.com>
parents: 3568
diff changeset
   672
def copyfile(src, dest):
4cfb72bcb978 util: add copyfile function
Matt Mackall <mpm@selenic.com>
parents: 3568
diff changeset
   673
    "copy a file, preserving mode"
4271
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   674
    if os.path.islink(src):
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   675
        try:
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   676
            os.unlink(dest)
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   677
        except:
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   678
            pass
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   679
        os.symlink(os.readlink(src), dest)
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   680
    else:
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   681
        try:
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   682
            shutil.copyfile(src, dest)
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   683
            shutil.copymode(src, dest)
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   684
        except shutil.Error, inst:
1eaa8d90c689 fix util.copyfile to deal with symlinks
Eric St-Jean <esj@wwd.ca>
parents: 4256
diff changeset
   685
            raise Abort(str(inst))
3629
4cfb72bcb978 util: add copyfile function
Matt Mackall <mpm@selenic.com>
parents: 3568
diff changeset
   686
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   687
def copyfiles(src, dst, hardlink=None):
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   688
    """Copy a directory tree using hardlinks if possible"""
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   689
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   690
    if hardlink is None:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   691
        hardlink = (os.stat(src).st_dev ==
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   692
                    os.stat(os.path.dirname(dst)).st_dev)
698
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
   693
1207
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
   694
    if os.path.isdir(src):
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
   695
        os.mkdir(dst)
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5360
diff changeset
   696
        for name, kind in osutil.listdir(src):
1207
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
   697
            srcname = os.path.join(src, name)
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
   698
            dstname = os.path.join(dst, name)
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   699
            copyfiles(srcname, dstname, hardlink)
1207
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
   700
    else:
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   701
        if hardlink:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   702
            try:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   703
                os_link(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
   704
            except (IOError, OSError):
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   705
                hardlink = False
1591
5a3229cf1492 do not copy atime and mtime in util.copyfiles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
   706
                shutil.copy(src, dst)
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   707
        else:
1591
5a3229cf1492 do not copy atime and mtime in util.copyfiles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
   708
            shutil.copy(src, dst)
698
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
   709
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   710
class path_auditor(object):
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   711
    '''ensure that a filesystem path contains no banned components.
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   712
    the following properties of a path are checked:
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   713
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   714
    - under top-level .hg
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   715
    - starts at the root of a windows drive
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   716
    - contains ".."
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   717
    - traverses a symlink (e.g. a/symlink_here/b)
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   718
    - inside a nested repository'''
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   719
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   720
    def __init__(self, root):
5200
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   721
        self.audited = set()
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   722
        self.auditeddir = set()
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   723
        self.root = root
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   724
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   725
    def __call__(self, path):
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   726
        if path in self.audited:
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   727
            return
5159
d84329a11fdd Make a few portability improvements to path auditing code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5158
diff changeset
   728
        normpath = os.path.normcase(path)
d84329a11fdd Make a few portability improvements to path auditing code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5158
diff changeset
   729
        parts = normpath.split(os.sep)
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   730
        if (os.path.splitdrive(path)[0] or parts[0] in ('.hg', '')
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   731
            or os.pardir in parts):
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   732
            raise Abort(_("path contains illegal component: %s") % path)
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   733
        def check(prefix):
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   734
            curpath = os.path.join(self.root, prefix)
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   735
            try:
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   736
                st = os.lstat(curpath)
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   737
            except OSError, err:
5162
9374373fb727 util: ignore invalid path errors in path_auditor.
Patrick Mezard <pmezard@gmail.com>
parents: 5159
diff changeset
   738
                # EINVAL can be raised as invalid path syntax under win32.
9374373fb727 util: ignore invalid path errors in path_auditor.
Patrick Mezard <pmezard@gmail.com>
parents: 5159
diff changeset
   739
                # They must be ignored for patterns can be checked too.
5487
7a64931e2d76 Fix file-changed-to-dir and dir-to-file commits (issue660).
Maxim Dounin <mdounin@mdounin.ru>
parents: 5481
diff changeset
   740
                if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   741
                    raise
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   742
            else:
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   743
                if stat.S_ISLNK(st.st_mode):
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   744
                    raise Abort(_('path %r traverses symbolic link %r') %
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   745
                                (path, prefix))
5159
d84329a11fdd Make a few portability improvements to path auditing code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5158
diff changeset
   746
                elif (stat.S_ISDIR(st.st_mode) and
d84329a11fdd Make a few portability improvements to path auditing code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5158
diff changeset
   747
                      os.path.isdir(os.path.join(curpath, '.hg'))):
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   748
                    raise Abort(_('path %r is inside repo %r') %
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
   749
                                (path, prefix))
5200
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   750
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   751
        prefixes = []
5159
d84329a11fdd Make a few portability improvements to path auditing code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5158
diff changeset
   752
        for c in strutil.rfindall(normpath, os.sep):
5200
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   753
            prefix = normpath[:c]
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   754
            if prefix in self.auditeddir:
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   755
                break
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   756
            check(prefix)
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   757
            prefixes.append(prefix)
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   758
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   759
        self.audited.add(path)
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   760
        # only add prefixes to the cache after checking everything: we don't
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   761
        # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
c7e8fe11f34a path_auditor: cache names of audited directories
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5162
diff changeset
   762
        self.auditeddir.update(prefixes)
1835
bdfb524d728a Validate paths before reading or writing files in repository or working dir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1830
diff changeset
   763
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
   764
def _makelock_file(info, pathname):
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
   765
    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
   766
    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
   767
    os.close(ld)
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
   768
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
   769
def _readlock_file(pathname):
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   770
    return posixfile(pathname).read()
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
   771
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   772
def nlinks(pathname):
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   773
    """Return number of hardlinks for the given file."""
2448
b77a2ef61b81 replace os.stat with os.lstat in some where.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2314
diff changeset
   774
    return os.lstat(pathname).st_nlink
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   775
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   776
if hasattr(os, 'link'):
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   777
    os_link = os.link
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   778
else:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   779
    def os_link(src, dst):
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
   780
        raise OSError(0, _("Hardlinks not supported"))
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
   781
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   782
def fstat(fp):
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   783
    '''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
   784
    try:
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   785
        return os.fstat(fp.fileno())
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   786
    except AttributeError:
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   787
        return os.stat(fp.name)
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   788
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   789
posixfile = file
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
   790
5659
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   791
def openhardlinks():
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   792
    '''return true if it is safe to hold open file handles to hardlinks'''
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   793
    return True
2250
45aef5ddcdbe windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2237
diff changeset
   794
3721
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   795
getuser_fallback = None
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   796
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   797
def getuser():
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   798
    '''return name of current user'''
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   799
    try:
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   800
        return getpass.getuser()
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   801
    except ImportError:
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   802
        # import of pwd will fail on windows - try fallback
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   803
        if getuser_fallback:
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   804
            return getuser_fallback()
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   805
    # raised if win32api not available
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   806
    raise Abort(_('user name not available - set USERNAME '
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   807
                  'environment variable'))
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3677
diff changeset
   808
3551
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   809
def username(uid=None):
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   810
    """Return the name of the user with the given uid.
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   811
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   812
    If uid is None, return the name of the current user."""
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   813
    try:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   814
        import pwd
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   815
        if uid is None:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   816
            uid = os.getuid()
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   817
        try:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   818
            return pwd.getpwuid(uid)[0]
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   819
        except KeyError:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   820
            return str(uid)
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   821
    except ImportError:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   822
        return None
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   823
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   824
def groupname(gid=None):
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   825
    """Return the name of the group with the given gid.
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   826
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   827
    If gid is None, return the name of the current group."""
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   828
    try:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   829
        import grp
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   830
        if gid is None:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   831
            gid = os.getgid()
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   832
        try:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   833
            return grp.getgrgid(gid)[0]
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   834
        except KeyError:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   835
            return str(gid)
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   836
    except ImportError:
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   837
        return None
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3466
diff changeset
   838
3784
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   839
# File system features
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   840
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   841
def checkfolding(path):
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   842
    """
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   843
    Check whether the given path is on a case-sensitive filesystem
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   844
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   845
    Requires a path (like /foo/.hg) ending with a foldable final
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   846
    directory component.
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   847
    """
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   848
    s1 = os.stat(path)
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   849
    d, b = os.path.split(path)
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   850
    p2 = os.path.join(d, b.upper())
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   851
    if path == p2:
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   852
        p2 = os.path.join(d, b.lower())
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   853
    try:
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   854
        s2 = os.stat(p2)
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   855
        if s2 == s1:
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   856
            return False
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   857
        return True
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   858
    except:
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   859
        return True
1427949b8f80 imported patch folding
Matt Mackall <mpm@selenic.com>
parents: 3770
diff changeset
   860
3994
1cc60eebc71f exec: checkexec checks whether filesystem supports exec flags
Matt Mackall <mpm@selenic.com>
parents: 3906
diff changeset
   861
def checkexec(path):
1cc60eebc71f exec: checkexec checks whether filesystem supports exec flags
Matt Mackall <mpm@selenic.com>
parents: 3906
diff changeset
   862
    """
1cc60eebc71f exec: checkexec checks whether filesystem supports exec flags
Matt Mackall <mpm@selenic.com>
parents: 3906
diff changeset
   863
    Check whether the given path is on a filesystem with UNIX-like exec flags
1cc60eebc71f exec: checkexec checks whether filesystem supports exec flags
Matt Mackall <mpm@selenic.com>
parents: 3906
diff changeset
   864
1cc60eebc71f exec: checkexec checks whether filesystem supports exec flags
Matt Mackall <mpm@selenic.com>
parents: 3906
diff changeset
   865
    Requires a directory (like /foo/.hg)
1cc60eebc71f exec: checkexec checks whether filesystem supports exec flags
Matt Mackall <mpm@selenic.com>
parents: 3906
diff changeset
   866
    """
5212
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   867
    try:
5420
6d1bd20ae14d Execution bit detection fixes for VFAT on Linux
Rafael Villar Burke <pachi@rvburke.com>
parents: 5396
diff changeset
   868
        EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
5212
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   869
        fh, fn = tempfile.mkstemp("", "", path)
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   870
        os.close(fh)
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   871
        m = os.stat(fn).st_mode
5420
6d1bd20ae14d Execution bit detection fixes for VFAT on Linux
Rafael Villar Burke <pachi@rvburke.com>
parents: 5396
diff changeset
   872
        # VFAT on Linux can flip mode but it doesn't persist a FS remount.
6d1bd20ae14d Execution bit detection fixes for VFAT on Linux
Rafael Villar Burke <pachi@rvburke.com>
parents: 5396
diff changeset
   873
        # frequently we can detect it if files are created with exec bit on.
6d1bd20ae14d Execution bit detection fixes for VFAT on Linux
Rafael Villar Burke <pachi@rvburke.com>
parents: 5396
diff changeset
   874
        new_file_has_exec = m & EXECFLAGS
6d1bd20ae14d Execution bit detection fixes for VFAT on Linux
Rafael Villar Burke <pachi@rvburke.com>
parents: 5396
diff changeset
   875
        os.chmod(fn, m ^ EXECFLAGS)
6d1bd20ae14d Execution bit detection fixes for VFAT on Linux
Rafael Villar Burke <pachi@rvburke.com>
parents: 5396
diff changeset
   876
        exec_flags_cannot_flip = (os.stat(fn).st_mode == m)
5212
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   877
        os.unlink(fn)
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   878
    except (IOError,OSError):
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   879
        # we don't care, the user probably won't be able to commit anyway
316ce5e85b3e check exec: return fallback in case of error during the check
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5077
diff changeset
   880
        return False
5420
6d1bd20ae14d Execution bit detection fixes for VFAT on Linux
Rafael Villar Burke <pachi@rvburke.com>
parents: 5396
diff changeset
   881
    return not (new_file_has_exec or exec_flags_cannot_flip)
3994
1cc60eebc71f exec: checkexec checks whether filesystem supports exec flags
Matt Mackall <mpm@selenic.com>
parents: 3906
diff changeset
   882
3996
c190df14338c exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents: 3995
diff changeset
   883
def execfunc(path, fallback):
c190df14338c exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents: 3995
diff changeset
   884
    '''return an is_exec() function with default to fallback'''
c190df14338c exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents: 3995
diff changeset
   885
    if checkexec(path):
3997
3f0ba82c103f exec: remove last flag from is_exec
Matt Mackall <mpm@selenic.com>
parents: 3996
diff changeset
   886
        return lambda x: is_exec(os.path.join(path, x))
3996
c190df14338c exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents: 3995
diff changeset
   887
    return fallback
c190df14338c exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents: 3995
diff changeset
   888
4002
d7b9ec589546 symlinks: use is_link wherever is_exec is used
Matt Mackall <mpm@selenic.com>
parents: 4000
diff changeset
   889
def checklink(path):
3998
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   890
    """check whether the given path is on a symlink-capable filesystem"""
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   891
    # mktemp is not racy because symlink creation will fail if the
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   892
    # file already exists
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   893
    name = tempfile.mktemp(dir=path)
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   894
    try:
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   895
        os.symlink(".", name)
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   896
        os.unlink(name)
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   897
        return True
4017
ea6174c96ae1 catch AttributeError in util.checklink
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4002
diff changeset
   898
    except (OSError, AttributeError):
3998
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   899
        return False
315d47991fd4 symlinks: check whether a filesystem supports symlinks
Matt Mackall <mpm@selenic.com>
parents: 3997
diff changeset
   900
4000
3297aa945cf2 symlinks: add a linkfunc
Matt Mackall <mpm@selenic.com>
parents: 3999
diff changeset
   901
def linkfunc(path, fallback):
3297aa945cf2 symlinks: add a linkfunc
Matt Mackall <mpm@selenic.com>
parents: 3999
diff changeset
   902
    '''return an is_link() function with default to fallback'''
3297aa945cf2 symlinks: add a linkfunc
Matt Mackall <mpm@selenic.com>
parents: 3999
diff changeset
   903
    if checklink(path):
4275
81402b2b294d use os.path.islink instead of util.is_link; remove util.is_link
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4271
diff changeset
   904
        return lambda x: os.path.islink(os.path.join(path, x))
4000
3297aa945cf2 symlinks: add a linkfunc
Matt Mackall <mpm@selenic.com>
parents: 3999
diff changeset
   905
    return fallback
3297aa945cf2 symlinks: add a linkfunc
Matt Mackall <mpm@selenic.com>
parents: 3999
diff changeset
   906
4327
aba90193f4e4 cache os.umask even on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4326
diff changeset
   907
_umask = os.umask(0)
aba90193f4e4 cache os.umask even on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4326
diff changeset
   908
os.umask(_umask)
aba90193f4e4 cache os.umask even on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4326
diff changeset
   909
4434
439b1c35348a Fix issue483 - mq does not work under windows with gnu-win32 patch.
Patrick Mezard <pmezard@gmail.com>
parents: 4407
diff changeset
   910
def needbinarypatch():
439b1c35348a Fix issue483 - mq does not work under windows with gnu-win32 patch.
Patrick Mezard <pmezard@gmail.com>
parents: 4407
diff changeset
   911
    """return True if patches should be applied in binary mode by default."""
439b1c35348a Fix issue483 - mq does not work under windows with gnu-win32 patch.
Patrick Mezard <pmezard@gmail.com>
parents: 4407
diff changeset
   912
    return os.name == 'nt'
439b1c35348a Fix issue483 - mq does not work under windows with gnu-win32 patch.
Patrick Mezard <pmezard@gmail.com>
parents: 4407
diff changeset
   913
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
   914
# Platform specific variants
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
   915
if os.name == 'nt':
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3860
diff changeset
   916
    import msvcrt
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
   917
    nulldev = 'NUL:'
1609
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   918
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   919
    class winstdout:
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   920
        '''stdout on windows misbehaves if sent through a pipe'''
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   921
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   922
        def __init__(self, fp):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   923
            self.fp = fp
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   924
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   925
        def __getattr__(self, key):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   926
            return getattr(self.fp, key)
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   927
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   928
        def close(self):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   929
            try:
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   930
                self.fp.close()
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   931
            except: pass
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   932
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   933
        def write(self, s):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   934
            try:
5647
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   935
                # This is workaround for "Not enough space" error on
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   936
                # writing large size of data to console.
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   937
                limit = 16000
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   938
                l = len(s)
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   939
                start = 0
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   940
                while start < l:
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   941
                    end = start + limit
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   942
                    self.fp.write(s[start:end])
165cda754d9e Workaround for "Not enough space" error due to the bug of Windows.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5646
diff changeset
   943
                    start = end
1609
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   944
            except IOError, inst:
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   945
                if inst.errno != 0: raise
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   946
                self.close()
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   947
                raise IOError(errno.EPIPE, 'Broken pipe')
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4508
diff changeset
   948
4129
e817c68edfed stdout raises EINVAL when flush() is called on a closed pipe under win32.
Patrick Mezard <pmezard@gmail.com>
parents: 4087
diff changeset
   949
        def flush(self):
e817c68edfed stdout raises EINVAL when flush() is called on a closed pipe under win32.
Patrick Mezard <pmezard@gmail.com>
parents: 4087
diff changeset
   950
            try:
e817c68edfed stdout raises EINVAL when flush() is called on a closed pipe under win32.
Patrick Mezard <pmezard@gmail.com>
parents: 4087
diff changeset
   951
                return self.fp.flush()
e817c68edfed stdout raises EINVAL when flush() is called on a closed pipe under win32.
Patrick Mezard <pmezard@gmail.com>
parents: 4087
diff changeset
   952
            except IOError, inst:
e817c68edfed stdout raises EINVAL when flush() is called on a closed pipe under win32.
Patrick Mezard <pmezard@gmail.com>
parents: 4087
diff changeset
   953
                if inst.errno != errno.EINVAL: raise
e817c68edfed stdout raises EINVAL when flush() is called on a closed pipe under win32.
Patrick Mezard <pmezard@gmail.com>
parents: 4087
diff changeset
   954
                self.close()
e817c68edfed stdout raises EINVAL when flush() is called on a closed pipe under win32.
Patrick Mezard <pmezard@gmail.com>
parents: 4087
diff changeset
   955
                raise IOError(errno.EPIPE, 'Broken pipe')
1609
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   956
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   957
    sys.stdout = winstdout(sys.stdout)
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
   958
5659
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   959
    def _is_win_9x():
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   960
        '''return true if run on windows 95, 98 or me.'''
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   961
        try:
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   962
            return sys.getwindowsversion()[3] == 1
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   963
        except AttributeError:
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   964
            return 'command' in os.environ.get('comspec', '')
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   965
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   966
    def openhardlinks():
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   967
        return not _is_win_9x and "win32api" in locals()
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
   968
2054
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
   969
    def system_rcpath():
2117
760339ccc799 fix issue 217.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2115
diff changeset
   970
        try:
760339ccc799 fix issue 217.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2115
diff changeset
   971
            return system_rcpath_win32()
760339ccc799 fix issue 217.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2115
diff changeset
   972
        except:
760339ccc799 fix issue 217.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2115
diff changeset
   973
            return [r'c:\mercurial\mercurial.ini']
2054
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
   974
4083
33c369afec94 Unified *_rcpath so the interface is similar across operating systems
Shane Holloway <shane.holloway@ieee.org>
parents: 4069
diff changeset
   975
    def user_rcpath():
33c369afec94 Unified *_rcpath so the interface is similar across operating systems
Shane Holloway <shane.holloway@ieee.org>
parents: 4069
diff changeset
   976
        '''return os-specific hgrc search path to the user dir'''
4098
c08b6af023bc util_win32.py: fix user_rcpath
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4097
diff changeset
   977
        try:
c08b6af023bc util_win32.py: fix user_rcpath
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4097
diff changeset
   978
            userrc = user_rcpath_win32()
c08b6af023bc util_win32.py: fix user_rcpath
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4097
diff changeset
   979
        except:
c08b6af023bc util_win32.py: fix user_rcpath
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4097
diff changeset
   980
            userrc = os.path.join(os.path.expanduser('~'), 'mercurial.ini')
c08b6af023bc util_win32.py: fix user_rcpath
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4097
diff changeset
   981
        path = [userrc]
2280
09ed44225571 On Windows look for mercurial.ini in $USERPROFILE, too, if available
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2278
diff changeset
   982
        userprofile = os.environ.get('USERPROFILE')
09ed44225571 On Windows look for mercurial.ini in $USERPROFILE, too, if available
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2278
diff changeset
   983
        if userprofile:
09ed44225571 On Windows look for mercurial.ini in $USERPROFILE, too, if available
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2278
diff changeset
   984
            path.append(os.path.join(userprofile, 'mercurial.ini'))
09ed44225571 On Windows look for mercurial.ini in $USERPROFILE, too, if available
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2278
diff changeset
   985
        return path
1292
141951276ba1 Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1285
diff changeset
   986
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
   987
    def parse_patch_output(output_line):
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
   988
        """parses the output produced by patch and returns the file name"""
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
   989
        pf = output_line[14:]
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
   990
        if pf[0] == '`':
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
   991
            pf = pf[1:-1] # Remove the quotes
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
   992
        return pf
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
   993
5644
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
   994
    def sshargs(sshcmd, host, user, port):
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
   995
        '''Build argument list for ssh or Plink'''
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
   996
        pflag = 'plink' in sshcmd.lower() and '-P' or '-p'
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
   997
        args = user and ("%s@%s" % (user, host)) or host
5646
c722bd73c948 fix typo in sshargs
Steve Borho <steve@borho.org>
parents: 5644
diff changeset
   998
        return port and ("%s %s %s" % (args, pflag, port)) or args
5644
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
   999
2054
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1000
    def testpid(pid):
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1001
        '''return False if pid dead, True if running or not known'''
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1002
        return True
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
  1003
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1004
    def set_exec(f, mode):
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1005
        pass
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1006
3999
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1007
    def set_link(f, mode):
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1008
        pass
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 508
diff changeset
  1009
1420
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
  1010
    def set_binary(fd):
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
  1011
        msvcrt.setmode(fd.fileno(), os.O_BINARY)
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
  1012
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
  1013
    def pconvert(path):
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
  1014
        return path.replace("\\", "/")
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
  1015
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1016
    def localpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1017
        return path.replace('/', '\\')
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1018
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1019
    def normpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1020
        return pconvert(os.path.normpath(path))
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1021
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1022
    makelock = _makelock_file
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1023
    readlock = _readlock_file
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
  1024
2193
fb28ce04b349 add util.samestat function for windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2177
diff changeset
  1025
    def samestat(s1, s2):
fb28ce04b349 add util.samestat function for windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2177
diff changeset
  1026
        return False
fb28ce04b349 add util.samestat function for windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2177
diff changeset
  1027
4087
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1028
    # A sequence of backslashes is special iff it precedes a double quote:
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1029
    # - if there's an even number of backslashes, the double quote is not
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1030
    #   quoted (i.e. it ends the quoted region)
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1031
    # - if there's an odd number of backslashes, the double quote is quoted
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1032
    # - in both cases, every pair of backslashes is unquoted into a single
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1033
    #   backslash
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1034
    # (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx )
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1035
    # So, to quote a string, we must surround it in double quotes, double
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1036
    # the number of backslashes that preceed double quotes and add another
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1037
    # backslash before every double quote (being careful with the double
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1038
    # quote we've appended to the end)
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1039
    _quotere = None
2791
f4d916351366 Add portable shell-quoting function; teach mq to use it.
Brendan Cully <brendan@kublai.com>
parents: 2760
diff changeset
  1040
    def shellquote(s):
4087
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1041
        global _quotere
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1042
        if _quotere is None:
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1043
            _quotere = re.compile(r'(\\*)("|\\$)')
587c6c652f82 Fix util.shellquote on windows.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4086
diff changeset
  1044
        return '"%s"' % _quotere.sub(r'\1\1\\\2', s)
2791
f4d916351366 Add portable shell-quoting function; teach mq to use it.
Brendan Cully <brendan@kublai.com>
parents: 2760
diff changeset
  1045
5292
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1046
    def quotecommand(cmd):
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1047
        """Build a command string suitable for os.popen* calls."""
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1048
        # The extra quotes are needed because popen* runs the command
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1049
        # through the current COMSPEC. cmd.exe suppress enclosing quotes.
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1050
        return '"' + cmd + '"'
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1051
5481
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1052
    def popen(command):
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1053
        # Work around "popen spawned process may not write to stdout
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1054
        # under windows"
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1055
        # http://bugs.python.org/issue1366
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1056
        command += " 2> %s" % nulldev
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1057
        return os.popen(quotecommand(command))
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1058
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1059
    def explain_exit(code):
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
  1060
        return _("exited with status %d") % code, code
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1061
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1062
    # if you change this stub into a real check, please try to implement the
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1063
    # username and groupname functions above, too.
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1064
    def isowner(fp, st=None):
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1065
        return True
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4508
diff changeset
  1066
4407
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1067
    def find_in_path(name, path, default=None):
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1068
        '''find name in search path. path can be string (will be split
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1069
        with os.pathsep), or iterable thing that returns strings.  if name
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1070
        found, return path to name. else return default. name is looked up
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1071
        using cmd.exe rules, using PATHEXT.'''
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1072
        if isinstance(path, str):
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1073
            path = path.split(os.pathsep)
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4508
diff changeset
  1074
4407
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1075
        pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1076
        pathext = pathext.lower().split(os.pathsep)
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1077
        isexec = os.path.splitext(name)[1].lower() in pathext
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4508
diff changeset
  1078
4407
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1079
        for p in path:
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1080
            p_name = os.path.join(p, name)
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4508
diff changeset
  1081
4407
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1082
            if isexec and os.path.exists(p_name):
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1083
                return p_name
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4508
diff changeset
  1084
4407
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1085
            for ext in pathext:
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1086
                p_name_ext = p_name + ext
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1087
                if os.path.exists(p_name_ext):
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1088
                    return p_name_ext
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1089
        return default
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1090
4803
7549cd526b7f Fix serve on Windows without win32* modules.
Nathan Jones <nathanj@insightbb.com>
parents: 4720
diff changeset
  1091
    def set_signal_handler():
7549cd526b7f Fix serve on Windows without win32* modules.
Nathan Jones <nathanj@insightbb.com>
parents: 4720
diff changeset
  1092
        try:
7549cd526b7f Fix serve on Windows without win32* modules.
Nathan Jones <nathanj@insightbb.com>
parents: 4720
diff changeset
  1093
            set_signal_handler_win32()
7549cd526b7f Fix serve on Windows without win32* modules.
Nathan Jones <nathanj@insightbb.com>
parents: 4720
diff changeset
  1094
        except NameError:
7549cd526b7f Fix serve on Windows without win32* modules.
Nathan Jones <nathanj@insightbb.com>
parents: 4720
diff changeset
  1095
            pass
7549cd526b7f Fix serve on Windows without win32* modules.
Nathan Jones <nathanj@insightbb.com>
parents: 4720
diff changeset
  1096
2054
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1097
    try:
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1098
        # override functions with win32 versions if possible
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1099
        from util_win32 import *
5659
3da652f2039c util: get rid of is_win_9x wart
Matt Mackall <mpm@selenic.com>
parents: 5647
diff changeset
  1100
        if not _is_win_9x():
2250
45aef5ddcdbe windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2237
diff changeset
  1101
            posixfile = posixfile_nt
2054
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1102
    except ImportError:
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1103
        pass
e18beba54a7e fix exception handling on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2050
diff changeset
  1104
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
  1105
else:
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
  1106
    nulldev = '/dev/null'
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
  1107
1583
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
  1108
    def rcfiles(path):
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
  1109
        rcs = [os.path.join(path, 'hgrc')]
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
  1110
        rcdir = os.path.join(path, 'hgrc.d')
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
  1111
        try:
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5360
diff changeset
  1112
            rcs.extend([os.path.join(rcdir, f)
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5360
diff changeset
  1113
                        for f, kind in osutil.listdir(rcdir)
1583
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
  1114
                        if f.endswith(".rc")])
3131
cff3c58a5766 fix warnings spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3098
diff changeset
  1115
        except OSError:
cff3c58a5766 fix warnings spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3098
diff changeset
  1116
            pass
1583
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
  1117
        return rcs
1951
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1118
4083
33c369afec94 Unified *_rcpath so the interface is similar across operating systems
Shane Holloway <shane.holloway@ieee.org>
parents: 4069
diff changeset
  1119
    def system_rcpath():
1951
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1120
        path = []
2263
2f64cbaa1e92 make reason for sys.argv change obvious in code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2262
diff changeset
  1121
        # old mod_python does not set sys.argv
2261
20cf545b4725 Check existance of sys.argv for the use from mod_python.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 2237
diff changeset
  1122
        if len(getattr(sys, 'argv', [])) > 0:
1951
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1123
            path.extend(rcfiles(os.path.dirname(sys.argv[0]) +
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1124
                                  '/../etc/mercurial'))
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1125
        path.extend(rcfiles('/etc/mercurial'))
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1126
        return path
1292
141951276ba1 Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1285
diff changeset
  1127
4083
33c369afec94 Unified *_rcpath so the interface is similar across operating systems
Shane Holloway <shane.holloway@ieee.org>
parents: 4069
diff changeset
  1128
    def user_rcpath():
33c369afec94 Unified *_rcpath so the interface is similar across operating systems
Shane Holloway <shane.holloway@ieee.org>
parents: 4069
diff changeset
  1129
        return [os.path.expanduser('~/.hgrc')]
33c369afec94 Unified *_rcpath so the interface is similar across operating systems
Shane Holloway <shane.holloway@ieee.org>
parents: 4069
diff changeset
  1130
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
  1131
    def parse_patch_output(output_line):
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
  1132
        """parses the output produced by patch and returns the file name"""
1593
6bb3463b124b if a filename contains spaces, patch adds quote around it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
  1133
        pf = output_line[14:]
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1134
        if os.sys.platform == 'OpenVMS':
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1135
            if pf[0] == '`':
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1136
                pf = pf[1:-1] # Remove the quotes
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1137
        else:
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1138
           if pf.startswith("'") and pf.endswith("'") and " " in pf:
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1139
                pf = pf[1:-1] # Remove the quotes
1593
6bb3463b124b if a filename contains spaces, patch adds quote around it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
  1140
        return pf
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
  1141
5644
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
  1142
    def sshargs(sshcmd, host, user, port):
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
  1143
        '''Build argument list for ssh'''
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
  1144
        args = user and ("%s@%s" % (user, host)) or host
5646
c722bd73c948 fix typo in sshargs
Steve Borho <steve@borho.org>
parents: 5644
diff changeset
  1145
        return port and ("%s -p %s" % (args, port)) or args
5644
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5525
diff changeset
  1146
3997
3f0ba82c103f exec: remove last flag from is_exec
Matt Mackall <mpm@selenic.com>
parents: 3996
diff changeset
  1147
    def is_exec(f):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
  1148
        """check whether a file is executable"""
2448
b77a2ef61b81 replace os.stat with os.lstat in some where.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2314
diff changeset
  1149
        return (os.lstat(f).st_mode & 0100 != 0)
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1150
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1151
    def set_exec(f, mode):
2448
b77a2ef61b81 replace os.stat with os.lstat in some where.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2314
diff changeset
  1152
        s = os.lstat(f).st_mode
5347
1df76921aab3 set_exec: do not chmod a symlink
Steve Borho <steve@ageia.com>
parents: 5292
diff changeset
  1153
        if stat.S_ISLNK(s) or (s & 0100 != 0) == mode:
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1154
            return
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1155
        if mode:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1156
            # Turn on +x for every +r bit when making a file executable
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1157
            # and obey umask.
4326
5e3936eabe5d pull umask-checking up
Matt Mackall <mpm@selenic.com>
parents: 4230
diff changeset
  1158
            os.chmod(f, s | (s & 0444) >> 2 & ~_umask)
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1159
        else:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1160
            os.chmod(f, s & 0666)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
  1161
3999
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1162
    def set_link(f, mode):
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1163
        """make a file a symbolic link/regular file
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1164
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1165
        if a file is changed to a link, its contents become the link data
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1166
        if a link is changed to a file, its link data become its contents
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1167
        """
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1168
4275
81402b2b294d use os.path.islink instead of util.is_link; remove util.is_link
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4271
diff changeset
  1169
        m = os.path.islink(f)
3999
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1170
        if m == bool(mode):
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1171
            return
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1172
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1173
        if mode: # switch file to link
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1174
            data = file(f).read()
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1175
            os.unlink(f)
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1176
            os.symlink(data, f)
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1177
        else:
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1178
            data = os.readlink(f)
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1179
            os.unlink(f)
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1180
            file(f, "w").write(data)
0b740dcf0cf1 symlinks: add basic symlink functions to util.py
Matt Mackall <mpm@selenic.com>
parents: 3998
diff changeset
  1181
1420
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
  1182
    def set_binary(fd):
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
  1183
        pass
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
  1184
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
  1185
    def pconvert(path):
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
  1186
        return path
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
  1187
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1188
    def localpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1189
        return path
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1190
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1191
    normpath = os.path.normpath
2193
fb28ce04b349 add util.samestat function for windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2177
diff changeset
  1192
    samestat = os.path.samestat
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
  1193
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
  1194
    def makelock(info, pathname):
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1195
        try:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1196
            os.symlink(info, pathname)
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1197
        except OSError, why:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1198
            if why.errno == errno.EEXIST:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1199
                raise
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1200
            else:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1201
                _makelock_file(info, pathname)
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
  1202
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
  1203
    def readlock(pathname):
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1204
        try:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1205
            return os.readlink(pathname)
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1206
        except OSError, why:
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1207
            if why.errno in (errno.EINVAL, errno.ENOSYS):
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1208
                return _readlock_file(pathname)
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1209
            else:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
  1210
                raise
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1211
2791
f4d916351366 Add portable shell-quoting function; teach mq to use it.
Brendan Cully <brendan@kublai.com>
parents: 2760
diff changeset
  1212
    def shellquote(s):
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1213
        if os.sys.platform == 'OpenVMS':
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1214
            return '"%s"' % s
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1215
        else:
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1216
            return "'%s'" % s.replace("'", "'\\''")
2791
f4d916351366 Add portable shell-quoting function; teach mq to use it.
Brendan Cully <brendan@kublai.com>
parents: 2760
diff changeset
  1217
5292
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1218
    def quotecommand(cmd):
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1219
        return cmd
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5291
diff changeset
  1220
5481
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1221
    def popen(command):
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1222
        return os.popen(command)
003d1f174fe1 Fix Windows os.popen bug with interleaved stdout/stderr output
Patrick Mezard <pmezard@gmail.com>
parents: 5454
diff changeset
  1223
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1224
    def testpid(pid):
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1225
        '''return False if pid dead, True if running or not sure'''
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1226
        if os.sys.platform == 'OpenVMS':
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1227
            return True
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1228
        try:
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1229
            os.kill(pid, 0)
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1230
            return True
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1231
        except OSError, inst:
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1232
            return inst.errno != errno.ESRCH
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1835
diff changeset
  1233
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1234
    def explain_exit(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1235
        """return a 2-tuple (desc, code) describing a process's status"""
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1236
        if os.WIFEXITED(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1237
            val = os.WEXITSTATUS(code)
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
  1238
            return _("exited with status %d") % val, val
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1239
        elif os.WIFSIGNALED(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1240
            val = os.WTERMSIG(code)
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
  1241
            return _("killed by signal %d") % val, val
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
  1242
        elif os.WIFSTOPPED(code):
912
302f83b85054 Minor tweak: os.STOPSIG -> os.WSTOPSIG. Pychecker spotted this one.
mark.williamson@cl.cam.ac.uk
parents: 897
diff changeset
  1243
            val = os.WSTOPSIG(code)
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
  1244
            return _("stopped by signal %d") % val, val
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
  1245
        raise ValueError(_("invalid exit code"))
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1246
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1247
    def isowner(fp, st=None):
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1248
        """Return True if the file object f belongs to the current user.
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1249
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1250
        The return value of a util.fstat(f) may be passed as the st argument.
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1251
        """
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1252
        if st is None:
3859
8c24b6fd5866 fix errors spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3854
diff changeset
  1253
            st = fstat(fp)
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1254
        return st.st_uid == os.getuid()
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4508
diff changeset
  1255
4407
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1256
    def find_in_path(name, path, default=None):
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1257
        '''find name in search path. path can be string (will be split
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1258
        with os.pathsep), or iterable thing that returns strings.  if name
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1259
        found, return path to name. else return default.'''
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1260
        if isinstance(path, str):
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1261
            path = path.split(os.pathsep)
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1262
        for p in path:
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1263
            p_name = os.path.join(p, name)
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1264
            if os.path.exists(p_name):
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1265
                return p_name
f97b89314fb3 Move win32 find_in_files from util_win32 to util.
Patrick Mezard <pmezard@gmail.com>
parents: 4388
diff changeset
  1266
        return default
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1267
4672
272c0a09b203 Handle CTRL+C in serve under Windows.
Marcos Chaves <marcos.nospam@gmail.com>
parents: 4647
diff changeset
  1268
    def set_signal_handler():
272c0a09b203 Handle CTRL+C in serve under Windows.
Marcos Chaves <marcos.nospam@gmail.com>
parents: 4647
diff changeset
  1269
        pass
272c0a09b203 Handle CTRL+C in serve under Windows.
Marcos Chaves <marcos.nospam@gmail.com>
parents: 4647
diff changeset
  1270
4488
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1271
def find_exe(name, default=None):
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1272
    '''find path of an executable.
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1273
    if name contains a path component, return it as is.  otherwise,
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1274
    use normal executable search path.'''
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1275
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1276
    if os.sep in name or sys.platform == 'OpenVMS':
4488
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1277
        # don't check the executable bit.  if the file isn't
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1278
        # executable, whoever tries to actually run it will give a
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1279
        # much more useful error message.
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1280
        return name
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1281
    return find_in_path(name, os.environ.get('PATH', ''), default=default)
62019c4427e3 Introduce find_exe. Use instead of find_in_path for programs.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4434
diff changeset
  1282
3852
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1283
def _buildencodefun():
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1284
    e = '_'
3860
8e907b86126b fix reserved char on windows, '[]+' are allowed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3859
diff changeset
  1285
    win_reserved = [ord(x) for x in '\\:*?"<>|']
3852
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1286
    cmap = dict([ (chr(x), chr(x)) for x in xrange(127) ])
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1287
    for x in (range(32) + range(126, 256) + win_reserved):
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1288
        cmap[chr(x)] = "~%02x" % x
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1289
    for x in range(ord("A"), ord("Z")+1) + [ord(e)]:
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1290
        cmap[chr(x)] = e + chr(x).lower()
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1291
    dmap = {}
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1292
    for k, v in cmap.iteritems():
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1293
        dmap[v] = k
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1294
    def decode(s):
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1295
        i = 0
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1296
        while i < len(s):
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1297
            for l in xrange(1, 4):
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1298
                try:
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1299
                    yield dmap[s[i:i+l]]
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1300
                    i += l
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1301
                    break
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1302
                except KeyError:
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1303
                    pass
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1304
            else:
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1305
                raise KeyError
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1306
    return (lambda s: "".join([cmap[c] for c in s]),
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1307
            lambda s: "".join(list(decode(s))))
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1308
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1309
encodefilename, decodefilename = _buildencodefun()
8a9a1a7e1698 create the encode and decode functions for the store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3784
diff changeset
  1310
3853
c0b449154a90 switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3852
diff changeset
  1311
def encodedopener(openerfn, fn):
c0b449154a90 switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3852
diff changeset
  1312
    def o(path, *args, **kw):
c0b449154a90 switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3852
diff changeset
  1313
        return openerfn(fn(path), *args, **kw)
c0b449154a90 switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3852
diff changeset
  1314
    return o
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
  1315
4827
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1316
def mktempcopy(name, emptyok=False):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1317
    """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
  1318
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1319
    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
  1320
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1321
    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
  1322
    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
  1323
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1324
    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
  1325
    """
4827
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1326
    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
  1327
    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
  1328
    os.close(fd)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1329
    # 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
  1330
    # 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
  1331
    # its mode.  Otherwise, manually obey umask.
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1332
    try:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1333
        st_mode = os.lstat(name).st_mode
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1334
    except OSError, inst:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1335
        if inst.errno != errno.ENOENT:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1336
            raise
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1337
        st_mode = 0666 & ~_umask
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1338
    os.chmod(temp, st_mode)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1339
    if emptyok:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1340
        return temp
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1341
    try:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1342
        try:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1343
            ifp = posixfile(name, "rb")
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1344
        except IOError, inst:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1345
            if inst.errno == errno.ENOENT:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1346
                return temp
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1347
            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
  1348
                inst.filename = name
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1349
            raise
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1350
        ofp = posixfile(temp, "wb")
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1351
        for chunk in filechunkiter(ifp):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1352
            ofp.write(chunk)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1353
        ifp.close()
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1354
        ofp.close()
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1355
    except:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1356
        try: os.unlink(temp)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1357
        except: pass
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1358
        raise
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1359
    return temp
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1360
4827
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1361
class atomictempfile(posixfile):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1362
    """file-like object that atomically updates a file
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1363
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1364
    All writes will be redirected to a temporary copy of the original
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1365
    file.  When rename is called, the copy is renamed to the original
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1366
    name, making the changes visible.
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1367
    """
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1368
    def __init__(self, name, mode):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1369
        self.__name = name
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1370
        self.temp = mktempcopy(name, emptyok=('w' in mode))
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1371
        posixfile.__init__(self, self.temp, mode)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1372
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1373
    def rename(self):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1374
        if not self.closed:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1375
            posixfile.close(self)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1376
            rename(self.temp, localpath(self.__name))
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1377
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1378
    def __del__(self):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1379
        if not self.closed:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1380
            try:
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1381
                os.unlink(self.temp)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1382
            except: pass
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1383
            posixfile.close(self)
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1384
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1385
class opener(object):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1386
    """Open files relative to a base directory
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1387
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1388
    This class is used to hide the details of COW semantics and
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1389
    remote file access from higher level code.
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1390
    """
4827
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1391
    def __init__(self, base, audit=True):
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1392
        self.base = base
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
  1393
        if audit:
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
  1394
            self.audit_path = path_auditor(base)
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
  1395
        else:
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
  1396
            self.audit_path = always
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1397
4828
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1398
    def __getattr__(self, name):
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1399
        if name == '_can_symlink':
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1400
            self._can_symlink = checklink(self.base)
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1401
            return self._can_symlink
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1402
        raise AttributeError(name)
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1403
4827
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1404
    def __call__(self, path, mode="r", text=False, atomictemp=False):
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
  1405
        self.audit_path(path)
4827
89defeae88f3 turn util.opener into a class
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4803
diff changeset
  1406
        f = os.path.join(self.base, path)
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1407
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
  1408
        if not text and "b" not in mode:
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1409
            mode += "b" # for that other OS
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1410
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1411
        if mode[0] != "r":
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1412
            try:
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1413
                nlink = nlinks(f)
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1414
            except OSError:
4328
1083ae4b5f0e util.opener: if requested, use atomicfile even if the file doesn't exist
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4327
diff changeset
  1415
                nlink = 0
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1416
                d = os.path.dirname(f)
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1417
                if not os.path.isdir(d):
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1418
                    os.makedirs(d)
4508
0026ccc2bf23 Remove atomicfile class.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4488
diff changeset
  1419
            if atomictemp:
4328
1083ae4b5f0e util.opener: if requested, use atomicfile even if the file doesn't exist
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4327
diff changeset
  1420
                return atomictempfile(f, mode)
1083ae4b5f0e util.opener: if requested, use atomicfile even if the file doesn't exist
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4327
diff changeset
  1421
            if nlink > 1:
1083ae4b5f0e util.opener: if requested, use atomicfile even if the file doesn't exist
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4327
diff changeset
  1422
                rename(mktempcopy(f), f)
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1423
        return posixfile(f, mode)
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2117
diff changeset
  1424
4828
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1425
    def symlink(self, src, dst):
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5124
diff changeset
  1426
        self.audit_path(dst)
4828
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1427
        linkname = os.path.join(self.base, dst)
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1428
        try:
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1429
            os.unlink(linkname)
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1430
        except OSError:
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1431
            pass
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1432
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1433
        dirname = os.path.dirname(linkname)
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1434
        if not os.path.exists(dirname):
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1435
            os.makedirs(dirname)
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1436
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1437
        if self._can_symlink:
4948
c8d1aa1822d5 Print meaningful error message if os.symlink fails
Bryan O'Sullivan <bos@serpentine.com>
parents: 4876
diff changeset
  1438
            try:
c8d1aa1822d5 Print meaningful error message if os.symlink fails
Bryan O'Sullivan <bos@serpentine.com>
parents: 4876
diff changeset
  1439
                os.symlink(src, linkname)
c8d1aa1822d5 Print meaningful error message if os.symlink fails
Bryan O'Sullivan <bos@serpentine.com>
parents: 4876
diff changeset
  1440
            except OSError, err:
c8d1aa1822d5 Print meaningful error message if os.symlink fails
Bryan O'Sullivan <bos@serpentine.com>
parents: 4876
diff changeset
  1441
                raise OSError(err.errno, _('could not symlink to %r: %s') %
c8d1aa1822d5 Print meaningful error message if os.symlink fails
Bryan O'Sullivan <bos@serpentine.com>
parents: 4876
diff changeset
  1442
                              (src, err.strerror), linkname)
4828
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1443
        else:
5077
84b10dc3dccc Fix issue 653: symlinks checkout failure on non-supporting platforms
Patrick Mezard <pmezard@gmail.com>
parents: 5062
diff changeset
  1444
            f = self(dst, "w")
4828
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1445
            f.write(src)
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1446
            f.close()
41ad4105dde9 Add symlink method to util.opener.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4827
diff changeset
  1447
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1448
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
  1449
    """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
  1450
    iterator over chunks of arbitrary size."""
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
  1451
5446
fa836e050c50 chunkbuffer: removed unused method and arg
Matt Mackall <mpm@selenic.com>
parents: 5420
diff changeset
  1452
    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
  1453
        """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
  1454
        targetsize is how big a buffer to try to maintain."""
5447
56591846f819 chunkiter: simplify iter logic
Matt Mackall <mpm@selenic.com>
parents: 5446
diff changeset
  1455
        self.iter = iter(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
  1456
        self.buf = ''
5446
fa836e050c50 chunkbuffer: removed unused method and arg
Matt Mackall <mpm@selenic.com>
parents: 5420
diff changeset
  1457
        self.targetsize = 2**16
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
  1458
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1459
    def read(self, l):
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
  1460
        """Read L bytes of data from the iterator of chunks of data.
1308
2073e5a71008 Cleanup of tabs and trailing spaces.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1285
diff changeset
  1461
        Returns less than L bytes if the iterator runs dry."""
5447
56591846f819 chunkiter: simplify iter logic
Matt Mackall <mpm@selenic.com>
parents: 5446
diff changeset
  1462
        if l > len(self.buf) and self.iter:
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1463
            # Clamp to a multiple of self.targetsize
5449
17a4b20eda7b chunkiter: handle large reads more efficiently
Matt Mackall <mpm@selenic.com>
parents: 5447
diff changeset
  1464
            targetsize = max(l, self.targetsize)
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1465
            collector = cStringIO.StringIO()
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1466
            collector.write(self.buf)
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1467
            collected = len(self.buf)
5447
56591846f819 chunkiter: simplify iter logic
Matt Mackall <mpm@selenic.com>
parents: 5446
diff changeset
  1468
            for chunk in self.iter:
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1469
                collector.write(chunk)
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1470
                collected += len(chunk)
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1471
                if collected >= targetsize:
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1472
                    break
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1473
            if collected < targetsize:
5447
56591846f819 chunkiter: simplify iter logic
Matt Mackall <mpm@selenic.com>
parents: 5446
diff changeset
  1474
                self.iter = False
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1475
            self.buf = collector.getvalue()
5449
17a4b20eda7b chunkiter: handle large reads more efficiently
Matt Mackall <mpm@selenic.com>
parents: 5447
diff changeset
  1476
        if len(self.buf) == l:
5450
c728424d44c6 revlog: fix caching of buffer objects
Matt Mackall <mpm@selenic.com>
parents: 5449
diff changeset
  1477
            s, self.buf = str(self.buf), ''
5449
17a4b20eda7b chunkiter: handle large reads more efficiently
Matt Mackall <mpm@selenic.com>
parents: 5447
diff changeset
  1478
        else:
17a4b20eda7b chunkiter: handle large reads more efficiently
Matt Mackall <mpm@selenic.com>
parents: 5447
diff changeset
  1479
            s, self.buf = self.buf[:l], buffer(self.buf, l)
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1480
        return s
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
  1481
2462
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1482
def filechunkiter(f, size=65536, limit=None):
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1483
    """Create a generator that produces the data in the file size
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1484
    (default 65536) bytes at a time, up to optional limit (default is
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1485
    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
  1486
    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
  1487
    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
  1488
    requested."""
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1489
    assert size >= 0
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1490
    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
  1491
    while True:
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1492
        if limit is None: nbytes = size
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1493
        else: nbytes = min(limit, size)
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1494
        s = nbytes and f.read(nbytes)
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1495
        if not s: break
d610bcfd66a8 util: add limit to amount filechunkiter will read
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2448
diff changeset
  1496
        if limit: 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
  1497
        yield s
1320
5f277e73778f Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1312
diff changeset
  1498
1321
b47f96a178a3 Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1320
diff changeset
  1499
def makedate():
1482
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
  1500
    lt = time.localtime()
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
  1501
    if lt[8] == 1 and time.daylight:
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
  1502
        tz = time.altzone
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
  1503
    else:
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
  1504
        tz = time.timezone
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
  1505
    return time.mktime(lt), tz
1329
8f06817bf266 Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1321
diff changeset
  1506
5269
46c5e1ee8aaa Added support for the Atom syndication format
Robert Bachmann <rbach@rbach.priv.at>
parents: 5236
diff changeset
  1507
def datestr(date=None, format='%a %b %d %H:%M:%S %Y', timezone=True, timezone_format=" %+03d%02d"):
1321
b47f96a178a3 Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1320
diff changeset
  1508
    """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
  1509
    unixtime is seconds since the epoch, and offset is the time zone's
1987
04c17fc39c84 add changelog style to command line template.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1976
diff changeset
  1510
    number of seconds away from UTC. if timezone is false, do not
04c17fc39c84 add changelog style to command line template.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1976
diff changeset
  1511
    append time zone to string."""
1321
b47f96a178a3 Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1320
diff changeset
  1512
    t, tz = date or makedate()
1987
04c17fc39c84 add changelog style to command line template.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1976
diff changeset
  1513
    s = time.strftime(format, time.gmtime(float(t) - tz))
04c17fc39c84 add changelog style to command line template.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1976
diff changeset
  1514
    if timezone:
5269
46c5e1ee8aaa Added support for the Atom syndication format
Robert Bachmann <rbach@rbach.priv.at>
parents: 5236
diff changeset
  1515
        s += timezone_format % (-tz / 3600, ((-tz % 3600) / 60))
1987
04c17fc39c84 add changelog style to command line template.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1976
diff changeset
  1516
    return s
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1517
5357
c6adf2be6069 util: add default argument to strdate
Bryan O'Sullivan <bos@serpentine.com>
parents: 5293
diff changeset
  1518
def strdate(string, format, defaults=[]):
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1519
    """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
  1520
    if the string cannot be parsed, ValueError is raised."""
3809
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1521
    def timezone(string):
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1522
        tz = string.split()[-1]
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1523
        if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit():
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1524
            tz = int(tz)
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1525
            offset = - 3600 * (tz / 100) - 60 * (tz % 100)
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1526
            return offset
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1527
        if tz == "GMT" or tz == "UTC":
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1528
            return 0
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1529
        return None
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1530
3255
e96d2956eb4a util.strdate: compute timestamp using UTC, not local timezone
Jose M. Prieto <jmprieto@gmx.net>
parents: 3176
diff changeset
  1531
    # NOTE: unixtime = localunixtime + offset
3809
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1532
    offset, date = timezone(string), string
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1533
    if offset != None:
4d93b37b5963 parsedate: add UTC and GMT timezones
Matt Mackall <mpm@selenic.com>
parents: 3808
diff changeset
  1534
        date = " ".join(string.split()[:-1])
3808
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
  1535
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1536
    # add missing elements from defaults
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1537
    for part in defaults:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1538
        found = [True for p in part if ("%"+p) in format]
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1539
        if not found:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1540
            date += "@" + defaults[part]
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1541
            format += "@%" + part[0]
3808
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
  1542
3256
e5c9a084ffe3 util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents: 3255
diff changeset
  1543
    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
  1544
    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
  1545
    if offset is None:
e5c9a084ffe3 util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents: 3255
diff changeset
  1546
        # local timezone
e5c9a084ffe3 util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents: 3255
diff changeset
  1547
        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
  1548
        offset = unixtime - localunixtime
e5c9a084ffe3 util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents: 3255
diff changeset
  1549
    else:
e5c9a084ffe3 util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents: 3255
diff changeset
  1550
        unixtime = localunixtime + offset
3255
e96d2956eb4a util.strdate: compute timestamp using UTC, not local timezone
Jose M. Prieto <jmprieto@gmx.net>
parents: 3176
diff changeset
  1551
    return unixtime, offset
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1552
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1553
def parsedate(string, formats=None, defaults=None):
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1554
    """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
  1555
    The date may be a "unixtime offset" string or in one of the specified
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1556
    formats."""
3807
e43b48f0f718 parsedate: allow '' for epoch
Matt Mackall <mpm@selenic.com>
parents: 3806
diff changeset
  1557
    if not string:
e43b48f0f718 parsedate: allow '' for epoch
Matt Mackall <mpm@selenic.com>
parents: 3806
diff changeset
  1558
        return 0, 0
2609
6c5b1b5cc160 util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents: 2601
diff changeset
  1559
    if not formats:
6c5b1b5cc160 util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents: 2601
diff changeset
  1560
        formats = defaultdateformats
3808
d6529582942a improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents: 3807
diff changeset
  1561
    string = string.strip()
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1562
    try:
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1563
        when, offset = map(int, string.split(' '))
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1564
    except ValueError:
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1565
        # fill out defaults
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1566
        if not defaults:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1567
            defaults = {}
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1568
        now = makedate()
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1569
        for part in "d mb yY HI M S".split():
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1570
            if part not in defaults:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1571
                if part[0] in "HMS":
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1572
                    defaults[part] = "00"
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1573
                elif part[0] in "dm":
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1574
                    defaults[part] = "1"
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1575
                else:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1576
                    defaults[part] = datestr(now, "%" + part[0], False)
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1577
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1578
        for format in formats:
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1579
            try:
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1580
                when, offset = strdate(string, format, defaults)
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1581
            except ValueError:
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1582
                pass
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1583
            else:
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1584
                break
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1585
        else:
3806
92a3532a01d9 parsedate: use Abort rather than ValueError
Matt Mackall <mpm@selenic.com>
parents: 3784
diff changeset
  1586
            raise Abort(_('invalid date: %r ') % string)
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1587
    # 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
  1588
    # 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
  1589
    # 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
  1590
    # to UTC+14
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
  1591
    if abs(when) > 0x7fffffff:
3806
92a3532a01d9 parsedate: use Abort rather than ValueError
Matt Mackall <mpm@selenic.com>
parents: 3784
diff changeset
  1592
        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
  1593
    if offset < -50400 or offset > 43200:
3806
92a3532a01d9 parsedate: use Abort rather than ValueError
Matt Mackall <mpm@selenic.com>
parents: 3784
diff changeset
  1594
        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
  1595
    return when, offset
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2480
diff changeset
  1596
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1597
def matchdate(date):
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1598
    """Return a function that matches a given date match specifier
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1599
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1600
    Formats include:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1601
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1602
    '{date}' match a given date to the accuracy provided
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1603
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1604
    '<{date}' on or before a given date
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1605
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1606
    '>{date}' on or after a given date
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1607
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1608
    """
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1609
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1610
    def lower(date):
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1611
        return parsedate(date, extendeddateformats)[0]
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1612
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1613
    def upper(date):
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1614
        d = dict(mb="12", HI="23", M="59", S="59")
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1615
        for days in "31 30 29".split():
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1616
            try:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1617
                d["d"] = days
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1618
                return parsedate(date, extendeddateformats, d)[0]
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1619
            except:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1620
                pass
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1621
        d["d"] = "28"
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1622
        return parsedate(date, extendeddateformats, d)[0]
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1623
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1624
    if date[0] == "<":
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1625
        when = upper(date[1:])
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1626
        return lambda x: x <= when
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1627
    elif date[0] == ">":
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1628
        when = lower(date[1:])
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1629
        return lambda x: x >= when
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1630
    elif date[0] == "-":
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1631
        try:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1632
            days = int(date[1:])
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1633
        except ValueError:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1634
            raise Abort(_("invalid day spec: %s") % date[1:])
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1635
        when = makedate()[0] - days * 3600 * 24
3813
fc5ba0ab7f45 Add --date support to log
Matt Mackall <mpm@selenic.com>
parents: 3812
diff changeset
  1636
        return lambda x: x >= when
3812
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1637
    elif " to " in date:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1638
        a, b = date.split(" to ")
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1639
        start, stop = lower(a), upper(b)
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1640
        return lambda x: x >= start and x <= stop
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1641
    else:
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1642
        start, stop = lower(date), upper(date)
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1643
        return lambda x: x >= start and x <= stop
bf6ab30559e6 Add date matching support
Matt Mackall <mpm@selenic.com>
parents: 3809
diff changeset
  1644
1903
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1645
def shortuser(user):
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1646
    """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
  1647
    f = user.find('@')
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1648
    if f >= 0:
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1649
        user = user[:f]
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1650
    f = user.find('<')
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1651
    if f >= 0:
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1652
        user = user[f+1:]
3176
7492b33bdd9f shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3147
diff changeset
  1653
    f = user.find(' ')
7492b33bdd9f shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3147
diff changeset
  1654
    if f >= 0:
7492b33bdd9f shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3147
diff changeset
  1655
        user = user[:f]
3533
bb44489b901f shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents: 3466
diff changeset
  1656
    f = user.find('.')
bb44489b901f shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents: 3466
diff changeset
  1657
    if f >= 0:
bb44489b901f shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents: 3466
diff changeset
  1658
        user = user[:f]
1903
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1659
    return user
1920
b7cc0f323a4c merge with crew.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1903 1882
diff changeset
  1660
3767
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
  1661
def ellipsis(text, maxlength=400):
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
  1662
    """Trim string to at most maxlength (default: 400) characters."""
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
  1663
    if len(text) <= maxlength:
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
  1664
        return text
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
  1665
    else:
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
  1666
        return "%s..." % (text[:maxlength-3])
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
  1667
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1668
def walkrepos(path):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1669
    '''yield every hg repository under path, recursively.'''
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1670
    def errhandler(err):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1671
        if err.filename == path:
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1672
            raise err
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1673
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1674
    for root, dirs, files in os.walk(path, onerror=errhandler):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1675
        for d in dirs:
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1676
            if d == '.hg':
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1677
                yield root
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1678
                dirs[:] = []
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
  1679
                break
1951
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1680
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1681
_rcpath = None
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1682
4097
403c4ddd74bb Combined the two os_rcpath methods into a single one near rcpath in mercurial/util.py
Shane Holloway <shane.holloway@ieee.org>
parents: 4096
diff changeset
  1683
def os_rcpath():
403c4ddd74bb Combined the two os_rcpath methods into a single one near rcpath in mercurial/util.py
Shane Holloway <shane.holloway@ieee.org>
parents: 4096
diff changeset
  1684
    '''return default os-specific hgrc search path'''
403c4ddd74bb Combined the two os_rcpath methods into a single one near rcpath in mercurial/util.py
Shane Holloway <shane.holloway@ieee.org>
parents: 4096
diff changeset
  1685
    path = system_rcpath()
403c4ddd74bb Combined the two os_rcpath methods into a single one near rcpath in mercurial/util.py
Shane Holloway <shane.holloway@ieee.org>
parents: 4096
diff changeset
  1686
    path.extend(user_rcpath())
403c4ddd74bb Combined the two os_rcpath methods into a single one near rcpath in mercurial/util.py
Shane Holloway <shane.holloway@ieee.org>
parents: 4096
diff changeset
  1687
    path = [os.path.normpath(f) for f in path]
403c4ddd74bb Combined the two os_rcpath methods into a single one near rcpath in mercurial/util.py
Shane Holloway <shane.holloway@ieee.org>
parents: 4096
diff changeset
  1688
    return path
403c4ddd74bb Combined the two os_rcpath methods into a single one near rcpath in mercurial/util.py
Shane Holloway <shane.holloway@ieee.org>
parents: 4096
diff changeset
  1689
1951
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1690
def rcpath():
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1691
    '''return hgrc search path. if env var HGRCPATH is set, use it.
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1692
    for each item in path, if directory, use files ending in .rc,
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1693
    else use item.
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1694
    make HGRCPATH empty to only look in .hg/hgrc of current repo.
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1695
    if no HGRCPATH, use default os-specific path.'''
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1696
    global _rcpath
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1697
    if _rcpath is None:
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1698
        if 'HGRCPATH' in os.environ:
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1699
            _rcpath = []
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1700
            for p in os.environ['HGRCPATH'].split(os.pathsep):
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1701
                if not p: continue
1956
16750010813d use a proper test instead of catching every exception
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1951
diff changeset
  1702
                if os.path.isdir(p):
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5360
diff changeset
  1703
                    for f, kind in osutil.listdir(p):
1951
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1704
                        if f.endswith('.rc'):
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1705
                            _rcpath.append(os.path.join(p, f))
1956
16750010813d use a proper test instead of catching every exception
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1951
diff changeset
  1706
                else:
16750010813d use a proper test instead of catching every exception
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1951
diff changeset
  1707
                    _rcpath.append(p)
1951
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1708
        else:
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1709
            _rcpath = os_rcpath()
696230e52e4d add HGRCPATH env var, list of places to look for hgrc files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
  1710
    return _rcpath
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1711
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1712
def bytecount(nbytes):
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1713
    '''return byte count formatted as readable string, with units'''
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1714
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1715
    units = (
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1716
        (100, 1<<30, _('%.0f GB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1717
        (10, 1<<30, _('%.1f GB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1718
        (1, 1<<30, _('%.2f GB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1719
        (100, 1<<20, _('%.0f MB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1720
        (10, 1<<20, _('%.1f MB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1721
        (1, 1<<20, _('%.2f MB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1722
        (100, 1<<10, _('%.0f KB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1723
        (10, 1<<10, _('%.1f KB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1724
        (1, 1<<10, _('%.2f KB')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1725
        (1, 1, _('%.0f bytes')),
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1726
        )
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1727
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1728
    for multiplier, divisor, format in units:
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1729
        if nbytes >= divisor * multiplier:
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1730
            return format % (nbytes / float(divisor))
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2609
diff changeset
  1731
    return units[-1][2] % nbytes
2740
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1732
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1733
def drop_scheme(scheme, path):
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1734
    sc = scheme + ':'
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1735
    if path.startswith(sc):
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1736
        path = path[len(sc):]
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1737
        if path.startswith('//'):
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1738
            path = path[2:]
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2655
diff changeset
  1739
    return path
5291
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5213
diff changeset
  1740
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5213
diff changeset
  1741
def uirepr(s):
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5213
diff changeset
  1742
    # 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
  1743
    return repr(s).replace('\\\\', '\\')
5525
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1744
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1745
def hidepassword(url):
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1746
    '''replaces the password in the url string by three asterisks (***)
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1747
    
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1748
    >>> hidepassword('http://www.example.com/some/path#fragment')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1749
    'http://www.example.com/some/path#fragment'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1750
    >>> hidepassword('http://me@www.example.com/some/path#fragment')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1751
    'http://me@www.example.com/some/path#fragment'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1752
    >>> hidepassword('http://me:simplepw@www.example.com/path#frag')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1753
    'http://me:***@www.example.com/path#frag'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1754
    >>> hidepassword('http://me:complex:pw@www.example.com/path#frag')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1755
    'http://me:***@www.example.com/path#frag'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1756
    >>> hidepassword('/path/to/repo')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1757
    '/path/to/repo'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1758
    >>> hidepassword('relative/path/to/repo')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1759
    'relative/path/to/repo'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1760
    >>> hidepassword('c:\\\\path\\\\to\\\\repo')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1761
    'c:\\\\path\\\\to\\\\repo'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1762
    >>> hidepassword('c:/path/to/repo')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1763
    'c:/path/to/repo'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1764
    >>> hidepassword('bundle://path/to/bundle')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1765
    'bundle://path/to/bundle'
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1766
    '''
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1767
    url_parts = list(urlparse.urlparse(url))
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1768
    host_with_pw_pattern = re.compile('^([^:]*):([^@]*)@(.*)$')
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1769
    if host_with_pw_pattern.match(url_parts[1]):
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1770
        url_parts[1] = re.sub(host_with_pw_pattern, r'\1:***@\3',
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1771
            url_parts[1])
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1772
    return urlparse.urlunparse(url_parts)
dcbda0c4c3eb Do not display passwords with pull/push/incoming/outgoing
Manuel Holtgrewe <purestorm@ggnore.net>
parents: 5487
diff changeset
  1773