mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-06-15 13:08:59 +00:00
157 lines
5.0 KiB
Python
157 lines
5.0 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import os
|
|
|
|
from mozpack import path as mozpath
|
|
from mozpack.files import FileFinder
|
|
|
|
|
|
class FilterPath(object):
|
|
"""Helper class to make comparing and matching file paths easier."""
|
|
def __init__(self, path, exclude=None):
|
|
self.path = os.path.normpath(path)
|
|
self._finder = None
|
|
self.exclude = exclude
|
|
|
|
@property
|
|
def finder(self):
|
|
if self._finder:
|
|
return self._finder
|
|
self._finder = FileFinder(
|
|
self.path, find_executables=False, ignore=self.exclude)
|
|
return self._finder
|
|
|
|
@property
|
|
def ext(self):
|
|
return os.path.splitext(self.path)[1]
|
|
|
|
@property
|
|
def exists(self):
|
|
return os.path.exists(self.path)
|
|
|
|
@property
|
|
def isfile(self):
|
|
return os.path.isfile(self.path)
|
|
|
|
@property
|
|
def isdir(self):
|
|
return os.path.isdir(self.path)
|
|
|
|
def join(self, *args):
|
|
return FilterPath(os.path.join(self, *args))
|
|
|
|
def match(self, patterns):
|
|
return any(mozpath.match(self.path, pattern.path) for pattern in patterns)
|
|
|
|
def contains(self, other):
|
|
"""Return True if other is a subdirectory of self or equals self."""
|
|
if isinstance(other, FilterPath):
|
|
other = other.path
|
|
a = os.path.abspath(self.path)
|
|
b = os.path.normpath(os.path.abspath(other))
|
|
|
|
if b.startswith(a):
|
|
return True
|
|
return False
|
|
|
|
def __repr__(self):
|
|
return repr(self.path)
|
|
|
|
|
|
def filterpaths(paths, linter, **lintargs):
|
|
"""Filters a list of paths.
|
|
|
|
Given a list of paths, and a linter definition plus extra
|
|
arguments, return the set of paths that should be linted.
|
|
|
|
:param paths: A starting list of paths to possibly lint.
|
|
:param linter: A linter definition.
|
|
:param lintargs: Extra arguments passed to the linter.
|
|
:returns: A list of file paths to lint.
|
|
"""
|
|
include = linter.get('include', [])
|
|
exclude = lintargs.get('exclude', [])
|
|
exclude.extend(linter.get('exclude', []))
|
|
root = lintargs['root']
|
|
|
|
if not lintargs.get('use_filters', True) or (not include and not exclude):
|
|
return paths
|
|
|
|
def normalize(path):
|
|
if not os.path.isabs(path):
|
|
path = os.path.join(root, path)
|
|
return FilterPath(path)
|
|
|
|
include = map(normalize, include)
|
|
exclude = map(normalize, exclude)
|
|
|
|
# Paths with and without globs will be handled separately,
|
|
# pull them apart now.
|
|
includepaths = [p for p in include if p.exists]
|
|
excludepaths = [p for p in exclude if p.exists]
|
|
|
|
includeglobs = [p for p in include if not p.exists]
|
|
excludeglobs = [p for p in exclude if not p.exists]
|
|
|
|
extensions = linter.get('extensions')
|
|
keep = set()
|
|
discard = set()
|
|
for path in map(FilterPath, paths):
|
|
# Exclude bad file extensions
|
|
if extensions and path.isfile and path.ext not in extensions:
|
|
continue
|
|
|
|
if path.match(excludeglobs):
|
|
continue
|
|
|
|
# First handle include/exclude directives
|
|
# that exist (i.e don't have globs)
|
|
for inc in includepaths:
|
|
# Only excludes that are subdirectories of the include
|
|
# path matter.
|
|
excs = [e for e in excludepaths if inc.contains(e)]
|
|
|
|
if path.contains(inc):
|
|
# If specified path is an ancestor of include path,
|
|
# then lint the include path.
|
|
keep.add(inc)
|
|
|
|
# We can't apply these exclude paths without explicitly
|
|
# including every sibling file. Rather than do that,
|
|
# just return them and hope the underlying linter will
|
|
# deal with them.
|
|
discard.update(excs)
|
|
|
|
elif inc.contains(path):
|
|
# If the include path is an ancestor of the specified
|
|
# path, then add the specified path only if there are
|
|
# no exclude paths in-between them.
|
|
if not any(e.contains(path) for e in excs):
|
|
keep.add(path)
|
|
|
|
# Next handle include/exclude directives that
|
|
# contain globs.
|
|
if path.isfile:
|
|
# If the specified path is a file it must be both
|
|
# matched by an include directive and not matched
|
|
# by an exclude directive.
|
|
if not path.match(includeglobs):
|
|
continue
|
|
|
|
keep.add(path)
|
|
elif path.isdir:
|
|
# If the specified path is a directory, use a
|
|
# FileFinder to resolve all relevant globs.
|
|
path.exclude = [e.path for e in excludeglobs]
|
|
for pattern in includeglobs:
|
|
for p, f in path.finder.find(pattern.path):
|
|
keep.add(path.join(p))
|
|
|
|
# Only pass paths we couldn't exclude here to the underlying linter
|
|
lintargs['exclude'] = [f.path for f in discard]
|
|
return [f.path for f in keep]
|