ref: rm LinkTarget filter
This commit is contained in:
48
brew.py
48
brew.py
@@ -562,13 +562,13 @@ def cli_cleanup(args: ArgParams) -> None:
|
|||||||
|
|
||||||
# should never happen but just in case, remove symlinks which point nowhere
|
# should never happen but just in case, remove symlinks which point nowhere
|
||||||
Log.info('==> Removing dead links')
|
Log.info('==> Removing dead links')
|
||||||
binLinks = Cellar.allBinLinks() + Cellar.allOptLinks()
|
links = Cellar.allBinLinks() + Cellar.allOptLinks()
|
||||||
if args.packages:
|
if args.packages:
|
||||||
deadPaths = set(x.path + '/' for x in packages)
|
deadPaths = [pkg.path + '/' for pkg in packages]
|
||||||
binLinks = [x for x in binLinks
|
links = [lnk for lnk in links
|
||||||
if any(x.target.startswith(y) for y in deadPaths)]
|
if any(lnk.target.startswith(x) for x in deadPaths)]
|
||||||
|
|
||||||
for link in binLinks:
|
for link in links:
|
||||||
if not os.path.exists(link.target):
|
if not os.path.exists(link.target):
|
||||||
total_savings += File.remove(link.path, dryRun=args.dry)
|
total_savings += File.remove(link.path, dryRun=args.dry)
|
||||||
|
|
||||||
@@ -1119,20 +1119,17 @@ class LinkTarget(NamedTuple):
|
|||||||
raw: str = '' # relative target
|
raw: str = '' # relative target
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read(filePath: str, startswith: str = '') -> 'LinkTarget|None':
|
def read(filePath: str) -> 'LinkTarget|None':
|
||||||
''' Read a single symlink and populate with absolute paths '''
|
''' Read a single symlink and populate with absolute paths '''
|
||||||
if not os.path.islink(filePath):
|
if not os.path.islink(filePath):
|
||||||
return None
|
return None
|
||||||
raw = os.readlink(filePath)
|
raw = os.readlink(filePath)
|
||||||
real = os.path.realpath(os.path.join(os.path.dirname(filePath), raw))
|
real = os.path.realpath(os.path.join(os.path.dirname(filePath), raw))
|
||||||
if real.startswith(startswith or ''):
|
return LinkTarget(filePath, real, raw)
|
||||||
return LinkTarget(filePath, real, raw)
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def allInDir(path: str, startswith: str = '') -> 'list[LinkTarget]':
|
def allInDir(path: str) -> 'list[LinkTarget]':
|
||||||
return [lnk for file in os.scandir(path)
|
return [x for f in os.scandir(path) if (x := LinkTarget.read(f.path))]
|
||||||
if (lnk := LinkTarget.read(file.path, startswith))]
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------
|
# -----------------------------------
|
||||||
@@ -1257,22 +1254,21 @@ class LocalPackage:
|
|||||||
|
|
||||||
# Symlink processing
|
# Symlink processing
|
||||||
|
|
||||||
def readOptLink(self, *, ensurePkg: bool) -> 'LinkTarget|None':
|
|
||||||
''' Read `@/opt/<pkg>` link. Returns `None` if non-exist '''
|
|
||||||
pkgPath = (self.path + '/') if ensurePkg else ''
|
|
||||||
# TODO: should opt-links have "@version" suffix or not?
|
|
||||||
# if no, fix-dylib needs adjustments
|
|
||||||
return LinkTarget.read(os.path.join(Cellar.OPT, self.name), pkgPath)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def optLink(self) -> 'LinkTarget|None':
|
def optLink(self) -> 'LinkTarget|None':
|
||||||
''' Return `OPT` link but only if it links to the current package '''
|
''' Read `@/opt/<pkg>` link. `None` if non-exist or not link to pkg '''
|
||||||
return self.readOptLink(ensurePkg=True)
|
# TODO: should opt-links have "@version" suffix or not?
|
||||||
|
# if no, fix-dylib needs adjustments
|
||||||
|
lnk = LinkTarget.read(os.path.join(Cellar.OPT, self.name))
|
||||||
|
if lnk and not lnk.target.startswith(self.path + '/'):
|
||||||
|
return None
|
||||||
|
return lnk
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def binLinks(self) -> list[LinkTarget]:
|
def binLinks(self) -> list[LinkTarget]:
|
||||||
''' List of `@/bin/...` links that match `<pkg>` destination '''
|
''' List of `@/bin/...` links that match `<pkg>` destination '''
|
||||||
return Cellar.allBinLinks(self.path + '/')
|
return [lnk for lnk in Cellar.allBinLinks()
|
||||||
|
if lnk.target.startswith(self.path + '/')]
|
||||||
|
|
||||||
def unlink(
|
def unlink(
|
||||||
self, *, unlinkOpt: bool = True, unlinkBin: bool = True,
|
self, *, unlinkOpt: bool = True, unlinkBin: bool = True,
|
||||||
@@ -1284,7 +1280,7 @@ class LocalPackage:
|
|||||||
rv += self.binLinks
|
rv += self.binLinks
|
||||||
|
|
||||||
if unlinkOpt:
|
if unlinkOpt:
|
||||||
rv += filter(None, [self.readOptLink(ensurePkg=False)])
|
rv += filter(None, [self.optLink])
|
||||||
|
|
||||||
for lnk in rv:
|
for lnk in rv:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
@@ -1617,9 +1613,9 @@ class Cellar:
|
|||||||
return DependencyTree(forward)
|
return DependencyTree(forward)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def allBinLinks(matching: str = '') -> list[LinkTarget]:
|
def allBinLinks() -> list[LinkTarget]:
|
||||||
''' List of all `@/bin/...` links with `<matching>` destination '''
|
''' List of all `@/bin/...` links '''
|
||||||
return LinkTarget.allInDir(Cellar.BIN, matching)
|
return LinkTarget.allInDir(Cellar.BIN)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def allOptLinks() -> list[LinkTarget]:
|
def allOptLinks() -> list[LinkTarget]:
|
||||||
|
|||||||
Reference in New Issue
Block a user