Created
June 7, 2021 04:11
-
-
Save zbentley/f58d2836657b90a72d83e07e2e319d56 to your computer and use it in GitHub Desktop.
dat zb good shit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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