From c5f4f0d5147cf83bf3e59fd022a47954e40682c1 Mon Sep 17 00:00:00 2001 From: Dave MacFarlane Date: Wed, 30 Dec 2015 11:21:15 -0500 Subject: [PATCH] Added "bug status" and "bug priority" commands --- BugApplication.go | 65 +++++++++++++++++++ BugHelp.go | 60 +++++++++++++---- README.md | 31 +++++---- bugs/Bug.go | 60 +++++++++++++++++ bugs/Find.go | 22 +++++++ .../Description | 3 + .../Status | 1 + .../Description | 3 - .../Description | 4 ++ .../tags/feature | 0 .../Description | 7 ++ .../tags/feature} | 0 issues/bug-tag-with-no-arguments/Description | 2 + issues/bug-tag-with-no-arguments/tags/bug | 0 issues/bug-tag-with-no-arguments/tags/feature | 0 main.go | 4 ++ 16 files changed, 236 insertions(+), 26 deletions(-) create mode 100644 issues/Add-support-for-other-source-control-engines/Description create mode 100644 issues/Dashes-in-titles-are-not-interpreted-according-to-spec/Status delete mode 100644 issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/Description create mode 100644 issues/Should-have-bug-relabel-command/Description rename issues/{Should-be-able-to-assign-priorities-and-statuses-through-command-line => Should-have-bug-relabel-command}/tags/feature (100%) create mode 100644 issues/Should-have-milestone-and-roadmap-command/Description rename issues/{Should-be-able-to-assign-priorities-and-statuses-through-command-line/tags/newcommand => Should-have-milestone-and-roadmap-command/tags/feature} (100%) create mode 100644 issues/bug-tag-with-no-arguments/Description create mode 100644 issues/bug-tag-with-no-arguments/tags/bug create mode 100644 issues/bug-tag-with-no-arguments/tags/feature diff --git a/BugApplication.go b/BugApplication.go index cd893a4..f607d2f 100644 --- a/BugApplication.go +++ b/BugApplication.go @@ -207,6 +207,71 @@ func (a BugApplication) Create(Args []string) { } } +func (a BugApplication) Priority(args []string) { + if len(args) < 1 { + fmt.Printf("Usage: %s priority issuenum [set priority]\n", os.Args[0]) + return + } + + idx, err := strconv.Atoi(args[0]) + if err != nil { + fmt.Printf("Invalid issue number. \"%s\" is not a number.\n\n", args[0]) + fmt.Printf("Usage: %s priority issuenum [set priority]\n", os.Args[0]) + return + } + b, err := bugs.LoadBugByIndex(idx) + if err != nil { + fmt.Printf("Invalid issue number %s\n", args[0]) + return + } + if len(args) > 1 { + newPriority := strings.Join(args[1:], " ") + err := b.SetPriority(newPriority) + if err != nil { + fmt.Printf("Error setting priority: %s", err.Error()) + } + } else { + priority := b.Priority() + if priority == "" { + fmt.Printf("Priority not defined\n") + } else { + fmt.Printf("%s\n", priority) + } + } +} +func (a BugApplication) Status(args []string) { + if len(args) < 1 { + fmt.Printf("Usage: %s status issuenum [set status]\n", os.Args[0]) + return + } + + idx, err := strconv.Atoi(args[0]) + if err != nil { + fmt.Printf("Invalid bug number. \"%s\" is not a number.\n\n", args[0]) + fmt.Printf("Usage: %s status issuenum [set status]\n", os.Args[0]) + return + } + b, err := bugs.LoadBugByIndex(idx) + if err != nil { + fmt.Printf("Invalid bug number %s\n", args[0]) + return + } + if len(args) > 1 { + newStatus := strings.Join(args[1:], " ") + fmt.Printf("Setting status to %s\n", newStatus) + err := b.SetStatus(newStatus) + if err != nil { + fmt.Printf("Error setting status: %s", err.Error()) + } + } else { + status := b.Status() + if status == "" { + fmt.Printf("Status not defined\n") + } else { + fmt.Printf("%s\n", status) + } + } +} func (a BugApplication) Dir() { fmt.Printf("%s", bugs.GetRootDir()+"/issues") } diff --git a/BugHelp.go b/BugHelp.go index 8431d82..15d0beb 100644 --- a/BugHelp.go +++ b/BugHelp.go @@ -46,6 +46,35 @@ print any issues which have that tag (in short form) `This will launch your standard editor to edit the description of the bug numbered IssueNumber, where IssueNumber is a reference to same index provided with a "bug list" command. +`) + case "status": + fmt.Printf("Usage: " + os.Args[0] + " status IssueNumber [NewStatus]\n\n") + fmt.Printf( + `This will edit or display the status of the bug numbered IssueNumber. + +If NewStatus is provided, it will update the first line of the Status file +for the issue (creating the file as necessary). If not provided, it will +display the first line of the Status file to STDOUT. + +Note that you can manually edit the Status file in the issues/ directory +to provide further explanation (for instance, why that status is set.) +This command will preserve the explanation when updating a status. +`) + case "priority": + fmt.Printf("Usage: " + os.Args[0] + " priority IssueNumber [NewPriority]\n\n") + fmt.Printf( + `This will edit or display the priority of the bug numbered IssueNumber. +By convention, priorities should be an integer number (higher is more +urgent), but that is not enforced by this command and NewPriority can +be any free-form text if you prefer. + +If NewPriority is provided, it will update the first line of the Priority +file for the issue (creating the file as necessary). If not provided, it +will display the first line of the Priority file to STDOUT. + +Note that you can manually edit the Priority file in the issues/ directory +to provide further explanation (for instance, why that priority is set.) +This command will preserve the explanation when updating a priority. `) case "rm": fallthrough @@ -107,17 +136,24 @@ Tags can be any string which would make a valid file name. fmt.Printf("Usage: " + os.Args[0] + " command [options]\n\n") fmt.Printf("Use \"bug help [command]\" for more information about any command below\n\n") fmt.Printf("Valid commands\n") - fmt.Printf("\tcreate\tFile a new bug\n") - fmt.Printf("\tlist\tList existing bugs\n") - fmt.Printf("\tedit\tEdit an existing bug\n") - fmt.Printf("\ttag\tTag a bug with a category\n") - fmt.Printf("\tclose\tDelete an existing bug\n") - fmt.Printf("\tcommit\tCommit any new, changed or deleted bug to git\n") - fmt.Printf("\tpurge\tRemove all issues not tracked by git\n") - fmt.Printf("\trm\tAlias of close\n") - fmt.Printf("\tenv\tShow settings that bug will use if invoked from this directory\n") - fmt.Printf("\tdir\tPrints the issues directory to stdout (useful subcommand in the shell)\n") - fmt.Printf("\tpwd\tAlias of dir\n") - fmt.Printf("\thelp\tShow this screen\n") + fmt.Printf("\nIssue editing commands:\n") + fmt.Printf("\tcreate\t File a new bug\n") + fmt.Printf("\tlist\t List existing bugs\n") + fmt.Printf("\tedit\t Edit an existing bug\n") + fmt.Printf("\ttag\t Tag a bug with a category\n") + fmt.Printf("\tclose\t Delete an existing bug\n") + fmt.Printf("\trm\t Alias of close\n") + fmt.Printf("\tstatus\t View or edit a bug's status\n") + fmt.Printf("\tpriority View or edit a bug's priority\n") + + fmt.Printf("\nSource control commands:\n") + fmt.Printf("\tcommit\t Commit any new, changed or deleted bug to git\n") + fmt.Printf("\tpurge\t Remove all issues not tracked by git\n") + + fmt.Printf("\nOther commands:\n") + fmt.Printf("\tenv\t Show settings that bug will use if invoked from this directory\n") + fmt.Printf("\tdir\t Prints the issues directory to stdout (useful subcommand in the shell)\n") + fmt.Printf("\tpwd\t Alias of dir\n") + fmt.Printf("\thelp\t Show this screen\n") } } diff --git a/README.md b/README.md index 0b43591..bc00fc1 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,26 @@ Usage: bug command [options] Use "bug help [command]" for more information about any command below Valid commands - create File a new bug - list List existing bugs - edit Edit an existing bug - close Delete an existing bug - commit Commit any new, changed or deleted bug to git - purge Remove all issues not tracked by git - rm Alias of close - env Show settings that bug will use if invoked from this directory - dir Prints the issues directory to stdout (useful subcommand in the shell) - pwd Alias of dir - help Show this screen + +Issue editing commands: + create File a new bug + list List existing bugs + edit Edit an existing bug + tag Tag a bug with a category + close Delete an existing bug + rm Alias of close + status View or edit a bug's status + priority View or edit a bug's priority + +Source control commands: + commit Commit any new, changed or deleted bug to git + purge Remove all issues not tracked by git + +Other commands: + env Show settings that bug will use if invoked from this directory + dir Prints the issues directory to stdout (useful subcommand in the shell) + pwd Alias of dir + help Show this screen $ bug create I don't know what I'm doing # (Your standard editor will open here for you to enter a description, save it when you're done) diff --git a/bugs/Bug.go b/bugs/Bug.go index ae93a01..79344e5 100644 --- a/bugs/Bug.go +++ b/bugs/Bug.go @@ -47,10 +47,19 @@ func (b Bug) ViewBug() { fmt.Printf("Title: %s\n\n", b.Title) fmt.Printf("Description:\n%s", b.Description) + status := b.Status() + if status != "" { + fmt.Printf("\nStatus: %s", status) + } + priority := b.Priority() + if priority != "" { + fmt.Printf("\nPriority: %s", priority) + } tags := b.Tags() if tags != nil { fmt.Printf("\nTags: %s", strings.Join(tags, ", ")) } + } func (b Bug) Tags() []string { @@ -68,3 +77,54 @@ func (b Bug) Tags() []string { return tags } + +func (b Bug) getField(fieldName string) string { + dir, _ := b.GetDirectory() + field, err := ioutil.ReadFile(string(dir) + "/" + fieldName) + if err != nil { + return "" + } + lines := strings.Split(string(field), "\n") + if len(lines) > 0 { + return strings.TrimSpace(lines[0]) + } + return "" +} + +func (b Bug) setField(fieldName, value string) error { + dir, _ := b.GetDirectory() + oldValue, err := ioutil.ReadFile(string(dir) + "/" + fieldName) + var oldLines []string + if err == nil { + oldLines = strings.Split(string(oldValue), "\n") + } + + newValue := "" + if len(oldLines) >= 1 { + // If there were 0 or 1 old lines, overwrite them + oldLines[0] = value + newValue = strings.Join(oldLines, "\n") + } else { + newValue = value + } + + err = ioutil.WriteFile(string(dir)+"/"+fieldName, []byte(newValue), 0644) + if err != nil { + return err + } + return nil +} +func (b Bug) Status() string { + return b.getField("Status") +} + +func (b Bug) SetStatus(newStatus string) error { + return b.setField("Status", newStatus) +} +func (b Bug) Priority() string { + return b.getField("Priority") +} + +func (b Bug) SetPriority(newValue string) error { + return b.setField("Priority", newValue) +} diff --git a/bugs/Find.go b/bugs/Find.go index 0cf5688..bb21b1d 100644 --- a/bugs/Find.go +++ b/bugs/Find.go @@ -1,5 +1,27 @@ package bugs +import ( + "fmt" + "io/ioutil" +) + +type BugNotFoundError string + +func (b BugNotFoundError) Error() string { + return "Bug not found" +} func FindBugsByTag(tags []string) []Bug { return []Bug{} } + +func LoadBugByIndex(idx int) (*Bug, error) { + issues, _ := ioutil.ReadDir(string(GetRootDir()) + "/issues") + if idx < 1 || idx > len(issues) { + return nil, BugNotFoundError("Invalid Index") + } + + b := Bug{} + directoryString := fmt.Sprintf("%s%s%s", GetRootDir(), "/issues/", issues[idx-1].Name()) + b.LoadBug(Directory(directoryString)) + return &b, nil +} diff --git a/issues/Add-support-for-other-source-control-engines/Description b/issues/Add-support-for-other-source-control-engines/Description new file mode 100644 index 0000000..0ca9a07 --- /dev/null +++ b/issues/Add-support-for-other-source-control-engines/Description @@ -0,0 +1,3 @@ +It would be nice to support things other than +git as a storage engine. In particular, a +BugsEverywhere user requested hg support. diff --git a/issues/Dashes-in-titles-are-not-interpreted-according-to-spec/Status b/issues/Dashes-in-titles-are-not-interpreted-according-to-spec/Status new file mode 100644 index 0000000..ce4a72b --- /dev/null +++ b/issues/Dashes-in-titles-are-not-interpreted-according-to-spec/Status @@ -0,0 +1 @@ +open \ No newline at end of file diff --git a/issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/Description b/issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/Description deleted file mode 100644 index a8e9d0f..0000000 --- a/issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/Description +++ /dev/null @@ -1,3 +0,0 @@ -There is no way to assign priorities with the command line -(or statuses) as defined in the poor man issue tracker -definition. This should be implemented diff --git a/issues/Should-have-bug-relabel-command/Description b/issues/Should-have-bug-relabel-command/Description new file mode 100644 index 0000000..1c3ef67 --- /dev/null +++ b/issues/Should-have-bug-relabel-command/Description @@ -0,0 +1,4 @@ +There is currently no way to update a bug's title. There +should be a relabel command to make it easier to change +the title of a bug without manually doing a mv and commiting +to source control diff --git a/issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/tags/feature b/issues/Should-have-bug-relabel-command/tags/feature similarity index 100% rename from issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/tags/feature rename to issues/Should-have-bug-relabel-command/tags/feature diff --git a/issues/Should-have-milestone-and-roadmap-command/Description b/issues/Should-have-milestone-and-roadmap-command/Description new file mode 100644 index 0000000..2a222d5 --- /dev/null +++ b/issues/Should-have-milestone-and-roadmap-command/Description @@ -0,0 +1,7 @@ +There should be a command to add a milestone to issues, and +another command to display all issues sorted by milestone +(and subsorted by priority?) in markdown (or other easy, human +readable) format. + +Then there can be a git hook to generate a roadmap automatically +on commit. diff --git a/issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/tags/newcommand b/issues/Should-have-milestone-and-roadmap-command/tags/feature similarity index 100% rename from issues/Should-be-able-to-assign-priorities-and-statuses-through-command-line/tags/newcommand rename to issues/Should-have-milestone-and-roadmap-command/tags/feature diff --git a/issues/bug-tag-with-no-arguments/Description b/issues/bug-tag-with-no-arguments/Description new file mode 100644 index 0000000..ae4721f --- /dev/null +++ b/issues/bug-tag-with-no-arguments/Description @@ -0,0 +1,2 @@ +"bug tag" with no arguments should print a show usage +line. It should also display all currently in use tags. diff --git a/issues/bug-tag-with-no-arguments/tags/bug b/issues/bug-tag-with-no-arguments/tags/bug new file mode 100644 index 0000000..e69de29 diff --git a/issues/bug-tag-with-no-arguments/tags/feature b/issues/bug-tag-with-no-arguments/tags/feature new file mode 100644 index 0000000..e69de29 diff --git a/main.go b/main.go index 97bb8c5..e3e01cf 100644 --- a/main.go +++ b/main.go @@ -35,6 +35,10 @@ func main() { fallthrough case "list": app.List(os.Args[2:]) + case "priority": + app.Priority(os.Args[2:]) + case "status": + app.Status(os.Args[2:]) case "tag": app.Tag(os.Args[2:]) case "purge":