| # Copyright 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import posixpath |
| |
| |
| # TODO(kalman): Write a Path class and use that everywhere rather than a |
| # utility class. |
| |
| |
| def IsDirectory(path): |
| '''Returns whether |path| should be considered a directory. |
| ''' |
| # This assertion is sprinkled throughout the code base. |
| AssertIsValid(path) |
| return path in ('', '.', '..') or path.endswith('/') or path.endswith('/..') |
| |
| |
| def IsValid(path): |
| '''Returns whether |path| is a valid path for the purposes of the docserver. |
| Paths may not start with /, must be posix paths, and for sanity shouldn't |
| repeat the path separator //. |
| ''' |
| return not path.startswith('/') and not '\\' in path and not '//' in path |
| |
| |
| def AssertIsValid(path): |
| assert IsValid(path), 'Path "%s" is invalid' % path |
| |
| |
| def Join(*paths): |
| assert all(IsValid(path) for path in paths), paths |
| return posixpath.join(*paths) |
| |
| |
| def SplitParent(path): |
| '''Returns the parent directory and base name of |path| in a tuple. |
| Any trailing slash of |path| is preserved, such that the parent of |
| '/hello/world/' is '/hello' and the base is 'world/'. |
| ''' |
| parent, base = posixpath.split(path.rstrip('/')) |
| if path.endswith('/'): |
| base += '/' |
| return parent, base |
| |
| |
| def Split(path): |
| '''Returns a list of the directories and filename in a path. 'p1/p2/p3' |
| will return ['p1/', 'p2/', 'p3']. |
| ''' |
| AssertIsValid(path) |
| names = [name + '/' for name in path.rstrip('/').split('/')] |
| if names and not path.endswith('/'): |
| names[-1] = names[-1][:-1] |
| return names |
| |
| |
| def ToDirectory(path): |
| '''Returns a string representing |path| as a directory, that is, |
| IsDirectory(result) is True (and does not fail assertions). If |path| is |
| already a directory then this is a no-op. |
| ''' |
| return path if IsDirectory(path) else (path + '/') |
| |
| |
| def AssertIsDirectory(path): |
| assert IsDirectory(path), '"%s" is not a directory' % path |
| |
| |
| def AssertIsFile(path): |
| assert not IsDirectory(path), '"%s" is not a file' % path |
| |
| def Segment(path): |
| '''Yields a tuple (url, file) for directory split pairs. |
| For example, if we split the path 'foo/bar/baz', it will yield: |
| ('', 'foo/bar/baz'), ('foo', "bar/baz'), ('foo/bar', 'baz'), |
| ('foo/bar/baz', '') |
| ''' |
| AssertIsValid(path) |
| |
| last_path = '' |
| yield (last_path, path) |
| |
| for segment in (segment for segment in path.split('/') if segment != ''): |
| last_path = posixpath.join(last_path, segment) |
| rel_path = posixpath.relpath(path, last_path) |
| |
| # Don't let relpath say the filename is '.' |
| if rel_path == '.': |
| rel_path = '' |
| else: |
| last_path = ToDirectory(last_path) |
| |
| yield (last_path, rel_path) |