From ddc34722c86738f6697a08c408a58068f59bc457 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Fri, 12 Feb 2010 10:04:51 -0600 Subject: [PATCH] Reorganized into classes. Implemented generic filtering. --- issue-tracker/{0001f5.rst => 0001c5.rst} | 0 issue-tracker/0005t1.rst | 4 + issue-tracker/0006t1.rst | 4 + issue-tracker/0007t1.rst | 4 + issue-tracker/0008t1.rst | 4 + issue-tracker/0009t1.rst | 4 + issue-tracker/0010t1.rst | 4 + pit.groovy | 180 +++++++++++++++-------- 8 files changed, 145 insertions(+), 59 deletions(-) rename issue-tracker/{0001f5.rst => 0001c5.rst} (100%) mode change 100644 => 100755 create mode 100644 issue-tracker/0005t1.rst create mode 100644 issue-tracker/0006t1.rst create mode 100644 issue-tracker/0007t1.rst create mode 100644 issue-tracker/0008t1.rst create mode 100644 issue-tracker/0009t1.rst create mode 100644 issue-tracker/0010t1.rst mode change 100644 => 100755 pit.groovy diff --git a/issue-tracker/0001f5.rst b/issue-tracker/0001c5.rst old mode 100644 new mode 100755 similarity index 100% rename from issue-tracker/0001f5.rst rename to issue-tracker/0001c5.rst diff --git a/issue-tracker/0005t1.rst b/issue-tracker/0005t1.rst new file mode 100644 index 0000000..d92adc3 --- /dev/null +++ b/issue-tracker/0005t1.rst @@ -0,0 +1,4 @@ +Add unit tests for LIST operation +================================= + +Add unit tests for listing issues with no filter. diff --git a/issue-tracker/0006t1.rst b/issue-tracker/0006t1.rst new file mode 100644 index 0000000..3a0a0a4 --- /dev/null +++ b/issue-tracker/0006t1.rst @@ -0,0 +1,4 @@ +Add unit tests for the PRIORITY filter +====================================== + +Add unit tests covering the priority selection criteria of the filter. diff --git a/issue-tracker/0007t1.rst b/issue-tracker/0007t1.rst new file mode 100644 index 0000000..3779ac3 --- /dev/null +++ b/issue-tracker/0007t1.rst @@ -0,0 +1,4 @@ +Add unit tests for the CATEGORIES filter +======================================== + +Add unit tests covering the categories filter criteria. diff --git a/issue-tracker/0008t1.rst b/issue-tracker/0008t1.rst new file mode 100644 index 0000000..70b8044 --- /dev/null +++ b/issue-tracker/0008t1.rst @@ -0,0 +1,4 @@ +Add unit tests for the PROJECTS filter +====================================== + +Add unit tests covering the projects filter criteria. diff --git a/issue-tracker/0009t1.rst b/issue-tracker/0009t1.rst new file mode 100644 index 0000000..3d1a8bd --- /dev/null +++ b/issue-tracker/0009t1.rst @@ -0,0 +1,4 @@ +Add unit tests for the RECURSE filter +===================================== + +Add unit tests covering the subprojects filter criteria. diff --git a/issue-tracker/0010t1.rst b/issue-tracker/0010t1.rst new file mode 100644 index 0000000..56b0097 --- /dev/null +++ b/issue-tracker/0010t1.rst @@ -0,0 +1,4 @@ +Add unit tests for the VERBOSE option +===================================== + +Add unit tests covering the verbose option diff --git a/pit.groovy b/pit.groovy old mode 100644 new mode 100755 index 67f5d18..a2e879e --- a/pit.groovy +++ b/pit.groovy @@ -32,14 +32,23 @@ if (opts.c) categories = opts.c.split(/[,\s]/) categories = categories.collect { Category.toCategory(it) } // build issue list -issuedb = buildDB(new File('.'), - 'categories': categories, +issuedb = new Project(new File('.'), + new Filter('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)) + 'projects': (opts.r ? opts.r.toLowerCase().split(/[,\s]/).asType(List.class) : []), + 'ids': (opts.i ? opts.i.split(/[,\s]/).asType(List.class) : []), + 'acceptProjects': (opts.s || !opts.S))) -listDB(issuedb, 'verbose': opts.v) +// list first +if (opts.l) issuedb.list('verbose': opts.v) + +// change priority second +//else if (opts.cp) + +// change category third +//else if (opts.cc) + +// new entry last enum Category { BUG, @@ -54,70 +63,123 @@ enum Category { } } -def buildDB(Map options, File dir) { - if (!options.priority) options.priority = 9 +class Project { - def newdb = ['projects':[:], 'issues':[:], 'name': dir.name] + String name + Map issues = [:] + Map projects = [:] - dir.eachFile { child -> + Project(File dir, Filter filter = null) { + 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()))) + // add sub projects + if (child.isDirectory()) { + if ( child.name ==~ /\d{4}/ || // just an issue folder + (filter && !filter.accept(child.name))) + return + + // otherwise build and add to list + projects[(child.name)] = new Project(child, filter) + } else if (child.isFile()) { + def issue + + // if exception, then not an issue + try { issue = new Issue(child) } catch (all) { return } + + if (filter && !filter.accept(issue)) return + + issues[(issue.id)] = issue + } + } + } + + public void eachIssue(Closure c) { + for (i in issues.values()) c.call(i) + for (p in projects.values()) p.eachIssue(c) + } + + public void each(Filter filter = null, Closure c) { + def is = filter?.issueSorter ?: { it.id } + def ps = filter?.projectSorter ?: { it.name } + + for (issue in issues.values().sort(is)) { + if (filter && !filter.accept(issue)) return - // otherwise build and add to list - newdb['projects'][(child.name)] = buildDB(options, child) - } else if (child.isFile()) { - def issue = buildIssue(child) + c.call(issue) + } - 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))) + for (project in projects.values().sort(ps)) { + if (filter && !filter.accept(project)) return - newdb['issues'][(issue.id)] = issue + c.call(project) + project.each(c) } } - return newdb -} + public void list(Map options = [:]) { + if (!options.offset) options.offset = "" + if (!options.verbose) options.verbose = false -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) + each(options.filter) { + if (it instanceof Project) { + println "\n${options.offset}${it.name}" + println "${options.offset}${'-'.multiply(p.name.length())}" + } else { + println "${options.offset}${it.id}(${it.priority}): " + + "${it.category} ${it.title}" + if (options.verbose) println "\n${it.text}" + } + } + } +} + +class Issue { + + String id + Category category + int priority + String title + String text + + Issue(File file) { + + def matcher = file.name =~ /(\d{4})([bftc])(\d).*/ + if (!matcher) return null + + id = matcher[0][1] + category = Category.toCategory(matcher[0][2]) + priority = matcher[0][3].toInteger() + + file.withReader { title = it.readLine() } + text = file.text + } +} + +class Filter { + + List categories = null + List projects = null + List ids = null + int priority = 9 + boolean acceptProjects = true + Closure projectSorter + Closure issueSorter + + public boolean accept(Issue i) { + return (i.priority <= priority && + (!categories || categories.contains(i.category)) && + (!ids || ids.contains(i.id))) + } + + public boolean accept(Project p) { + return (acceptProjects && + (!projects || projects.contains(p.name))) + } + + public boolean accept(String name) { + return (acceptProjects && + (!projects || projects.contains(name))) } }