Rename WebKitTools to Tools
[WebKit-https.git] / Tools / Scripts / webkitpy / common / system / ospath.py
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