~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

(mbp) merge bzr.dev to 0.8, prepare for release

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
import os
25
25
import re
26
26
import sha
 
27
import shutil
27
28
import string
28
29
import sys
29
30
import time
35
36
                           BzrBadParameterNotUnicode,
36
37
                           NoSuchFile,
37
38
                           PathNotChild,
 
39
                           IllegalPath,
38
40
                           )
39
41
from bzrlib.trace import mutter
40
42
 
170
172
            else:
171
173
                rename_func(tmp_name, new)
172
174
 
173
 
# Default is to just use the python builtins
 
175
# Default is to just use the python builtins, but these can be rebound on
 
176
# particular platforms.
174
177
abspath = os.path.abspath
175
178
realpath = os.path.realpath
176
179
pathjoin = os.path.join
180
183
rename = os.rename
181
184
dirname = os.path.dirname
182
185
basename = os.path.basename
 
186
rmtree = shutil.rmtree
 
187
 
 
188
MIN_ABS_PATHLENGTH = 1
183
189
 
184
190
if os.name == "posix":
185
191
    # In Python 2.4.2 and older, os.path.abspath and os.path.realpath
217
223
    def rename(old, new):
218
224
        fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
219
225
 
 
226
    MIN_ABS_PATHLENGTH = 3
 
227
 
 
228
    def _win32_delete_readonly(function, path, excinfo):
 
229
        """Error handler for shutil.rmtree function [for win32]
 
230
        Helps to remove files and dirs marked as read-only.
 
231
        """
 
232
        type_, value = excinfo[:2]
 
233
        if function in (os.remove, os.rmdir) \
 
234
            and type_ == OSError \
 
235
            and value.errno == errno.EACCES:
 
236
            bzrlib.osutils.make_writable(path)
 
237
            function(path)
 
238
        else:
 
239
            raise
 
240
 
 
241
    def rmtree(path, ignore_errors=False, onerror=_win32_delete_readonly):
 
242
        """Replacer for shutil.rmtree: could remove readonly dirs/files"""
 
243
        return shutil.rmtree(path, ignore_errors, onerror)
 
244
 
220
245
 
221
246
def normalizepath(f):
222
247
    if hasattr(os.path, 'realpath'):
530
555
 
531
556
def split_lines(s):
532
557
    """Split s into lines, but without removing the newline characters."""
533
 
    return StringIO(s).readlines()
 
558
    lines = s.split('\n')
 
559
    result = [line + '\n' for line in lines[:-1]]
 
560
    if lines[-1]:
 
561
        result.append(lines[-1])
 
562
    return result
534
563
 
535
564
 
536
565
def hardlinks_good():
595
624
    on string prefixes, assuming that '/u' is a prefix of '/u2'.  This
596
625
    avoids that problem.
597
626
    """
598
 
    if sys.platform != "win32":
599
 
        minlength = 1
600
 
    else:
601
 
        minlength = 3
602
 
    assert len(base) >= minlength, ('Length of base must be equal or exceed the'
603
 
        ' platform minimum length (which is %d)' % minlength)
 
627
 
 
628
    assert len(base) >= MIN_ABS_PATHLENGTH, ('Length of base must be equal or'
 
629
        ' exceed the platform minimum length (which is %d)' % 
 
630
        MIN_ABS_PATHLENGTH)
604
631
    rp = abspath(path)
605
632
 
606
633
    s = []
653
680
 
654
681
def supports_executable():
655
682
    return sys.platform != "win32"
 
683
 
 
684
 
 
685
def strip_trailing_slash(path):
 
686
    """Strip trailing slash, except for root paths.
 
687
    The definition of 'root path' is platform-dependent.
 
688
    """
 
689
    if len(path) != MIN_ABS_PATHLENGTH and path[-1] == '/':
 
690
        return path[:-1]
 
691
    else:
 
692
        return path
 
693
 
 
694
 
 
695
_validWin32PathRE = re.compile(r'^([A-Za-z]:[/\\])?[^:<>*"?\|]*$')
 
696
 
 
697
 
 
698
def check_legal_path(path):
 
699
    """Check whether the supplied path is legal.  
 
700
    This is only required on Windows, so we don't test on other platforms
 
701
    right now.
 
702
    """
 
703
    if sys.platform != "win32":
 
704
        return
 
705
    if _validWin32PathRE.match(path) is None:
 
706
        raise IllegalPath(path)