Created
February 16, 2016 23:13
-
-
Save aslpavel/ffb813f68781f55c39cd to your computer and use it in GitHub Desktop.
Revisions
-
aslpavel created this gist
Feb 16, 2016 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,78 @@ #! /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()