WebKitTools/Scripts/webkitpy/common/system/ospath.py
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
       
     2 #
       
     3 # Redistribution and use in source and binary forms, with or without
       
     4 # modification, are permitted provided that the following conditions
       
     5 # are met:
       
     6 # 1.  Redistributions of source code must retain the above copyright
       
     7 #     notice, this list of conditions and the following disclaimer.
       
     8 # 2.  Redistributions in binary form must reproduce the above copyright
       
     9 #     notice, this list of conditions and the following disclaimer in the
       
    10 #     documentation and/or other materials provided with the distribution.
       
    11 #
       
    12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
       
    13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
       
    16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
       
    18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
       
    19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
       
    20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    22 
       
    23 """Contains a substitute for Python 2.6's os.path.relpath()."""
       
    24 
       
    25 import os
       
    26 
       
    27 
       
    28 # This function is a replacement for os.path.relpath(), which is only
       
    29 # available in Python 2.6:
       
    30 #
       
    31 # http://docs.python.org/library/os.path.html#os.path.relpath
       
    32 #
       
    33 # It should behave essentially the same as os.path.relpath(), except for
       
    34 # returning None on paths not contained in abs_start_path.
       
    35 def relpath(path, start_path, os_path_abspath=None):
       
    36     """Return a path relative to the given start path, or None.
       
    37 
       
    38     Returns None if the path is not contained in the directory start_path.
       
    39 
       
    40     Args:
       
    41       path: An absolute or relative path to convert to a relative path.
       
    42       start_path: The path relative to which the given path should be
       
    43                   converted.
       
    44       os_path_abspath: A replacement function for unit testing.  This
       
    45                        function should strip trailing slashes just like
       
    46                        os.path.abspath().  Defaults to os.path.abspath.
       
    47 
       
    48     """
       
    49     if os_path_abspath is None:
       
    50         os_path_abspath = os.path.abspath
       
    51 
       
    52     # Since os_path_abspath() calls os.path.normpath()--
       
    53     #
       
    54     # (see http://docs.python.org/library/os.path.html#os.path.abspath )
       
    55     #
       
    56     # it also removes trailing slashes and converts forward and backward
       
    57     # slashes to the preferred slash os.sep.
       
    58     start_path = os_path_abspath(start_path)
       
    59     path = os_path_abspath(path)
       
    60 
       
    61     if not path.lower().startswith(start_path.lower()):
       
    62         # Then path is outside the directory given by start_path.
       
    63         return None
       
    64 
       
    65     rel_path = path[len(start_path):]
       
    66 
       
    67     if not rel_path:
       
    68         # Then the paths are the same.
       
    69         pass
       
    70     elif rel_path[0] == os.sep:
       
    71         # It is probably sufficient to remove just the first character
       
    72         # since os.path.normpath() collapses separators, but we use
       
    73         # lstrip() just to be sure.
       
    74         rel_path = rel_path.lstrip(os.sep)
       
    75     else:
       
    76         # We are in the case typified by the following example:
       
    77         #
       
    78         # start_path = "/tmp/foo"
       
    79         # path = "/tmp/foobar"
       
    80         # rel_path = "bar"
       
    81         return None
       
    82 
       
    83     return rel_path