Handle case sensitivity.

This commit is contained in:
Jelmer Vernooij 2021-03-25 16:09:45 +00:00
parent 609b8b2196
commit ac1f25d0be
No known key found for this signature in database
GPG key ID: 579C160D4C9E23E8
3 changed files with 30 additions and 14 deletions

View file

@ -81,10 +81,10 @@ class AptManager(object):
self._apt_cache = apt.Cache(rootdir=self.session.location) self._apt_cache = apt.Cache(rootdir=self.session.location)
return package in self._apt_cache return package in self._apt_cache
def get_packages_for_paths(self, paths, regex=False): def get_packages_for_paths(self, paths, regex=False, case_insensitive=False):
logging.debug("Searching for packages containing %r", paths) logging.debug("Searching for packages containing %r", paths)
# TODO(jelmer): Make sure we use whatever is configured in self.session # TODO(jelmer): Make sure we use whatever is configured in self.session
return get_packages_for_paths(paths, self.searchers(), regex=regex) return get_packages_for_paths(paths, self.searchers(), regex=regex, case_insensitive=case_insensitive)
def missing(self, packages): def missing(self, packages):
root = getattr(self.session, "location", "/") root = getattr(self.session, "location", "/")

View file

@ -29,7 +29,7 @@ from .. import USER_AGENT
class FileSearcher(object): class FileSearcher(object):
def search_files(self, path: str, regex: bool = False) -> Iterator[str]: def search_files(self, path: str, regex: bool = False, case_insensitive: bool = False) -> Iterator[str]:
raise NotImplementedError(self.search_files) raise NotImplementedError(self.search_files)
@ -216,10 +216,16 @@ class AptCachedContentsFileSearcher(FileSearcher):
def __setitem__(self, path, package): def __setitem__(self, path, package):
self._db[path] = package self._db[path] = package
def search_files(self, path, regex=False): def search_files(self, path, regex=False, case_insensitive=False):
path = path.lstrip('/').encode('utf-8', 'surrogateescape') path = path.lstrip('/').encode('utf-8', 'surrogateescape')
if case_insensitive and not regex:
regex = True
path = re.escape(path)
if regex: if regex:
c = re.compile(path) flags = 0
if case_insensitive:
flags |= re.I
c = re.compile(path, flags=flags)
ret = [] ret = []
for p, rest in self._db.items(): for p, rest in self._db.items():
if c.match(p): if c.match(p):
@ -256,10 +262,16 @@ class GeneratedFileSearcher(FileSearcher):
(path, pkg) = line.strip().split(None, 1) (path, pkg) = line.strip().split(None, 1)
self._db[path] = pkg self._db[path] = pkg
def search_files(self, path: str, regex: bool = False) -> Iterator[str]: def search_files(self, path: str, regex: bool = False, case_insensitive: bool = False) -> Iterator[str]:
for p, pkg in sorted(self._db.items()): for p, pkg in sorted(self._db.items()):
if regex: if regex:
if re.match(path, p): flags = 0
if case_insensitive:
flags |= re.I
if re.match(path, p, flags=flags):
yield pkg
elif case_insensitive:
if path.lower() == p.lower():
yield pkg yield pkg
else: else:
if path == p: if path == p:
@ -281,12 +293,13 @@ GENERATED_FILE_SEARCHER = GeneratedFileSearcher(
def get_packages_for_paths( def get_packages_for_paths(
paths: List[str], searchers: List[FileSearcher], regex: bool = False paths: List[str], searchers: List[FileSearcher], regex: bool = False,
case_insensitive: bool = False
) -> List[str]: ) -> List[str]:
candidates: List[str] = list() candidates: List[str] = list()
for path in paths: for path in paths:
for searcher in searchers: for searcher in searchers:
for pkg in searcher.search_files(path, regex=regex): for pkg in searcher.search_files(path, regex=regex, case_insensitive=case_insensitive):
if pkg not in candidates: if pkg not in candidates:
candidates.append(pkg) candidates.append(pkg)
return candidates return candidates

View file

@ -110,16 +110,19 @@ class AptRequirement(Requirement):
return False return False
def find_package_names(apt_mgr: AptManager, paths: List[str], regex: bool = False) -> List[str]: def find_package_names(apt_mgr: AptManager, paths: List[str], regex: bool = False, case_insensitive=False) -> List[str]:
if not isinstance(paths, list): if not isinstance(paths, list):
raise TypeError(paths) raise TypeError(paths)
return apt_mgr.get_packages_for_paths(paths, regex) return apt_mgr.get_packages_for_paths(paths, regex, case_insensitive)
def find_reqs_simple(apt_mgr: AptManager, paths: List[str], regex: bool = False, minimum_version=None) -> List[str]: def find_reqs_simple(
apt_mgr: AptManager, paths: List[str], regex: bool = False,
minimum_version=None, case_insensitive=False) -> List[str]:
if not isinstance(paths, list): if not isinstance(paths, list):
raise TypeError(paths) raise TypeError(paths)
return [AptRequirement.simple(package, minimum_version=minimum_version) for package in find_package_names(apt_mgr, paths, regex)] return [AptRequirement.simple(package, minimum_version=minimum_version)
for package in find_package_names(apt_mgr, paths, regex, case_insensitive)]
def python_spec_to_apt_rels(pkg_name, specs): def python_spec_to_apt_rels(pkg_name, specs):
@ -163,7 +166,7 @@ def get_package_for_python_package(apt_mgr, package, python_version: Optional[st
paths = [cpython3_regex, cpython2_regex, pypy_regex] paths = [cpython3_regex, cpython2_regex, pypy_regex]
else: else:
raise NotImplementedError('unsupported python version %s' % python_version) raise NotImplementedError('unsupported python version %s' % python_version)
names = find_package_names(apt_mgr, paths, regex=True) names = find_package_names(apt_mgr, paths, regex=True, case_insensitive=True)
return [AptRequirement(python_spec_to_apt_rels(name, specs)) for name in names] return [AptRequirement(python_spec_to_apt_rels(name, specs)) for name in names]