/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2095.3.1 by Martin Pool
Tests shouldn't assume os.listdir returns sorted results
1
# Copyright (C) 2005, 2006 Canonical Ltd
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
2
#
1 by mbp at sourcefrog
import from baz patch-364
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
7
#
1 by mbp at sourcefrog
import from baz patch-364
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
12
#
1 by mbp at sourcefrog
import from baz patch-364
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
1390 by Robert Collins
pair programming worx... merge integration and weave
17
from cStringIO import StringIO
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
18
import os
19
import re
20
import stat
21
from stat import (S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE,
22
                  S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
23
import sys
24
import time
25
26
from bzrlib.lazy_import import lazy_import
27
lazy_import(globals(), """
2215.6.1 by James Henstridge
Don't rely on time.timezone and time.altzone in local_time_offset(),
28
from datetime import datetime
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
29
import errno
1711.4.5 by John Arbash Meinel
the _posix_* routines should use posixpath not os.path, so tests pass on win32
30
from ntpath import (abspath as _nt_abspath,
31
                    join as _nt_join,
32
                    normpath as _nt_normpath,
33
                    realpath as _nt_realpath,
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
34
                    splitdrive as _nt_splitdrive,
1711.4.5 by John Arbash Meinel
the _posix_* routines should use posixpath not os.path, so tests pass on win32
35
                    )
36
import posixpath
1236 by Martin Pool
- fix up imports
37
import sha
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
38
import shutil
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
39
from shutil import (
40
    rmtree,
41
    )
1185.16.38 by Martin Pool
- move contains_whitespace and contains_linebreaks to osutils
42
import string
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
43
import tempfile
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
44
from tempfile import (
45
    mkdtemp,
46
    )
1185.85.75 by John Arbash Meinel
Adding bzrlib.osutils.unicode_filename to handle unicode normalization for file paths.
47
import unicodedata
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
48
49
from bzrlib import (
50
    errors,
51
    )
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
52
""")
1 by mbp at sourcefrog
import from baz patch-364
53
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
54
import bzrlib
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
55
from bzrlib.symbol_versioning import (
56
    deprecated_function,
57
    zero_nine,
58
    )
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
59
from bzrlib.trace import mutter
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
60
1 by mbp at sourcefrog
import from baz patch-364
61
1755.3.7 by John Arbash Meinel
Clean up and write tests for permissions. Now we use fstat which should be cheap, and lets us check the permissions and the file size
62
# On win32, O_BINARY is used to indicate the file should
63
# be opened in binary mode, rather than text mode.
64
# On other platforms, O_BINARY doesn't exist, because
65
# they always open in binary mode, so it is okay to
66
# OR with 0 on those platforms
67
O_BINARY = getattr(os, 'O_BINARY', 0)
68
69
1 by mbp at sourcefrog
import from baz patch-364
70
def make_readonly(filename):
71
    """Make a filename read-only."""
72
    mod = os.stat(filename).st_mode
73
    mod = mod & 0777555
74
    os.chmod(filename, mod)
75
76
77
def make_writable(filename):
78
    mod = os.stat(filename).st_mode
79
    mod = mod | 0200
80
    os.chmod(filename, mod)
81
82
1077 by Martin Pool
- avoid compiling REs at module load time
83
_QUOTE_RE = None
969 by Martin Pool
- Add less-sucky is_within_any
84
85
1 by mbp at sourcefrog
import from baz patch-364
86
def quotefn(f):
779 by Martin Pool
- better quotefn for windows: use doublequotes for strings with
87
    """Return a quoted filename filename
88
89
    This previously used backslash quoting, but that works poorly on
90
    Windows."""
91
    # TODO: I'm not really sure this is the best format either.x
1077 by Martin Pool
- avoid compiling REs at module load time
92
    global _QUOTE_RE
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
93
    if _QUOTE_RE is None:
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
94
        _QUOTE_RE = re.compile(r'([^a-zA-Z0-9.,:/\\_~-])')
1077 by Martin Pool
- avoid compiling REs at module load time
95
        
779 by Martin Pool
- better quotefn for windows: use doublequotes for strings with
96
    if _QUOTE_RE.search(f):
97
        return '"' + f + '"'
98
    else:
99
        return f
1 by mbp at sourcefrog
import from baz patch-364
100
101
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
102
_directory_kind = 'directory'
103
1732.1.10 by John Arbash Meinel
Updated version of file_kind. Rather than multiple function calls, one mask + dictionary lookup
104
_formats = {
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
105
    stat.S_IFDIR:_directory_kind,
1732.1.10 by John Arbash Meinel
Updated version of file_kind. Rather than multiple function calls, one mask + dictionary lookup
106
    stat.S_IFCHR:'chardev',
107
    stat.S_IFBLK:'block',
108
    stat.S_IFREG:'file',
109
    stat.S_IFIFO:'fifo',
110
    stat.S_IFLNK:'symlink',
111
    stat.S_IFSOCK:'socket',
112
}
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
113
114
115
def file_kind_from_stat_mode(stat_mode, _formats=_formats, _unknown='unknown'):
116
    """Generate a file kind from a stat mode. This is used in walkdirs.
117
118
    Its performance is critical: Do not mutate without careful benchmarking.
119
    """
1732.1.12 by John Arbash Meinel
improve bzrlib.osutils.file_kind performance from 324ms => 275ms
120
    try:
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
121
        return _formats[stat_mode & 0170000]
1732.1.12 by John Arbash Meinel
improve bzrlib.osutils.file_kind performance from 324ms => 275ms
122
    except KeyError:
1732.1.30 by John Arbash Meinel
More file_kind tweaks. Use keyword parameters to make everything a local variable.
123
        return _unknown
488 by Martin Pool
- new helper function kind_marker()
124
125
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
126
def file_kind(f, _lstat=os.lstat, _mapper=file_kind_from_stat_mode):
1757.2.4 by Robert Collins
Teach file_kind about NoSuchFile, reducing duplicate code, and add user files before entering the main loop in smart_add.
127
    try:
128
        return _mapper(_lstat(f).st_mode)
129
    except OSError, e:
130
        if getattr(e, 'errno', None) == errno.ENOENT:
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
131
            raise errors.NoSuchFile(f)
1757.2.4 by Robert Collins
Teach file_kind about NoSuchFile, reducing duplicate code, and add user files before entering the main loop in smart_add.
132
        raise
133
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
134
1755.3.7 by John Arbash Meinel
Clean up and write tests for permissions. Now we use fstat which should be cheap, and lets us check the permissions and the file size
135
def get_umask():
136
    """Return the current umask"""
137
    # Assume that people aren't messing with the umask while running
138
    # XXX: This is not thread safe, but there is no way to get the
139
    #      umask without setting it
140
    umask = os.umask(0)
141
    os.umask(umask)
142
    return umask
143
144
488 by Martin Pool
- new helper function kind_marker()
145
def kind_marker(kind):
146
    if kind == 'file':
147
        return ''
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
148
    elif kind == _directory_kind:
488 by Martin Pool
- new helper function kind_marker()
149
        return '/'
150
    elif kind == 'symlink':
151
        return '@'
152
    else:
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
153
        raise errors.BzrError('invalid file kind %r' % kind)
1 by mbp at sourcefrog
import from baz patch-364
154
1732.1.2 by John Arbash Meinel
just use os.path.lexists if it exists
155
lexists = getattr(os.path, 'lexists', None)
156
if lexists is None:
157
    def lexists(f):
158
        try:
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
159
            if getattr(os, 'lstat') is not None:
1732.1.2 by John Arbash Meinel
just use os.path.lexists if it exists
160
                os.lstat(f)
161
            else:
162
                os.stat(f)
163
            return True
164
        except OSError,e:
165
            if e.errno == errno.ENOENT:
166
                return False;
167
            else:
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
168
                raise errors.BzrError("lstat/stat of (%r): %r" % (f, e))
1732.1.2 by John Arbash Meinel
just use os.path.lexists if it exists
169
1 by mbp at sourcefrog
import from baz patch-364
170
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
171
def fancy_rename(old, new, rename_func, unlink_func):
172
    """A fancy rename, when you don't have atomic rename.
173
    
174
    :param old: The old path, to rename from
175
    :param new: The new path, to rename to
176
    :param rename_func: The potentially non-atomic rename function
177
    :param unlink_func: A way to delete the target file if the full rename succeeds
178
    """
179
180
    # sftp rename doesn't allow overwriting, so play tricks:
181
    import random
182
    base = os.path.basename(new)
183
    dirname = os.path.dirname(new)
1553.5.22 by Martin Pool
Change fancy_rename to use rand_chars rather than reinvent it.
184
    tmp_name = u'tmp.%s.%.9f.%d.%s' % (base, time.time(), os.getpid(), rand_chars(10))
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
185
    tmp_name = pathjoin(dirname, tmp_name)
186
187
    # Rename the file out of the way, but keep track if it didn't exist
188
    # We don't want to grab just any exception
189
    # something like EACCES should prevent us from continuing
190
    # The downside is that the rename_func has to throw an exception
191
    # with an errno = ENOENT, or NoSuchFile
192
    file_existed = False
193
    try:
194
        rename_func(new, tmp_name)
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
195
    except (errors.NoSuchFile,), e:
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
196
        pass
1532 by Robert Collins
Merge in John Meinels integration branch.
197
    except IOError, e:
198
        # RBC 20060103 abstraction leakage: the paramiko SFTP clients rename
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
199
        # function raises an IOError with errno is None when a rename fails.
1532 by Robert Collins
Merge in John Meinels integration branch.
200
        # This then gets caught here.
1185.50.37 by John Arbash Meinel
Fixed exception handling for fancy_rename
201
        if e.errno not in (None, errno.ENOENT, errno.ENOTDIR):
1532 by Robert Collins
Merge in John Meinels integration branch.
202
            raise
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
203
    except Exception, e:
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
204
        if (getattr(e, 'errno', None) is None
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
205
            or e.errno not in (errno.ENOENT, errno.ENOTDIR)):
206
            raise
207
    else:
208
        file_existed = True
209
210
    success = False
211
    try:
212
        # This may throw an exception, in which case success will
213
        # not be set.
214
        rename_func(old, new)
215
        success = True
216
    finally:
217
        if file_existed:
218
            # If the file used to exist, rename it back into place
219
            # otherwise just delete it from the tmp location
220
            if success:
221
                unlink_func(tmp_name)
222
            else:
1185.31.49 by John Arbash Meinel
Some corrections using the new osutils.rename. **ALL TESTS PASS**
223
                rename_func(tmp_name, new)
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
224
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
225
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
226
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
227
# choke on a Unicode string containing a relative path if
228
# os.getcwd() returns a non-sys.getdefaultencoding()-encoded
229
# string.
2093.1.1 by John Arbash Meinel
(Bart Teeuwisse) if sys.getfilesystemencoding() is None, use 'utf-8'
230
_fs_enc = sys.getfilesystemencoding() or 'utf-8'
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
231
def _posix_abspath(path):
1711.4.5 by John Arbash Meinel
the _posix_* routines should use posixpath not os.path, so tests pass on win32
232
    # jam 20060426 rather than encoding to fsencoding
233
    # copy posixpath.abspath, but use os.getcwdu instead
234
    if not posixpath.isabs(path):
235
        path = posixpath.join(getcwd(), path)
236
    return posixpath.normpath(path)
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
237
238
239
def _posix_realpath(path):
1711.4.5 by John Arbash Meinel
the _posix_* routines should use posixpath not os.path, so tests pass on win32
240
    return posixpath.realpath(path.encode(_fs_enc)).decode(_fs_enc)
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
241
242
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
243
def _win32_fixdrive(path):
244
    """Force drive letters to be consistent.
245
246
    win32 is inconsistent whether it returns lower or upper case
247
    and even if it was consistent the user might type the other
248
    so we force it to uppercase
249
    running python.exe under cmd.exe return capital C:\\
250
    running win32 python inside a cygwin shell returns lowercase c:\\
251
    """
252
    drive, path = _nt_splitdrive(path)
253
    return drive.upper() + path
254
255
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
256
def _win32_abspath(path):
1711.4.6 by John Arbash Meinel
Removing hacks for _win32_abspath, on real win32 abspath handles unicode just fine, it doesn't handle encoding into 'mbcs'
257
    # Real _nt_abspath doesn't have a problem with a unicode cwd
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
258
    return _win32_fixdrive(_nt_abspath(unicode(path)).replace('\\', '/'))
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
259
260
261
def _win32_realpath(path):
1711.4.6 by John Arbash Meinel
Removing hacks for _win32_abspath, on real win32 abspath handles unicode just fine, it doesn't handle encoding into 'mbcs'
262
    # Real _nt_realpath doesn't have a problem with a unicode cwd
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
263
    return _win32_fixdrive(_nt_realpath(unicode(path)).replace('\\', '/'))
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
264
265
266
def _win32_pathjoin(*args):
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
267
    return _nt_join(*args).replace('\\', '/')
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
268
269
270
def _win32_normpath(path):
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
271
    return _win32_fixdrive(_nt_normpath(unicode(path)).replace('\\', '/'))
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
272
273
274
def _win32_getcwd():
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
275
    return _win32_fixdrive(os.getcwdu().replace('\\', '/'))
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
276
277
278
def _win32_mkdtemp(*args, **kwargs):
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
279
    return _win32_fixdrive(tempfile.mkdtemp(*args, **kwargs).replace('\\', '/'))
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
280
281
282
def _win32_rename(old, new):
1711.7.6 by John Arbash Meinel
Change _win32_rename() so that it raises ENOENT *before* it tries any renaming.
283
    """We expect to be able to atomically replace 'new' with old.
284
1711.7.17 by John Arbash Meinel
Delay the extra syscall in _win32_rename until we get a failure.
285
    On win32, if new exists, it must be moved out of the way first,
286
    and then deleted. 
1711.7.6 by John Arbash Meinel
Change _win32_rename() so that it raises ENOENT *before* it tries any renaming.
287
    """
1711.7.17 by John Arbash Meinel
Delay the extra syscall in _win32_rename until we get a failure.
288
    try:
289
        fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
290
    except OSError, e:
1830.3.15 by John Arbash Meinel
On Mac we get EINVAL when renaming cwd
291
        if e.errno in (errno.EPERM, errno.EACCES, errno.EBUSY, errno.EINVAL):
292
            # If we try to rename a non-existant file onto cwd, we get 
293
            # EPERM or EACCES instead of ENOENT, this will raise ENOENT 
294
            # if the old path doesn't exist, sometimes we get EACCES
295
            # On Linux, we seem to get EBUSY, on Mac we get EINVAL
1711.7.17 by John Arbash Meinel
Delay the extra syscall in _win32_rename until we get a failure.
296
            os.lstat(old)
297
        raise
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
298
299
1830.3.11 by John Arbash Meinel
Create a mac version of 'getcwd()' which normalizes the path.
300
def _mac_getcwd():
301
    return unicodedata.normalize('NFKC', os.getcwdu())
302
303
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
304
# Default is to just use the python builtins, but these can be rebound on
305
# particular platforms.
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
306
abspath = _posix_abspath
307
realpath = _posix_realpath
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
308
pathjoin = os.path.join
309
normpath = os.path.normpath
310
getcwd = os.getcwdu
311
rename = os.rename
312
dirname = os.path.dirname
313
basename = os.path.basename
2215.4.2 by Alexander Belchenko
split and splitext now the part of osutils
314
split = os.path.split
315
splitext = os.path.splitext
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
316
# These were already imported into local scope
317
# mkdtemp = tempfile.mkdtemp
318
# rmtree = shutil.rmtree
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
319
1551.2.53 by abentley
Strip trailing slashes in a platform-sensible way
320
MIN_ABS_PATHLENGTH = 1
321
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
322
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
323
if sys.platform == 'win32':
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
324
    abspath = _win32_abspath
325
    realpath = _win32_realpath
326
    pathjoin = _win32_pathjoin
327
    normpath = _win32_normpath
328
    getcwd = _win32_getcwd
329
    mkdtemp = _win32_mkdtemp
330
    rename = _win32_rename
331
1551.2.53 by abentley
Strip trailing slashes in a platform-sensible way
332
    MIN_ABS_PATHLENGTH = 3
1532 by Robert Collins
Merge in John Meinels integration branch.
333
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
334
    def _win32_delete_readonly(function, path, excinfo):
335
        """Error handler for shutil.rmtree function [for win32]
336
        Helps to remove files and dirs marked as read-only.
337
        """
2116.5.1 by Henri Wiechers
Fixes osutils.rmtree on Windows with Python 2.5
338
        exception = excinfo[1]
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
339
        if function in (os.remove, os.rmdir) \
2116.5.1 by Henri Wiechers
Fixes osutils.rmtree on Windows with Python 2.5
340
            and isinstance(exception, OSError) \
341
            and exception.errno == errno.EACCES:
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
342
            make_writable(path)
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
343
            function(path)
344
        else:
345
            raise
346
347
    def rmtree(path, ignore_errors=False, onerror=_win32_delete_readonly):
348
        """Replacer for shutil.rmtree: could remove readonly dirs/files"""
349
        return shutil.rmtree(path, ignore_errors, onerror)
1830.3.11 by John Arbash Meinel
Create a mac version of 'getcwd()' which normalizes the path.
350
elif sys.platform == 'darwin':
351
    getcwd = _mac_getcwd
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
352
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
353
1711.4.10 by John Arbash Meinel
Pull out sys.stdout.encoding handling into a separate function so it can be tested, and used elsewhere.
354
def get_terminal_encoding():
355
    """Find the best encoding for printing to the screen.
356
357
    This attempts to check both sys.stdout and sys.stdin to see
358
    what encoding they are in, and if that fails it falls back to
359
    bzrlib.user_encoding.
360
    The problem is that on Windows, locale.getpreferredencoding()
361
    is not the same encoding as that used by the console:
362
    http://mail.python.org/pipermail/python-list/2003-May/162357.html
363
364
    On my standard US Windows XP, the preferred encoding is
365
    cp1252, but the console is cp437
366
    """
367
    output_encoding = getattr(sys.stdout, 'encoding', None)
368
    if not output_encoding:
369
        input_encoding = getattr(sys.stdin, 'encoding', None)
370
        if not input_encoding:
371
            output_encoding = bzrlib.user_encoding
372
            mutter('encoding stdout as bzrlib.user_encoding %r', output_encoding)
373
        else:
374
            output_encoding = input_encoding
375
            mutter('encoding stdout as sys.stdin encoding %r', output_encoding)
376
    else:
377
        mutter('encoding stdout as sys.stdout encoding %r', output_encoding)
2127.4.1 by Alexander Belchenko
(jam, bialix) Workaround for cp0 console encoding on Windows
378
    if output_encoding == 'cp0':
379
        # invalid encoding (cp0 means 'no codepage' on Windows)
380
        output_encoding = bzrlib.user_encoding
381
        mutter('cp0 is invalid encoding.'
382
               ' encoding stdout as bzrlib.user_encoding %r', output_encoding)
1711.4.10 by John Arbash Meinel
Pull out sys.stdout.encoding handling into a separate function so it can be tested, and used elsewhere.
383
    return output_encoding
384
385
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
386
def normalizepath(f):
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
387
    if getattr(os.path, 'realpath', None) is not None:
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
388
        F = realpath
389
    else:
390
        F = abspath
391
    [p,e] = os.path.split(f)
392
    if e == "" or e == "." or e == "..":
393
        return F(f)
394
    else:
395
        return pathjoin(F(p), e)
396
1 by mbp at sourcefrog
import from baz patch-364
397
779 by Martin Pool
- better quotefn for windows: use doublequotes for strings with
398
def backup_file(fn):
399
    """Copy a file to a backup.
400
401
    Backups are named in GNU-style, with a ~ suffix.
402
403
    If the file is already a backup, it's not copied.
404
    """
405
    if fn[-1] == '~':
406
        return
407
    bfn = fn + '~'
408
1448 by Robert Collins
revert symlinks correctly
409
    if has_symlinks() and os.path.islink(fn):
410
        target = os.readlink(fn)
411
        os.symlink(target, bfn)
412
        return
779 by Martin Pool
- better quotefn for windows: use doublequotes for strings with
413
    inf = file(fn, 'rb')
414
    try:
415
        content = inf.read()
416
    finally:
417
        inf.close()
418
    
419
    outf = file(bfn, 'wb')
420
    try:
421
        outf.write(content)
422
    finally:
423
        outf.close()
424
425
1 by mbp at sourcefrog
import from baz patch-364
426
def isdir(f):
427
    """True if f is an accessible directory."""
428
    try:
429
        return S_ISDIR(os.lstat(f)[ST_MODE])
430
    except OSError:
431
        return False
432
433
434
def isfile(f):
435
    """True if f is a regular file."""
436
    try:
437
        return S_ISREG(os.lstat(f)[ST_MODE])
438
    except OSError:
439
        return False
440
1092.2.6 by Robert Collins
symlink support updated to work
441
def islink(f):
442
    """True if f is a symlink."""
443
    try:
444
        return S_ISLNK(os.lstat(f)[ST_MODE])
445
    except OSError:
446
        return False
1 by mbp at sourcefrog
import from baz patch-364
447
485 by Martin Pool
- move commit code into its own module
448
def is_inside(dir, fname):
449
    """True if fname is inside dir.
969 by Martin Pool
- Add less-sucky is_within_any
450
    
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
451
    The parameters should typically be passed to osutils.normpath first, so
969 by Martin Pool
- Add less-sucky is_within_any
452
    that . and .. and repeated slashes are eliminated, and the separators
453
    are canonical for the platform.
454
    
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
455
    The empty string as a dir name is taken as top-of-tree and matches 
456
    everything.
485 by Martin Pool
- move commit code into its own module
457
    """
969 by Martin Pool
- Add less-sucky is_within_any
458
    # XXX: Most callers of this can actually do something smarter by 
459
    # looking at the inventory
972 by Martin Pool
- less dodgy is_inside function
460
    if dir == fname:
461
        return True
462
    
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
463
    if dir == '':
464
        return True
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
465
1185.31.34 by John Arbash Meinel
Removing instances of os.sep
466
    if dir[-1] != '/':
467
        dir += '/'
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
468
972 by Martin Pool
- less dodgy is_inside function
469
    return fname.startswith(dir)
470
485 by Martin Pool
- move commit code into its own module
471
472
def is_inside_any(dir_list, fname):
473
    """True if fname is inside any of given dirs."""
474
    for dirname in dir_list:
475
        if is_inside(dirname, fname):
476
            return True
477
    else:
478
        return False
479
480
1740.3.4 by Jelmer Vernooij
Move inventory to commit builder.
481
def is_inside_or_parent_of_any(dir_list, fname):
482
    """True if fname is a child or a parent of any of the given files."""
483
    for dirname in dir_list:
484
        if is_inside(dirname, fname) or is_inside(fname, dirname):
485
            return True
486
    else:
487
        return False
488
489
1 by mbp at sourcefrog
import from baz patch-364
490
def pumpfile(fromfile, tofile):
491
    """Copy contents of one file to another."""
1185.49.12 by John Arbash Meinel
Changed pumpfile to work on blocks, rather than reading the entire file at once.
492
    BUFSIZE = 32768
493
    while True:
494
        b = fromfile.read(BUFSIZE)
495
        if not b:
496
            break
1185.49.13 by John Arbash Meinel
Removed delayed setup, since it broke some tests. Fixed other small bugs. All tests pass.
497
        tofile.write(b)
1 by mbp at sourcefrog
import from baz patch-364
498
499
1185.67.7 by Aaron Bentley
Refactored a bit
500
def file_iterator(input_file, readsize=32768):
501
    while True:
502
        b = input_file.read(readsize)
503
        if len(b) == 0:
504
            break
505
        yield b
506
507
1 by mbp at sourcefrog
import from baz patch-364
508
def sha_file(f):
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
509
    if getattr(f, 'tell', None) is not None:
1 by mbp at sourcefrog
import from baz patch-364
510
        assert f.tell() == 0
511
    s = sha.new()
320 by Martin Pool
- Compute SHA-1 of files in chunks
512
    BUFSIZE = 128<<10
513
    while True:
514
        b = f.read(BUFSIZE)
515
        if not b:
516
            break
517
        s.update(b)
1 by mbp at sourcefrog
import from baz patch-364
518
    return s.hexdigest()
519
520
1235 by Martin Pool
- split sha_strings into osutils
521
522
def sha_strings(strings):
523
    """Return the sha-1 of concatenation of strings"""
524
    s = sha.new()
525
    map(s.update, strings)
526
    return s.hexdigest()
527
528
1 by mbp at sourcefrog
import from baz patch-364
529
def sha_string(f):
530
    s = sha.new()
531
    s.update(f)
532
    return s.hexdigest()
533
534
124 by mbp at sourcefrog
- check file text for past revisions is correct
535
def fingerprint_file(f):
536
    s = sha.new()
126 by mbp at sourcefrog
Use just one big read to fingerprint files
537
    b = f.read()
538
    s.update(b)
539
    size = len(b)
124 by mbp at sourcefrog
- check file text for past revisions is correct
540
    return {'size': size,
541
            'sha1': s.hexdigest()}
542
543
1 by mbp at sourcefrog
import from baz patch-364
544
def compare_files(a, b):
545
    """Returns true if equal in contents"""
74 by mbp at sourcefrog
compare_files: read in one page at a time rather than
546
    BUFSIZE = 4096
547
    while True:
548
        ai = a.read(BUFSIZE)
549
        bi = b.read(BUFSIZE)
550
        if ai != bi:
551
            return False
552
        if ai == '':
553
            return True
1 by mbp at sourcefrog
import from baz patch-364
554
555
49 by mbp at sourcefrog
fix local-time-offset calculation
556
def local_time_offset(t=None):
557
    """Return offset of local zone from GMT, either at present or at time t."""
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
558
    if t is None:
73 by mbp at sourcefrog
fix time.localtime call for python 2.3
559
        t = time.time()
2215.6.1 by James Henstridge
Don't rely on time.timezone and time.altzone in local_time_offset(),
560
    offset = datetime.fromtimestamp(t) - datetime.utcfromtimestamp(t)
561
    return offset.days * 86400 + offset.seconds
8 by mbp at sourcefrog
store committer's timezone in revision and show
562
563
    
1185.12.24 by Aaron Bentley
Made format_date more flexible
564
def format_date(t, offset=0, timezone='original', date_fmt=None, 
565
                show_offset=True):
1 by mbp at sourcefrog
import from baz patch-364
566
    ## TODO: Perhaps a global option to use either universal or local time?
567
    ## Or perhaps just let people set $TZ?
568
    assert isinstance(t, float)
569
    
8 by mbp at sourcefrog
store committer's timezone in revision and show
570
    if timezone == 'utc':
1 by mbp at sourcefrog
import from baz patch-364
571
        tt = time.gmtime(t)
572
        offset = 0
8 by mbp at sourcefrog
store committer's timezone in revision and show
573
    elif timezone == 'original':
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
574
        if offset is None:
23 by mbp at sourcefrog
format_date: handle revisions with no timezone offset
575
            offset = 0
16 by mbp at sourcefrog
fix inverted calculation for original timezone -> utc
576
        tt = time.gmtime(t + offset)
12 by mbp at sourcefrog
new --timezone option for bzr log
577
    elif timezone == 'local':
1 by mbp at sourcefrog
import from baz patch-364
578
        tt = time.localtime(t)
49 by mbp at sourcefrog
fix local-time-offset calculation
579
        offset = local_time_offset(t)
12 by mbp at sourcefrog
new --timezone option for bzr log
580
    else:
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
581
        raise errors.BzrError("unsupported timezone format %r" % timezone,
582
                              ['options are "utc", "original", "local"'])
1185.12.24 by Aaron Bentley
Made format_date more flexible
583
    if date_fmt is None:
584
        date_fmt = "%a %Y-%m-%d %H:%M:%S"
585
    if show_offset:
586
        offset_str = ' %+03d%02d' % (offset / 3600, (offset / 60) % 60)
587
    else:
588
        offset_str = ''
589
    return (time.strftime(date_fmt, tt) +  offset_str)
1 by mbp at sourcefrog
import from baz patch-364
590
591
592
def compact_date(when):
593
    return time.strftime('%Y%m%d%H%M%S', time.gmtime(when))
594
    
595
1957.1.4 by John Arbash Meinel
create a helper for formatting a time delta
596
def format_delta(delta):
597
    """Get a nice looking string for a time delta.
598
599
    :param delta: The time difference in seconds, can be positive or negative.
600
        positive indicates time in the past, negative indicates time in the
601
        future. (usually time.time() - stored_time)
602
    :return: String formatted to show approximate resolution
603
    """
604
    delta = int(delta)
605
    if delta >= 0:
606
        direction = 'ago'
607
    else:
608
        direction = 'in the future'
609
        delta = -delta
610
611
    seconds = delta
612
    if seconds < 90: # print seconds up to 90 seconds
613
        if seconds == 1:
614
            return '%d second %s' % (seconds, direction,)
615
        else:
616
            return '%d seconds %s' % (seconds, direction)
617
618
    minutes = int(seconds / 60)
619
    seconds -= 60 * minutes
620
    if seconds == 1:
621
        plural_seconds = ''
622
    else:
623
        plural_seconds = 's'
624
    if minutes < 90: # print minutes, seconds up to 90 minutes
625
        if minutes == 1:
626
            return '%d minute, %d second%s %s' % (
627
                    minutes, seconds, plural_seconds, direction)
628
        else:
629
            return '%d minutes, %d second%s %s' % (
630
                    minutes, seconds, plural_seconds, direction)
631
632
    hours = int(minutes / 60)
633
    minutes -= 60 * hours
634
    if minutes == 1:
635
        plural_minutes = ''
636
    else:
637
        plural_minutes = 's'
638
639
    if hours == 1:
640
        return '%d hour, %d minute%s %s' % (hours, minutes,
641
                                            plural_minutes, direction)
642
    return '%d hours, %d minute%s %s' % (hours, minutes,
643
                                         plural_minutes, direction)
1 by mbp at sourcefrog
import from baz patch-364
644
645
def filesize(f):
646
    """Return size of given open file."""
647
    return os.fstat(f.fileno())[ST_SIZE]
648
1553.5.5 by Martin Pool
New utility routine rand_chars
649
1185.1.7 by Robert Collins
Nathaniel McCallums patch for urandom friendliness on aix.
650
# Define rand_bytes based on platform.
651
try:
652
    # Python 2.4 and later have os.urandom,
653
    # but it doesn't work on some arches
654
    os.urandom(1)
1 by mbp at sourcefrog
import from baz patch-364
655
    rand_bytes = os.urandom
1185.1.7 by Robert Collins
Nathaniel McCallums patch for urandom friendliness on aix.
656
except (NotImplementedError, AttributeError):
657
    # If python doesn't have os.urandom, or it doesn't work,
658
    # then try to first pull random data from /dev/urandom
2067.1.1 by John Arbash Meinel
Catch an exception while opening /dev/urandom rather than using os.path.exists()
659
    try:
1185.1.7 by Robert Collins
Nathaniel McCallums patch for urandom friendliness on aix.
660
        rand_bytes = file('/dev/urandom', 'rb').read
661
    # Otherwise, use this hack as a last resort
2067.1.1 by John Arbash Meinel
Catch an exception while opening /dev/urandom rather than using os.path.exists()
662
    except (IOError, OSError):
1185.1.7 by Robert Collins
Nathaniel McCallums patch for urandom friendliness on aix.
663
        # not well seeded, but better than nothing
664
        def rand_bytes(n):
665
            import random
666
            s = ''
667
            while n:
668
                s += chr(random.randint(0, 255))
669
                n -= 1
670
            return s
1 by mbp at sourcefrog
import from baz patch-364
671
1553.5.5 by Martin Pool
New utility routine rand_chars
672
673
ALNUM = '0123456789abcdefghijklmnopqrstuvwxyz'
674
def rand_chars(num):
675
    """Return a random string of num alphanumeric characters
676
    
677
    The result only contains lowercase chars because it may be used on 
678
    case-insensitive filesystems.
679
    """
680
    s = ''
681
    for raw_byte in rand_bytes(num):
682
        s += ALNUM[ord(raw_byte) % 36]
683
    return s
684
685
1 by mbp at sourcefrog
import from baz patch-364
686
## TODO: We could later have path objects that remember their list
1759.2.2 by Jelmer Vernooij
Revert some of my spelling fixes and fix some typos after review by Aaron.
687
## decomposition (might be too tricksy though.)
1 by mbp at sourcefrog
import from baz patch-364
688
689
def splitpath(p):
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
690
    """Turn string into list of parts."""
691
    assert isinstance(p, basestring)
271 by Martin Pool
- Windows path fixes
692
693
    # split on either delimiter because people might use either on
694
    # Windows
695
    ps = re.split(r'[\\/]', p)
696
697
    rps = []
1 by mbp at sourcefrog
import from baz patch-364
698
    for f in ps:
699
        if f == '..':
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
700
            raise errors.BzrError("sorry, %r not allowed in path" % f)
271 by Martin Pool
- Windows path fixes
701
        elif (f == '.') or (f == ''):
702
            pass
703
        else:
704
            rps.append(f)
705
    return rps
1 by mbp at sourcefrog
import from baz patch-364
706
707
def joinpath(p):
708
    assert isinstance(p, list)
709
    for f in p:
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
710
        if (f == '..') or (f is None) or (f == ''):
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
711
            raise errors.BzrError("sorry, %r not allowed in path" % f)
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
712
    return pathjoin(*p)
1 by mbp at sourcefrog
import from baz patch-364
713
714
1732.1.1 by John Arbash Meinel
deprecating appendpath, it does exactly what pathjoin does
715
@deprecated_function(zero_nine)
1 by mbp at sourcefrog
import from baz patch-364
716
def appendpath(p1, p2):
717
    if p1 == '':
718
        return p2
719
    else:
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
720
        return pathjoin(p1, p2)
1 by mbp at sourcefrog
import from baz patch-364
721
    
722
1231 by Martin Pool
- more progress on fetch on top of weaves
723
def split_lines(s):
724
    """Split s into lines, but without removing the newline characters."""
1666.1.6 by Robert Collins
Make knit the default format.
725
    lines = s.split('\n')
726
    result = [line + '\n' for line in lines[:-1]]
727
    if lines[-1]:
728
        result.append(lines[-1])
729
    return result
1391 by Robert Collins
merge from integration
730
731
1185.10.4 by Aaron Bentley
Disabled hardlinks on cygwin, mac OS
732
def hardlinks_good():
1185.10.5 by Aaron Bentley
Fixed hardlinks_good test
733
    return sys.platform not in ('win32', 'cygwin', 'darwin')
1185.10.4 by Aaron Bentley
Disabled hardlinks on cygwin, mac OS
734
1185.1.46 by Robert Collins
Aarons branch --basis patch
735
1185.10.3 by Aaron Bentley
Made copy_multi_immutable create hardlinks opportunistically
736
def link_or_copy(src, dest):
737
    """Hardlink a file, or copy it if it can't be hardlinked."""
1185.10.4 by Aaron Bentley
Disabled hardlinks on cygwin, mac OS
738
    if not hardlinks_good():
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
739
        shutil.copyfile(src, dest)
1185.10.3 by Aaron Bentley
Made copy_multi_immutable create hardlinks opportunistically
740
        return
741
    try:
742
        os.link(src, dest)
743
    except (OSError, IOError), e:
744
        if e.errno != errno.EXDEV:
745
            raise
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
746
        shutil.copyfile(src, dest)
1399.1.4 by Robert Collins
move diff and symlink conditionals into inventory.py from diff.py
747
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
748
def delete_any(full_path):
749
    """Delete a file or directory."""
750
    try:
751
        os.unlink(full_path)
752
    except OSError, e:
753
    # We may be renaming a dangling inventory id
754
        if e.errno not in (errno.EISDIR, errno.EACCES, errno.EPERM):
755
            raise
756
        os.rmdir(full_path)
757
1399.1.4 by Robert Collins
move diff and symlink conditionals into inventory.py from diff.py
758
759
def has_symlinks():
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
760
    if getattr(os, 'symlink', None) is not None:
1399.1.4 by Robert Collins
move diff and symlink conditionals into inventory.py from diff.py
761
        return True
762
    else:
763
        return False
1185.16.38 by Martin Pool
- move contains_whitespace and contains_linebreaks to osutils
764
        
765
766
def contains_whitespace(s):
767
    """True if there are any whitespace characters in s."""
768
    for ch in string.whitespace:
769
        if ch in s:
770
            return True
771
    else:
772
        return False
773
774
775
def contains_linebreaks(s):
776
    """True if there is any vertical whitespace in s."""
777
    for ch in '\f\n\r':
778
        if ch in s:
779
            return True
780
    else:
781
        return False
1457.1.2 by Robert Collins
move branch._relpath into osutils as relpath
782
783
784
def relpath(base, path):
785
    """Return path relative to base, or raise exception.
786
787
    The path may be either an absolute path or a path relative to the
788
    current working directory.
789
790
    os.path.commonprefix (python2.4) has a bad bug that it works just
791
    on string prefixes, assuming that '/u' is a prefix of '/u2'.  This
1636.1.1 by Robert Collins
Fix calling relpath() and abspath() on transports at their root.
792
    avoids that problem.
793
    """
1685.1.12 by John Arbash Meinel
Some more work to get LocalTransport to only support URLs
794
1551.2.53 by abentley
Strip trailing slashes in a platform-sensible way
795
    assert len(base) >= MIN_ABS_PATHLENGTH, ('Length of base must be equal or'
796
        ' exceed the platform minimum length (which is %d)' % 
797
        MIN_ABS_PATHLENGTH)
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
798
1685.1.12 by John Arbash Meinel
Some more work to get LocalTransport to only support URLs
799
    rp = abspath(path)
1457.1.2 by Robert Collins
move branch._relpath into osutils as relpath
800
801
    s = []
1685.1.12 by John Arbash Meinel
Some more work to get LocalTransport to only support URLs
802
    head = rp
1457.1.2 by Robert Collins
move branch._relpath into osutils as relpath
803
    while len(head) >= len(base):
804
        if head == base:
805
            break
806
        head, tail = os.path.split(head)
807
        if tail:
808
            s.insert(0, tail)
809
    else:
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
810
        raise errors.PathNotChild(rp, base)
1457.1.2 by Robert Collins
move branch._relpath into osutils as relpath
811
1185.31.35 by John Arbash Meinel
Couple small fixes, all tests pass on cygwin.
812
    if s:
813
        return pathjoin(*s)
814
    else:
815
        return ''
1185.33.60 by Martin Pool
Use full terminal width for verbose test output.
816
817
1534.3.1 by Robert Collins
* bzrlib.osutils.safe_unicode now exists to provide parameter coercion
818
def safe_unicode(unicode_or_utf8_string):
819
    """Coerce unicode_or_utf8_string into unicode.
820
821
    If it is unicode, it is returned.
822
    Otherwise it is decoded from utf-8. If a decoding error
823
    occurs, it is wrapped as a If the decoding fails, the exception is wrapped 
824
    as a BzrBadParameter exception.
825
    """
826
    if isinstance(unicode_or_utf8_string, unicode):
827
        return unicode_or_utf8_string
828
    try:
829
        return unicode_or_utf8_string.decode('utf8')
830
    except UnicodeDecodeError:
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
831
        raise errors.BzrBadParameterNotUnicode(unicode_or_utf8_string)
1534.3.1 by Robert Collins
* bzrlib.osutils.safe_unicode now exists to provide parameter coercion
832
833
1185.85.75 by John Arbash Meinel
Adding bzrlib.osutils.unicode_filename to handle unicode normalization for file paths.
834
_platform_normalizes_filenames = False
835
if sys.platform == 'darwin':
836
    _platform_normalizes_filenames = True
837
838
839
def normalizes_filenames():
840
    """Return True if this platform normalizes unicode filenames.
841
842
    Mac OSX does, Windows/Linux do not.
843
    """
844
    return _platform_normalizes_filenames
845
846
1830.3.2 by John Arbash Meinel
normalized_filename is a much better name
847
def _accessible_normalized_filename(path):
1830.3.1 by John Arbash Meinel
Change the return value of unicode_filename, and make it testable on all platforms
848
    """Get the unicode normalized path, and if you can access the file.
849
850
    On platforms where the system normalizes filenames (Mac OSX),
851
    you can access a file by any path which will normalize correctly.
852
    On platforms where the system does not normalize filenames 
853
    (Windows, Linux), you have to access a file by its exact path.
854
855
    Internally, bzr only supports NFC/NFKC normalization, since that is 
856
    the standard for XML documents.
857
858
    So return the normalized path, and a flag indicating if the file
859
    can be accessed by that path.
860
    """
861
1830.3.8 by John Arbash Meinel
unicodedata.normalize requires unicode strings
862
    return unicodedata.normalize('NFKC', unicode(path)), True
1830.3.1 by John Arbash Meinel
Change the return value of unicode_filename, and make it testable on all platforms
863
864
1830.3.2 by John Arbash Meinel
normalized_filename is a much better name
865
def _inaccessible_normalized_filename(path):
866
    __doc__ = _accessible_normalized_filename.__doc__
1830.3.1 by John Arbash Meinel
Change the return value of unicode_filename, and make it testable on all platforms
867
1830.3.8 by John Arbash Meinel
unicodedata.normalize requires unicode strings
868
    normalized = unicodedata.normalize('NFKC', unicode(path))
1830.3.1 by John Arbash Meinel
Change the return value of unicode_filename, and make it testable on all platforms
869
    return normalized, normalized == path
870
871
1185.85.75 by John Arbash Meinel
Adding bzrlib.osutils.unicode_filename to handle unicode normalization for file paths.
872
if _platform_normalizes_filenames:
1830.3.2 by John Arbash Meinel
normalized_filename is a much better name
873
    normalized_filename = _accessible_normalized_filename
1185.85.75 by John Arbash Meinel
Adding bzrlib.osutils.unicode_filename to handle unicode normalization for file paths.
874
else:
1830.3.2 by John Arbash Meinel
normalized_filename is a much better name
875
    normalized_filename = _inaccessible_normalized_filename
1185.85.75 by John Arbash Meinel
Adding bzrlib.osutils.unicode_filename to handle unicode normalization for file paths.
876
877
1185.33.60 by Martin Pool
Use full terminal width for verbose test output.
878
def terminal_width():
879
    """Return estimated terminal width."""
1704.2.3 by Martin Pool
(win32) Detect terminal width using GetConsoleScreenBufferInfo (Alexander)
880
    if sys.platform == 'win32':
881
        import bzrlib.win32console
882
        return bzrlib.win32console.get_console_size()[0]
1704.2.2 by Martin Pool
Detect terminal width using ioctl
883
    width = 0
1185.33.60 by Martin Pool
Use full terminal width for verbose test output.
884
    try:
1704.2.2 by Martin Pool
Detect terminal width using ioctl
885
        import struct, fcntl, termios
886
        s = struct.pack('HHHH', 0, 0, 0, 0)
887
        x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
888
        width = struct.unpack('HHHH', x)[1]
889
    except IOError:
890
        pass
891
    if width <= 0:
892
        try:
893
            width = int(os.environ['COLUMNS'])
894
        except:
895
            pass
896
    if width <= 0:
897
        width = 80
898
899
    return width
1534.7.25 by Aaron Bentley
Added set_executability
900
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
901
1534.7.25 by Aaron Bentley
Added set_executability
902
def supports_executable():
1534.7.160 by Aaron Bentley
Changed implementation of supports_executable
903
    return sys.platform != "win32"
1551.2.53 by abentley
Strip trailing slashes in a platform-sensible way
904
905
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
906
def set_or_unset_env(env_variable, value):
907
    """Modify the environment, setting or removing the env_variable.
908
909
    :param env_variable: The environment variable in question
910
    :param value: The value to set the environment to. If None, then
911
        the variable will be removed.
912
    :return: The original value of the environment variable.
913
    """
914
    orig_val = os.environ.get(env_variable)
915
    if value is None:
916
        if orig_val is not None:
917
            del os.environ[env_variable]
918
    else:
919
        if isinstance(value, unicode):
920
            value = value.encode(bzrlib.user_encoding)
921
        os.environ[env_variable] = value
922
    return orig_val
923
924
1551.2.56 by Aaron Bentley
Better illegal pathname check for Windows
925
_validWin32PathRE = re.compile(r'^([A-Za-z]:[/\\])?[^:<>*"?\|]*$')
926
927
928
def check_legal_path(path):
929
    """Check whether the supplied path is legal.  
930
    This is only required on Windows, so we don't test on other platforms
931
    right now.
932
    """
933
    if sys.platform != "win32":
934
        return
935
    if _validWin32PathRE.match(path) is None:
1996.3.25 by John Arbash Meinel
Make importing errors lazy for osutils
936
        raise errors.IllegalPath(path)
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
937
938
1757.2.8 by Robert Collins
Teach walkdirs to walk a subdir of a tree.
939
def walkdirs(top, prefix=""):
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
940
    """Yield data about all the directories in a tree.
941
    
942
    This yields all the data about the contents of a directory at a time.
943
    After each directory has been yielded, if the caller has mutated the list
944
    to exclude some directories, they are then not descended into.
945
    
946
    The data yielded is of the form:
1897.1.2 by Robert Collins
cleanup osutils.walkdirs changes after review.
947
    ((directory-relpath, directory-path-from-top),
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
948
    [(relpath, basename, kind, lstat), ...]),
1897.1.2 by Robert Collins
cleanup osutils.walkdirs changes after review.
949
     - directory-relpath is the relative path of the directory being returned
950
       with respect to top. prefix is prepended to this.
951
     - directory-path-from-root is the path including top for this directory. 
952
       It is suitable for use with os functions.
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
953
     - relpath is the relative path within the subtree being walked.
954
     - basename is the basename of the path
1897.1.2 by Robert Collins
cleanup osutils.walkdirs changes after review.
955
     - kind is the kind of the file now. If unknown then the file is not
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
956
       present within the tree - but it may be recorded as versioned. See
957
       versioned_kind.
958
     - lstat is the stat data *if* the file was statted.
959
     - planned, not implemented: 
960
       path_from_tree_root is the path from the root of the tree.
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
961
1757.2.16 by Robert Collins
Review comments.
962
    :param prefix: Prefix the relpaths that are yielded with 'prefix'. This 
963
        allows one to walk a subtree but get paths that are relative to a tree
964
        rooted higher up.
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
965
    :return: an iterator over the dirs.
966
    """
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
967
    #TODO there is a bit of a smell where the results of the directory-
968
    # summary in this, and the path from the root, may not agree 
969
    # depending on top and prefix - i.e. ./foo and foo as a pair leads to
970
    # potentially confusing output. We should make this more robust - but
1897.1.2 by Robert Collins
cleanup osutils.walkdirs changes after review.
971
    # not at a speed cost. RBC 20060731
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
972
    lstat = os.lstat
973
    pending = []
974
    _directory = _directory_kind
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
975
    _listdir = os.listdir
1757.2.8 by Robert Collins
Teach walkdirs to walk a subdir of a tree.
976
    pending = [(prefix, "", _directory, None, top)]
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
977
    while pending:
978
        dirblock = []
979
        currentdir = pending.pop()
980
        # 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
981
        top = currentdir[4]
982
        if currentdir[0]:
983
            relroot = currentdir[0] + '/'
984
        else:
985
            relroot = ""
986
        for name in sorted(_listdir(top)):
987
            abspath = top + '/' + name
988
            statvalue = lstat(abspath)
1897.1.2 by Robert Collins
cleanup osutils.walkdirs changes after review.
989
            dirblock.append((relroot + name, name,
990
                file_kind_from_stat_mode(statvalue.st_mode),
991
                statvalue, abspath))
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
992
        yield (currentdir[0], top), dirblock
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
993
        # push the user specified dirs from dirblock
994
        for dir in reversed(dirblock):
995
            if dir[2] == _directory:
996
                pending.append(dir)
1773.3.1 by Robert Collins
Add path_prefix_key and compare_paths_prefix_order utility functions.
997
998
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
999
def copy_tree(from_path, to_path, handlers={}):
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1000
    """Copy all of the entries in from_path into to_path.
1001
1002
    :param from_path: The base directory to copy. 
1003
    :param to_path: The target directory. If it does not exist, it will
1004
        be created.
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
1005
    :param handlers: A dictionary of functions, which takes a source and
1006
        destinations for files, directories, etc.
1007
        It is keyed on the file kind, such as 'directory', 'symlink', or 'file'
1008
        'file', 'directory', and 'symlink' should always exist.
1009
        If they are missing, they will be replaced with 'os.mkdir()',
1010
        'os.readlink() + os.symlink()', and 'shutil.copy2()', respectively.
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1011
    """
1012
    # Now, just copy the existing cached tree to the new location
1013
    # We use a cheap trick here.
1014
    # Absolute paths are prefixed with the first parameter
1015
    # relative paths are prefixed with the second.
1016
    # So we can get both the source and target returned
1017
    # without any extra work.
1018
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
1019
    def copy_dir(source, dest):
1020
        os.mkdir(dest)
1021
1022
    def copy_link(source, dest):
1023
        """Copy the contents of a symlink"""
1024
        link_to = os.readlink(source)
1025
        os.symlink(link_to, dest)
1026
1027
    real_handlers = {'file':shutil.copy2,
1028
                     'symlink':copy_link,
1029
                     'directory':copy_dir,
1030
                    }
1031
    real_handlers.update(handlers)
1032
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1033
    if not os.path.exists(to_path):
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
1034
        real_handlers['directory'](from_path, to_path)
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1035
1036
    for dir_info, entries in walkdirs(from_path, prefix=to_path):
1037
        for relpath, name, kind, st, abspath in entries:
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
1038
            real_handlers[kind](abspath, relpath)
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1039
1040
1773.3.1 by Robert Collins
Add path_prefix_key and compare_paths_prefix_order utility functions.
1041
def path_prefix_key(path):
1042
    """Generate a prefix-order path key for path.
1043
1044
    This can be used to sort paths in the same way that walkdirs does.
1045
    """
1773.3.2 by Robert Collins
New corner case from John Meinel, showing up the need to check the directory lexographically outside of a single tree's root. Fixed.
1046
    return (dirname(path) , path)
1773.3.1 by Robert Collins
Add path_prefix_key and compare_paths_prefix_order utility functions.
1047
1048
1049
def compare_paths_prefix_order(path_a, path_b):
1050
    """Compare path_a and path_b to generate the same order walkdirs uses."""
1051
    key_a = path_prefix_key(path_a)
1052
    key_b = path_prefix_key(path_b)
1053
    return cmp(key_a, key_b)
1955.2.2 by John Arbash Meinel
Change the name of the test classes (test_lang => test_locale), move the function into osutils.py
1054
1055
1056
_cached_user_encoding = None
1057
1058
1059
def get_user_encoding():
1060
    """Find out what the preferred user encoding is.
1061
1062
    This is generally the encoding that is used for command line parameters
1063
    and file contents. This may be different from the terminal encoding
1064
    or the filesystem encoding.
1065
1066
    :return: A string defining the preferred user encoding
1067
    """
1068
    global _cached_user_encoding
1069
    if _cached_user_encoding is not None:
1070
        return _cached_user_encoding
1071
1072
    if sys.platform == 'darwin':
1073
        # work around egregious python 2.4 bug
1074
        sys.platform = 'posix'
1075
        try:
1076
            import locale
1077
        finally:
1078
            sys.platform = 'darwin'
1079
    else:
1080
        import locale
1081
1082
    try:
1083
        _cached_user_encoding = locale.getpreferredencoding()
1084
    except locale.Error, e:
1955.2.3 by John Arbash Meinel
Change error message text
1085
        sys.stderr.write('bzr: warning: %s\n'
2001.2.1 by Jelmer Vernooij
Fix typo in encoding warning.
1086
                         '  Could not determine what text encoding to use.\n'
1955.2.3 by John Arbash Meinel
Change error message text
1087
                         '  This error usually means your Python interpreter\n'
1088
                         '  doesn\'t support the locale set by $LANG (%s)\n'
1089
                         "  Continuing with ascii encoding.\n"
1955.2.2 by John Arbash Meinel
Change the name of the test classes (test_lang => test_locale), move the function into osutils.py
1090
                         % (e, os.environ.get('LANG')))
1091
2127.4.1 by Alexander Belchenko
(jam, bialix) Workaround for cp0 console encoding on Windows
1092
    # Windows returns 'cp0' to indicate there is no code page. So we'll just
1093
    # treat that as ASCII, and not support printing unicode characters to the
1094
    # console.
1095
    if _cached_user_encoding in (None, 'cp0'):
1955.2.2 by John Arbash Meinel
Change the name of the test classes (test_lang => test_locale), move the function into osutils.py
1096
        _cached_user_encoding = 'ascii'
1097
    return _cached_user_encoding
2091.1.1 by Martin Pool
Avoid MSG_WAITALL as it doesn't work on Windows
1098
1099
1100
def recv_all(socket, bytes):
1101
    """Receive an exact number of bytes.
1102
1103
    Regular Socket.recv() may return less than the requested number of bytes,
1104
    dependning on what's in the OS buffer.  MSG_WAITALL is not available
1105
    on all platforms, but this should work everywhere.  This will return
1106
    less than the requested amount if the remote end closes.
1107
1108
    This isn't optimized and is intended mostly for use in testing.
1109
    """
1110
    b = ''
1111
    while len(b) < bytes:
1112
        new = socket.recv(bytes - len(b))
1113
        if new == '':
1114
            break # eof
1115
        b += new
1116
    return b
1117
2091.3.7 by Aaron Bentley
Rename real_parent to dereferenced_path
1118
def dereference_path(path):
1119
    """Determine the real path to a file.
1120
1121
    All parent elements are dereferenced.  But the file itself is not
1122
    dereferenced.
1123
    :param path: The original path.  May be absolute or relative.
1124
    :return: the real path *to* the file
1125
    """
2091.3.5 by Aaron Bentley
Move realpath functionality into osutils
1126
    parent, base = os.path.split(path)
1127
    # The pathjoin for '.' is a workaround for Python bug #1213894.
1128
    # (initial path components aren't dereferenced)
1129
    return pathjoin(realpath(pathjoin('.', parent)), base)