initial import

This commit is contained in:
Erik Osheim 2010-08-02 11:14:18 -04:00
commit f2e836da0d
5 changed files with 299 additions and 0 deletions

22
cleanse Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/python
#
# by Erik osheim
import optparse, os
epilog = 'Remove various junky files left lying around.'
patterns = ('*~', '.#*', '#*', '*.orig', '*-')
parser = optparse.OptionParser(epilog=epilog)
parser.add_option('-f', '--fake', dest='fake', action='store_true',
help="print files; do not remove them")
opts, args = parser.parse_args()
stanzas = ' -o '.join(["-name '%s'" % x for x in patterns])
cmd = "find . -type f \\( %s \\) -print" % stanzas
if opts.fake:
print "files that would be deleted:"
else:
cmd += " -exec rm {} ';'";
os.system(cmd)

105
histo Executable file
View File

@ -0,0 +1,105 @@
#!/usr/bin/python
import optparse
import os
import sys
# this is a dictionary of all the "items" (lines) that have been seen, mapping
# to a count of how many times it was seen.
seen = {}
parser = optparse.OptionParser()
parser.set_defaults(draw=False, nullok=False, valsort=False, reverse=False,
hwidth=None, percent=False, strip=False, delim=' ',
swap=False, josh=False, nopad=False)
parser.add_option('-d', '--draw', action='store_true', dest='draw',
help='draw histogram with horizontal graph')
parser.add_option('-D', '--delim', action='store', type="string", dest='delim',
help='use STR as delimiter (default: " ")', metavar='STR')
parser.add_option('-f', '--frequency', action='store_true', dest='valsort',
help='sort by frequency')
parser.add_option('-J', '--josh', action='store_true', dest='josh',
help='josh rosenberg compatibility mode')
parser.add_option('-N', '--nopad', action='store_true', dest='nopad',
help='do not column-align output')
parser.add_option('-p', '--percent', action='store_true', dest='percent',
help='show percent rather than count')
parser.add_option('-r', '--reverse', action='store_true', dest='reverse',
help='reverse sort')
parser.add_option('-s', '--strip', action='store_true', dest='strip',
help='strip input lines')
parser.add_option('-S', '--swap', action='store_true', dest='swap',
help='swap output fields')
parser.add_option('-w', '--width', action='store', type='int', dest='hwidth',
help='use NUM characters for graph drawing', metavar="NUM")
parser.add_option('-z', '--null', action='store_true', dest='nullok',
help='allow null lines')
(opts, args) = parser.parse_args()
# allow some special delimiters to be translated
delims = {'\\t': '\t', '\\v': '\v', '\\0': '\0'}
opts.delim = delims.get(opts.delim, opts.delim)
# josh rosenberg compatiblity mode
if opts.josh:
opts.delim = '\t'
opts.swap = True
opts.nopad = True
# process each line on stdin. we can optionally strip whitespace, and we always
# strip a trailing newline. by default we ignore empty lines, but nullok causes
# us to count them as well.
for line in sys.stdin:
key = line[:-1]
if opts.strip:
key = key.strip()
if key or opts.nullok:
seen.setdefault(key, 0)
seen[key] += 1
# sort either by key or by count, depending on the user wanted
keys = seen.keys()
if opts.valsort:
cmpf = lambda a, b: cmp(seen[b], seen[a])
else:
cmpf = lambda a, b: cmp(a, b)
keys.sort(cmpf)
# optionally reverse the sort if the user wanted
if opts.reverse: keys.reverse()
# determine max key length, max count, and total count; also, the printed length
# of the max count.
kmax, cmax, total = 0, 0, 0
for key in keys:
cmax, kmax, total = max(seen[key], cmax), max(len(key), kmax), total + seen[key]
smax = len(str(cmax))
# if we need to draw, we should make some guesses about the screen size. we
# should probably never try to draw more than 40 characters worth of stars.
width = os.environ.get("COLUMNS", 80)
if opts.hwidth is None:
opts.hwidth = min(abs(width - kmax), 40)
for key in keys:
# figure out how to draw the key
if opts.nopad:
vkey = key
else:
vkey = '%-*s' % (kmax, key)
# figure out how to draw the value
if opts.draw:
ratio = float(seen[key]) / cmax
nstar = int(round(opts.hwidth * ratio))
value = '%*s' % (opts.hwidth, '*' * nstar)
elif opts.percent:
perc = float(seen[key]) * 100 / total
value = '%5.1f%%' % perc
else:
value = '%*d' % (smax, seen[key])
# figure out which order to write them in
if opts.swap:
print "%s%s%s" % (vkey, opts.delim, value)
else:
print "%s%s%s" % (value, opts.delim, key)

