commit bde8d01aaeb841463266107de52d68a4c0eb44aa Author: Jonathan Bernard Date: Fri Feb 12 05:21:08 2010 -0600 Initial commit diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..6f3cc06 --- /dev/null +++ b/.hgignore @@ -0,0 +1 @@ +\..*sw[op] diff --git a/bt.groovy b/bt.groovy new file mode 100644 index 0000000..67f5d18 --- /dev/null +++ b/bt.groovy @@ -0,0 +1,123 @@ +#!/usr/bin/groovy + +def cli = new CliBuilder(usage: '') +cli.h(longOpt: 'help', 'Show help information.') +cli.v(longOpt: 'verbose', 'Show verbose task information') +cli.l(longOpt: 'list', 'List issues. Unless otherwise specified it lists all ' + + 'sub projects and all unclosed issue categories.') +cli.i(argName: 'id', longOpt: 'id', args: 1, + 'Filter issues by id. Accepts a comma-delimited list.') +cli.c(argName: 'category', longOpt: 'category', args: 1, + 'Filter issues by category (bug, feature, task, closed). Accepts a ' + + 'comma-delimited list.') +cli.p(argName: 'priority', longOpt: 'priority', args: 1, + 'Filter issues by priority. This acts as a threshhold, listing all issues ' + + 'greater than or equal to the given priority.') +cli.r(argName: 'project', longOpt: 'project', args: 1, + 'Filter issues by project (relative to the current directory). Accepts a ' + + 'comma-delimited list.') +cli.s(longOpt: 'show-subprojects', + 'Include sup projects in listing (default behaviour)') +cli.S(longOpt: 'no-subprojects', 'Do not list subprojects.') + +def opts = cli.parse(args) +def issuedb = [:] + +if (!opts) System.exit(1) // better solution? + +if (opts.h) cli.usage() + +def categories = ['bug','feature','task'] +if (opts.c) categories = opts.c.split(/[,\s]/) +categories = categories.collect { Category.toCategory(it) } + +// build issue list +issuedb = buildDB(new File('.'), + 'categories': categories, + 'priority': (opts.p ? opts.p.toInteger() : 9), + 'projects': (opts.r ? opts.r.toLowerCase().split(/[,\s]/).asType(List.class) : false), + 'ids': (opts.i ? opts.i.split(/[,\s]/).asType(List.class) : false), + 'recurse': (opts.s || !opts.S)) + +listDB(issuedb, 'verbose': opts.v) + +enum Category { + BUG, + FEATURE, + TASK, + CLOSED + + public static Category toCategory(String s) { + for(c in Category.values()) + if (c.toString().startsWith(s.toUpperCase())) return c + throw new IllegalArgumentException("No category matches ${s}.") + } +} + +def buildDB(Map options, File dir) { + if (!options.priority) options.priority = 9 + + def newdb = ['projects':[:], 'issues':[:], 'name': dir.name] + + dir.eachFile { child -> + + // add sub projects + if (child.isDirectory()) { + if ( child.name ==~ /\d{4}/ || // just an issue folder + !options.recurse || // we are not looking at subprojects + (options.projects && // not in the list of sub + !options.projects.contains(child.name.toLowerCase()))) + return + + // otherwise build and add to list + newdb['projects'][(child.name)] = buildDB(options, child) + } else if (child.isFile()) { + def issue = buildIssue(child) + + if ( issue == null || // not an issue + issue.priority > options.priority || // not above threshold + (options.categories && // not in list of cats + !options.categories.contains(issue.category)) || + (options.ids && + !options.ids.contains(issue.id))) + return + + newdb['issues'][(issue.id)] = issue + } + } + + return newdb +} + +def buildIssue(File file) { + def issue = [:] + + def matcher = file.name =~ /(\d{4})([bftc])(\d).*/ + if (!matcher) return null + + issue.id = matcher[0][1] + issue.category = Category.toCategory(matcher[0][2]) + issue.priority = matcher[0][3].toInteger() + + file.withReader { issue.title = it.readLine() } + issue.text = file.text + + return issue +} + +def listDB(Map options, def issuedb) { + if (!options.offset) options.offset = "" + if (!options.verbose) options.verbose = false + + for (i in issuedb.issues.values()) { + println "${options.offset}${i.id}(${i.priority}): ${i.category} ${i.title}" + if (options.verbose) println "\n${i.text}" + } + for (p in issuedb.projects.values()) { + println "" + println "${options.offset}${p.name}" + println "${options.offset}${'-'.multiply(p.name.length())}" + + listDB(p, 'offset': options.offset + " ", 'verbose': options.verbose) + } +}