mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-08 19:04:15 +02:00
[fix][arch] not retrieving all unnecessary packages when uninstalling a package
This commit is contained in:
@@ -901,3 +901,111 @@ def map_conflicts_with(names: Iterable[str], remote: bool) -> Dict[str, Set[str]
|
||||
conflicts.update(conflicts.update((d for d in l.strip().split(' ') if d)))
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def _list_unnecessary_deps(pkgs: Iterable[str], already_checked: Set[str], all_provided: Dict[str, Set[str]], recursive: bool = False) -> Set[str]:
|
||||
output = run_cmd('pacman -Qi {}'.format(' '.join(pkgs)))
|
||||
|
||||
if output:
|
||||
res = set()
|
||||
deps_field = False
|
||||
|
||||
for l in output.split('\n'):
|
||||
if l:
|
||||
if l[0] != ' ':
|
||||
line = l.strip()
|
||||
field_sep_idx = line.index(':')
|
||||
field = line[0:field_sep_idx].strip()
|
||||
|
||||
if field == 'Depends On':
|
||||
deps_field = True
|
||||
val = line[field_sep_idx + 1:].strip()
|
||||
|
||||
if val != 'None':
|
||||
if ':' in val:
|
||||
dep_info = val.split(':')
|
||||
|
||||
real_deps = all_provided.get(dep_info[0].strip())
|
||||
|
||||
if real_deps:
|
||||
res.update(real_deps)
|
||||
else:
|
||||
for dep in val.split(' '):
|
||||
if dep:
|
||||
real_deps = all_provided.get(dep.strip())
|
||||
|
||||
if real_deps:
|
||||
res.update(real_deps)
|
||||
|
||||
elif deps_field:
|
||||
latest_field = False
|
||||
|
||||
elif deps_field:
|
||||
if ':' in l:
|
||||
dep_info = l.split(':')
|
||||
|
||||
real_deps = all_provided.get(dep_info[0].strip())
|
||||
|
||||
if real_deps:
|
||||
res.update(real_deps)
|
||||
else:
|
||||
for dep in l.split(' '):
|
||||
if dep:
|
||||
real_deps = all_provided.get(dep.strip())
|
||||
|
||||
if real_deps:
|
||||
res.update(real_deps)
|
||||
|
||||
if res:
|
||||
res = {dep for dep in res if dep not in already_checked}
|
||||
already_checked.update(res)
|
||||
|
||||
if recursive and res:
|
||||
subdeps = _list_unnecessary_deps(res, already_checked, all_provided)
|
||||
|
||||
if subdeps:
|
||||
res.update(subdeps)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def list_unnecessary_deps(pkgs: Iterable[str], all_provided: Dict[str, Set[str]] = None) -> Set[str]:
|
||||
all_checked = set(pkgs)
|
||||
all_deps = _list_unnecessary_deps(pkgs, all_checked, map_provided(remote=False) if not all_provided else all_provided, recursive=True)
|
||||
|
||||
unnecessary = set(pkgs)
|
||||
if all_deps:
|
||||
requirements_map = map_required_by(all_deps)
|
||||
|
||||
to_clean = set()
|
||||
for dep, required_by in requirements_map.items():
|
||||
if not required_by or not required_by.difference(unnecessary):
|
||||
unnecessary.add(dep)
|
||||
to_clean.add(dep)
|
||||
elif required_by.difference(all_checked): # checking if there are requirements outside the context
|
||||
to_clean.add(dep)
|
||||
|
||||
if to_clean:
|
||||
for dep in to_clean:
|
||||
del requirements_map[dep]
|
||||
|
||||
if requirements_map:
|
||||
while True:
|
||||
to_clean = set()
|
||||
for dep, required_by in requirements_map.items():
|
||||
if not required_by.difference(unnecessary):
|
||||
unnecessary.add(dep)
|
||||
to_clean.add(dep)
|
||||
|
||||
if to_clean:
|
||||
for dep in to_clean:
|
||||
del requirements_map[dep]
|
||||
else:
|
||||
break
|
||||
|
||||
if requirements_map: # if it reaches this points it is possible to exist mutual dependent packages
|
||||
for dep, required_by in requirements_map.items():
|
||||
if not required_by.difference({*requirements_map.keys(), *unnecessary}):
|
||||
unnecessary.add(dep)
|
||||
|
||||
return unnecessary.difference(pkgs)
|
||||
|
||||
Reference in New Issue
Block a user