mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset d917152c263d (bug 920938) for build warning/failures
This commit is contained in:
parent
aa726f5c98
commit
a773a5c6bc
@ -877,68 +877,108 @@ class ManifestParser(object):
|
||||
### directory importers
|
||||
|
||||
@classmethod
|
||||
def _walk_directories(cls, directories, callback, pattern=None, ignore=()):
|
||||
def _walk_directories(cls, directories, function, pattern=None, ignore=()):
|
||||
"""
|
||||
internal function to import directories
|
||||
"""
|
||||
|
||||
if isinstance(pattern, basestring):
|
||||
patterns = [pattern]
|
||||
else:
|
||||
patterns = pattern
|
||||
ignore = set(ignore)
|
||||
class FilteredDirectoryContents(object):
|
||||
"""class to filter directory contents"""
|
||||
|
||||
if not patterns:
|
||||
accept_filename = lambda filename: True
|
||||
else:
|
||||
def accept_filename(filename):
|
||||
for pattern in patterns:
|
||||
if fnmatch.fnmatch(filename, pattern):
|
||||
return True
|
||||
sort = sorted
|
||||
|
||||
if not ignore:
|
||||
accept_dirname = lambda dirname: True
|
||||
else:
|
||||
accept_dirname = lambda dirname: dirname not in ignore
|
||||
def __init__(self, pattern=pattern, ignore=ignore, cache=None):
|
||||
if pattern is None:
|
||||
pattern = set()
|
||||
if isinstance(pattern, basestring):
|
||||
pattern = [pattern]
|
||||
self.patterns = pattern
|
||||
self.ignore = set(ignore)
|
||||
|
||||
rootdirectories = directories[:]
|
||||
seen_directories = set()
|
||||
for rootdirectory in rootdirectories:
|
||||
# let's recurse directories using list
|
||||
directories = [os.path.realpath(rootdirectory)]
|
||||
while directories:
|
||||
directory = directories.pop(0)
|
||||
if directory in seen_directories:
|
||||
# eliminate possible infinite recursion due to
|
||||
# symbolic links
|
||||
continue
|
||||
seen_directories.add(directory)
|
||||
# cache of (dirnames, filenames) keyed on directory real path
|
||||
# assumes volume is frozen throughout scope
|
||||
self._cache = cache or {}
|
||||
|
||||
files = []
|
||||
subdirs = []
|
||||
for name in sorted(os.listdir(directory)):
|
||||
path = os.path.join(directory, name)
|
||||
if os.path.isfile(path):
|
||||
# os.path.isfile follow symbolic links, we don't
|
||||
# need to handle them here.
|
||||
if accept_filename(name):
|
||||
files.append(name)
|
||||
continue
|
||||
elif os.path.islink(path):
|
||||
# eliminate symbolic links
|
||||
path = os.path.realpath(path)
|
||||
def __call__(self, directory):
|
||||
"""returns 2-tuple: dirnames, filenames"""
|
||||
directory = os.path.realpath(directory)
|
||||
if directory not in self._cache:
|
||||
dirnames, filenames = self.contents(directory)
|
||||
|
||||
# we must have a directory here
|
||||
if accept_dirname(name):
|
||||
subdirs.append(name)
|
||||
# this subdir is added for recursion
|
||||
directories.insert(0, path)
|
||||
# filter out directories without progeny
|
||||
# XXX recursive: should keep track of seen directories
|
||||
dirnames = [ dirname for dirname in dirnames
|
||||
if not self.empty(os.path.join(directory, dirname)) ]
|
||||
|
||||
# here we got all subdirs and files filtered, we can
|
||||
# call the callback function if directory is not empty
|
||||
if subdirs or files:
|
||||
callback(rootdirectory, directory, subdirs, files)
|
||||
self._cache[directory] = (tuple(dirnames), filenames)
|
||||
|
||||
# return cached values
|
||||
return self._cache[directory]
|
||||
|
||||
def empty(self, directory):
|
||||
"""
|
||||
returns if a directory and its descendents are empty
|
||||
"""
|
||||
return self(directory) == ((), ())
|
||||
|
||||
def contents(self, directory, sort=None):
|
||||
"""
|
||||
return directory contents as (dirnames, filenames)
|
||||
with `ignore` and `pattern` applied
|
||||
"""
|
||||
|
||||
if sort is None:
|
||||
sort = self.sort
|
||||
|
||||
# split directories and files
|
||||
dirnames = []
|
||||
filenames = []
|
||||
for item in os.listdir(directory):
|
||||
path = os.path.join(directory, item)
|
||||
if os.path.isdir(path):
|
||||
dirnames.append(item)
|
||||
else:
|
||||
# XXX not sure what to do if neither a file or directory
|
||||
# (if anything)
|
||||
assert os.path.isfile(path)
|
||||
filenames.append(item)
|
||||
|
||||
# filter contents;
|
||||
# this could be done in situ re the above for loop
|
||||
# but it is really disparate in intent
|
||||
# and could conceivably go to a separate method
|
||||
dirnames = [dirname for dirname in dirnames
|
||||
if dirname not in self.ignore]
|
||||
filenames = set(filenames)
|
||||
# we use set functionality to filter filenames
|
||||
if self.patterns:
|
||||
matches = set()
|
||||
matches.update(*[fnmatch.filter(filenames, pattern)
|
||||
for pattern in self.patterns])
|
||||
filenames = matches
|
||||
|
||||
if sort is not None:
|
||||
# sort dirnames, filenames
|
||||
dirnames = sort(dirnames)
|
||||
filenames = sort(filenames)
|
||||
|
||||
return (tuple(dirnames), tuple(filenames))
|
||||
|
||||
# make a filtered directory object
|
||||
directory_contents = FilteredDirectoryContents(pattern=pattern, ignore=ignore)
|
||||
|
||||
# walk the directories, generating manifests
|
||||
for index, directory in enumerate(directories):
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(directory):
|
||||
|
||||
# get the directory contents from the caching object
|
||||
_dirnames, filenames = directory_contents(dirpath)
|
||||
# filter out directory names
|
||||
dirnames[:] = _dirnames
|
||||
|
||||
# call callback function
|
||||
function(directory, dirpath, dirnames, filenames)
|
||||
|
||||
@classmethod
|
||||
def populate_directory_manifests(cls, directories, filename, pattern=None, ignore=(), overwrite=False):
|
||||
|
@ -9,13 +9,17 @@ import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from manifestparser import convert, ManifestParser
|
||||
from manifestparser import convert
|
||||
|
||||
class TestSymlinkConversion(unittest.TestCase):
|
||||
"""
|
||||
test conversion of a directory tree with symlinks to a manifest structure
|
||||
"""
|
||||
|
||||
# Currently broken: see
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=902610
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=920938
|
||||
|
||||
def create_stub(self, directory=None):
|
||||
"""stub out a directory with files in it"""
|
||||
|
||||
@ -48,21 +52,23 @@ class TestSymlinkConversion(unittest.TestCase):
|
||||
shutil.rmtree(stub)
|
||||
os.chdir(oldcwd)
|
||||
|
||||
@unittest.skipIf(not hasattr(os, 'symlink'),
|
||||
"symlinks unavailable on this platform")
|
||||
def test_relpath_symlink(self):
|
||||
"""
|
||||
Ensure `relative_to` works in a symlink.
|
||||
Not available on windows.
|
||||
"""
|
||||
|
||||
symlink = getattr(os, 'symlink', None)
|
||||
if symlink is None:
|
||||
return # symlinks unavailable on this platform
|
||||
|
||||
oldcwd = os.getcwd()
|
||||
workspace = tempfile.mkdtemp()
|
||||
try:
|
||||
tmpdir = os.path.join(workspace, 'directory')
|
||||
os.makedirs(tmpdir)
|
||||
linkdir = os.path.join(workspace, 'link')
|
||||
os.symlink(tmpdir, linkdir)
|
||||
symlink(tmpdir, linkdir)
|
||||
self.create_stub(tmpdir)
|
||||
|
||||
# subdir with in-memory manifest
|
||||
@ -84,7 +90,7 @@ class TestSymlinkConversion(unittest.TestCase):
|
||||
tmpdir = os.path.join(workspace, 'directory')
|
||||
os.makedirs(tmpdir)
|
||||
linkdir = os.path.join(workspace, 'link')
|
||||
os.symlink(tmpdir, linkdir)
|
||||
symlink(tmpdir, linkdir)
|
||||
self.create_stub(tmpdir)
|
||||
files = ['../bar', '../fleem', '../foo', 'subfile']
|
||||
subdir = os.path.join(linkdir, 'subdir')
|
||||
@ -92,8 +98,8 @@ class TestSymlinkConversion(unittest.TestCase):
|
||||
os.makedirs(subsubdir)
|
||||
linksubdir = os.path.join(linkdir, 'linky')
|
||||
linksubsubdir = os.path.join(subsubdir, 'linky')
|
||||
os.symlink(subdir, linksubdir)
|
||||
os.symlink(subdir, linksubsubdir)
|
||||
symlink(subdir, linksubdir)
|
||||
symlink(subdir, linksubsubdir)
|
||||
for dest in (subdir,):
|
||||
os.chdir(dest)
|
||||
for directory in (tmpdir, linkdir):
|
||||
@ -104,34 +110,6 @@ class TestSymlinkConversion(unittest.TestCase):
|
||||
shutil.rmtree(workspace)
|
||||
os.chdir(oldcwd)
|
||||
|
||||
@unittest.skipIf(not hasattr(os, 'symlink'),
|
||||
"symlinks unavailable on this platform")
|
||||
def test_recursion_symlinks(self):
|
||||
workspace = tempfile.mkdtemp()
|
||||
self.addCleanup(shutil.rmtree, workspace)
|
||||
|
||||
# create two dirs
|
||||
os.makedirs(os.path.join(workspace, 'dir1'))
|
||||
os.makedirs(os.path.join(workspace, 'dir2'))
|
||||
|
||||
# create cyclical symlinks
|
||||
os.symlink(os.path.join('..', 'dir1'),
|
||||
os.path.join(workspace, 'dir2', 'ldir1'))
|
||||
os.symlink(os.path.join('..', 'dir2'),
|
||||
os.path.join(workspace, 'dir1', 'ldir2'))
|
||||
|
||||
# create one file in each dir
|
||||
open(os.path.join(workspace, 'dir1', 'f1.txt'), 'a').close()
|
||||
open(os.path.join(workspace, 'dir1', 'ldir2', 'f2.txt'), 'a').close()
|
||||
|
||||
data = []
|
||||
def callback(rootdirectory, directory, subdirs, files):
|
||||
for f in files:
|
||||
data.append(f)
|
||||
|
||||
ManifestParser._walk_directories([workspace], callback)
|
||||
self.assertEqual(sorted(data), ['f1.txt', 'f2.txt'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user