| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import posixpath | 5 import posixpath |
| 6 import traceback | 6 import traceback |
| 7 | 7 |
| 8 from future import Future | 8 from future import Future |
| 9 from path_util import ( | 9 from path_util import ( |
| 10 AssertIsDirectory, AssertIsValid, IsDirectory, IsValid, SplitParent, | 10 AssertIsDirectory, AssertIsValid, IsDirectory, IsValid, SplitParent, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 - If |skip_not_found| is True, the resulting object will not contain any | 77 - If |skip_not_found| is True, the resulting object will not contain any |
| 78 mapping for that path. | 78 mapping for that path. |
| 79 - Otherwise, and by default, a FileNotFoundError is raised. This is | 79 - Otherwise, and by default, a FileNotFoundError is raised. This is |
| 80 guaranteed to only happen once the Future has been resolved (Get() | 80 guaranteed to only happen once the Future has been resolved (Get() |
| 81 called). | 81 called). |
| 82 | 82 |
| 83 For any other failure, raises a FileSystemError. | 83 For any other failure, raises a FileSystemError. |
| 84 ''' | 84 ''' |
| 85 raise NotImplementedError(self.__class__) | 85 raise NotImplementedError(self.__class__) |
| 86 | 86 |
| 87 def ReadSingle(self, path): | 87 def ReadSingle(self, path, skip_not_found=False): |
| 88 '''Reads a single file from the FileSystem. Returns a Future with the same | 88 '''Reads a single file from the FileSystem. Returns a Future with the same |
| 89 rules as Read(). If |path| is not found raise a FileNotFoundError on Get(). | 89 rules as Read(). If |path| is not found raise a FileNotFoundError on Get(), |
| 90 or if |skip_not_found| is True then return None. |
| 90 ''' | 91 ''' |
| 91 AssertIsValid(path) | 92 AssertIsValid(path) |
| 92 read_single = self.Read([path]) | 93 read_single = self.Read([path], skip_not_found=skip_not_found) |
| 93 return Future(callback=lambda: read_single.Get()[path]) | 94 return Future(callback=lambda: read_single.Get().get(path, None)) |
| 94 | 95 |
| 95 def Exists(self, path): | 96 def Exists(self, path): |
| 96 '''Returns a Future to the existence of |path|; True if |path| exists, | 97 '''Returns a Future to the existence of |path|; True if |path| exists, |
| 97 False if not. This method will not throw a FileNotFoundError unlike | 98 False if not. This method will not throw a FileNotFoundError unlike |
| 98 the Read* methods, however it may still throw a FileSystemError. | 99 the Read* methods, however it may still throw a FileSystemError. |
| 99 | 100 |
| 100 There are several ways to implement this method via the interface but this | 101 There are several ways to implement this method via the interface but this |
| 101 method exists to do so in a canonical and most efficient way for caching. | 102 method exists to do so in a canonical and most efficient way for caching. |
| 102 ''' | 103 ''' |
| 103 AssertIsValid(path) | 104 AssertIsValid(path) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 139 |
| 139 def GetIdentity(self): | 140 def GetIdentity(self): |
| 140 '''The identity of the file system, exposed for caching classes to | 141 '''The identity of the file system, exposed for caching classes to |
| 141 namespace their caches. this will usually depend on the configuration of | 142 namespace their caches. this will usually depend on the configuration of |
| 142 that file system - e.g. a LocalFileSystem with a base path of /var is | 143 that file system - e.g. a LocalFileSystem with a base path of /var is |
| 143 different to that of a SubversionFileSystem with a base path of /bar, is | 144 different to that of a SubversionFileSystem with a base path of /bar, is |
| 144 different to a LocalFileSystem with a base path of /usr. | 145 different to a LocalFileSystem with a base path of /usr. |
| 145 ''' | 146 ''' |
| 146 raise NotImplementedError(self.__class__) | 147 raise NotImplementedError(self.__class__) |
| 147 | 148 |
| 148 def Walk(self, root): | 149 def Walk(self, root, depth=-1): |
| 149 '''Recursively walk the directories in a file system, starting with root. | 150 '''Recursively walk the directories in a file system, starting with root. |
| 150 | 151 |
| 151 Behaviour is very similar to os.walk from the standard os module, yielding | 152 Behaviour is very similar to os.walk from the standard os module, yielding |
| 152 (base, dirs, files) recursively, where |base| is the base path of |files|, | 153 (base, dirs, files) recursively, where |base| is the base path of |files|, |
| 153 |dirs| relative to |root|, and |files| and |dirs| the list of files/dirs in | 154 |dirs| relative to |root|, and |files| and |dirs| the list of files/dirs in |
| 154 |base| respectively. | 155 |base| respectively. If |depth| is specified and greater than 0, Walk will |
| 156 only recurse |depth| times. |
| 155 | 157 |
| 156 Note that directories will always end with a '/', files never will. | 158 Note that directories will always end with a '/', files never will. |
| 157 | 159 |
| 158 If |root| cannot be found, raises a FileNotFoundError. | 160 If |root| cannot be found, raises a FileNotFoundError. |
| 159 For any other failure, raises a FileSystemError. | 161 For any other failure, raises a FileSystemError. |
| 160 ''' | 162 ''' |
| 161 AssertIsDirectory(root) | 163 AssertIsDirectory(root) |
| 162 basepath = root | 164 basepath = root |
| 163 | 165 |
| 164 def walk(root): | 166 def walk(root, depth): |
| 167 if depth == 0: |
| 168 return |
| 165 AssertIsDirectory(root) | 169 AssertIsDirectory(root) |
| 166 dirs, files = [], [] | 170 dirs, files = [], [] |
| 167 | 171 |
| 168 for f in self.ReadSingle(root).Get(): | 172 for f in self.ReadSingle(root).Get(): |
| 169 if IsDirectory(f): | 173 if IsDirectory(f): |
| 170 dirs.append(f) | 174 dirs.append(f) |
| 171 else: | 175 else: |
| 172 files.append(f) | 176 files.append(f) |
| 173 | 177 |
| 174 yield root[len(basepath):].rstrip('/'), dirs, files | 178 yield root[len(basepath):].rstrip('/'), dirs, files |
| 175 | 179 |
| 176 for d in dirs: | 180 for d in dirs: |
| 177 for walkinfo in walk(root + d): | 181 for walkinfo in walk(root + d, depth - 1): |
| 178 yield walkinfo | 182 yield walkinfo |
| 179 | 183 |
| 180 for walkinfo in walk(root): | 184 for walkinfo in walk(root, depth): |
| 181 yield walkinfo | 185 yield walkinfo |
| 182 | 186 |
| 183 def __eq__(self, other): | 187 def __eq__(self, other): |
| 184 return (isinstance(other, FileSystem) and | 188 return (isinstance(other, FileSystem) and |
| 185 self.GetIdentity() == other.GetIdentity()) | 189 self.GetIdentity() == other.GetIdentity()) |
| 186 | 190 |
| 187 def __ne__(self, other): | 191 def __ne__(self, other): |
| 188 return not (self == other) | 192 return not (self == other) |
| 189 | 193 |
| 190 def __repr__(self): | 194 def __repr__(self): |
| 191 return '<%s>' % type(self).__name__ | 195 return '<%s>' % type(self).__name__ |
| 192 | 196 |
| 193 def __str__(self): | 197 def __str__(self): |
| 194 return repr(self) | 198 return repr(self) |
| OLD | NEW |