def Canonicalize(self, path): '''Returns the canonical path for |path|. ''' canonical_paths, simplified_paths_map = self._LoadCache().Get() # Path may already be the canonical path. if path in canonical_paths: return path # Path not found. Our single heuristic: find |base| in the directory # structure with the longest common prefix of |path|. _, base = SplitParent(path) potential_paths = simplified_paths_map.get(_SimplifyFileName(base)) if not potential_paths: # There is no file with anything close to that name. return path # The most likely canonical file is the one with the longest common prefix # with |path|. This is slightly weaker than it could be; |path| is # compared, not the simplified form of |path|, which may matter. max_prefix = potential_paths[0] max_prefix_length = len(posixpath.commonprefix((max_prefix, path))) for path_for_file in potential_paths[1:]: prefix_length = len(posixpath.commonprefix((path_for_file, path))) if prefix_length > max_prefix_length: max_prefix, max_prefix_length = path_for_file, prefix_length return max_prefix
def Exists(self, path): '''Returns a Future to the existence of |path|; True if |path| exists, False if not. This method will not throw a FileNotFoundError unlike the Read* methods, however it may still throw a FileSystemError. There are several ways to implement this method via the interface but this method exists to do so in a canonical and most efficient way for caching. ''' AssertIsValid(path) if path == '': # There is always a root directory. return Future(value=True) parent, base = SplitParent(path) def handle(error): if isinstance(error, FileNotFoundError): return False raise error return self.ReadSingle(ToDirectory(parent)).Then( lambda l: base in l, handle)
def Exists(self, path): '''Returns a Future to the existence of |path|; True if |path| exists, False if not. This method will not throw a FileNotFoundError unlike the Read* methods, however it may still throw a FileSystemError. There are several ways to implement this method via the interface but this method exists to do so in a canonical and most efficient way for caching. ''' AssertIsValid(path) if path == '': # There is always a root directory. return Future(value=True) parent, base = SplitParent(path) list_future = self.ReadSingle(ToDirectory(parent)) def resolve(): try: return base in list_future.Get() except FileNotFoundError: return False return Future(callback=resolve)
def Canonicalize(self, path): '''Returns the canonical path for |path|. ''' canonical_paths, simplified_paths_map = self._LoadCache().Get() # Path may already be the canonical path. if path in canonical_paths: return path # Path not found. Our single heuristic: find |base| in the directory # structure with the longest common prefix of |path|. _, base = SplitParent(path) # Paths with a non-extension dot separator lose information in # _SimplifyFileName, so we try paths both with and without the dot to # maximize the possibility of finding the right path. potential_paths = ( simplified_paths_map.get(_Normalize(base), []) + simplified_paths_map.get(_Normalize(base, splittext=True), [])) if potential_paths == []: # There is no file with anything close to that name. return path # The most likely canonical file is the one with the longest common prefix # with |path|. This is slightly weaker than it could be; |path| is # compared without symbols, not the simplified form of |path|, # which may matter. max_prefix = potential_paths[0] max_prefix_length = len(_CommonNormalizedPrefix(max_prefix, path)) for path_for_file in potential_paths[1:]: prefix_length = len(_CommonNormalizedPrefix(path_for_file, path)) if prefix_length > max_prefix_length: max_prefix, max_prefix_length = path_for_file, prefix_length return max_prefix
def testSplitParent(self): self.assertEqual(('', 'hi'), SplitParent('hi')) self.assertEqual(('', 'hi/'), SplitParent('hi/')) self.assertEqual(('/', 'hi'), SplitParent('/hi')) self.assertEqual(('/', 'hi/'), SplitParent('/hi/')) self.assertEqual(('parent', 'hi'), SplitParent('parent/hi')) self.assertEqual(('parent', 'hi/'), SplitParent('parent/hi/')) self.assertEqual(('/parent', 'hi'), SplitParent('/parent/hi')) self.assertEqual(('/parent', 'hi/'), SplitParent('/parent/hi/')) self.assertEqual(('p1/p2', 'hi'), SplitParent('p1/p2/hi')) self.assertEqual(('p1/p2', 'hi/'), SplitParent('p1/p2/hi/')) self.assertEqual(('/p1/p2', 'hi'), SplitParent('/p1/p2/hi')) self.assertEqual(('/p1/p2', 'hi/'), SplitParent('/p1/p2/hi/'))