Skip to content

Instantly share code, notes, and snippets.

@aslpavel
Created February 16, 2016 23:13
Show Gist options
  • Save aslpavel/ffb813f68781f55c39cd to your computer and use it in GitHub Desktop.
Save aslpavel/ffb813f68781f55c39cd to your computer and use it in GitHub Desktop.
#! /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