83
patchinfo Executable file
View File

@ -0,0 +1,83 @@
#!/usr/bin/python
#
# by Erik Osheim
#
# available under the GNU GPL version 2.
#
# This program is designed to provide analysis of patches or diff files.
import optparse
import re
import sys
# matches the diff stanza, which have no leading identifier
diff_re = re.compile('^[0-9a-zA-Z,]+$')
# analyze a particular patch, which is assumed to contain multiple files
def info(f, verbose=False):
paths = []
l = 0
first = True
for line in f:
if first:
if diff_re.match(line):
paths.append(['-', 0, 0, 0, 0])
first = False
if diff_re.match(line):
if not paths:
paths.append(['-', 0, 0, 0, 0])
paths[-1][1] += 1
elif line.startswith('diff'):
path = line.split()[-1]
l = max(l, len(path))
paths.append([path, 0, 0, 0, 0])
elif line.startswith('Index'):
path = line.split()[1]
l = max(l, len(path))
paths.append([path, 0, 0, 0, 0])
elif line.startswith('---') or line.startswith('+++') or line.startswith('='):
pass
elif line.startswith('@@'):
paths[-1][1] += 1
elif line.startswith('+') or line.startswith('>'):
paths[-1][2] += 1
paths[-1][3] += 1
elif line.startswith('-') or line.startswith('<'):
paths[-1][2] -= 1
paths[-1][4] += 1
if len(paths) != 1:
title = '%d paths' % len(paths)
else:
title = '1 path'
if verbose:
title = 'TOTAL ' + title
else:
l = len(title)
totals = [0, 0, 0, 0]
for info in paths:
for i in range(0, 4):
totals[i] += info[i + 1]
lens = [len(str(n)) + 1 for n in totals[:2]]
fmt = '%%-%ds %%%dd groups, %%+%dd lines (+%%d -%%d)' % tuple([l] + lens)
for info in paths:
if verbose:
print fmt % tuple(info)
print fmt % tuple([title] + totals)
if __name__ == "__main__":
op = optparse.OptionParser()
op.add_option('-v', '--verbose', dest='verbose', action='store_true')
opts, args = op.parse_args()
if args:
for arg in args:
info(open(arg, 'r'), verbose=opts.verbose)
else:
info(sys.stdin, verbose=opts.verbose)

11
sgrep Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
grep --binary-files=without-match \
--exclude-dir=CVS \
--exclude-dir=.svn \
--exclude-dir=.hg \
--exclude-dir=.git \
--exclude '*~' \
--exclude '.#*' \
--exclude '#*' \
--exclude '*-' \
"$@"

78
unbox Executable file
View File

@ -0,0 +1,78 @@
#!/usr/bin/env python
#
# by Erik Osheim
#
# This program unboxes various archive
import os
import shutil
from subprocess import call
import sys
import tempfile
# list each kind of archive in terms of extension, and then program and
# arguments to use. Use None to indicate where the filename should be placed.
handlers = {
'.zip': ['unzip', None],
'.tgz': ['tar', 'xvzf', None],
'.tbz': ['tar', 'xvjf', None],
'.tar.gz': ['tar', 'xvzf', None],
'.tar.bz2': ['tar', 'xvjf', None],
#'.tar.xz': ['tar', 'xvJz', None],
}
# program usage
def usage(err=None):
retval = 0
if err:
retval = 1
print 'error: %s' % err
print 'usage: unbox ARCHIVE'
sys.exit(retval)
if __name__ == "__main__":
args = sys.argv[1:]
if not args:
usage()
elif len(args) > 1:
usage('too many arguments')
path = args[0]
if not os.path.exists(path):
usage('path %r does not exist' % path)
cmd = None
for ext in handlers:
if path.endswith(ext):
cmd = handlers[ext]
base = path[:-len(ext)]
if not cmd:
usage("can't handle path %r" % path)
d = tempfile.mkdtemp(prefix='unbox-')
fd, path2 = tempfile.mkstemp(dir=d)
os.write(fd, open(path, 'rb').read())
os.close(fd)
cwd = os.getcwd()
print d
os.chdir(d)
base2 = os.path.basename(path2)
# put the path into the command
cmd = [x or base2 for x in cmd]
retcode = call(cmd)
if retcode != 0:
print 'error: %s failed (%d)' % (cmd[0], retcode)
sys.exit(1)
os.unlink(path2)
items = os.listdir(d)
if len(items) == 1:
shutil.move(d + '/' + items[0], cwd)
shutil.rmtree(d)
else:
shutil.move(d, cwd + '/' + base)