Reorganizing into subprojects.
libpit - Personal Issue Tracker core libraries (Filter, Issue, Project, Category) pit-cli - Command Line Interface (CLI) to libpit pit-swing - Graphical, Swing interface to libpit (built using Griffon) libpit and pit-swing both build, though pit-swing is just an empty griffon poject.
This commit is contained in:
46
libpit/build.xml
Normal file
46
libpit/build.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<project name="Personal Issue Tracker">
|
||||
<property file="project.properties"/>
|
||||
<property environment="env"/>
|
||||
|
||||
<target name="init">
|
||||
<fail
|
||||
unless="env.GROOVY_HOME"
|
||||
message="GROOVY_HOME environment variable is not set."/>
|
||||
<echo message="GROOVY_HOME: ${env.GROOVY_HOME}"/>
|
||||
</target>
|
||||
|
||||
<path id="groovy.libs">
|
||||
<fileset dir="${env.GROOVY_HOME}/lib">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
<path id="groovy.cp">
|
||||
<path refid="groovy.libs"/>
|
||||
<fileset dir="${lib.dir}"/>
|
||||
</path>
|
||||
|
||||
<taskdef name="groovyc"
|
||||
classname="org.codehaus.groovy.ant.Groovyc"
|
||||
classpathref="groovy.libs"/>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<mkdir dir="${build.dir}/classes"/>
|
||||
<groovyc
|
||||
srcdir="${src.dir}"
|
||||
destdir="${build.dir}/classes"
|
||||
classpath="${groovyc.cp}"/>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="compile">
|
||||
<mkdir dir="${build.dir}/jar"/>
|
||||
<jar
|
||||
destfile="${build.dir}/jar/${build.jar}"
|
||||
basedir="${build.dir}/classes"
|
||||
compress="on"/>
|
||||
</target>
|
||||
</project>
|
4
libpit/issue-tracker/0001c5.rst
Normal file
4
libpit/issue-tracker/0001c5.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Show full issue text with -v, --verbose
|
||||
=======================================
|
||||
|
||||
Print the full issue when passed the verbose option.
|
6
libpit/issue-tracker/0002f6.rst
Normal file
6
libpit/issue-tracker/0002f6.rst
Normal file
@ -0,0 +1,6 @@
|
||||
Add the ability to change an issue's status
|
||||
===========================================
|
||||
|
||||
The -l/--list options lists issues, add a set of options to reclassify
|
||||
an issue from one category to another. The most common is CLOSED, but
|
||||
other categories should also be supported.
|
4
libpit/issue-tracker/0003f6.rst
Normal file
4
libpit/issue-tracker/0003f6.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Add the ability to re-prioritize a set of issues
|
||||
================================================
|
||||
|
||||
Add a mode that changes the priority of a selection of issues.
|
2
libpit/issue-tracker/0004f7.rst
Normal file
2
libpit/issue-tracker/0004f7.rst
Normal file
@ -0,0 +1,2 @@
|
||||
Add the ability to enter new issues
|
||||
===================================
|
4
libpit/issue-tracker/0005t1.rst
Normal file
4
libpit/issue-tracker/0005t1.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Add unit tests for LIST operation
|
||||
=================================
|
||||
|
||||
Add unit tests for listing issues with no filter.
|
4
libpit/issue-tracker/0006t1.rst
Normal file
4
libpit/issue-tracker/0006t1.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Add unit tests for the PRIORITY filter
|
||||
======================================
|
||||
|
||||
Add unit tests covering the priority selection criteria of the filter.
|
4
libpit/issue-tracker/0007t1.rst
Normal file
4
libpit/issue-tracker/0007t1.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Add unit tests for the CATEGORIES filter
|
||||
========================================
|
||||
|
||||
Add unit tests covering the categories filter criteria.
|
4
libpit/issue-tracker/0008t1.rst
Normal file
4
libpit/issue-tracker/0008t1.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Add unit tests for the PROJECTS filter
|
||||
======================================
|
||||
|
||||
Add unit tests covering the projects filter criteria.
|
4
libpit/issue-tracker/0009t1.rst
Normal file
4
libpit/issue-tracker/0009t1.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Add unit tests for the RECURSE filter
|
||||
=====================================
|
||||
|
||||
Add unit tests covering the subprojects filter criteria.
|
4
libpit/issue-tracker/0010t1.rst
Normal file
4
libpit/issue-tracker/0010t1.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Add unit tests for the VERBOSE option
|
||||
=====================================
|
||||
|
||||
Add unit tests covering the verbose option
|
5
libpit/project.properties
Normal file
5
libpit/project.properties
Normal file
@ -0,0 +1,5 @@
|
||||
app.version=1.0
|
||||
build.dir=build
|
||||
build.jar=pit-${app.version}.jar
|
||||
lib.dir=../lib
|
||||
src.dir=src
|
14
libpit/src/com/jdbernard/pit/Category.groovy
Normal file
14
libpit/src/com/jdbernard/pit/Category.groovy
Normal file
@ -0,0 +1,14 @@
|
||||
package com.jdbernard.pit
|
||||
|
||||
public 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}.")
|
||||
}
|
||||
}
|
28
libpit/src/com/jdbernard/pit/Filter.groovy
Normal file
28
libpit/src/com/jdbernard/pit/Filter.groovy
Normal file
@ -0,0 +1,28 @@
|
||||
package com.jdbernard.pit
|
||||
|
||||
class Filter {
|
||||
|
||||
List<Category> categories = null
|
||||
List<String> projects = null
|
||||
List<String> 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)))
|
||||
}
|
||||
}
|
24
libpit/src/com/jdbernard/pit/Issue.groovy
Normal file
24
libpit/src/com/jdbernard/pit/Issue.groovy
Normal file
@ -0,0 +1,24 @@
|
||||
package com.jdbernard.pit
|
||||
|
||||
public 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
|
||||
}
|
||||
|
||||
}
|
73
libpit/src/com/jdbernard/pit/Project.groovy
Normal file
73
libpit/src/com/jdbernard/pit/Project.groovy
Normal file
@ -0,0 +1,73 @@
|
||||
package com.jdbernard.pit
|
||||
|
||||
class Project {
|
||||
|
||||
String name
|
||||
Map<String, Issue> issues = [:]
|
||||
Map<String, Project> projects = [:]
|
||||
|
||||
Project(File dir, Filter filter = null) {
|
||||
dir.eachFile { child ->
|
||||
|
||||
// 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.toInteger() }
|
||||
def ps = filter?.projectSorter ?: { it.name }
|
||||
|
||||
for (issue in issues.values().sort(is)) {
|
||||
if (filter && !filter.accept(issue))
|
||||
return
|
||||
|
||||
c.call(issue)
|
||||
}
|
||||
|
||||
for (project in projects.values().sort(ps)) {
|
||||
if (filter && !filter.accept(project))
|
||||
return
|
||||
|
||||
c.call(project)
|
||||
project.each(c)
|
||||
}
|
||||
}
|
||||
|
||||
public void list(Map options = [:]) {
|
||||
if (!options.offset) options.offset = ""
|
||||
if (!options.verbose) options.verbose = false
|
||||
|
||||
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}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user