~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

merge cicp patch, correct rest syntax and news typo

Show diffs side-by-side

added added

removed removed

Lines of Context:
962
962
        return ''
963
963
 
964
964
 
 
965
def _cicp_canonical_relpath(base, path):
 
966
    """Return the canonical path relative to base.
 
967
 
 
968
    Like relpath, but on case-insensitive-case-preserving file-systems, this
 
969
    will return the relpath as stored on the file-system rather than in the
 
970
    case specified in the input string, for all existing portions of the path.
 
971
 
 
972
    This will cause O(N) behaviour if called for every path in a tree; if you
 
973
    have a number of paths to convert, you should use canonical_relpaths().
 
974
    """
 
975
    # TODO: it should be possible to optimize this for Windows by using the
 
976
    # win32 API FindFiles function to look for the specified name - but using
 
977
    # os.listdir() still gives us the correct, platform agnostic semantics in
 
978
    # the short term.
 
979
 
 
980
    rel = relpath(base, path)
 
981
    # '.' will have been turned into ''
 
982
    if not rel:
 
983
        return rel
 
984
 
 
985
    abs_base = abspath(base)
 
986
    current = abs_base
 
987
    _listdir = os.listdir
 
988
 
 
989
    # use an explicit iterator so we can easily consume the rest on early exit.
 
990
    bit_iter = iter(rel.split('/'))
 
991
    for bit in bit_iter:
 
992
        lbit = bit.lower()
 
993
        for look in _listdir(current):
 
994
            if lbit == look.lower():
 
995
                current = pathjoin(current, look)
 
996
                break
 
997
        else:
 
998
            # got to the end, nothing matched, so we just return the
 
999
            # non-existing bits as they were specified (the filename may be
 
1000
            # the target of a move, for example).
 
1001
            current = pathjoin(current, bit, *list(bit_iter))
 
1002
            break
 
1003
    return current[len(abs_base)+1:]
 
1004
 
 
1005
# XXX - TODO - we need better detection/integration of case-insensitive
 
1006
# file-systems; Linux often sees FAT32 devices, for example, so could
 
1007
# probably benefit from the same basic support there.  For now though, only
 
1008
# Windows gets that support, and it gets it for *all* file-systems!
 
1009
if sys.platform == "win32":
 
1010
    canonical_relpath = _cicp_canonical_relpath
 
1011
else:
 
1012
    canonical_relpath = relpath
 
1013
 
 
1014
def canonical_relpaths(base, paths):
 
1015
    """Create an iterable to canonicalize a sequence of relative paths.
 
1016
 
 
1017
    The intent is for this implementation to use a cache, vastly speeding
 
1018
    up multiple transformations in the same directory.
 
1019
    """
 
1020
    # but for now, we haven't optimized...
 
1021
    return [canonical_relpath(base, p) for p in paths]
 
1022
 
965
1023
def safe_unicode(unicode_or_utf8_string):
966
1024
    """Coerce unicode_or_utf8_string into unicode.
967
1025