94 lines
2.5 KiB
Python
94 lines
2.5 KiB
Python
from glob import glob
|
|
import fnmatch
|
|
|
|
|
|
class Registry(dict):
|
|
|
|
unregister = dict.__delitem__
|
|
|
|
def check_key(self, key):
|
|
pass
|
|
|
|
def check_value(self, value):
|
|
pass
|
|
|
|
def check(self, key, value):
|
|
try:
|
|
self.check_key(key)
|
|
except KeyError:
|
|
raise
|
|
except Exception as e:
|
|
raise KeyError(e.message)
|
|
|
|
try:
|
|
self.check_value(value)
|
|
except ValueError:
|
|
raise
|
|
except Exception as e:
|
|
raise ValueError(e.message)
|
|
|
|
def register(self, key, value):
|
|
self.__setitem__(key, value)
|
|
|
|
def __setitem__(self, key, value):
|
|
self.check(key, value)
|
|
super().__setitem__(key, value)
|
|
|
|
|
|
class PathMatcher(object):
|
|
"""
|
|
A configurable glob.
|
|
"""
|
|
|
|
def __init__(self, config):
|
|
if isinstance(config, str):
|
|
self.include = [config, ]
|
|
elif isinstance(config, list):
|
|
self.include = config
|
|
elif not isinstance(config, dict):
|
|
raise ValueError('Invalid pattern configuration')
|
|
|
|
if not config.get('include'):
|
|
raise ValueError('At least one inclusion pattern required')
|
|
elif isinstance(config['include'], str):
|
|
self.include = [config['include'], ]
|
|
elif isinstance(config['include'], list):
|
|
self.include = config['include']
|
|
else:
|
|
raise ValueError(
|
|
'"include" must be a pattern or list of patterns'
|
|
)
|
|
|
|
config.setdefault('exclude', [])
|
|
if isinstance(config['exclude'], str):
|
|
self.exclude = [config['exclude'], ]
|
|
elif isinstance(config['exclude'], list):
|
|
self.exclude = config['exclude']
|
|
else:
|
|
raise ValueError(
|
|
'"exclude" must be a pattern or list of patterns'
|
|
)
|
|
|
|
self._found = None
|
|
|
|
def all(self):
|
|
if self._found is not None:
|
|
return self._found
|
|
self._found = set()
|
|
|
|
for include_pattern in self.include:
|
|
self._found |= set(glob(include_pattern))
|
|
|
|
for exclude_pattern in self.exclude:
|
|
self._found -= set(fnmatch.filter(self._found, exclude_pattern))
|
|
|
|
self._found = list(map(Path, self._found))
|
|
return self._found
|
|
|
|
def get(self):
|
|
if not self.all():
|
|
raise ValueError('No matching paths found')
|
|
if len(self.all()) != 1:
|
|
raise ValueError('More than one matching path found')
|
|
return self.all()[0]
|