15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import posixpath 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# TODO(kalman): Write a Path class and use that everywhere rather than a 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# utility class. 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def IsDirectory(path): 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '''Returns whether |path| should be considered a directory. 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ''' 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # This assertion is sprinkled throughout the code base. 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssertIsValid(path) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return path in ('', '.', '..') or path.endswith('/') or path.endswith('/..') 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def IsValid(path): 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '''Returns whether |path| is a valid path for the purposes of the docserver. 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Paths may not start with /, must be posix paths, and for sanity shouldn't 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) repeat the path separator //. 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ''' 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return not path.startswith('/') and not '\\' in path and not '//' in path 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def AssertIsValid(path): 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert IsValid(path), 'Path "%s" is invalid' % path 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def Join(*paths): 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert all(IsValid(path) for path in paths), paths 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return posixpath.join(*paths) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def SplitParent(path): 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '''Returns the parent directory and base name of |path| in a tuple. 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Any trailing slash of |path| is preserved, such that the parent of 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '/hello/world/' is '/hello' and the base is 'world/'. 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ''' 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) parent, base = posixpath.split(path.rstrip('/')) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if path.endswith('/'): 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base += '/' 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return parent, base 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def ToDirectory(path): 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '''Returns a string representing |path| as a directory, that is, 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IsDirectory(result) is True (and does not fail assertions). If |path| is 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) already a directory then this is a no-op. 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ''' 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return path if IsDirectory(path) else (path + '/') 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def AssertIsDirectory(path): 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert IsDirectory(path), '"%s" is not a directory' % path 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def AssertIsFile(path): 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert not IsDirectory(path), '"%s" is not a file' % path 62