Initial commit
This commit is contained in:
commit
bde8d01aae
123
bt.groovy
Normal file
123
bt.groovy
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user