Created
February 16, 2016 23:13
-
-
Save aslpavel/ffb813f68781f55c39cd to your computer and use it in GitHub Desktop.
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 | |
import os | |
import re | |
import sys | |
import subprocess | |
def error(msg, code=1): | |
sys.stderr.write('[error] {}\n'.format(msg)) | |
sys.exit(code) | |
def confirm(msg): | |
sys.stdout.write('{} [y/N]: '.format(msg)) | |
sys.stdout.flush() | |
res = sys.stdin.readline() | |
if not res.lower().strip() == 'y': | |
sys.stderr.write('[info] canceled by user\n') | |
sys.exit(2) | |
def pkgutil(*args): | |
proc = subprocess.run(('pkgutil',) + args, stdout=subprocess.PIPE) | |
if proc.returncode != 0: | |
error('pkgutil failed') | |
return proc.stdout | |
def main(): | |
if len(sys.argv) != 2: | |
sys.stderr.write('Usage: {} <pkg-name>\n' | |
.format(os.path.basename(sys.argv[0]))) | |
sys.exit(1) | |
pkg = sys.argv[1] | |
info = pkgutil('--info', pkg) | |
vol_match, loc_match = (re.search(b'volume: ([^\n]+)', info), | |
re.search(b'location: ([^\n]*)', info)) | |
if not vol_match or not loc_match: | |
error('pkgutil info bad output: no location or volume') | |
location = (vol_match.group(1) + loc_match.group(1)).decode() | |
files = [os.path.join(location, file.decode()) for file in | |
pkgutil('--only-files', '--files', pkg).split(b'\n') | |
if file != b''] | |
dirs = [os.path.join(location, dir.decode()) for dir in | |
pkgutil('--only-dirs', '--files', pkg).split(b'\n') | |
if dir != b''] | |
dirs.sort(key=lambda s: -len(s)) | |
confirm('[action] delete package {} (loc:{}, files:{}, dirs:{})?' | |
.format(pkg, location, len(files), len(dirs))) | |
files_ok = 0 | |
for file in files: | |
if not os.path.exists(file): | |
files_ok += 1 | |
continue | |
try: | |
os.unlink(file) | |
files_ok += 1 | |
except Exception as err: | |
sys.stderr.write('{}: \x1b[01;31m{}\x1b[m\n' | |
.format(err.strerror, file)) | |
dirs_ok = 0 | |
for dir in dirs: | |
if not os.path.exists(dir): | |
dirs_ok += 1 | |
continue | |
if os.path.isdir(dir) and not os.listdir(dir): | |
try: | |
os.rmdir(dir) | |
dirs_ok += 1 | |
except Exception as err: | |
sys.stderr.write('{}: \x1b[01;31m{}\x1b[m\n' | |
.format(err.strerror, dir)) | |
else: | |
sys.stderr.write('\x1b[01;31m{}\x1b[m\n'.format(dir)) | |
sys.stderr.write('[info] deleted {} (files:{}/{}, dirs:{}/{})\n' | |
.format(pkg, files_ok, len(files), dirs_ok, len(dirs))) | |
confirm('[action] forget {}?'.format(pkg)) | |
pkgutil('--forget', pkg) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment