Skip to content

Instantly share code, notes, and snippets.

@zbentley
Created June 7, 2021 04:11
Show Gist options
  • Save zbentley/f58d2836657b90a72d83e07e2e319d56 to your computer and use it in GitHub Desktop.
Save zbentley/f58d2836657b90a72d83e07e2e319d56 to your computer and use it in GitHub Desktop.
dat zb good shit
#!/usr/bin/env python
import os
import os.path
import sys
from collections import namedtuple, defaultdict
ResultSpec = namedtuple('ResultSpec', ('subdir', 'file_filter', 'join'))
HOMEBREW_DIR = '/usr/local/opt/'
IGNORELIST = {
'git-extras', # Don't need to pollute PATH as they're included in git apps
'db', # Not useful/comes with OSX
'libffi', # Breaks the hell out of Python installs
}
RENAME_BINARIES = {
'coreutils',
'findutils',
'grep',
'sed',
'libtool',
'make',
}
TARGET_DIR = os.path.abspath(os.path.expanduser('~/.zbox/bin/'))
INCLUDE = ResultSpec(subdir='include', file_filter=lambda _: True, join=' -I')
RESULTS = {
'PATH': ResultSpec(subdir='bin', file_filter=lambda p: os.access(p, os.X_OK), join=':'),
'LDFLAGS': ResultSpec(subdir='lib', file_filter=lambda p: p.endswith(('.a', '.dylib', '.so', '.o')), join=' -L'),
'CFLAGS': INCLUDE,
'CPPFLAGS': INCLUDE,
'CXXFLAGS': INCLUDE,
'PKG_CONFIG_PATH': ResultSpec(subdir='lib/pkgconfig', file_filter=lambda p: p.endswith('.pc'), join=':'),
}
NOOP = sys.argv[-1] != '--execute'
def homebrew_apps():
seen = set()
for item in reversed(sorted(os.listdir(HOMEBREW_DIR))):
if item.startswith('.'):
continue
realpath = os.readlink(os.path.join(HOMEBREW_DIR, item))
realpath = os.path.join(HOMEBREW_DIR, realpath)
realpath = os.path.abspath(realpath)
if (
item not in seen
and realpath not in seen
and '@' not in item
and os.path.isdir(realpath)
and item not in IGNORELIST
):
seen.add(item)
seen.add(realpath) # Deal with synonyms
yield os.path.join(HOMEBREW_DIR, item)
def main():
results = defaultdict(list)
exitcode = 0
for app in homebrew_apps():
for env_var, matcher in RESULTS.items():
subdir = os.path.join(app, matcher.subdir)
if os.path.isdir(subdir):
matching = list(filter(lambda p: matcher.file_filter(os.path.join(subdir, p)), os.listdir(subdir)))
if len(matching):
# Do we need to get it onto PATH by making symlinks (a polyfill for things "brew link" refuses to do)?
if matcher.subdir == 'bin' and os.path.basename(app) in RENAME_BINARIES:
for item in filter(lambda i: i.startswith('g'), matching):
source = os.path.join(subdir, item)
target = os.path.join(TARGET_DIR, item[1:])
if os.path.abspath(target) != os.path.abspath(source):
if NOOP:
print('Would symlink {} to {}'.format(source, target))
exitcode = 1
else:
if os.path.exists(target):
os.remove(target)
os.symlink(source, target)
else:
results[env_var].append(subdir)
for env_var, accum in results.items():
accum = list(filter(None, map(str.strip, accum))) # Paranoia
existing = os.environ.get(env_var, '').strip()
join_char = RESULTS[env_var].join
candidate = (join_char + join_char.join(accum)).strip(' :')
# Can't compare equality due to us sticking the OG variable on there. This decision could cause some ordering-
# -related grief down the road.
if candidate not in existing:
if NOOP:
print('{} needs to change:'.format(env_var))
print('Old: {}'.format(os.environ.get(env_var)))
print('New: {}\n'.format(candidate))
exitcode = 1
else:
print('zbox_pathmunge {var} "{val}" start "{sep}"'.format(
var=env_var,
val=candidate,
sep=join_char if join_char == ':' else ' ',
))
sys.exit(exitcode)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment