Last active
August 20, 2022 08:02
-
-
Save nathants/edaae4554aeb9e1bbe604922edb3c4d9 to your computer and use it in GitHub Desktop.
check for updates and optionally upgrade packages via pip
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 python3 | |
# The MIT License (MIT) | |
# Copyright (c) 2022-present Nathan Todd-Stone | |
# https://en.wikipedia.org/wiki/MIT_License#License_terms | |
""" | |
check for updates and optionally upgrade packages via pip | |
""" | |
import os | |
import subprocess | |
import sys | |
import termios | |
import tty | |
_trace = lambda x: print(f'$ {x} [cwd={os.getcwd()}]', file=sys.stderr) or x | |
_kw = dict(shell=True, executable='/bin/bash') | |
_fmt = lambda a: _trace(' '.join(map(str, a))) | |
co = lambda *a: subprocess.check_output(_fmt(a), **_kw).decode('utf-8').strip() | |
cc = lambda *a: subprocess.check_call(_fmt(a), **_kw) | |
def getch(): | |
fd = sys.stdin.fileno() | |
old = termios.tcgetattr(fd) | |
try: | |
tty.setraw(fd) | |
val = sys.stdin.read(1).lower() | |
if val == '\x03': | |
sys.exit(1) | |
else: | |
return val | |
except KeyboardInterrupt: | |
sys.exit(1) | |
finally: | |
termios.tcsetattr(fd, termios.TCSADRAIN, old) | |
def pip_checks(): | |
checks = co('pip check || echo failed: $?').splitlines() | |
failed = (checks[-1].startswith('failed: ') | |
and len(checks[-1].split()) == 2 | |
and checks[-1].split()[1].isdigit()) | |
if failed: | |
gits = co('pip freeze').splitlines() | |
gits = {x.split('egg=')[-1] | |
.split('&')[0] | |
.replace('-', '_') | |
for x in gits | |
if 'egg=' in x} | |
checks = {x.split()[0].replace('-', '_') | |
for x in checks[:-1]} | |
return checks - gits | |
else: | |
return [] | |
def pip_packages(): | |
pip = os.environ.get('pip', 'pip') | |
for outdated in co(pip, 'list --outdated').splitlines()[2:]: | |
try: | |
name, old, new, kind, location = outdated.split() | |
print('skip:', name, location) | |
continue | |
except ValueError: | |
name, old, new, kind = outdated.split() | |
print('upgrade:', name, old, '->', new) | |
yield name | |
if __name__ == '__main__': | |
packages = list(pip_packages()) | |
if packages: | |
print('\nwould you like to proceed? y/n\n') | |
assert getch() == 'y', 'abort' | |
cc('pip install --upgrade', *packages) | |
else: | |
print('nothing to upgrade') | |
for package in pip_checks(): | |
cc('pip install', package) | |
checks = pip_checks() | |
if checks: | |
print('error: pip check failed', file=sys.stderr) | |
print('\n'.join(checks)) | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment