def test_no_ignore(self): dirs = ['a', 'b', 'c'] files = ['z', 'y', 'x'] utils.apply_ignore(None, '/dir/path', dirs, files) self.assertEqual(dirs, ['a', 'b', 'c']) self.assertEqual(files, ['z', 'y', 'x'])
def test_with_ignore(self): ignore = mock.Mock(return_value=['b', 'y']) dirs = ['a', 'b', 'c'] files = ['z', 'y', 'x'] utils.apply_ignore(ignore, '/dir/path', dirs, files) ignore.assert_called_once_with('/dir/path', ['a', 'b', 'c', 'z', 'y', 'x']) self.assertEqual(dirs, ['a', 'c']) self.assertEqual(files, ['z', 'x'])
def walk(self, path=os.curdir, topdown=True, onerror=None, followlinks=False, absolute=False, ignore=None): """ Walk the directory tree. Similar to the ``os.walk()`` generator. :param path: An optional path to a subelement of this directory. :param topdown: If ``True`` (the default), the yielded tuple for a directory is generated before that for any of the subdirectories. When ``True``, the caller may modify the directory names list in-place to influence how ``walk()`` recurses through those directories. :param onerror: An optional callable that is called with the ``OSError`` instance if an error occurs. If not provided, errors are ignored. :param followlinks: If ``False`` (the default), directories pointed to by symbolic links will not be traversed during the walk. :param absolute: If ``True``, the directory name returned as part of the yielded tuple will be an absolute path to the directory. By default, this path name will be relative to the tree root. :param ignore: An optional callable. This callable will be called with the absolute directory path and a list of files and directories in that directory; it should return a list of file and directory names which should be subsequently ignored. Note that, if ``topdown`` is ``False``, directories selected to be ignored by this callable will be visited anyway. :returns: A generator yielding 3-tuples consisting of the name of the directory, a list of subdirectories, and a list of filenames. """ # Walk the tree, starting from there for dirpath, dirnames, filenames in os.walk(self._abs(path), topdown, onerror, followlinks): # Apply the ignore filter, if any utils.apply_ignore(ignore, dirpath, dirnames, filenames) if not absolute: # Trim the directory path dirpath = dirpath[len(self.tree.path):] yield dirpath, dirnames, filenames
def link(self, src, dst=os.curdir, ignore=None): """ Create a hard link to a given file. :param src: The filesystem path to the source file. Can be an ``FSEntry`` instance. :param dst: The destination for the link operation. If it is a directory, the basename of the source file will be added. :param ignore: An optional callable. If ``src`` is a directory, this callable will be called with a directory name and a list of the file and directory names in that directory; it should return a list of file and directory names which should be subsequently ignored. :returns: An ``FSEntry`` instance representing the hard link ``dst``. """ # Resolve the paths src, dst, full_dst = self._paths(src, dst) # You can make hard links of symlinks, so if source is a link # or not a directory, we want to go with the simple case if os.path.islink(src) or not os.path.isdir(src): # Create the hard link os.link(src, full_dst) else: # We can't hard link a directory, so make a tree of hard # links for srcpath, dirnames, filenames in os.walk(src): # Apply the ignore filter utils.apply_ignore(ignore, srcpath, dirnames, filenames) # Transplant srcpath on top of full_dst dstpath = full_dst + srcpath[len(src):] # Create the hard links for filename in filenames: os.link(os.path.join(srcpath, filename), os.path.join(dstpath, filename)) # Create the subdirectories for dirname in dirnames: os.makedirs(os.path.join(dstpath, dirname)) # Return a reference to the hard link return self.tree._get(dst)