def test_nodes_symlink_globbed_dir(self): self.assert_fsnodes(Files, ['*/2'], [ # Scandir for the root. (Dir(''), DirectoryListing), # Read links to determine whether they're actually directories. (Link('c.ln'), ReadLink), (Link('d.ln'), ReadLink), # Scan second level destinations: `a/b` is matched via `c.ln`. (Dir('a'), DirectoryListing), (Dir('a/b'), DirectoryListing), ])
def test_nodes_symlink_file(self): self.assert_fsnodes(['c.ln/2'], [ (Dir(''), DirectoryListing), (Link('c.ln'), ReadLink), (Dir('a'), DirectoryListing), (Dir('a/b'), DirectoryListing), ]) self.assert_fsnodes(['d.ln/b/1.txt'], [ (Dir(''), DirectoryListing), (Link('d.ln'), ReadLink), (Dir('a'), DirectoryListing), (Dir('a/b'), DirectoryListing), ])
def generate_subjects(self, filenames): """Given filenames, generate a set of subjects for invalidation predicate matching.""" for f in filenames: # ReadLink, or FileContent for the literal path. yield File(f) yield Link(f) # DirectoryListing for parent dirs. yield Dir(dirname(f))
def test_nodes_symlink_globbed_file(self): self.assert_fsnodes(Files, ['d.ln/b/*.txt'], [ # NB: Needs to scandir every Dir on the way down to track whether # it is traversing a symlink. (Dir(''), DirectoryListing), # Traverse one symlink. (Link('d.ln'), ReadLink), (Dir('a'), DirectoryListing), (Dir('a/b'), DirectoryListing), ])
def generate_fs_subjects(filenames): """Given filenames, generate a set of subjects for invalidation predicate matching.""" for f in filenames: # ReadLink, FileContent, or DirectoryListing for the literal path. yield File(f) yield Link(f) yield Dir(f) # Additionally, since the FS event service does not send invalidation events # for the root directory, treat any changed file in the root as an invalidation # of the root's listing. if dirname(f) in ('.', ''): yield Dir('')
def _lstat(self, relpath): mode = type(self._reader.lstat(self._scm_relpath(relpath))) if mode == NoneType: return None elif mode == self._reader.Symlink: return Link(relpath) elif mode == self._reader.Dir: return Dir(relpath) elif mode == self._reader.File: return File(relpath) else: raise IOError('Unsupported file type in {}: {}'.format(self, relpath))
def _scandir_raw(self, relpath): # Sanity check. TODO: this should probably be added to the ProjectTree interface as # an optional call, so that we can use it in fs.py rather than applying it by default. abspath = os.path.normpath(self._join(relpath)) if os.path.realpath(abspath) != abspath: raise ValueError( 'scandir for non-canonical path "{}" not supported in {}.'. format(relpath, self)) for entry in os.scandir(abspath): # NB: We don't use `DirEntry.stat`, as the scandir docs indicate that that always requires # an additional syscall on Unixes. entry_path = os.path.normpath(os.path.join(relpath, entry.name)) if entry.is_file(follow_symlinks=False): yield File(entry_path) elif entry.is_dir(follow_symlinks=False): yield Dir(entry_path) elif entry.is_symlink(): yield Link(entry_path) else: raise IOError('Unsupported file type in {}: {}'.format( self, entry_path))