* Added support for extended properties to `Filter`. Unlike the basic properties, which allow the caller to specify a list of acceptable values, the extended properties only supports a map of properties, all of which must be available on the issue and match the given value. * Made `Issue` a concrete class. There was no reason it could not be a concrete object. The main difference is that the extending classes all add some sort of persistence to the issue, but having an in-memory `Issue` in its most basic form can be useful and should be allowed. * Changed the default priority for new issues from 9 to 5. * Bug fix on `FileIssue.formatIssue()`. If was not properly returning its result leading to failure if no extended properties were given. * Reworked `FileIssue.formatIssue()` to only print the horizontal rule seperating the issue text from the extended properties if there are extended properties to print as well. * Changed the `FileProject.createNewIssue()` to handle extended properties and handle the basic properties in a manner more consistent with `Issue`. It is now creating an `Issue` object and using the `FileIssue.formatIssue()` function to write that to a new issue file, then loading that file back in as a `FileIssue`. This cuts down on code duplication and makes it so that the options map that `FileProject.createNewIssue()` expects is the same as the options to the `Issue` constructor.
108 lines
3.3 KiB
Groovy
Executable File
108 lines
3.3 KiB
Groovy
Executable File
package com.jdbernard.pit.file
|
|
|
|
import com.jdbernard.pit.*
|
|
|
|
class FileProject extends Project {
|
|
|
|
protected File source
|
|
|
|
public FileProject(File dir) {
|
|
super(dir.canonicalFile.name)
|
|
|
|
if (!dir.isDirectory())
|
|
throw new IllegalArgumentException(
|
|
"${dir.name} is not a directory.")
|
|
|
|
this.source = dir
|
|
|
|
dir.eachFile { child ->
|
|
|
|
// add sub projects
|
|
if (child.isDirectory()) {
|
|
if (child.name ==~ /\d+/ ||
|
|
child.isHidden()) return // just an issue folder
|
|
|
|
// otherwise build and add to list
|
|
projects[(child.name)] = new FileProject(child) }
|
|
else if (child.isFile() &&
|
|
FileIssue.isValidFilename(child.name)) {
|
|
def issue
|
|
|
|
// if exception, then not an issue
|
|
try { issue = new FileIssue(child) } catch (all) { return }
|
|
|
|
issues[(issue.id)] = issue } }}
|
|
|
|
public void setName(String name) {
|
|
super.setName(name)
|
|
source.renameTo(new File(source.canonicalFile.parentFile, name)) }
|
|
|
|
public FileIssue createNewIssue(Map options) {
|
|
Issue issue
|
|
File issueFile
|
|
|
|
if (!options) options = [:]
|
|
|
|
// We want some different defaults for issues due to the parser being
|
|
// unable to handle empty title or text.
|
|
if (!options.title) options.title = "Default issue title."
|
|
if (!options.text) options.text = "Describe the issue here."
|
|
|
|
// We are also going to find the next id based on the issues already in the
|
|
// project.
|
|
if (issues.size() == 0) options.id = '0000'
|
|
else {
|
|
def lastId = (issues.values().max { it.id.toInteger() }).id
|
|
options.id = (lastId.toInteger() + 1).toString().padLeft(
|
|
lastId.length(), '0') }
|
|
|
|
// Create an Issue object from the options (we will discard it later).
|
|
issue = new Issue(options)
|
|
|
|
// Create the filename and File object based on the options given.
|
|
issueFile = new File(source, FileIssue.makeFilename(
|
|
issue.id, issue.category, issue.status, issue.priority))
|
|
|
|
// Create the actual file on the system
|
|
issueFile.createNewFile()
|
|
|
|
// Write the issue to the file created.
|
|
issueFile.write(FileIssue.formatIssue(issue))
|
|
|
|
// Read that new file back in as a FileIssue
|
|
issue = new FileIssue(issueFile)
|
|
|
|
// Add the issue to our collection.
|
|
issues[(issue.id)] = issue
|
|
|
|
return issue }
|
|
|
|
public FileProject createNewProject(String name) {
|
|
def newDir = new File(source, name)
|
|
newDir.mkdirs()
|
|
|
|
return new FileProject(newDir) }
|
|
|
|
public boolean deleteIssue(Issue issue) {
|
|
if (!issues[(issue.id)]) return false
|
|
|
|
issues.remove(issue.id)
|
|
if (issue instanceof FileIssue)
|
|
return issue.deleteFile()
|
|
|
|
else return true }
|
|
|
|
public boolean deleteProject(Project project) {
|
|
if (!projects[(project.name)]) return false
|
|
|
|
projects.remove(project.name)
|
|
if (project instanceof FileProject)
|
|
return project.source.delete()
|
|
|
|
return true }
|
|
|
|
@Override
|
|
public String toString() { return name }
|
|
|
|
}
|