From 07dc7cf50d667d21be1d557c978d634a91d459f2 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 10:51:52 -0500
Subject: [PATCH 01/47] Added or removed issues with the tool "bug"
---
issues/Roadmap.md | 3 +++
.../Description | 12 ++++++++++++
2 files changed, 15 insertions(+)
create mode 100644 issues/bug-close-multiple-issues-incorrect-after-first-issue/Description
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index 0a5848c..150ecbe 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -3,3 +3,6 @@
## v0.4:
- bug-serve should have feature parity with bug
- Implement golang io interfaces in Bug class
+
+## No milestone set:
+- bug close multiple issues incorrect after first issue
diff --git a/issues/bug-close-multiple-issues-incorrect-after-first-issue/Description b/issues/bug-close-multiple-issues-incorrect-after-first-issue/Description
new file mode 100644
index 0000000..f2dfba1
--- /dev/null
+++ b/issues/bug-close-multiple-issues-incorrect-after-first-issue/Description
@@ -0,0 +1,12 @@
+When do you "bug close 1 2 3" for multiple issues by directory
+index, after it coses 1, the index of the ones following 1 changes,
+resulting in the wrong bugs being closed for 2 and 3. The "new" index
+2 is closed from after 1 being removed, not the old "2" that the user
+expected to be closed from when they did "bug list"
+
+Possible solutions:
+1. Only allow 1 issue to be closed at a time
+2. Reverse sort the input before closing. (If this works it
+ would be ideal, but I'd first need to verify that unlinking
+ a file changes the rest of the indexes in a predictable order.)
+
From 5caba8a5a4f6c90fbd3b898f71334ee1df0f6695 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 10:59:40 -0500
Subject: [PATCH 02/47] Updated version number
---
bugapp/Version.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bugapp/Version.go b/bugapp/Version.go
index c40dd30..bd2eb9d 100644
--- a/bugapp/Version.go
+++ b/bugapp/Version.go
@@ -6,6 +6,6 @@ import (
)
func Version() {
- fmt.Printf("%s version 0.3.1\n", os.Args[0])
+ fmt.Printf("%s version 0.4-dev\n", os.Args[0])
}
From 2484cd153cfeccc6ba420f4f91427a6d314f05f0 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 11:25:13 -0500
Subject: [PATCH 03/47] Fixed issue where closing multiple issues closed
incorrect issues
Removing the directory was changing the indexes for further lookups
when closing multiple issues, resulting in the wrong bugs being closed.
This makes it a 2 step process (first look up the directories for
everything passed on the command, and then remove them all, instead
of removing them as we find them.), and adds regression tests to make
sure it stays fixed.
---
bugapp/Close.go | 10 ++-
bugapp/Close_test.go | 77 +++++++++++++++++++
issues/Roadmap.md | 3 -
.../Description | 12 ---
4 files changed, 84 insertions(+), 18 deletions(-)
delete mode 100644 issues/bug-close-multiple-issues-incorrect-after-first-issue/Description
diff --git a/bugapp/Close.go b/bugapp/Close.go
index 54a55c7..c64d36b 100644
--- a/bugapp/Close.go
+++ b/bugapp/Close.go
@@ -15,13 +15,17 @@ func Close(args ArgumentList) {
// There were parameters, so show the full description of each
// of those issues
+ var bugsToClose []string
for _, bugID := range args {
if bug, err := bugs.LoadBugByHeuristic(bugID); err == nil {
dir := bug.GetDirectory()
- fmt.Printf("Removing %s\n", dir)
- os.RemoveAll(string(dir))
+ bugsToClose = append(bugsToClose, string(dir))
} else {
- fmt.Printf("Could not close bug %s: %s\n", bugID, err)
+ fmt.Fprintf(os.Stderr, "Could not close bug %s: %s\n", bugID, err)
}
}
+ for _, dir := range bugsToClose {
+ fmt.Printf("Removing %s\n", dir)
+ os.RemoveAll(dir)
+ }
}
diff --git a/bugapp/Close_test.go b/bugapp/Close_test.go
index 38e7b02..590b287 100644
--- a/bugapp/Close_test.go
+++ b/bugapp/Close_test.go
@@ -120,3 +120,80 @@ func TestCloseBugByIdentifier(t *testing.T) {
t.Error("Unexpected number of issues in issues dir\n")
}
}
+
+func TestCloseMultipleIndexesWithLastIndex(t *testing.T) {
+ dir, err := ioutil.TempDir("", "closetest")
+ defer os.RemoveAll(dir)
+ if err != nil {
+ t.Error("Could not create temporary dir for test")
+ return
+ }
+ os.Chdir(dir)
+ os.Setenv("PMIT", dir)
+ os.MkdirAll("issues/Test", 0700)
+ os.MkdirAll("issues/Test2", 0700)
+ os.MkdirAll("issues/Test3", 0700)
+ issuesDir, err := ioutil.ReadDir(fmt.Sprintf("%s/issues/", dir))
+ if err != nil {
+ t.Error("Could not read issues directory")
+ return
+ }
+ if len(issuesDir) != 3 {
+ t.Error("Unexpected number of issues in issues dir after creating multiple issues\n")
+ }
+ _, stderr := captureOutput(func() {
+ Close(ArgumentList{"1", "3"})
+ }, t)
+ issuesDir, err = ioutil.ReadDir(fmt.Sprintf("%s/issues/", dir))
+ if err != nil {
+ t.Error("Could not read issues directory")
+ return
+ }
+ // After closing, there should be 1 bug. Otherwise, it probably
+ // means that the last error was "invalid index" since indexes
+ // were renumbered after closing the first bug.
+ if len(issuesDir) != 1 {
+ fmt.Printf("%s\n\n", stderr)
+ t.Error("Unexpected number of issues in issues dir after closing multiple issues\n")
+ }
+}
+
+func TestCloseMultipleIndexesAtOnce(t *testing.T) {
+ dir, err := ioutil.TempDir("", "closetest")
+ defer os.RemoveAll(dir)
+ if err != nil {
+ t.Error("Could not create temporary dir for test")
+ return
+ }
+ os.Chdir(dir)
+ os.Setenv("PMIT", dir)
+ os.MkdirAll("issues/Test", 0700)
+ os.MkdirAll("issues/Test2", 0700)
+ os.MkdirAll("issues/Test3", 0700)
+ issuesDir, err := ioutil.ReadDir(fmt.Sprintf("%s/issues/", dir))
+ if err != nil {
+ t.Error("Could not read issues directory")
+ return
+ }
+ if len(issuesDir) != 3 {
+ t.Error("Unexpected number of issues in issues dir after creating multiple issues\n")
+ }
+ _, _ = captureOutput(func() {
+ Close(ArgumentList{"1", "2"})
+ }, t)
+ issuesDir, err = ioutil.ReadDir(fmt.Sprintf("%s/issues/", dir))
+ if err != nil {
+ t.Error("Could not read issues directory")
+ return
+ }
+ if len(issuesDir) != 1 {
+ t.Error("Unexpected number of issues in issues dir after closing multiple issues\n")
+ return
+ }
+
+ // 1 and 2 should have closed. If 3 was renumbered after 1 was closed,
+ // it would be closed instead.
+ if issuesDir[0].Name() != "Test3" {
+ t.Error("Closed incorrect issue when closing multiple issues.")
+ }
+}
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index 150ecbe..0a5848c 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -3,6 +3,3 @@
## v0.4:
- bug-serve should have feature parity with bug
- Implement golang io interfaces in Bug class
-
-## No milestone set:
-- bug close multiple issues incorrect after first issue
diff --git a/issues/bug-close-multiple-issues-incorrect-after-first-issue/Description b/issues/bug-close-multiple-issues-incorrect-after-first-issue/Description
deleted file mode 100644
index f2dfba1..0000000
--- a/issues/bug-close-multiple-issues-incorrect-after-first-issue/Description
+++ /dev/null
@@ -1,12 +0,0 @@
-When do you "bug close 1 2 3" for multiple issues by directory
-index, after it coses 1, the index of the ones following 1 changes,
-resulting in the wrong bugs being closed for 2 and 3. The "new" index
-2 is closed from after 1 being removed, not the old "2" that the user
-expected to be closed from when they did "bug list"
-
-Possible solutions:
-1. Only allow 1 issue to be closed at a time
-2. Reverse sort the input before closing. (If this works it
- would be ideal, but I'd first need to verify that unlinking
- a file changes the rest of the indexes in a predictable order.)
-
From c8cdbcf47cee5031bb3d58646e672f3caa970a97 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 13:15:52 -0500
Subject: [PATCH 04/47] Removed unused error types
---
scm/GitManager.go | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/scm/GitManager.go b/scm/GitManager.go
index 4710c38..862a873 100644
--- a/scm/GitManager.go
+++ b/scm/GitManager.go
@@ -10,18 +10,6 @@ import (
"strings"
)
-type PreconditionFailed string
-
-func (a PreconditionFailed) Error() string {
- return string(a)
-}
-
-type ExecutionFailed string
-
-func (a ExecutionFailed) Error() string {
- return string(a)
-}
-
type UnsupportedType string
func (a UnsupportedType) Error() string {
From a3bacb9484ccb02dc045b0e1e9a503f429b7b40e Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 13:17:39 -0500
Subject: [PATCH 05/47] Moved errors in package to a different file
---
scm/GitManager.go | 6 ------
scm/errors.go | 8 ++++++++
2 files changed, 8 insertions(+), 6 deletions(-)
create mode 100644 scm/errors.go
diff --git a/scm/GitManager.go b/scm/GitManager.go
index 862a873..7681438 100644
--- a/scm/GitManager.go
+++ b/scm/GitManager.go
@@ -10,12 +10,6 @@ import (
"strings"
)
-type UnsupportedType string
-
-func (a UnsupportedType) Error() string {
- return string(a)
-}
-
type GitManager struct {
Autoclose bool
}
diff --git a/scm/errors.go b/scm/errors.go
new file mode 100644
index 0000000..4ca0e74
--- /dev/null
+++ b/scm/errors.go
@@ -0,0 +1,8 @@
+package scm
+
+type UnsupportedType string
+
+func (a UnsupportedType) Error() string {
+ return string(a)
+}
+
From 422c5747258d98aa754f92762f439abd99e252ac Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 13:58:04 -0500
Subject: [PATCH 06/47] Added tests for git manager's purge function
---
scm/GitManager_test.go | 6 ++++++
scm/TestHelpers_test.go | 34 ++++++++++++++++++++++++++++++++++
scm/errors.go | 1 -
3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/scm/GitManager_test.go b/scm/GitManager_test.go
index 8559c8e..16d3269 100644
--- a/scm/GitManager_test.go
+++ b/scm/GitManager_test.go
@@ -144,3 +144,9 @@ func TestGitManagerGetType(t *testing.T) {
t.Error("Incorrect SCM Type for GitManager. Got " + getType)
}
}
+
+func TestGitManagerPurge(t *testing.T) {
+ gm := GitTester{}
+ gm.handler = GitManager{}
+ runtestPurgeFiles(&gm, t)
+}
diff --git a/scm/TestHelpers_test.go b/scm/TestHelpers_test.go
index d3eead5..97f1abb 100644
--- a/scm/TestHelpers_test.go
+++ b/scm/TestHelpers_test.go
@@ -123,3 +123,37 @@ func runtestCommitDirtyTree(tester ManagerTester, t *testing.T) {
FileStatus{"donotcommit.txt", "A", " "},
})
}
+
+func runtestPurgeFiles(tester ManagerTester, t *testing.T) {
+ err := tester.Setup()
+ if err != nil {
+ panic("Something went wrong trying to initialize: " + err.Error())
+ }
+ defer tester.TearDown()
+ m := tester.GetManager()
+ if m == nil {
+ t.Error("Could not get manager")
+ return
+ }
+ os.Mkdir("issues", 0755)
+ // Commit a bug which should stay around after the purge
+ runCmd("bug", "create", "-n", "Test", "bug")
+ m.Commit(bugs.Directory(tester.GetWorkDir()+"/issues"), "Initial commit")
+
+ // Create another bug to elimate with "bug purge"
+ runCmd("bug", "create", "-n", "Test", "purge", "bug")
+ err = m.Purge(bugs.Directory(tester.GetWorkDir() + "/issues"))
+ if err != nil {
+ t.Error("Error purging bug directory: " + err.Error())
+ }
+ issuesDir, err := ioutil.ReadDir("issues") //fmt.Sprintf("%s/issues/", tester.GetWorkDir()))
+ if err != nil {
+ t.Error("Error reading issues directory")
+ }
+ if len(issuesDir) != 1 {
+ t.Error("Unexpected number of directories in issues/ after purge.")
+ }
+ if len(issuesDir) > 0 && issuesDir[0].Name() != "Test-bug" {
+ t.Error("Expected Test-bug to remain.")
+ }
+}
diff --git a/scm/errors.go b/scm/errors.go
index 4ca0e74..d3da5d0 100644
--- a/scm/errors.go
+++ b/scm/errors.go
@@ -5,4 +5,3 @@ type UnsupportedType string
func (a UnsupportedType) Error() string {
return string(a)
}
-
From 781b7bd3a01494fed9368b150a4b4a89c16ba35f Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 19:23:56 -0500
Subject: [PATCH 07/47] Added or removed issues with the tool "bug"
---
bug-serve/issues/Should-include-REST-API/Description | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 bug-serve/issues/Should-include-REST-API/Description
diff --git a/bug-serve/issues/Should-include-REST-API/Description b/bug-serve/issues/Should-include-REST-API/Description
new file mode 100644
index 0000000..8e17c9c
--- /dev/null
+++ b/bug-serve/issues/Should-include-REST-API/Description
@@ -0,0 +1,2 @@
+The bug-server should be redone as a more usable, well-documented
+REST API, in order to make it more useful to third parties.
From 709d577bc5d9997904e1d34549628b08426c4ebe Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 19:24:28 -0500
Subject: [PATCH 08/47] Use go-bindata to store files, not the file system
---
bug-serve/Makefile | 4 +-
bug-serve/bindata.go | 283 +++++++++++++++++++++++++++++++++++++++++++
bug-serve/main.go | 18 ++-
3 files changed, 301 insertions(+), 4 deletions(-)
create mode 100644 bug-serve/bindata.go
diff --git a/bug-serve/Makefile b/bug-serve/Makefile
index f5fc7b3..ab6fc9d 100644
--- a/bug-serve/Makefile
+++ b/bug-serve/Makefile
@@ -1,5 +1,7 @@
-all: Go React
+all: Generate React Go
+Generate:
+ go generate
Go:
go build .
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
new file mode 100644
index 0000000..25c49f4
--- /dev/null
+++ b/bug-serve/bindata.go
@@ -0,0 +1,283 @@
+// Code generated by go-bindata.
+// sources:
+// js/BugApp.js
+// js/BugList.js
+// js/BugPage.js
+// DO NOT EDIT!
+
+package main
+
+import (
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+)
+
+func bindataRead(data []byte, name string) ([]byte, error) {
+ gz, err := gzip.NewReader(bytes.NewBuffer(data))
+ if err != nil {
+ return nil, fmt.Errorf("Read %q: %v", name, err)
+ }
+
+ var buf bytes.Buffer
+ _, err = io.Copy(&buf, gz)
+ clErr := gz.Close()
+
+ if err != nil {
+ return nil, fmt.Errorf("Read %q: %v", name, err)
+ }
+ if clErr != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+}
+
+type asset struct {
+ bytes []byte
+ info os.FileInfo
+}
+
+type bindataFileInfo struct {
+ name string
+ size int64
+ mode os.FileMode
+ modTime time.Time
+}
+
+func (fi bindataFileInfo) Name() string {
+ return fi.name
+}
+func (fi bindataFileInfo) Size() int64 {
+ return fi.size
+}
+func (fi bindataFileInfo) Mode() os.FileMode {
+ return fi.mode
+}
+func (fi bindataFileInfo) ModTime() time.Time {
+ return fi.modTime
+}
+func (fi bindataFileInfo) IsDir() bool {
+ return false
+}
+func (fi bindataFileInfo) Sys() interface{} {
+ return nil
+}
+
+var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x54\xcb\x4e\xe3\x4a\x10\x5d\x3b\x5f\x51\xd7\x0b\x64\x84\x65\xb8\x57\x77\x15\x14\x8d\x78\x09\x18\xf1\x18\x41\x16\x23\x8d\x66\xd1\xd8\x95\xa4\xa1\xd3\xf6\x74\x97\x19\x10\xca\xbf\x4f\xf5\x23\xd8\x81\xa0\x09\x9b\x28\xae\xae\x73\xfa\x54\x9d\xaa\x7e\x14\x06\x0e\xdb\xe9\x41\xd3\xc0\x08\x6e\x50\x94\x54\x94\x06\x05\xe1\x91\x12\xd6\x66\x2f\x83\xa4\x92\xb6\x51\xe2\xf9\x4a\xcc\x71\x08\x69\xc8\x4d\xf3\xc1\x20\x29\xeb\x79\x53\x6b\xd4\x74\x2c\xab\xcb\xba\xd5\x34\x84\x49\xab\x4b\x92\xb5\x86\x6c\x1b\x18\x9a\x38\x76\x9a\x09\x62\x6e\x9a\x49\xbb\xcf\xa1\x83\x7b\xf1\x74\x8a\x94\xa5\xbb\xd2\xda\x16\xed\x6e\x9a\xf7\x60\x06\x2d\x73\x5a\x0c\xf0\xc4\x61\x0b\x8b\x74\x4b\xac\x28\xf3\xa1\xc4\x49\xb0\xe9\x10\xbe\xde\x5e\x5f\x15\x8d\x30\x16\x3b\x94\x4b\x58\x6c\xbb\x6b\xc2\x6f\x77\x19\x93\x90\xd4\x0c\xfc\xec\x6d\xb7\x4b\xe0\x46\x37\x2e\xf2\x41\x32\x45\x3a\xd7\x92\xa4\x50\x9e\xe8\x7d\x57\x0c\x52\x6b\x74\xb8\xb3\xcf\xff\xe2\xd0\x1c\x1a\x4b\x52\xc8\xdf\xe9\x75\x83\x1a\xce\x7d\x9b\xd2\x70\x14\x6b\xff\xf1\x33\x8f\x60\x85\x25\x61\xc5\x61\x27\x8e\x4f\x74\xab\x94\x13\x13\xb5\x58\x9f\xc0\xc7\x67\x42\x57\x0a\x4d\x5f\x4c\x2c\x1b\x8b\xc6\xe0\xa3\xb3\x11\x27\xa2\x55\x94\xf9\x6a\x9c\x73\x77\xed\x94\x8d\xc3\xa2\x6c\x8d\xe1\xf3\xb1\x30\x5c\x5a\x41\xf8\x44\x47\xb5\x26\x8e\xec\x6f\x6a\x31\xec\x78\xb2\x1d\x48\xbf\x4c\x6a\x33\x17\x34\xba\xb7\xb5\xfe\x84\x17\xd0\xab\x74\xbd\x11\xf0\xc6\x05\x3e\x60\x74\x44\xbd\xf7\xc0\x69\xed\xf3\xf7\x5b\x19\xdb\x08\x3d\x2e\x5d\xad\xf6\xae\x1b\xef\xb2\x6b\x85\x9c\x40\x16\x78\x1d\x69\xd1\x63\x84\x7f\x46\x9e\x32\x16\x17\x31\x6f\x36\xee\x44\xe1\x9c\xa3\x19\xe7\x7f\x13\x53\xcc\xe1\x05\xfc\x24\x0c\x61\x3d\x69\xe1\x4f\x73\x38\x46\x5b\x1a\xd9\x38\x61\x1f\xa6\xf6\x72\x72\xa8\xf5\xa1\x28\x1f\x62\xee\x4a\x9f\x72\x38\x50\xca\xcd\xd8\x0a\x91\x0b\x38\xd4\x35\xcd\xd0\xf0\xc7\x91\x92\xe5\x83\x6b\x6a\x6c\xe2\xea\x88\x2d\x8d\x00\x54\x16\x37\xac\xf7\x42\x5a\x5a\x5f\x6f\xac\xf1\x43\x4d\x1b\xcb\xe9\xf6\x6e\x9d\x06\xbf\x4d\x95\x7c\x0c\x6b\xe6\xac\xf2\x7f\x3e\x4a\x4d\xd2\xd9\xbf\x21\xb5\xcb\x4d\xd2\xb0\xa9\xc0\x13\xce\xbb\x1b\x62\x2b\x76\x84\x45\x0f\x25\xb9\xd3\xed\xbf\xdc\xf1\xaa\xa7\x77\x49\x6c\xa5\x87\xf3\x8f\x9f\xd0\x81\x2b\x71\xe0\x86\x31\x6e\x1e\x37\xba\x1b\xd5\xd6\xa8\x1c\x4a\xa1\xd4\x1d\x9b\xee\x07\xd0\x65\x3e\xcd\xd5\x8c\xc8\x3d\xfa\x1a\x7f\xc3\xf7\xcb\x8b\x33\xfe\xba\xc1\x5f\x5c\x40\x78\x01\x62\x42\x51\x6b\x56\x56\x3d\xfb\x1a\xca\x99\xd0\x53\x5c\x61\x0f\x13\xfd\x3a\xf9\x3e\xd7\xef\x14\x8c\x46\x23\xf8\x1f\xb6\xb6\x3a\xd7\x5a\xcb\x41\xf8\x6f\x6f\x6f\xb9\x06\x51\xd4\x12\x1a\x36\x79\xcc\xef\xcb\xd2\xb2\x45\x5f\x08\x3f\x86\x59\x7a\x7a\x32\xe6\x67\xc3\xd7\x44\xa6\xc5\xbe\x52\xcb\x5b\xea\xa4\x2f\xf6\xff\x04\x00\x00\xff\xff\x2c\x2b\xb1\x94\xd5\x06\x00\x00")
+
+func jsBugappJsBytes() ([]byte, error) {
+ return bindataRead(
+ _jsBugappJs,
+ "js/BugApp.js",
+ )
+}
+
+func jsBugappJs() (*asset, error) {
+ bytes, err := jsBugappJsBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "js/BugApp.js", size: 1749, mode: os.FileMode(436), modTime: time.Unix(1452990114, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _jsBuglistJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x53\x51\x6b\xdb\x30\x10\x7e\xb6\x7e\xc5\xa1\x51\x90\xdb\x60\x43\x1f\x53\x27\x0f\x6d\xc7\x18\x8c\x31\xba\xbe\x2d\xa3\x28\xf1\x39\x11\x55\xa4\x20\xc9\x81\x50\xfc\xdf\x77\x92\xec\x36\xa3\x94\xbe\x28\xd2\xe5\xee\xbb\xef\xbb\xef\x7c\x94\x0e\x6e\xfb\xed\x0f\xe5\x03\x2c\xe0\x01\xe5\x26\x54\x1b\x87\x32\xe0\x9d\x96\xde\x8b\x17\x56\xb4\xca\x1f\xb4\x3c\xfd\x94\x7b\x9c\x03\x1f\x93\xf9\x8c\xb1\x62\x8b\xe1\x1e\x3b\xd9\xeb\xf0\xcb\xd9\x83\x9f\x43\xd7\x9b\x4d\x50\xd6\x80\x28\x81\x2a\x0b\x87\xa1\x77\x26\x5d\x0b\xfe\xa8\x82\x46\x9e\x21\x3c\xd5\xc7\x58\xba\xce\xe1\xcf\xdf\xf4\xb4\x86\xde\x77\x5a\x6d\x9e\xb1\x3d\x07\xc3\x8c\x56\x14\x58\x1d\x1c\x1e\xd1\x4c\x6d\x45\x79\x93\x5b\xdc\xc4\xbf\x07\x3a\x06\xba\x0d\x04\xe6\xd0\xb4\xe8\xde\x33\x8a\x7a\xc3\x4e\x46\xb1\x61\xa7\xfc\xcd\x18\x42\x8d\x7b\x82\xf5\x63\x98\xda\x90\x9e\x2a\xb2\xab\xf6\xf2\x20\xde\x50\x8e\x52\x8f\x64\x46\x6d\xe7\x23\xfb\x9a\x51\x44\xe2\xca\xb5\xca\x22\x8b\x17\x78\xc6\xd3\xdb\xe8\xbe\x07\xdc\x73\xb8\x02\x82\x82\x21\x67\x7c\x08\x52\x70\x39\x82\x10\xca\xce\x61\x47\x30\x5f\xf8\x0c\xac\x49\x63\x9a\x27\x2d\x23\xdb\xf3\xe9\x4d\xc0\x24\x4e\xa7\x4b\x19\xcf\x32\xca\x1d\xd2\xf9\x09\x7b\xde\xaa\x63\x6e\x6c\x7a\xad\xd3\xe5\x63\xa1\xbb\xeb\x91\xe3\x6b\x6e\x71\x36\xc4\x64\x7b\xea\xfe\x09\x8c\xd5\xef\x60\x26\x5b\xd8\xa8\x20\x52\x1f\x58\x54\x50\x5f\xb2\x68\x0a\x88\xf5\xb4\xbe\x0f\xc9\x71\x74\x25\x7c\xc3\x70\x6b\xdb\x13\x39\xee\x83\x53\x66\x1b\xfd\x52\xde\xf7\xe8\x67\xf0\x04\xf3\x05\x28\xdb\x07\xa5\x2b\xa2\xd2\xde\x2b\x27\xd6\xd1\x66\x2a\x7a\xb0\x36\xc4\x77\x49\xe6\xf0\x3a\x57\xf0\x92\xc5\x65\x0a\xb1\x8c\x37\xbb\xeb\x65\x74\x6e\x9d\x45\xc5\xb4\xa6\xa6\x58\x63\xf5\x92\xb3\xa2\xb3\x0e\x9e\x66\x90\x0a\x63\xbe\x93\x66\x8b\xf9\xe9\x5f\x97\xaf\x55\x0e\x52\x43\xea\x84\x9b\x60\xdd\x89\x76\xee\xff\x80\x48\x25\x55\xfc\xe0\x44\x59\x66\xb3\xe0\x6a\x01\xdd\x3e\x54\xbf\x0f\xa4\x28\x74\x82\x37\x5a\x2d\x1b\x99\x76\x62\xb1\x9a\xd8\xd6\x17\x7e\xc5\x97\x17\xbe\xa9\xe5\xb2\xa9\x29\x63\x65\x68\x59\x04\xf5\x2c\x67\xb1\x73\xf5\x68\x13\xf3\x04\x3b\xb0\x09\x98\x54\x24\x05\x6c\x5a\x0b\xfa\x61\xc3\x65\xfd\x2f\x00\x00\xff\xff\x05\xd5\x94\xee\x1d\x04\x00\x00")
+
+func jsBuglistJsBytes() ([]byte, error) {
+ return bindataRead(
+ _jsBuglistJs,
+ "js/BugList.js",
+ )
+}
+
+func jsBuglistJs() (*asset, error) {
+ bytes, err := jsBuglistJsBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "js/BugList.js", size: 1053, mode: os.FileMode(436), modTime: time.Unix(1452990114, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x92\xcf\x4a\x03\x31\x10\xc6\xcf\xc9\x53\x0c\xf1\xd2\x85\xb6\x07\xf1\x20\x2d\x1e\x6c\xf5\x20\x88\x4a\xf1\x05\x42\x76\xda\x0d\x4d\x93\x25\x7f\x0a\xb2\xec\xbb\x3b\xcd\x6e\x6d\x2b\xac\x8a\x97\x25\xcc\x7c\xf3\x9b\xf9\x3e\x76\x2f\x3d\x2c\xd2\xe6\x4d\x6e\x10\xee\x60\x85\x52\xc5\xa9\xf2\x28\x23\x2e\x8d\x0c\x61\xd4\x70\x56\xea\x50\x1b\xf9\xf1\x22\x77\x38\x03\xd1\x8b\xc5\x98\x73\xe6\xd1\x96\xe8\x67\xb0\x4e\x56\x45\xed\x2c\x8c\x0a\xa0\x01\xaa\xc7\xe4\xed\x05\xed\xd1\xe0\x0e\x6d\x1c\x51\x97\x89\x52\xef\x69\x9e\x5e\x36\x19\x93\x1f\x43\xd2\x33\x2d\x6b\x40\x1d\x4e\xea\xef\x50\xce\x4c\x76\xe5\xe4\x56\x40\xdb\xb5\x07\x11\x4c\x54\xd7\x3d\xe2\xb4\x90\xb1\x58\xe9\x30\xad\xbd\xab\xc3\xf4\x5d\x47\x83\xb9\x5a\xfc\xca\x3a\xdd\x33\x00\x7b\xc0\xa0\xbc\xae\x0f\x79\xfc\x11\x29\x8f\xc0\x06\x2a\x8f\x6b\x32\x77\x25\xc6\xe0\xec\xd2\x68\xb5\x9d\xc1\x19\xdb\xd9\x85\x54\xdb\xa3\x63\x26\x56\x5d\xd0\xd1\x81\xd1\x21\x8a\x6e\x1f\xff\x5a\xfa\xef\x54\x6f\x7e\x4c\x95\x7e\x81\x67\x5a\x37\x86\x06\x72\x72\x34\xf7\x1a\x2b\xf4\xf0\x14\x42\xc2\x70\x74\x43\xb2\x70\x71\xfd\xbd\x31\x87\x5a\xdf\x26\x2f\x69\x93\x2d\x62\xf9\xcd\x64\xa6\x9d\xba\x59\xdf\x76\xbe\xe8\x53\xcc\x39\x6b\x79\x5b\xcc\x3f\x03\x00\x00\xff\xff\x17\xca\x22\xd1\xbc\x02\x00\x00")
+
+func jsBugpageJsBytes() ([]byte, error) {
+ return bindataRead(
+ _jsBugpageJs,
+ "js/BugPage.js",
+ )
+}
+
+func jsBugpageJs() (*asset, error) {
+ bytes, err := jsBugpageJsBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "js/BugPage.js", size: 700, mode: os.FileMode(436), modTime: time.Unix(1452990114, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+// Asset loads and returns the asset for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func Asset(name string) ([]byte, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+ }
+ return a.bytes, nil
+ }
+ return nil, fmt.Errorf("Asset %s not found", name)
+}
+
+// MustAsset is like Asset but panics when Asset would return an error.
+// It simplifies safe initialization of global variables.
+func MustAsset(name string) []byte {
+ a, err := Asset(name)
+ if err != nil {
+ panic("asset: Asset(" + name + "): " + err.Error())
+ }
+
+ return a
+}
+
+// AssetInfo loads and returns the asset info for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func AssetInfo(name string) (os.FileInfo, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+ }
+ return a.info, nil
+ }
+ return nil, fmt.Errorf("AssetInfo %s not found", name)
+}
+
+// AssetNames returns the names of the assets.
+func AssetNames() []string {
+ names := make([]string, 0, len(_bindata))
+ for name := range _bindata {
+ names = append(names, name)
+ }
+ return names
+}
+
+// _bindata is a table, holding each asset generator, mapped to its name.
+var _bindata = map[string]func() (*asset, error){
+ "js/BugApp.js": jsBugappJs,
+ "js/BugList.js": jsBuglistJs,
+ "js/BugPage.js": jsBugpageJs,
+}
+
+// AssetDir returns the file names below a certain
+// directory embedded in the file by go-bindata.
+// For example if you run go-bindata on data/... and data contains the
+// following hierarchy:
+// data/
+// foo.txt
+// img/
+// a.png
+// b.png
+// then AssetDir("data") would return []string{"foo.txt", "img"}
+// AssetDir("data/img") would return []string{"a.png", "b.png"}
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error
+// AssetDir("") will return []string{"data"}.
+func AssetDir(name string) ([]string, error) {
+ node := _bintree
+ if len(name) != 0 {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ pathList := strings.Split(cannonicalName, "/")
+ for _, p := range pathList {
+ node = node.Children[p]
+ if node == nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ }
+ }
+ if node.Func != nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ rv := make([]string, 0, len(node.Children))
+ for childName := range node.Children {
+ rv = append(rv, childName)
+ }
+ return rv, nil
+}
+
+type bintree struct {
+ Func func() (*asset, error)
+ Children map[string]*bintree
+}
+var _bintree = &bintree{nil, map[string]*bintree{
+ "js": &bintree{nil, map[string]*bintree{
+ "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
+ "BugList.js": &bintree{jsBuglistJs, map[string]*bintree{}},
+ "BugPage.js": &bintree{jsBugpageJs, map[string]*bintree{}},
+ }},
+}}
+
+// RestoreAsset restores an asset under the given directory
+func RestoreAsset(dir, name string) error {
+ data, err := Asset(name)
+ if err != nil {
+ return err
+ }
+ info, err := AssetInfo(name)
+ if err != nil {
+ return err
+ }
+ err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+ if err != nil {
+ return err
+ }
+ err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// RestoreAssets restores an asset under the given directory recursively
+func RestoreAssets(dir, name string) error {
+ children, err := AssetDir(name)
+ // File
+ if err != nil {
+ return RestoreAsset(dir, name)
+ }
+ // Dir
+ for _, child := range children {
+ err = RestoreAssets(dir, filepath.Join(name, child))
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func _filePath(dir, name string) string {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+}
+
diff --git a/bug-serve/main.go b/bug-serve/main.go
index 34b9af2..305f40a 100644
--- a/bug-serve/main.go
+++ b/bug-serve/main.go
@@ -103,15 +103,27 @@ func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (str
return HTMLPageRenderer.Render(page), nil
}
+
}
+type JSAssetHandler struct {
+ URLHandler.DefaultHandler
+}
+func (s JSAssetHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
+ data, err := Asset(r.URL.Path[1:])
+ if err == nil {
+ return string(data), nil
+
+ }
+ return "File Not found", URLHandler.NotFoundError{}
+}
func main() {
URLHandler.RegisterHandler(MainPageHandler{}, "/")
URLHandler.RegisterHandler(SettingsHandler{}, "/settings")
URLHandler.RegisterHandler(BugPageHandler{}, "/issues/")
- URLHandler.RegisterStaticHandler("/js/", "./js")
+ URLHandler.RegisterHandler(JSAssetHandler{}, "/js/")
http.ListenAndServe(":8080", nil)
}
-//go:generate FileConstGenerator main js/BugApp.js BugListConst.go BugListJS
-//go:generate FileConstGenerator main js/BugApp.js BugListConst.go BugListJS
+//go:generate babel --out-dir=js jsx
+//go:generate go-bindata js/
From fd99077a65698146231224731e4c5141abb20336 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 19:48:51 -0500
Subject: [PATCH 09/47] Reorganized files in bug-serve to be more manageable
---
bug-serve/BugPageHandler.go | 71 ++++++++++++++++++++++
bug-serve/JSAssetHandler.go | 19 ++++++
bug-serve/MainPageHandler.go | 34 +++++++++++
bug-serve/SettingsHandler.go | 21 +++++++
bug-serve/bindata.go | 6 +-
bug-serve/main.go | 112 -----------------------------------
6 files changed, 148 insertions(+), 115 deletions(-)
create mode 100644 bug-serve/BugPageHandler.go
create mode 100644 bug-serve/JSAssetHandler.go
create mode 100644 bug-serve/MainPageHandler.go
create mode 100644 bug-serve/SettingsHandler.go
diff --git a/bug-serve/BugPageHandler.go b/bug-serve/BugPageHandler.go
new file mode 100644
index 0000000..89dafb2
--- /dev/null
+++ b/bug-serve/BugPageHandler.go
@@ -0,0 +1,71 @@
+package main
+
+import (
+ "encoding/json"
+ // "fmt"
+ "github.com/driusan/GoWebapp/HTMLPageRenderer"
+ "github.com/driusan/GoWebapp/URLHandler"
+ "github.com/driusan/bug/bugs"
+ "io/ioutil"
+ "net/http"
+)
+
+type BugRenderer struct {
+ HTMLPageRenderer.ReactPage
+ Bug bugs.Bug
+}
+type BugPageHandler struct {
+ URLHandler.DefaultHandler
+}
+
+func getBugList() (string, error) {
+ issues, _ := ioutil.ReadDir(string(bugs.GetRootDir()) + "/issues")
+
+ var issuesSlice []string
+
+ for _, issue := range issues {
+ issuesSlice = append(issuesSlice, issue.Name())
+ }
+
+ retVal, _ := json.Marshal(issuesSlice)
+ return string(retVal), nil
+}
+
+func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (string, error) {
+ if r.URL.Path == "/issues" || r.URL.Path == "/issues/" {
+ return getBugList()
+ }
+ bugDir := string(bugs.GetRootDir()) + r.URL.Path
+ b := bugs.Bug{}
+ b.LoadBug(bugs.Directory(bugDir))
+
+ bJSONStruct := struct {
+ Title string
+ Description string
+ }{Title: b.Title(""), Description: b.Description()}
+
+ bJSON, _ := json.Marshal(bJSONStruct)
+ return string(bJSON), nil
+ /*
+ switch r.URL.Query().Get("format") {
+ case "json":
+ default:
+ page := BugRenderer{Bug: b}
+ page.RootElement = "RBugPage"
+ page.Title = b.Title("")
+ page.JSFiles = []string{
+ // Bootstrap JS
+ //"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
+ // React JS
+ "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
+ "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
+ "/js/BugPage.js",
+ }
+ page.CSSFiles = []string{
+ "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
+ "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css"}
+ return HTMLPageRenderer.Render(page), nil
+ }
+ */
+
+}
diff --git a/bug-serve/JSAssetHandler.go b/bug-serve/JSAssetHandler.go
new file mode 100644
index 0000000..6de9204
--- /dev/null
+++ b/bug-serve/JSAssetHandler.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+ "github.com/driusan/GoWebapp/URLHandler"
+ "net/http"
+)
+
+type JSAssetHandler struct {
+ URLHandler.DefaultHandler
+}
+
+func (s JSAssetHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
+ data, err := Asset(r.URL.Path[1:])
+ if err == nil {
+ return string(data), nil
+
+ }
+ return "File Not found", URLHandler.NotFoundError{}
+}
diff --git a/bug-serve/MainPageHandler.go b/bug-serve/MainPageHandler.go
new file mode 100644
index 0000000..950a7d4
--- /dev/null
+++ b/bug-serve/MainPageHandler.go
@@ -0,0 +1,34 @@
+package main
+
+import (
+ "github.com/driusan/GoWebapp/HTMLPageRenderer"
+ "github.com/driusan/GoWebapp/URLHandler"
+ "net/http"
+)
+
+type MainPageHandler struct {
+ URLHandler.DefaultHandler
+}
+
+func (m MainPageHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
+ page := HTMLPageRenderer.ReactPage{
+ Title: "Open Issues",
+ JSFiles: []string{
+ // Bootstrap
+ //"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
+ // React
+ "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
+ "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
+ "/js/BugApp.js",
+ "/js/BugList.js",
+ "/js/BugPage.js",
+ },
+ CSSFiles: []string{
+ // Bootstrap
+ "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
+ "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css",
+ },
+ RootElement: "BugApp",
+ }
+ return HTMLPageRenderer.Render(page), nil
+}
diff --git a/bug-serve/SettingsHandler.go b/bug-serve/SettingsHandler.go
new file mode 100644
index 0000000..d20fa66
--- /dev/null
+++ b/bug-serve/SettingsHandler.go
@@ -0,0 +1,21 @@
+package main
+
+import (
+ "encoding/json"
+ "github.com/driusan/GoWebapp/URLHandler"
+ "github.com/driusan/bug/bugs"
+ "net/http"
+)
+
+type SettingsHandler struct {
+ URLHandler.DefaultHandler
+}
+
+func (s SettingsHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
+ settings := struct {
+ Title string
+ Directory string
+ }{bugs.GetRootDir().GetShortName().ToTitle(), string(bugs.GetRootDir())}
+ retVal, _ := json.Marshal(settings)
+ return string(retVal), nil
+}
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
index 25c49f4..5b98cd7 100644
--- a/bug-serve/bindata.go
+++ b/bug-serve/bindata.go
@@ -182,7 +182,7 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
- "js/BugApp.js": jsBugappJs,
+ "js/BugApp.js": jsBugappJs,
"js/BugList.js": jsBuglistJs,
"js/BugPage.js": jsBugpageJs,
}
@@ -226,9 +226,10 @@ type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
+
var _bintree = &bintree{nil, map[string]*bintree{
"js": &bintree{nil, map[string]*bintree{
- "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
+ "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
"BugList.js": &bintree{jsBuglistJs, map[string]*bintree{}},
"BugPage.js": &bintree{jsBugpageJs, map[string]*bintree{}},
}},
@@ -280,4 +281,3 @@ func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
-
diff --git a/bug-serve/main.go b/bug-serve/main.go
index 305f40a..e41a302 100644
--- a/bug-serve/main.go
+++ b/bug-serve/main.go
@@ -1,122 +1,10 @@
package main
import (
- "encoding/json"
- // "fmt"
- "github.com/driusan/GoWebapp/HTMLPageRenderer"
"github.com/driusan/GoWebapp/URLHandler"
- "github.com/driusan/bug/bugs"
- "io/ioutil"
"net/http"
)
-type MainPageHandler struct {
- URLHandler.DefaultHandler
-}
-
-type BugPageHandler struct {
- URLHandler.DefaultHandler
-}
-
-type SettingsHandler struct {
- URLHandler.DefaultHandler
-}
-type BugListRenderer struct {
- HTMLPageRenderer.ReactPage
-}
-
-type BugRenderer struct {
- HTMLPageRenderer.ReactPage
- Bug bugs.Bug
-}
-
-func (s SettingsHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
- settings := struct {
- Title string
- Directory string
- }{bugs.GetRootDir().GetShortName().ToTitle(), string(bugs.GetRootDir())}
- retVal, _ := json.Marshal(settings)
- return string(retVal), nil
-}
-func (m MainPageHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
- page := BugListRenderer{}
- page.Title = "Open Issues"
- page.JSFiles = []string{
- // Bootstrap
- //"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
- // React
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
- "/js/BugApp.js",
- "/js/BugList.js",
- "/js/BugPage.js",
- }
- page.CSSFiles = []string{
- // Bootstrap
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css",
- }
- page.RootElement = "BugApp"
-
- return HTMLPageRenderer.Render(page), nil
-}
-
-func getBugList() (string, error) {
- issues, _ := ioutil.ReadDir(string(bugs.GetRootDir()) + "/issues")
-
- var issuesSlice []string
-
- for _, issue := range issues {
- issuesSlice = append(issuesSlice, issue.Name())
- }
-
- retVal, _ := json.Marshal(issuesSlice)
- return string(retVal), nil
-}
-func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (string, error) {
- if r.URL.Path == "/issues" || r.URL.Path == "/issues/" {
- return getBugList()
- }
- bugDir := string(bugs.GetRootDir()) + r.URL.Path
- b := bugs.Bug{}
- b.LoadBug(bugs.Directory(bugDir))
-
- switch r.URL.Query().Get("format") {
- case "json":
- bJSON, _ := json.Marshal(b)
- return string(bJSON), nil
- default:
- page := BugRenderer{Bug: b}
- page.RootElement = "RBugPage"
- page.Title = b.Title("")
- page.JSFiles = []string{
- // Bootstrap JS
- //"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
- // React JS
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
- "/js/BugPage.js",
- }
- page.CSSFiles = []string{
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css"}
- return HTMLPageRenderer.Render(page), nil
- }
-
-
-}
-
-type JSAssetHandler struct {
- URLHandler.DefaultHandler
-}
-func (s JSAssetHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
- data, err := Asset(r.URL.Path[1:])
- if err == nil {
- return string(data), nil
-
- }
- return "File Not found", URLHandler.NotFoundError{}
-}
func main() {
URLHandler.RegisterHandler(MainPageHandler{}, "/")
URLHandler.RegisterHandler(SettingsHandler{}, "/settings")
From dd35fab56bc4d8d8f2bd70b789df2f5bd92f36f2 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 16 Jan 2016 20:17:02 -0500
Subject: [PATCH 10/47] Made JSON retrieval of bug a little more robust
---
bug-serve/BugPageHandler.go | 35 +++++++++++++++++++++++++++++------
bug-serve/jsx/BugApp.js | 3 +--
bugs/Find.go | 9 +++++++++
3 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/bug-serve/BugPageHandler.go b/bug-serve/BugPageHandler.go
index 89dafb2..5a8ac48 100644
--- a/bug-serve/BugPageHandler.go
+++ b/bug-serve/BugPageHandler.go
@@ -2,12 +2,12 @@ package main
import (
"encoding/json"
- // "fmt"
"github.com/driusan/GoWebapp/HTMLPageRenderer"
"github.com/driusan/GoWebapp/URLHandler"
"github.com/driusan/bug/bugs"
"io/ioutil"
"net/http"
+ "strings"
)
type BugRenderer struct {
@@ -24,7 +24,9 @@ func getBugList() (string, error) {
var issuesSlice []string
for _, issue := range issues {
- issuesSlice = append(issuesSlice, issue.Name())
+ if issue.IsDir() {
+ issuesSlice = append(issuesSlice, issue.Name())
+ }
}
retVal, _ := json.Marshal(issuesSlice)
@@ -35,14 +37,35 @@ func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (str
if r.URL.Path == "/issues" || r.URL.Path == "/issues/" {
return getBugList()
}
- bugDir := string(bugs.GetRootDir()) + r.URL.Path
- b := bugs.Bug{}
- b.LoadBug(bugs.Directory(bugDir))
+ // Strip off the "/issues/"
+ bugURL := r.URL.Path[8:]
+
+ // See if we're getting the whole bug JSON or
+ // a field from it.
+ pieces := strings.Split(bugURL, "/")
+
+ b, err := bugs.LoadBugByDirectory(pieces[0])
+ if err != nil {
+ return "", URLHandler.NotFoundError{}
+ }
bJSONStruct := struct {
+ Identifier string `json:",omitempty"`
Title string
Description string
- }{Title: b.Title(""), Description: b.Description()}
+ Status string `json:",omitempty"`
+ Priority string `json:",omitempty"`
+ Milestone string `json:",omitempty"`
+ Tags []string `json:",omitempty"`
+ }{
+ Identifier: b.Identifier(),
+ Title: b.Title(""),
+ Description: b.Description(),
+ Status: b.Status(),
+ Priority: b.Priority(),
+ Milestone: b.Milestone(),
+ Tags: b.StringTags(),
+ }
bJSON, _ := json.Marshal(bJSONStruct)
return string(bJSON), nil
diff --git a/bug-serve/jsx/BugApp.js b/bug-serve/jsx/BugApp.js
index 6483f20..c1c8f2d 100644
--- a/bug-serve/jsx/BugApp.js
+++ b/bug-serve/jsx/BugApp.js
@@ -1,5 +1,4 @@
var BugApp = React.createClass({
-
componentDidMount: function() {
var that = this;
AjaxGet("/issues/", function(response) {
@@ -25,7 +24,7 @@ var BugApp = React.createClass({
e.preventDefault();
var bug = e.currentTarget.textContent;
var that = this;
- AjaxGet("/issues/" + bug + "?format=json", function(response) {
+ AjaxGet("/issues/" + bug + "/", function(response) {
that.setState({SelectedBug : JSON.parse(response)});
});
},
diff --git a/bugs/Find.go b/bugs/Find.go
index 1305969..bf9a546 100644
--- a/bugs/Find.go
+++ b/bugs/Find.go
@@ -32,6 +32,15 @@ func FindBugsByTag(tags []string) []Bug {
return []Bug{}
}
+func LoadBugByDirectory(dir string) (*Bug, error) {
+ _, err := ioutil.ReadDir(string(GetRootDir()) + "/issues/" + dir)
+ if err != nil {
+ return nil, BugNotFoundError("Could not find bug " + dir)
+ }
+ bug := Bug{}
+ bug.LoadBug(GetIssuesDir() + Directory(dir))
+ return &bug, nil
+}
func LoadBugByHeuristic(id string) (*Bug, error) {
issues, _ := ioutil.ReadDir(string(GetRootDir()) + "/issues")
From 4e0355763dad53dfb1c07c9cc946912085d27a53 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Wed, 20 Jan 2016 19:12:02 -0500
Subject: [PATCH 11/47] Added or removed issues with the tool "bug"
---
bug-serve/issues/Add-ability-to-edit-bugs/Identifier | 1 +
bug-serve/issues/Add-ability-to-edit-bugs/Milestone | 1 +
bug-serve/issues/Add-ability-to-edit-bugs/Priority | 1 +
bug-serve/issues/Add-ability-to-edit-bugs/Status | 1 +
bug-serve/issues/Add-ability-to-edit-bugs/tags/test | 0
bug-serve/issues/Add-ability-to-edit-bugs/tags/whee | 0
bug-serve/issues/Implement-HTML5-history-API/Description | 0
.../issues/Send-Unmodified-header-when-appropriate/Description | 1 +
bug-serve/issues/return-to-list next previous-broken/Description | 0
9 files changed, 5 insertions(+)
create mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Identifier
create mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Milestone
create mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Priority
create mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Status
create mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/tags/test
create mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/tags/whee
create mode 100644 bug-serve/issues/Implement-HTML5-history-API/Description
create mode 100644 bug-serve/issues/Send-Unmodified-header-when-appropriate/Description
create mode 100644 bug-serve/issues/return-to-list next previous-broken/Description
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Identifier b/bug-serve/issues/Add-ability-to-edit-bugs/Identifier
new file mode 100644
index 0000000..0c05f99
--- /dev/null
+++ b/bug-serve/issues/Add-ability-to-edit-bugs/Identifier
@@ -0,0 +1 @@
+editbug
\ No newline at end of file
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Milestone b/bug-serve/issues/Add-ability-to-edit-bugs/Milestone
new file mode 100644
index 0000000..866c31a
--- /dev/null
+++ b/bug-serve/issues/Add-ability-to-edit-bugs/Milestone
@@ -0,0 +1 @@
+v0.4
\ No newline at end of file
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Priority b/bug-serve/issues/Add-ability-to-edit-bugs/Priority
new file mode 100644
index 0000000..bf0d87a
--- /dev/null
+++ b/bug-serve/issues/Add-ability-to-edit-bugs/Priority
@@ -0,0 +1 @@
+4
\ No newline at end of file
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Status b/bug-serve/issues/Add-ability-to-edit-bugs/Status
new file mode 100644
index 0000000..fa1c255
--- /dev/null
+++ b/bug-serve/issues/Add-ability-to-edit-bugs/Status
@@ -0,0 +1 @@
+Up next
\ No newline at end of file
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/tags/test b/bug-serve/issues/Add-ability-to-edit-bugs/tags/test
new file mode 100644
index 0000000..e69de29
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/tags/whee b/bug-serve/issues/Add-ability-to-edit-bugs/tags/whee
new file mode 100644
index 0000000..e69de29
diff --git a/bug-serve/issues/Implement-HTML5-history-API/Description b/bug-serve/issues/Implement-HTML5-history-API/Description
new file mode 100644
index 0000000..e69de29
diff --git a/bug-serve/issues/Send-Unmodified-header-when-appropriate/Description b/bug-serve/issues/Send-Unmodified-header-when-appropriate/Description
new file mode 100644
index 0000000..7db570e
--- /dev/null
+++ b/bug-serve/issues/Send-Unmodified-header-when-appropriate/Description
@@ -0,0 +1 @@
+Everything responds with a 200 or 404 now.
diff --git a/bug-serve/issues/return-to-list next previous-broken/Description b/bug-serve/issues/return-to-list next previous-broken/Description
new file mode 100644
index 0000000..e69de29
From 00683555d0b26a4144b26d862023c314c0316b5d Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Wed, 20 Jan 2016 19:12:28 -0500
Subject: [PATCH 12/47] Improved look of bug navigaion a little
---
bug-serve/Makefile | 2 +-
bug-serve/bindata.go | 18 +++++++++---------
bug-serve/jsx/BugApp.js | 19 +++++++++++++++++--
bug-serve/jsx/BugList.js | 13 -------------
bug-serve/jsx/BugPage.js | 39 +++++++++++++++++++++++++++++++++++----
5 files changed, 62 insertions(+), 29 deletions(-)
diff --git a/bug-serve/Makefile b/bug-serve/Makefile
index ab6fc9d..6300594 100644
--- a/bug-serve/Makefile
+++ b/bug-serve/Makefile
@@ -1,4 +1,4 @@
-all: Generate React Go
+all: Generate Go serve
Generate:
go generate
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
index 5b98cd7..2f33395 100644
--- a/bug-serve/bindata.go
+++ b/bug-serve/bindata.go
@@ -70,7 +70,7 @@ func (fi bindataFileInfo) Sys() interface{} {
return nil
}
-var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x54\xcb\x4e\xe3\x4a\x10\x5d\x3b\x5f\x51\xd7\x0b\x64\x84\x65\xb8\x57\x77\x15\x14\x8d\x78\x09\x18\xf1\x18\x41\x16\x23\x8d\x66\xd1\xd8\x95\xa4\xa1\xd3\xf6\x74\x97\x19\x10\xca\xbf\x4f\xf5\x23\xd8\x81\xa0\x09\x9b\x28\xae\xae\x73\xfa\x54\x9d\xaa\x7e\x14\x06\x0e\xdb\xe9\x41\xd3\xc0\x08\x6e\x50\x94\x54\x94\x06\x05\xe1\x91\x12\xd6\x66\x2f\x83\xa4\x92\xb6\x51\xe2\xf9\x4a\xcc\x71\x08\x69\xc8\x4d\xf3\xc1\x20\x29\xeb\x79\x53\x6b\xd4\x74\x2c\xab\xcb\xba\xd5\x34\x84\x49\xab\x4b\x92\xb5\x86\x6c\x1b\x18\x9a\x38\x76\x9a\x09\x62\x6e\x9a\x49\xbb\xcf\xa1\x83\x7b\xf1\x74\x8a\x94\xa5\xbb\xd2\xda\x16\xed\x6e\x9a\xf7\x60\x06\x2d\x73\x5a\x0c\xf0\xc4\x61\x0b\x8b\x74\x4b\xac\x28\xf3\xa1\xc4\x49\xb0\xe9\x10\xbe\xde\x5e\x5f\x15\x8d\x30\x16\x3b\x94\x4b\x58\x6c\xbb\x6b\xc2\x6f\x77\x19\x93\x90\xd4\x0c\xfc\xec\x6d\xb7\x4b\xe0\x46\x37\x2e\xf2\x41\x32\x45\x3a\xd7\x92\xa4\x50\x9e\xe8\x7d\x57\x0c\x52\x6b\x74\xb8\xb3\xcf\xff\xe2\xd0\x1c\x1a\x4b\x52\xc8\xdf\xe9\x75\x83\x1a\xce\x7d\x9b\xd2\x70\x14\x6b\xff\xf1\x33\x8f\x60\x85\x25\x61\xc5\x61\x27\x8e\x4f\x74\xab\x94\x13\x13\xb5\x58\x9f\xc0\xc7\x67\x42\x57\x0a\x4d\x5f\x4c\x2c\x1b\x8b\xc6\xe0\xa3\xb3\x11\x27\xa2\x55\x94\xf9\x6a\x9c\x73\x77\xed\x94\x8d\xc3\xa2\x6c\x8d\xe1\xf3\xb1\x30\x5c\x5a\x41\xf8\x44\x47\xb5\x26\x8e\xec\x6f\x6a\x31\xec\x78\xb2\x1d\x48\xbf\x4c\x6a\x33\x17\x34\xba\xb7\xb5\xfe\x84\x17\xd0\xab\x74\xbd\x11\xf0\xc6\x05\x3e\x60\x74\x44\xbd\xf7\xc0\x69\xed\xf3\xf7\x5b\x19\xdb\x08\x3d\x2e\x5d\xad\xf6\xae\x1b\xef\xb2\x6b\x85\x9c\x40\x16\x78\x1d\x69\xd1\x63\x84\x7f\x46\x9e\x32\x16\x17\x31\x6f\x36\xee\x44\xe1\x9c\xa3\x19\xe7\x7f\x13\x53\xcc\xe1\x05\xfc\x24\x0c\x61\x3d\x69\xe1\x4f\x73\x38\x46\x5b\x1a\xd9\x38\x61\x1f\xa6\xf6\x72\x72\xa8\xf5\xa1\x28\x1f\x62\xee\x4a\x9f\x72\x38\x50\xca\xcd\xd8\x0a\x91\x0b\x38\xd4\x35\xcd\xd0\xf0\xc7\x91\x92\xe5\x83\x6b\x6a\x6c\xe2\xea\x88\x2d\x8d\x00\x54\x16\x37\xac\xf7\x42\x5a\x5a\x5f\x6f\xac\xf1\x43\x4d\x1b\xcb\xe9\xf6\x6e\x9d\x06\xbf\x4d\x95\x7c\x0c\x6b\xe6\xac\xf2\x7f\x3e\x4a\x4d\xd2\xd9\xbf\x21\xb5\xcb\x4d\xd2\xb0\xa9\xc0\x13\xce\xbb\x1b\x62\x2b\x76\x84\x45\x0f\x25\xb9\xd3\xed\xbf\xdc\xf1\xaa\xa7\x77\x49\x6c\xa5\x87\xf3\x8f\x9f\xd0\x81\x2b\x71\xe0\x86\x31\x6e\x1e\x37\xba\x1b\xd5\xd6\xa8\x1c\x4a\xa1\xd4\x1d\x9b\xee\x07\xd0\x65\x3e\xcd\xd5\x8c\xc8\x3d\xfa\x1a\x7f\xc3\xf7\xcb\x8b\x33\xfe\xba\xc1\x5f\x5c\x40\x78\x01\x62\x42\x51\x6b\x56\x56\x3d\xfb\x1a\xca\x99\xd0\x53\x5c\x61\x0f\x13\xfd\x3a\xf9\x3e\xd7\xef\x14\x8c\x46\x23\xf8\x1f\xb6\xb6\x3a\xd7\x5a\xcb\x41\xf8\x6f\x6f\x6f\xb9\x06\x51\xd4\x12\x1a\x36\x79\xcc\xef\xcb\xd2\xb2\x45\x5f\x08\x3f\x86\x59\x7a\x7a\x32\xe6\x67\xc3\xd7\x44\xa6\xc5\xbe\x52\xcb\x5b\xea\xa4\x2f\xf6\xff\x04\x00\x00\xff\xff\x2c\x2b\xb1\x94\xd5\x06\x00\x00")
+var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x55\x4b\x4f\x1b\x31\x10\x3e\x6f\x7e\x85\xbb\x07\xb4\x88\x68\xa1\x55\x4f\x41\x39\xf0\x12\x50\xf1\x12\xe4\x50\xa9\xea\xc1\xec\x4e\x12\x17\xc7\xbb\xb5\xc7\x14\x84\xf2\xdf\x3b\x7e\x84\x75\x80\x6d\xe1\x12\x25\x33\xdf\x37\xfe\xe6\x99\x7b\xae\xd9\xbe\x9d\xed\xb5\x2d\x1b\xb3\x6b\xe0\x15\x96\x95\x06\x8e\x70\x20\xb9\x31\xc5\xd3\x20\xab\x85\x69\x25\x7f\xbc\xe0\x0b\x18\xb1\x3c\x60\xf3\xe1\x60\x90\x55\xcd\xa2\x6d\x14\x28\x3c\x14\xf5\x79\x63\x15\x8e\xd8\xd4\xaa\x0a\x45\xa3\x58\xb1\xc9\x88\x9a\xb9\xe8\x38\xe7\x48\xb1\x71\x2e\xcc\x2e\x99\xf6\x7e\xf1\x87\x63\xc0\x22\xdf\x16\xc6\x58\x30\xdb\xf9\x30\xa1\x69\x30\x14\xd3\x40\xa0\x67\x8e\x5b\x1a\xc0\x1b\x24\x45\x85\x37\x65\x4e\x82\xc9\x47\xec\xdb\xcd\xe5\x45\xd9\x72\x6d\xa0\x63\x39\xc0\x72\xd3\x3d\x13\x3e\xbb\xc7\x28\x08\x0a\x45\xc4\x8f\xbe\x76\xb3\x22\xbe\xeb\xc5\xe5\x70\x90\xcd\x00\x4f\x95\x40\xc1\xa5\x0f\xf4\xba\x2a\x1a\xd0\x6a\x15\xde\x4c\xe3\x3f\x39\x36\x99\x26\x02\x25\xd0\xef\xfc\xb2\x05\xc5\x4e\x7d\x99\xf2\xe0\x8a\xb9\xff\xf8\x39\x8c\x64\x09\x15\x42\x4d\x66\x27\x8e\x3c\xca\x4a\xe9\xc4\x44\x2d\xc6\x03\xc8\x7d\xc2\x55\x2d\x41\xa7\x62\x62\xda\x50\xb6\x1a\xee\x5d\x1b\x61\xca\xad\xc4\xc2\x67\xe3\x3a\x77\x6b\x67\xd4\x38\x28\x2b\xab\x35\xf9\x27\x5c\x53\x6a\x25\xc2\x03\x1e\x34\x0a\xc9\xb2\xfb\xde\x16\xb3\x2d\x1f\x6c\x8b\xe5\x1f\x69\x37\x4b\xd2\x7b\xbb\xfa\xec\x45\xe9\xc9\x41\xec\xc8\x7a\x5d\x78\x27\x30\x8d\x9f\xd6\x2f\xd6\x8e\x25\xb1\x54\xbd\x5e\xb0\x6e\xa6\xab\x2e\x7f\x31\x65\x45\x88\xeb\x82\x96\x49\x44\xf6\x69\xec\x43\xc6\xe4\x22\xe7\xc5\x9a\x1d\x49\x58\x90\xb5\x20\xfc\x15\x9f\xc1\x30\x60\x33\x3f\x02\x23\xf6\x76\xe0\xd2\x7b\xfd\x04\x64\x87\x60\x2a\x2d\x5a\x27\xb0\x17\x9e\x60\x02\xe9\x5c\x48\x30\x48\xbb\xdb\x4b\x79\x46\x04\x82\x2b\x98\x35\xbd\xe8\xe0\x0e\xd0\x2b\x2d\x1a\x2d\xf0\xb1\x17\xbc\x02\x04\xf8\x69\x4d\xd9\x8b\xa9\x70\x95\xee\x21\x74\x90\x40\x99\xf0\x59\xbf\x14\xe7\x0c\xb0\x46\xed\xf3\xea\x2e\x02\xd7\x06\x23\xf8\xf7\xa4\x74\xdb\xb4\x16\xc9\x19\x56\xec\x4b\x9c\x83\x26\xc3\x81\x14\xd5\x9d\x9b\xa6\x38\x3d\xeb\x0b\x95\xec\x3f\x03\x69\xe0\x9d\xbd\x3e\x13\x06\xfb\x7b\x9d\xf4\xf7\x9f\x12\x3f\xa2\xae\xbb\x3b\x6f\x49\xf2\xd7\xa4\x16\xf7\xe1\xcc\xb8\xa9\xf5\x5f\xfa\xa0\x59\x3e\xff\x1c\xa0\x1d\x36\xcb\xc3\xa5\x62\xd3\x86\x7a\x19\xbd\x6b\x5d\x0a\x87\x2e\x64\xe7\xbc\x9b\xff\x79\xe3\x59\x4f\xf2\x48\xac\xac\xa7\xd3\x87\x5f\xd6\x81\x4b\x71\xe0\xf6\x32\x5e\x1e\xaa\x7b\xb7\xb5\x56\xcb\x21\xab\xb8\x94\xb7\x34\x0e\x7e\x17\x1d\xf2\x61\x21\xe7\x88\xee\x4f\x4f\xc1\x1f\xf6\xfd\xfc\xec\x84\x7e\x5d\xc3\x6f\x4a\x20\x5c\xc0\x08\x28\x1b\x45\xca\xea\x47\x9f\x43\x35\xe7\x6a\x06\x6b\xd1\xc3\x72\x3f\x1f\x01\x8f\xf5\xe7\x85\x8d\xc7\x63\xf6\x95\x6d\x6c\x74\xcd\xb3\x86\x8c\xec\xcb\xce\xce\xea\x22\x44\x51\x2b\x6a\x38\x6a\x13\xba\xaf\xab\x96\x2d\x53\x21\xf4\x67\x50\xe4\xc7\x47\x13\xba\xa0\x3e\x27\xd4\x16\x52\xa5\x86\x0e\x96\x93\xbe\xdc\xfd\x1b\x00\x00\xff\xff\xe7\xbb\xf6\x88\xd5\x07\x00\x00")
func jsBugappJsBytes() ([]byte, error) {
return bindataRead(
@@ -85,12 +85,12 @@ func jsBugappJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugApp.js", size: 1749, mode: os.FileMode(436), modTime: time.Unix(1452990114, 0)}
+ info := bindataFileInfo{name: "js/BugApp.js", size: 2005, mode: os.FileMode(436), modTime: time.Unix(1453335009, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _jsBuglistJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x53\x51\x6b\xdb\x30\x10\x7e\xb6\x7e\xc5\xa1\x51\x90\xdb\x60\x43\x1f\x53\x27\x0f\x6d\xc7\x18\x8c\x31\xba\xbe\x2d\xa3\x28\xf1\x39\x11\x55\xa4\x20\xc9\x81\x50\xfc\xdf\x77\x92\xec\x36\xa3\x94\xbe\x28\xd2\xe5\xee\xbb\xef\xbb\xef\x7c\x94\x0e\x6e\xfb\xed\x0f\xe5\x03\x2c\xe0\x01\xe5\x26\x54\x1b\x87\x32\xe0\x9d\x96\xde\x8b\x17\x56\xb4\xca\x1f\xb4\x3c\xfd\x94\x7b\x9c\x03\x1f\x93\xf9\x8c\xb1\x62\x8b\xe1\x1e\x3b\xd9\xeb\xf0\xcb\xd9\x83\x9f\x43\xd7\x9b\x4d\x50\xd6\x80\x28\x81\x2a\x0b\x87\xa1\x77\x26\x5d\x0b\xfe\xa8\x82\x46\x9e\x21\x3c\xd5\xc7\x58\xba\xce\xe1\xcf\xdf\xf4\xb4\x86\xde\x77\x5a\x6d\x9e\xb1\x3d\x07\xc3\x8c\x56\x14\x58\x1d\x1c\x1e\xd1\x4c\x6d\x45\x79\x93\x5b\xdc\xc4\xbf\x07\x3a\x06\xba\x0d\x04\xe6\xd0\xb4\xe8\xde\x33\x8a\x7a\xc3\x4e\x46\xb1\x61\xa7\xfc\xcd\x18\x42\x8d\x7b\x82\xf5\x63\x98\xda\x90\x9e\x2a\xb2\xab\xf6\xf2\x20\xde\x50\x8e\x52\x8f\x64\x46\x6d\xe7\x23\xfb\x9a\x51\x44\xe2\xca\xb5\xca\x22\x8b\x17\x78\xc6\xd3\xdb\xe8\xbe\x07\xdc\x73\xb8\x02\x82\x82\x21\x67\x7c\x08\x52\x70\x39\x82\x10\xca\xce\x61\x47\x30\x5f\xf8\x0c\xac\x49\x63\x9a\x27\x2d\x23\xdb\xf3\xe9\x4d\xc0\x24\x4e\xa7\x4b\x19\xcf\x32\xca\x1d\xd2\xf9\x09\x7b\xde\xaa\x63\x6e\x6c\x7a\xad\xd3\xe5\x63\xa1\xbb\xeb\x91\xe3\x6b\x6e\x71\x36\xc4\x64\x7b\xea\xfe\x09\x8c\xd5\xef\x60\x26\x5b\xd8\xa8\x20\x52\x1f\x58\x54\x50\x5f\xb2\x68\x0a\x88\xf5\xb4\xbe\x0f\xc9\x71\x74\x25\x7c\xc3\x70\x6b\xdb\x13\x39\xee\x83\x53\x66\x1b\xfd\x52\xde\xf7\xe8\x67\xf0\x04\xf3\x05\x28\xdb\x07\xa5\x2b\xa2\xd2\xde\x2b\x27\xd6\xd1\x66\x2a\x7a\xb0\x36\xc4\x77\x49\xe6\xf0\x3a\x57\xf0\x92\xc5\x65\x0a\xb1\x8c\x37\xbb\xeb\x65\x74\x6e\x9d\x45\xc5\xb4\xa6\xa6\x58\x63\xf5\x92\xb3\xa2\xb3\x0e\x9e\x66\x90\x0a\x63\xbe\x93\x66\x8b\xf9\xe9\x5f\x97\xaf\x55\x0e\x52\x43\xea\x84\x9b\x60\xdd\x89\x76\xee\xff\x80\x48\x25\x55\xfc\xe0\x44\x59\x66\xb3\xe0\x6a\x01\xdd\x3e\x54\xbf\x0f\xa4\x28\x74\x82\x37\x5a\x2d\x1b\x99\x76\x62\xb1\x9a\xd8\xd6\x17\x7e\xc5\x97\x17\xbe\xa9\xe5\xb2\xa9\x29\x63\x65\x68\x59\x04\xf5\x2c\x67\xb1\x73\xf5\x68\x13\xf3\x04\x3b\xb0\x09\x98\x54\x24\x05\x6c\x5a\x0b\xfa\x61\xc3\x65\xfd\x2f\x00\x00\xff\xff\x05\xd5\x94\xee\x1d\x04\x00\x00")
+var _jsBuglistJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x91\x3f\x6b\xf3\x30\x10\xc6\x67\xf9\x53\x1c\x7a\x17\x9b\x37\x78\xe8\xe8\xd0\xa5\x69\x87\x42\x29\xa5\x74\x2b\x1d\x84\x7d\x89\x45\x64\xd9\x48\xb2\x21\x04\x7f\xf7\x9e\xfe\xb8\x31\x84\x90\xe5\x38\x9d\x4e\xbf\x7b\x9e\xd3\x24\x0c\x3c\x8d\x87\x37\x69\x1d\x3c\xc2\x27\x8a\xda\x95\xb5\x41\xe1\x70\xa7\x84\xb5\xf9\x39\x63\x8d\xb4\x83\x12\xa7\x77\xd1\x61\x05\x3c\x35\xf3\x4d\x96\xb1\x03\xba\x67\xdc\x8b\x51\xb9\x0f\xd3\x0f\xb6\x82\xfd\xa8\x6b\x27\x7b\x0d\x79\x01\xf4\x92\x19\x74\xa3\xd1\x21\x65\xfc\x4b\x3a\x85\x3c\x22\x2c\xbd\xf7\xb5\x90\x56\xf0\xfd\x13\x8e\xbd\xa6\xf3\x4e\xc9\xfa\x88\xcd\x1a\x86\x91\xc6\x18\x96\x83\xc1\x09\xf5\x32\x36\x2f\xb6\x71\xc4\xd6\x5f\xcf\x14\x66\xca\x66\x82\x19\xd4\x0d\x9a\x6b\x45\xde\xaf\x6b\x85\x37\xeb\x5a\x69\xb7\xa9\x84\x0a\x3b\xc2\xda\x54\xa6\x31\xe4\xa7\xf4\xea\xca\x4e\x0c\xf9\x85\x32\x09\x95\xc4\x24\x6f\xeb\x95\xbd\x44\x4a\x1e\xb4\x72\x25\xa3\x49\x76\x86\x23\x9e\x2e\xab\x7b\x75\xd8\x71\xf8\x0f\x84\x82\x39\x76\xdc\x84\x30\x2e\x12\x84\x28\xad\xc1\x3d\x61\xfe\xf1\x0d\xf4\x3a\xac\xa9\x0a\x5e\x92\xda\xf5\xf6\x16\x30\x99\x53\x21\x29\x7c\x2c\xbc\xdd\x39\xc4\x3b\xea\x79\x23\xa7\x38\x58\x8f\x4a\x85\xe4\xb6\xd1\xf6\x21\x69\xfc\xeb\x65\xab\x25\x86\x6f\x0f\xd3\xef\x60\x7a\x75\x85\x59\xbe\x25\x4b\x0e\xbc\xf4\x39\x23\x07\xbf\x01\x00\x00\xff\xff\xc0\x85\x8c\x9c\xb7\x02\x00\x00")
func jsBuglistJsBytes() ([]byte, error) {
return bindataRead(
@@ -105,12 +105,12 @@ func jsBuglistJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugList.js", size: 1053, mode: os.FileMode(436), modTime: time.Unix(1452990114, 0)}
+ info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453335009, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x92\xcf\x4a\x03\x31\x10\xc6\xcf\xc9\x53\x0c\xf1\xd2\x85\xb6\x07\xf1\x20\x2d\x1e\x6c\xf5\x20\x88\x4a\xf1\x05\x42\x76\xda\x0d\x4d\x93\x25\x7f\x0a\xb2\xec\xbb\x3b\xcd\x6e\x6d\x2b\xac\x8a\x97\x25\xcc\x7c\xf3\x9b\xf9\x3e\x76\x2f\x3d\x2c\xd2\xe6\x4d\x6e\x10\xee\x60\x85\x52\xc5\xa9\xf2\x28\x23\x2e\x8d\x0c\x61\xd4\x70\x56\xea\x50\x1b\xf9\xf1\x22\x77\x38\x03\xd1\x8b\xc5\x98\x73\xe6\xd1\x96\xe8\x67\xb0\x4e\x56\x45\xed\x2c\x8c\x0a\xa0\x01\xaa\xc7\xe4\xed\x05\xed\xd1\xe0\x0e\x6d\x1c\x51\x97\x89\x52\xef\x69\x9e\x5e\x36\x19\x93\x1f\x43\xd2\x33\x2d\x6b\x40\x1d\x4e\xea\xef\x50\xce\x4c\x76\xe5\xe4\x56\x40\xdb\xb5\x07\x11\x4c\x54\xd7\x3d\xe2\xb4\x90\xb1\x58\xe9\x30\xad\xbd\xab\xc3\xf4\x5d\x47\x83\xb9\x5a\xfc\xca\x3a\xdd\x33\x00\x7b\xc0\xa0\xbc\xae\x0f\x79\xfc\x11\x29\x8f\xc0\x06\x2a\x8f\x6b\x32\x77\x25\xc6\xe0\xec\xd2\x68\xb5\x9d\xc1\x19\xdb\xd9\x85\x54\xdb\xa3\x63\x26\x56\x5d\xd0\xd1\x81\xd1\x21\x8a\x6e\x1f\xff\x5a\xfa\xef\x54\x6f\x7e\x4c\x95\x7e\x81\x67\x5a\x37\x86\x06\x72\x72\x34\xf7\x1a\x2b\xf4\xf0\x14\x42\xc2\x70\x74\x43\xb2\x70\x71\xfd\xbd\x31\x87\x5a\xdf\x26\x2f\x69\x93\x2d\x62\xf9\xcd\x64\xa6\x9d\xba\x59\xdf\x76\xbe\xe8\x53\xcc\x39\x6b\x79\x5b\xcc\x3f\x03\x00\x00\xff\xff\x17\xca\x22\xd1\xbc\x02\x00\x00")
+var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xcc\x56\x4d\x8e\x1a\x3d\x10\xdd\x73\x0a\xcb\xdf\x06\x24\x40\x1a\x34\x9f\x14\x31\xca\x22\x33\xc9\x22\x52\x32\x41\x24\x17\x30\xdd\x05\x38\xe3\xb6\x5b\xfe\x21\x41\x23\xb6\x59\x47\x39\x41\xce\x92\xa3\xe4\x24\x71\xbb\x9b\x86\xa6\xdd\x3f\x4c\xc8\x80\x17\x48\x54\x95\xeb\x3d\xbb\xea\x55\x7b\x45\x24\xba\x35\x8b\x09\x59\x00\x7a\x89\xa6\x40\x02\x3d\x0c\x24\x10\x0d\x77\x8c\x28\xd5\x7d\xec\x20\xbb\x42\xaa\x62\x46\xd6\xf7\x24\x82\x31\xc2\x59\x3c\xee\x77\x9c\x53\x02\x0f\x41\x8e\xd1\xdc\xf0\x40\x53\xc1\x51\xb7\x87\xd2\x6d\xc9\x4a\x00\xe6\x14\x58\x38\x15\x5f\x2c\xc2\x2e\x88\xdb\x64\x7d\xeb\x66\x06\xf6\xe3\x93\x45\xe7\xa8\xeb\x75\xa4\x70\xda\x48\x5e\xa0\xfa\x86\x41\x04\x5c\x77\x4b\xb1\xc9\xc2\x21\x5d\x59\xaa\x3e\xd7\x23\x0a\x92\x43\x66\xc7\x92\x96\xa0\x63\x8a\xd1\xc6\x1f\xdf\x1a\xb3\x01\xb7\x8c\x1d\x08\x36\x88\xc2\xc1\x55\x25\xb4\xcb\xf8\xeb\x27\xf6\x3a\x7b\x67\xa2\x3b\x42\x8c\xcc\x80\xa5\xbf\x03\xca\xe7\xa2\x96\x7f\x52\xf1\x8b\xe2\x7f\x8d\x66\x24\xb4\x8d\x5c\x47\xda\xf5\xe1\x99\x59\xf3\x02\xeb\xff\x9f\xd8\x24\x25\x6b\xef\xa6\x60\xda\x14\xfe\xa5\x32\xdb\x45\x1c\x40\xc6\x92\x0a\x49\xf5\x3a\x91\x74\xa6\xee\x2e\x9e\x64\x46\xdc\x47\x7a\x49\xd5\x30\x96\x22\x56\xc3\xad\xf5\xe0\xbe\x94\x26\xda\xa8\x6c\x2a\xe4\x29\x3e\x3a\x6b\x31\x41\x6a\x3b\xd8\x1e\x51\x06\x4a\x0b\x0e\x85\xed\xef\xb7\xd6\x62\x86\xdc\xbc\x77\xe4\xb6\x73\xc4\x53\x22\x6e\x18\x2b\x5a\x5a\x15\xbd\xa2\xd8\xde\xd6\x7c\x81\x02\xc1\x35\xa1\x1c\xa4\xb7\xdc\xa7\x1f\x7f\x9f\x4d\x34\x13\x5a\xda\xd1\x3c\x33\x0b\x65\xa2\x88\xc8\xf5\x89\x26\xe1\x72\x54\xd3\xe3\xe5\xcb\xdc\x5f\x7b\x45\xfc\x44\x35\x3b\x9b\x12\x5b\xb3\x7c\x0d\x2a\x90\x34\x4e\xbe\x71\x6d\x65\xf8\x1c\xd5\x75\x12\x51\x95\xf5\xdc\xca\xd9\xef\xcd\xa5\xea\x77\xe7\x52\x2c\x1f\xad\x53\x73\xd0\x93\x6b\xe6\xba\xb5\x52\xec\x0b\xe6\x1d\x55\xba\x6f\xf3\xb8\xae\xb2\x39\x3e\xe8\x25\x48\xf4\x56\x29\x03\xaa\xe2\x46\xed\x2e\x35\xde\xaf\xf5\x2b\xc6\x12\x9b\x3f\x5a\x70\xeb\xbb\x63\x34\x78\x80\xb0\xb0\x4b\x70\x87\xb5\xf3\x96\xb6\x6f\x9e\xf7\xde\xae\x46\x7f\x39\x62\x0c\x6b\xd5\x83\xb1\x7d\x34\xfa\xa7\xd9\x51\x70\x0e\x92\xd1\xd6\x1f\xfb\x58\xc2\x8a\x0a\x53\xdd\xfc\x47\xa3\x3b\x06\xa4\x86\x40\x4a\x62\x29\x61\x6e\xf1\xff\xab\x05\x7e\x12\xb8\x23\xa0\x62\xc2\x1b\x38\xa4\x3c\x30\x91\x94\x0c\x96\x34\x0c\x81\x63\x4b\x48\x4b\x53\xff\xe6\xc9\x21\x7e\x7f\xfb\xee\x7f\x4c\x6c\x57\xc5\xe4\xcd\x13\xa0\xc9\xf6\xf2\x2b\xe3\xca\x03\xb1\x26\xf1\x3f\x6b\x92\xf4\x35\x70\xbe\x16\xe9\xdb\x79\xe1\xc6\xc1\xc1\xa8\xb8\x25\xc1\x43\x53\xa9\xf0\x34\x7d\xca\x68\x81\x98\x9d\x6a\x97\x7e\xd5\x1c\xbe\xea\xcb\xd5\x22\xbe\xb7\xf4\x50\x43\xbe\x0b\x16\xec\x8f\x06\xc1\x1e\xdb\x1c\x4d\xdf\xf4\xfc\x5f\xf6\xb4\xde\x74\x36\xbd\x9b\x3f\x01\x00\x00\xff\xff\xca\x4d\xd7\xd1\x56\x10\x00\x00")
func jsBugpageJsBytes() ([]byte, error) {
return bindataRead(
@@ -125,7 +125,7 @@ func jsBugpageJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugPage.js", size: 700, mode: os.FileMode(436), modTime: time.Unix(1452990114, 0)}
+ info := bindataFileInfo{name: "js/BugPage.js", size: 4182, mode: os.FileMode(436), modTime: time.Unix(1453335009, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -182,7 +182,7 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
- "js/BugApp.js": jsBugappJs,
+ "js/BugApp.js": jsBugappJs,
"js/BugList.js": jsBuglistJs,
"js/BugPage.js": jsBugpageJs,
}
@@ -226,10 +226,9 @@ type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
-
var _bintree = &bintree{nil, map[string]*bintree{
"js": &bintree{nil, map[string]*bintree{
- "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
+ "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
"BugList.js": &bintree{jsBuglistJs, map[string]*bintree{}},
"BugPage.js": &bintree{jsBugpageJs, map[string]*bintree{}},
}},
@@ -281,3 +280,4 @@ func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
+
diff --git a/bug-serve/jsx/BugApp.js b/bug-serve/jsx/BugApp.js
index c1c8f2d..526b4e5 100644
--- a/bug-serve/jsx/BugApp.js
+++ b/bug-serve/jsx/BugApp.js
@@ -34,9 +34,24 @@ var BugApp = React.createClass({
render: function() {
var content;
if(this.state.SelectedBug != null) {
- content =
+ content =
} else {
- content =
+ content =
}
return (
Issues for: {this.state.Settings.Title}
diff --git a/bug-serve/jsx/BugList.js b/bug-serve/jsx/BugList.js
index bdd24f4..9415918 100644
--- a/bug-serve/jsx/BugList.js
+++ b/bug-serve/jsx/BugList.js
@@ -22,16 +22,3 @@ var BugList = React.createClass({
);
}
});
-/*
-func (b BugListRenderer) GetBody() string {
- issues, _ := ioutil.ReadDir(bugs.GetRootDir() + "/issues")
-
- ret := "
" + b.Title + "
"
- for _, issue := range issues {
- var dir bugs.Directory = bugs.Directory(issue.Name())
- ret += fmt.Sprintf("- %s
\n", (dir), dir.ToTitle())
- }
- ret += "
"
-
- return ret
-}*/
diff --git a/bug-serve/jsx/BugPage.js b/bug-serve/jsx/BugPage.js
index eb368fe..6d48ad6 100644
--- a/bug-serve/jsx/BugPage.js
+++ b/bug-serve/jsx/BugPage.js
@@ -1,11 +1,35 @@
var BugPage = React.createClass({
render: function() {
+ var fieldRow = function(name, value) {
+ if (value) {
+ return (
+
+
+
+ {name}
+
+
+ {value}
+
+
+
);
+ }
+ return;
+ }, priority = fieldRow("Priority", this.props.Priority),
+ statusRow = fieldRow("Status", this.props.Status),
+ milestone = fieldRow("Milestone", this.props.Milestone);
return (
-
-
{this.props.Title}
-
{this.props.Description}
-
Return to list
+
+
+
{this.props.Title}
+
{this.props.Description}
+
+
+ {priority}
+ {statusRow}
+ {milestone}
+
+
);
}
});
From 50ecf8a3864577f8ad9d2b5ff066b219fc73e06a Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 9 Jan 2016 10:59:25 -0500
Subject: [PATCH 13/47] Added or removed issues with the tool "bug"
---
issues/Roadmap.md | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index 0a5848c..29e1790 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -3,3 +3,14 @@
## v0.4:
- bug-serve should have feature parity with bug
- Implement golang io interfaces in Bug class
+<<<<<<< 00683555d0b26a4144b26d862023c314c0316b5d
+=======
+
+## v0.3:
+- Use pager for long bugs
+- More options for bug roadmap
+- Include method of defining stable identifiers
+- update bug lookup to handle identifiers instead of idx
+- bug-import tool should be able to import from other issue trackers
+- Bug list should show identifier instead of number when available
+>>>>>>> Added or removed issues with the tool "bug"
From df31edd462a00e104cab632998da3e821d2d32b6 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 9 Jan 2016 13:09:28 -0500
Subject: [PATCH 14/47] Made bugs.Bug implement io.Reader and io.Closer
interfaces
---
bugapp/List.go | 2 +-
bugs/Bug.go | 41 ++++++++++++++++++++++++++++++++++++-----
2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/bugapp/List.go b/bugapp/List.go
index 49e040d..5c4ad1d 100644
--- a/bugapp/List.go
+++ b/bugapp/List.go
@@ -42,7 +42,7 @@ func List(args ArgumentList, stdout *os.File) {
continue
}
var dir bugs.Directory = bugs.GetIssuesDir() + bugs.Directory(issue.Name())
- b := bugs.Bug{dir}
+ b := bugs.Bug{Dir: dir}
name := getBugName(b, idx)
if wantTags == false {
fmt.Printf("%s: %s\n", name, b.Title(""))
diff --git a/bugs/Bug.go b/bugs/Bug.go
index f2ffc88..bf1223c 100644
--- a/bugs/Bug.go
+++ b/bugs/Bug.go
@@ -1,6 +1,7 @@
package bugs
import (
+ "errors"
"fmt"
"io/ioutil"
"os"
@@ -8,8 +9,11 @@ import (
"strings"
)
+var NoDescriptionError = errors.New("No description provided")
+
type Bug struct {
- Dir Directory
+ Dir Directory
+ descFile *os.File
}
type Tag string
@@ -85,15 +89,42 @@ func (b Bug) Title(options string) string {
}
return title
}
+
+func (b Bug) Close() error {
+ if b.descFile != nil {
+ err := b.descFile.Close()
+ b.descFile = nil
+ return err
+ }
+ return nil
+}
+func (b *Bug) Read(p []byte) (int, error) {
+ dir, _ := b.GetDirectory()
+ if b.descFile == nil {
+ fp, err := os.Open(string(dir) + "/Description")
+ b.descFile = fp
+ if err != nil {
+ fmt.Printf("err: " + err.Error())
+ return 0, NoDescriptionError
+ }
+ }
+
+ return b.descFile.Read(p)
+}
func (b Bug) Description() string {
- dir := b.GetDirectory()
- desc, err := ioutil.ReadFile(string(dir) + "/Description")
+ value, err := ioutil.ReadAll(&b)
if err != nil {
- return "No description provided"
+ if err == NoDescriptionError {
+ return "No description provided."
+ }
+ panic("Unhandled error" + err.Error())
}
- return string(desc)
+ if string(value) == "" {
+ return "No description provided."
+ }
+ return string(value)
}
func (b Bug) SetDescription(val string) error {
dir := b.GetDirectory()
From c70bb945e98b66ff5a6912f548f8c9c0306738e4 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Wed, 20 Jan 2016 20:01:30 -0500
Subject: [PATCH 15/47] Implemented io.Writer interface
---
bugs/Bug.go | 21 ------------------
bugs/IO.go | 56 +++++++++++++++++++++++++++++++++++++++++++++++
bugs/IO_test.go | 48 ++++++++++++++++++++++++++++++++++++++++
issues/Roadmap.md | 11 ----------
4 files changed, 104 insertions(+), 32 deletions(-)
create mode 100644 bugs/IO.go
create mode 100644 bugs/IO_test.go
diff --git a/bugs/Bug.go b/bugs/Bug.go
index bf1223c..c0ed495 100644
--- a/bugs/Bug.go
+++ b/bugs/Bug.go
@@ -90,27 +90,6 @@ func (b Bug) Title(options string) string {
return title
}
-func (b Bug) Close() error {
- if b.descFile != nil {
- err := b.descFile.Close()
- b.descFile = nil
- return err
- }
- return nil
-}
-func (b *Bug) Read(p []byte) (int, error) {
- dir, _ := b.GetDirectory()
- if b.descFile == nil {
- fp, err := os.Open(string(dir) + "/Description")
- b.descFile = fp
- if err != nil {
- fmt.Printf("err: " + err.Error())
- return 0, NoDescriptionError
- }
- }
-
- return b.descFile.Read(p)
-}
func (b Bug) Description() string {
value, err := ioutil.ReadAll(&b)
diff --git a/bugs/IO.go b/bugs/IO.go
new file mode 100644
index 0000000..aa4f97a
--- /dev/null
+++ b/bugs/IO.go
@@ -0,0 +1,56 @@
+package bugs
+
+import (
+ "fmt"
+ "os"
+)
+
+func (b *Bug) Read(p []byte) (int, error) {
+ if b.descFile == nil {
+ dir := b.GetDirectory()
+ fp, err := os.OpenFile(string(dir)+"/Description", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
+ b.descFile = fp
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "err: %s", err.Error())
+ return 0, NoDescriptionError
+ }
+ }
+
+ return b.descFile.Read(p)
+}
+
+func (b *Bug) Write(data []byte) (n int, err error) {
+ if b.descFile == nil {
+ dir := b.GetDirectory()
+ os.MkdirAll(string(dir), 0755)
+ fp, err := os.OpenFile(string(dir)+"/Description", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing to bug: %s", err.Error())
+ return 0, err
+ }
+ b.descFile = fp
+ }
+ return b.descFile.Write(data)
+}
+
+func (b *Bug) WriteAt(data []byte, off int64) (n int, err error) {
+ if b.descFile == nil {
+ dir := b.GetDirectory()
+ os.MkdirAll(string(dir), 0755)
+ fp, err := os.OpenFile(string(dir)+"/Description", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing to bug: %s", err.Error())
+ return 0, err
+ }
+ b.descFile = fp
+ }
+ return b.descFile.WriteAt(data, off)
+}
+func (b Bug) Close() error {
+ if b.descFile != nil {
+ err := b.descFile.Close()
+ b.descFile = nil
+ return err
+ }
+ return nil
+}
diff --git a/bugs/IO_test.go b/bugs/IO_test.go
new file mode 100644
index 0000000..9b101ee
--- /dev/null
+++ b/bugs/IO_test.go
@@ -0,0 +1,48 @@
+package bugs
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "testing"
+)
+
+func TestBugWrite(t *testing.T) {
+ var b *Bug
+ if dir, err := ioutil.TempDir("", "BugWrite"); err == nil {
+ os.Chdir(dir)
+ b = &Bug{Dir: Directory(dir + "/issues/Test-bug")}
+ defer os.RemoveAll(dir)
+ } else {
+ t.Error("Could not get temporary directory to test bug write()")
+ return
+ }
+
+ _, err := b.Write([]byte("Hello there, Mr. Test"))
+ if err != nil {
+ t.Error("Error writing to bug at %s.", b.Dir)
+ }
+ b.Close()
+
+ fp, _ := os.Open("issues/Test-bug/Description")
+ desc, err := ioutil.ReadAll(fp)
+ fp.Close()
+
+ if err != nil {
+ t.Error("Error reading description file.")
+ return
+ }
+
+ // Cast the values to strings because []byte complains that
+ // slices can only be compared to nil.
+ if string(desc) != string("Hello there, Mr. Test") {
+ t.Error("Incorrect description file after writing to bug")
+ }
+}
+
+func ExampleBugWriter() {
+ b := &Bug{Dir: "/path/to/log/bug/issues/Bug-Title"}
+
+ fmt.Fprintf(b, "This is a bug report.\n")
+ fmt.Fprintf(b, "The bug will be created as necessary.\n")
+}
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index 29e1790..0a5848c 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -3,14 +3,3 @@
## v0.4:
- bug-serve should have feature parity with bug
- Implement golang io interfaces in Bug class
-<<<<<<< 00683555d0b26a4144b26d862023c314c0316b5d
-=======
-
-## v0.3:
-- Use pager for long bugs
-- More options for bug roadmap
-- Include method of defining stable identifiers
-- update bug lookup to handle identifiers instead of idx
-- bug-import tool should be able to import from other issue trackers
-- Bug list should show identifier instead of number when available
->>>>>>> Added or removed issues with the tool "bug"
From 06cb615fd84b353995bf720d2deaa4f1bb2155f0 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Wed, 20 Jan 2016 20:04:56 -0500
Subject: [PATCH 16/47] Fixed compilation error with bug-import
---
bug-import/be.go | 2 +-
bug-import/github.go | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/bug-import/be.go b/bug-import/be.go
index 69f88c2..c673c8e 100644
--- a/bug-import/be.go
+++ b/bug-import/be.go
@@ -79,7 +79,7 @@ func beImportBug(identifier, issuesDir, fullbepath string) {
bugdir := bugs.TitleToDir(beBug.Summary)
- b := bugs.Bug{bugs.Directory(issuesDir) + bugdir}
+ b := bugs.Bug{Dir: bugs.Directory(issuesDir) + bugdir}
if dir := b.GetDirectory(); dir != "" {
os.Mkdir(string(dir), 0755)
}
diff --git a/bug-import/github.go b/bug-import/github.go
index a133f48..161abf8 100644
--- a/bug-import/github.go
+++ b/bug-import/github.go
@@ -22,7 +22,7 @@ func githubImport(user, repo string) {
for lastPage := false; lastPage != true; {
for _, issue := range issues {
if issue.PullRequestLinks == nil {
- b := bugs.Bug{issueDir + bugs.TitleToDir(*issue.Title)}
+ b := bugs.Bug{Dir: issueDir + bugs.TitleToDir(*issue.Title)}
if dir := b.GetDirectory(); dir != "" {
os.Mkdir(string(dir), 0755)
}
From e26aa659dd2c34da613c003089a8961fd7042064 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Wed, 20 Jan 2016 21:52:58 -0500
Subject: [PATCH 17/47] Fix next/previous links in bug-serve
---
bug-serve/bindata.go | 10 ++---
.../Description | 1 -
.../Description | 0
bug-serve/jsx/BugApp.js | 18 ++++++---
bug-serve/jsx/BugPage.js | 39 +++++++++++++++++--
5 files changed, 54 insertions(+), 14 deletions(-)
delete mode 100644 bug-serve/issues/Include-directory-being-served-in-title/Description
delete mode 100644 bug-serve/issues/return-to-list next previous-broken/Description
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
index 2f33395..643382b 100644
--- a/bug-serve/bindata.go
+++ b/bug-serve/bindata.go
@@ -70,7 +70,7 @@ func (fi bindataFileInfo) Sys() interface{} {
return nil
}
-var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x55\x4b\x4f\x1b\x31\x10\x3e\x6f\x7e\x85\xbb\x07\xb4\x88\x68\xa1\x55\x4f\x41\x39\xf0\x12\x50\xf1\x12\xe4\x50\xa9\xea\xc1\xec\x4e\x12\x17\xc7\xbb\xb5\xc7\x14\x84\xf2\xdf\x3b\x7e\x84\x75\x80\x6d\xe1\x12\x25\x33\xdf\x37\xfe\xe6\x99\x7b\xae\xd9\xbe\x9d\xed\xb5\x2d\x1b\xb3\x6b\xe0\x15\x96\x95\x06\x8e\x70\x20\xb9\x31\xc5\xd3\x20\xab\x85\x69\x25\x7f\xbc\xe0\x0b\x18\xb1\x3c\x60\xf3\xe1\x60\x90\x55\xcd\xa2\x6d\x14\x28\x3c\x14\xf5\x79\x63\x15\x8e\xd8\xd4\xaa\x0a\x45\xa3\x58\xb1\xc9\x88\x9a\xb9\xe8\x38\xe7\x48\xb1\x71\x2e\xcc\x2e\x99\xf6\x7e\xf1\x87\x63\xc0\x22\xdf\x16\xc6\x58\x30\xdb\xf9\x30\xa1\x69\x30\x14\xd3\x40\xa0\x67\x8e\x5b\x1a\xc0\x1b\x24\x45\x85\x37\x65\x4e\x82\xc9\x47\xec\xdb\xcd\xe5\x45\xd9\x72\x6d\xa0\x63\x39\xc0\x72\xd3\x3d\x13\x3e\xbb\xc7\x28\x08\x0a\x45\xc4\x8f\xbe\x76\xb3\x22\xbe\xeb\xc5\xe5\x70\x90\xcd\x00\x4f\x95\x40\xc1\xa5\x0f\xf4\xba\x2a\x1a\xd0\x6a\x15\xde\x4c\xe3\x3f\x39\x36\x99\x26\x02\x25\xd0\xef\xfc\xb2\x05\xc5\x4e\x7d\x99\xf2\xe0\x8a\xb9\xff\xf8\x39\x8c\x64\x09\x15\x42\x4d\x66\x27\x8e\x3c\xca\x4a\xe9\xc4\x44\x2d\xc6\x03\xc8\x7d\xc2\x55\x2d\x41\xa7\x62\x62\xda\x50\xb6\x1a\xee\x5d\x1b\x61\xca\xad\xc4\xc2\x67\xe3\x3a\x77\x6b\x67\xd4\x38\x28\x2b\xab\x35\xf9\x27\x5c\x53\x6a\x25\xc2\x03\x1e\x34\x0a\xc9\xb2\xfb\xde\x16\xb3\x2d\x1f\x6c\x8b\xe5\x1f\x69\x37\x4b\xd2\x7b\xbb\xfa\xec\x45\xe9\xc9\x41\xec\xc8\x7a\x5d\x78\x27\x30\x8d\x9f\xd6\x2f\xd6\x8e\x25\xb1\x54\xbd\x5e\xb0\x6e\xa6\xab\x2e\x7f\x31\x65\x45\x88\xeb\x82\x96\x49\x44\xf6\x69\xec\x43\xc6\xe4\x22\xe7\xc5\x9a\x1d\x49\x58\x90\xb5\x20\xfc\x15\x9f\xc1\x30\x60\x33\x3f\x02\x23\xf6\x76\xe0\xd2\x7b\xfd\x04\x64\x87\x60\x2a\x2d\x5a\x27\xb0\x17\x9e\x60\x02\xe9\x5c\x48\x30\x48\xbb\xdb\x4b\x79\x46\x04\x82\x2b\x98\x35\xbd\xe8\xe0\x0e\xd0\x2b\x2d\x1a\x2d\xf0\xb1\x17\xbc\x02\x04\xf8\x69\x4d\xd9\x8b\xa9\x70\x95\xee\x21\x74\x90\x40\x99\xf0\x59\xbf\x14\xe7\x0c\xb0\x46\xed\xf3\xea\x2e\x02\xd7\x06\x23\xf8\xf7\xa4\x74\xdb\xb4\x16\xc9\x19\x56\xec\x4b\x9c\x83\x26\xc3\x81\x14\xd5\x9d\x9b\xa6\x38\x3d\xeb\x0b\x95\xec\x3f\x03\x69\xe0\x9d\xbd\x3e\x13\x06\xfb\x7b\x9d\xf4\xf7\x9f\x12\x3f\xa2\xae\xbb\x3b\x6f\x49\xf2\xd7\xa4\x16\xf7\xe1\xcc\xb8\xa9\xf5\x5f\xfa\xa0\x59\x3e\xff\x1c\xa0\x1d\x36\xcb\xc3\xa5\x62\xd3\x86\x7a\x19\xbd\x6b\x5d\x0a\x87\x2e\x64\xe7\xbc\x9b\xff\x79\xe3\x59\x4f\xf2\x48\xac\xac\xa7\xd3\x87\x5f\xd6\x81\x4b\x71\xe0\xf6\x32\x5e\x1e\xaa\x7b\xb7\xb5\x56\xcb\x21\xab\xb8\x94\xb7\x34\x0e\x7e\x17\x1d\xf2\x61\x21\xe7\x88\xee\x4f\x4f\xc1\x1f\xf6\xfd\xfc\xec\x84\x7e\x5d\xc3\x6f\x4a\x20\x5c\xc0\x08\x28\x1b\x45\xca\xea\x47\x9f\x43\x35\xe7\x6a\x06\x6b\xd1\xc3\x72\x3f\x1f\x01\x8f\xf5\xe7\x85\x8d\xc7\x63\xf6\x95\x6d\x6c\x74\xcd\xb3\x86\x8c\xec\xcb\xce\xce\xea\x22\x44\x51\x2b\x6a\x38\x6a\x13\xba\xaf\xab\x96\x2d\x53\x21\xf4\x67\x50\xe4\xc7\x47\x13\xba\xa0\x3e\x27\xd4\x16\x52\xa5\x86\x0e\x96\x93\xbe\xdc\xfd\x1b\x00\x00\xff\xff\xe7\xbb\xf6\x88\xd5\x07\x00\x00")
+var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x55\xcf\x4f\xe3\x3a\x10\x3e\xa7\x7f\x85\x5f\x0e\x28\xe8\x55\x81\xf7\xb4\xa7\xa2\x1e\xa0\x20\x60\xc5\x2f\x41\x0f\x2b\xad\xf6\x60\x92\x69\xeb\xc5\x75\xb2\xb6\xc3\x82\x50\xff\xf7\x1d\x7b\x9c\xc6\x85\x66\x81\x4b\xa5\x8e\xbf\x6f\xe6\x9b\x9f\x79\xe4\x9a\x1d\x35\xf3\xc3\xba\x66\x63\x76\x0b\xbc\xb0\x79\xa1\x81\x5b\x98\x48\x6e\x4c\xf6\x32\x48\x4a\x61\x6a\xc9\x9f\xaf\xf8\x12\x46\x2c\x25\x6c\x3a\x1c\x0c\x92\xa2\x5a\xd6\x95\x02\x65\x8f\x45\x79\x59\x35\xca\x8e\xd8\xac\x51\x85\x15\x95\x62\xd9\x2e\x43\x6a\xe2\xbc\xdb\x05\xb7\xe8\xdb\x2e\x84\x39\x40\xd3\xe1\x4f\xfe\x74\x0a\x36\x4b\xf7\x84\x31\x0d\x98\xbd\x74\x18\xd1\x34\x18\xf4\x69\x80\xe8\x89\xe3\xe6\x06\xec\x9d\x45\x45\x99\x37\x25\x4e\x82\x49\x47\xec\xeb\xdd\xf5\x55\x5e\x73\x6d\xa0\x63\x39\xc0\x6a\xd7\x85\xa1\xdf\x2e\x18\x3a\xb1\x42\x21\xf1\xb3\xd1\xee\x5a\xe2\x87\x22\xae\x86\x83\x64\x0e\xf6\x5c\x09\x2b\xb8\xf4\x8e\xde\x56\x45\x83\x6d\xb4\xa2\x98\xb1\xff\x17\xc7\x46\xd3\x54\x58\x09\xf8\x3f\xbd\xae\x41\xb1\x73\x5f\xa6\x94\x9e\x42\xee\xdf\x7f\x0c\x03\x59\x42\x61\xa1\x44\x33\x5a\x55\x23\xe5\x1b\xfb\xb1\xd0\xce\x55\xea\x14\x06\x81\xb2\xe2\xee\x25\x16\x76\xdf\xcc\x3f\xd1\x31\xf6\x2f\x43\x02\xfe\xa6\x9f\xee\x5e\xa4\x6c\x7b\x41\x87\x6d\xd9\x5f\x65\x80\x01\xb7\xd4\xda\x78\x18\x82\xce\xb8\x2a\x25\xe8\x38\xa7\x20\x03\xf2\x5a\xc3\xa3\x1b\x53\x98\xf1\x46\xda\xcc\x7b\x70\xc9\xe5\xa1\x10\x19\xe4\x45\xa3\x35\x42\xa6\x5c\x63\xf7\x72\x0b\x4f\x76\x52\x29\x8b\x96\x36\x10\xea\xc3\x44\x82\xa8\xb7\x2d\xf5\xee\xba\x54\xd9\x96\xce\xb0\x55\xe7\x4b\x95\x9b\x52\xbb\xda\x17\x14\xd6\x49\x14\x33\x96\x91\x5f\xe7\x34\x8f\x3c\xb2\x7f\xc6\xde\x65\xa8\x73\xe0\xbc\x5a\xe0\x13\x09\x4b\xb4\x66\x88\xbf\xe1\x73\x18\x12\x36\xf1\xc3\x35\x62\xdb\x1d\xe7\xfe\x95\x5a\x70\x0c\xa6\xd0\xa2\x76\x02\x7b\xe1\x11\x86\x48\x97\x42\x82\xb1\x78\x15\x7a\x29\x6b\x04\x11\x5c\xc1\x1a\xd3\x8b\xa6\x67\x82\xde\x68\x51\x69\x61\x9f\x7b\xc1\x2d\x80\xe0\xe7\x25\x66\x2f\x66\xc2\x55\xba\x87\xd0\x41\x88\x32\xe5\xf3\x7e\x29\xee\x91\x60\x95\x3a\xe2\xc5\x43\x00\x6e\x0c\x06\xbd\x1f\x4a\xe9\xf6\x74\xc3\x93\x33\xd0\xeb\x84\x46\xcd\x2f\xc0\xf6\x50\x38\xf0\x6d\xa0\x6b\xbb\x00\x8d\xa6\x89\x14\xc5\x83\x1b\xbc\x30\x68\x9b\x53\x4f\xe8\x8b\x76\xad\xe3\xd9\x8e\x76\x86\x81\x34\xf0\xc1\x89\xb9\x10\xc6\xf6\x4f\x4c\x34\x25\x7f\x49\x14\xcb\xf4\x9e\xf0\x48\x5d\x77\x17\xb7\x49\xf2\x57\xad\x14\x8f\x74\x06\xd7\x87\xae\x0f\x9a\xa4\x8b\xff\x08\xda\x61\x93\x94\x2e\x29\x9b\x55\x38\x11\xe1\x75\xa3\x01\x74\x88\x29\x3b\xf7\xba\xfb\x4e\x8c\xb5\x9e\x28\x48\xa8\xac\xa7\xe3\x8f\x5f\xf9\x81\x4b\x71\xe0\xb6\x3b\x9c\x52\xac\x7b\xb7\xfb\x8d\x96\x43\x56\x70\x29\xef\x71\xa8\xfc\x46\x3b\xe4\xd3\x52\x2e\xac\x75\x1f\x65\x05\xbf\xd9\xb7\xcb\x8b\x33\xfc\x77\x0b\xbf\x30\x01\xba\x60\x01\x90\x57\x0a\x95\x95\xcf\x3e\x87\x62\xc1\xd5\x1c\x36\xbc\xd3\x89\x58\x9f\x12\x8f\xf5\x47\x8a\x8d\xc7\x63\xf6\x85\xed\xec\x74\xcd\x6b\x0c\x1a\xd9\xff\xfb\xfb\xed\x5d\x09\xa2\x5a\x2a\x5d\xe8\x29\x1e\xc7\xb6\x65\xab\x58\x08\x7e\xac\xb2\xf4\xf4\x64\x8a\x9f\x04\x9f\x93\xd5\x0d\xc4\x4a\x0d\x9e\x3d\x27\x7d\x75\xf0\x27\x00\x00\xff\xff\xb1\x0c\x38\xdf\x75\x08\x00\x00")
func jsBugappJsBytes() ([]byte, error) {
return bindataRead(
@@ -85,7 +85,7 @@ func jsBugappJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugApp.js", size: 2005, mode: os.FileMode(436), modTime: time.Unix(1453335009, 0)}
+ info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453344686, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -105,12 +105,12 @@ func jsBuglistJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453335009, 0)}
+ info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453344686, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xcc\x56\x4d\x8e\x1a\x3d\x10\xdd\x73\x0a\xcb\xdf\x06\x24\x40\x1a\x34\x9f\x14\x31\xca\x22\x33\xc9\x22\x52\x32\x41\x24\x17\x30\xdd\x05\x38\xe3\xb6\x5b\xfe\x21\x41\x23\xb6\x59\x47\x39\x41\xce\x92\xa3\xe4\x24\x71\xbb\x9b\x86\xa6\xdd\x3f\x4c\xc8\x80\x17\x48\x54\x95\xeb\x3d\xbb\xea\x55\x7b\x45\x24\xba\x35\x8b\x09\x59\x00\x7a\x89\xa6\x40\x02\x3d\x0c\x24\x10\x0d\x77\x8c\x28\xd5\x7d\xec\x20\xbb\x42\xaa\x62\x46\xd6\xf7\x24\x82\x31\xc2\x59\x3c\xee\x77\x9c\x53\x02\x0f\x41\x8e\xd1\xdc\xf0\x40\x53\xc1\x51\xb7\x87\xd2\x6d\xc9\x4a\x00\xe6\x14\x58\x38\x15\x5f\x2c\xc2\x2e\x88\xdb\x64\x7d\xeb\x66\x06\xf6\xe3\x93\x45\xe7\xa8\xeb\x75\xa4\x70\xda\x48\x5e\xa0\xfa\x86\x41\x04\x5c\x77\x4b\xb1\xc9\xc2\x21\x5d\x59\xaa\x3e\xd7\x23\x0a\x92\x43\x66\xc7\x92\x96\xa0\x63\x8a\xd1\xc6\x1f\xdf\x1a\xb3\x01\xb7\x8c\x1d\x08\x36\x88\xc2\xc1\x55\x25\xb4\xcb\xf8\xeb\x27\xf6\x3a\x7b\x67\xa2\x3b\x42\x8c\xcc\x80\xa5\xbf\x03\xca\xe7\xa2\x96\x7f\x52\xf1\x8b\xe2\x7f\x8d\x66\x24\xb4\x8d\x5c\x47\xda\xf5\xe1\x99\x59\xf3\x02\xeb\xff\x9f\xd8\x24\x25\x6b\xef\xa6\x60\xda\x14\xfe\xa5\x32\xdb\x45\x1c\x40\xc6\x92\x0a\x49\xf5\x3a\x91\x74\xa6\xee\x2e\x9e\x64\x46\xdc\x47\x7a\x49\xd5\x30\x96\x22\x56\xc3\xad\xf5\xe0\xbe\x94\x26\xda\xa8\x6c\x2a\xe4\x29\x3e\x3a\x6b\x31\x41\x6a\x3b\xd8\x1e\x51\x06\x4a\x0b\x0e\x85\xed\xef\xb7\xd6\x62\x86\xdc\xbc\x77\xe4\xb6\x73\xc4\x53\x22\x6e\x18\x2b\x5a\x5a\x15\xbd\xa2\xd8\xde\xd6\x7c\x81\x02\xc1\x35\xa1\x1c\xa4\xb7\xdc\xa7\x1f\x7f\x9f\x4d\x34\x13\x5a\xda\xd1\x3c\x33\x0b\x65\xa2\x88\xc8\xf5\x89\x26\xe1\x72\x54\xd3\xe3\xe5\xcb\xdc\x5f\x7b\x45\xfc\x44\x35\x3b\x9b\x12\x5b\xb3\x7c\x0d\x2a\x90\x34\x4e\xbe\x71\x6d\x65\xf8\x1c\xd5\x75\x12\x51\x95\xf5\xdc\xca\xd9\xef\xcd\xa5\xea\x77\xe7\x52\x2c\x1f\xad\x53\x73\xd0\x93\x6b\xe6\xba\xb5\x52\xec\x0b\xe6\x1d\x55\xba\x6f\xf3\xb8\xae\xb2\x39\x3e\xe8\x25\x48\xf4\x56\x29\x03\xaa\xe2\x46\xed\x2e\x35\xde\xaf\xf5\x2b\xc6\x12\x9b\x3f\x5a\x70\xeb\xbb\x63\x34\x78\x80\xb0\xb0\x4b\x70\x87\xb5\xf3\x96\xb6\x6f\x9e\xf7\xde\xae\x46\x7f\x39\x62\x0c\x6b\xd5\x83\xb1\x7d\x34\xfa\xa7\xd9\x51\x70\x0e\x92\xd1\xd6\x1f\xfb\x58\xc2\x8a\x0a\x53\xdd\xfc\x47\xa3\x3b\x06\xa4\x86\x40\x4a\x62\x29\x61\x6e\xf1\xff\xab\x05\x7e\x12\xb8\x23\xa0\x62\xc2\x1b\x38\xa4\x3c\x30\x91\x94\x0c\x96\x34\x0c\x81\x63\x4b\x48\x4b\x53\xff\xe6\xc9\x21\x7e\x7f\xfb\xee\x7f\x4c\x6c\x57\xc5\xe4\xcd\x13\xa0\xc9\xf6\xf2\x2b\xe3\xca\x03\xb1\x26\xf1\x3f\x6b\x92\xf4\x35\x70\xbe\x16\xe9\xdb\x79\xe1\xc6\xc1\xc1\xa8\xb8\x25\xc1\x43\x53\xa9\xf0\x34\x7d\xca\x68\x81\x98\x9d\x6a\x97\x7e\xd5\x1c\xbe\xea\xcb\xd5\x22\xbe\xb7\xf4\x50\x43\xbe\x0b\x16\xec\x8f\x06\xc1\x1e\xdb\x1c\x4d\xdf\xf4\xfc\x5f\xf6\xb4\xde\x74\x36\xbd\x9b\x3f\x01\x00\x00\xff\xff\xca\x4d\xd7\xd1\x56\x10\x00\x00")
+var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xcd\x6e\xdb\x38\x10\xbe\xfb\x29\xb8\x5a\x20\xb0\x11\xdb\x88\x83\x2c\xb0\x88\x37\x0b\x34\x6e\x0f\x05\xd2\x34\x48\x7b\x2b\x72\xa0\x25\xda\x66\x43\x93\x02\x49\xa5\x0d\x02\x5f\x7b\x2e\xfa\x04\x7d\x96\x3e\x4a\x9f\xa4\x43\x5a\x92\xf5\x43\xfd\x24\x71\x13\x97\x87\xc4\x26\x39\x33\xdf\x7c\xe2\x7c\x1c\xf9\x06\x4b\x74\x1a\xcd\x2f\xf0\x9c\xa0\x13\x74\x49\xb0\xaf\x87\xbe\x24\x58\x93\x09\xc3\x4a\x75\xef\x3a\x08\x46\x40\x55\xc8\xf0\xed\x39\x5e\x92\x63\xe4\xc5\xfb\xbd\x7e\xc7\x2e\x32\x81\x83\x0b\x49\x6e\xa8\x88\x14\x2c\x1d\xa3\x59\xc4\x7d\x4d\x05\x47\xdd\x1e\x5a\xdb\x9b\x31\x13\x12\x75\x4d\x38\x0a\x81\x46\x63\xf8\xf7\x1f\xd2\x0b\xaa\x86\xa1\x14\xa1\x1a\xbe\x60\x0c\x8c\xd5\x90\x11\x3e\xd7\x0b\xb3\xbc\x0f\xdb\xb2\x0e\xcc\x30\xf6\xd3\x68\x3e\xc1\x3c\xa0\x01\x80\x04\x57\x65\x1f\x1f\xe8\xd5\x38\x67\x45\x67\xa8\x9b\xb7\x3a\xc9\xd9\x4d\x22\x29\x09\xd7\x60\x5b\x8c\x67\x46\x66\xe3\x19\xa4\x0a\xbb\xba\xae\x98\x68\x80\x46\x57\xbd\x71\xc9\x5c\x12\x1d\x49\x9e\x9f\x5f\x75\xca\x9f\xb2\xfb\x56\xfd\x94\xd9\x73\xf2\x59\xb7\x65\xf5\xa0\x81\x55\x03\xf1\x4f\x64\x76\x7f\xeb\xcc\x02\xa8\x80\xc8\x2a\x52\x0d\x17\x33\x4a\x58\x70\x29\x3e\x01\x0f\x9b\x4d\x1c\x0a\xa0\x0f\xcb\x2c\x22\xc5\x7c\x0c\x13\xce\x85\x0d\x82\x5c\x79\xbd\x62\x64\x09\xcc\x74\x4b\x7b\xcd\xf0\x02\x7a\xe3\xf5\x9d\x4b\x77\xc8\x37\x85\x19\x97\xa2\x04\x80\x16\xa9\x97\x64\x56\x1c\xad\x63\x36\xc4\x2d\xc7\xf6\x05\x1b\x2c\x83\xc1\xa8\x32\xb4\xf5\xf8\xe3\xbb\xe7\x5c\xec\x3d\x13\xdc\x43\xc4\xf0\x94\xb0\xf5\xdf\x01\xe5\x33\x51\x8b\xdf\x3c\xf1\x9d\xc2\x7f\x84\xa6\x38\x00\xf1\xad\x03\x6d\xcf\xe1\x4e\xa1\xfe\xe7\x81\x87\xa4\x34\xdb\xab\x2a\x77\x33\x8a\x82\x50\x08\x19\x4a\x2a\x24\xd5\xb7\xa6\xa4\xe3\xea\xee\x7a\x17\xf1\xa4\xd7\xcf\xca\x51\x32\x5b\xe0\x4b\x69\xac\x23\x15\xab\x42\xea\xe2\x9d\x9d\xcd\x3b\x58\xcf\x15\xcc\x97\x94\x11\xa5\x05\x27\x39\xf3\x37\xc9\x6c\xde\x43\x3a\x9d\x49\xd9\x08\x53\x08\x57\xad\xbd\x9b\xfb\x88\xc3\xdd\x60\x3f\x6e\x76\x18\x19\xaa\xd6\xff\xff\xd1\x08\xed\xed\xb9\x84\xfd\xe0\x0a\xfd\xd5\x52\xb9\x53\x00\x90\x85\x17\xc6\x17\xbf\x97\x61\x1d\x11\xa6\x48\x1b\x23\xd3\x57\xe0\x29\x23\x41\xd6\xfa\xd1\xa9\xd4\x5e\x7f\xed\xd3\x4c\xc9\x35\x88\xcd\x97\xa6\x14\x4b\x06\xf5\xe9\xb5\xbd\x13\x1c\xe5\xc6\x23\xc6\xf2\x33\xad\x0a\xb8\xa2\x70\x9d\x05\xfb\x2f\xf2\x05\xd7\x98\x72\x22\x9d\xa5\xbb\xfd\xab\xec\x63\xb4\x9c\x0a\x2d\xe1\x9a\x85\x86\x42\x45\xcb\x25\x96\xb7\x5b\xba\xd5\x16\x87\x35\x7a\x55\x26\x33\x3b\x32\x47\xe5\x3d\xd5\xec\xd9\x54\xb5\x35\xca\x97\x44\xf9\x92\x86\xa6\x5f\x69\x2b\xa9\x4f\xf1\x74\xad\xdc\xa9\xca\xe7\x99\x48\xb3\x7b\x35\x95\x5d\xf7\x72\x2a\xab\xe5\xd4\x3a\x35\x89\x6e\xbd\x66\x8e\x5a\x57\x0a\xc8\xcd\x19\x55\xba\x0f\x7e\xec\xa9\x02\x1f\x6f\xf5\x82\x48\xf4\x5a\xa9\x88\xa8\x0a\x46\x8d\x94\x1d\x3b\x14\xcf\xbd\x5b\x70\x58\x9b\x30\xea\x5f\x93\x20\x67\x25\xb8\x8d\xb5\x59\x2d\x99\xaf\x9e\x96\xb7\xd1\xe1\x23\x25\x26\x62\xad\xce\x60\x08\x2f\xad\x6e\x35\xbb\x57\x38\x1b\x92\xd1\xb6\x2d\xd0\xe6\xe6\xab\xe9\x80\xee\x15\xdc\x02\xc0\x35\xf1\xd7\x18\x16\x92\xcc\x20\xeb\xbf\xa1\xad\x10\xdc\x3e\xea\xf8\x18\x14\x5e\xd8\xeb\x70\x3d\x08\x9b\xc5\xa7\x42\xcc\x1b\x20\xae\x61\x7a\x58\x52\x3c\x58\xd0\x20\x20\xdc\x03\xbc\x5a\x46\xf5\xdd\x6d\x1a\xe2\xe7\x97\xaf\xee\xb6\x31\x19\x15\xba\x9c\x3a\x40\x09\x0b\xd5\x6e\xca\x72\x59\xe3\xf8\x77\x1d\x21\x6f\xdd\x2b\xd4\xb2\xf2\xa4\x27\x28\x11\x92\x53\xec\x5f\x37\x3d\x2a\xef\x72\xdd\xe8\x68\x81\x18\x68\xde\x8e\x53\xbd\x69\xe2\x76\x85\xeb\xcc\x8f\x40\x8d\x54\x9b\x7d\xa8\x21\xd4\x0e\x97\xf3\xb7\x86\x72\xbe\xef\xd1\x69\xea\x07\xd2\x6f\xf1\x2b\xd6\xaa\xb3\xea\x8d\x7f\x05\x00\x00\xff\xff\x20\x81\xd8\x6b\x12\x15\x00\x00")
func jsBugpageJsBytes() ([]byte, error) {
return bindataRead(
@@ -125,7 +125,7 @@ func jsBugpageJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugPage.js", size: 4182, mode: os.FileMode(436), modTime: time.Unix(1453335009, 0)}
+ info := bindataFileInfo{name: "js/BugPage.js", size: 5394, mode: os.FileMode(436), modTime: time.Unix(1453344687, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
diff --git a/bug-serve/issues/Include-directory-being-served-in-title/Description b/bug-serve/issues/Include-directory-being-served-in-title/Description
deleted file mode 100644
index e8709d1..0000000
--- a/bug-serve/issues/Include-directory-being-served-in-title/Description
+++ /dev/null
@@ -1 +0,0 @@
-The title in bug-serve include the directory being served
diff --git a/bug-serve/issues/return-to-list next previous-broken/Description b/bug-serve/issues/return-to-list next previous-broken/Description
deleted file mode 100644
index e69de29..0000000
diff --git a/bug-serve/jsx/BugApp.js b/bug-serve/jsx/BugApp.js
index 526b4e5..431c101 100644
--- a/bug-serve/jsx/BugApp.js
+++ b/bug-serve/jsx/BugApp.js
@@ -17,16 +17,22 @@ var BugApp = React.createClass({
"Settings" : {},
"Title" : "Open Issues",
"Bugs": [],
- "SelectedBugJSON" : null
+ "SelectedBug" : null,
+ "SelectedBugDir" : ""
}
},
- selectBugHandler: function(e) {
- e.preventDefault();
- var bug = e.currentTarget.textContent;
+ loadBug: function(bug) {
var that = this;
AjaxGet("/issues/" + bug + "/", function(response) {
- that.setState({SelectedBug : JSON.parse(response)});
+ that.setState({
+ SelectedBug : JSON.parse(response),
+ "SelectedBugDir" : bug
+ });
});
+ },
+ selectBugHandler: function(e) {
+ e.preventDefault();
+ this.loadBug(e.currentTarget.textContent);
},
resetSelected: function() {
this.setState({ "SelectedBug" : null});
@@ -44,7 +50,9 @@ var BugApp = React.createClass({
Tags={this.state.SelectedBug.Tags}
onBack={this.resetSelected}
AllBugs={this.state.Bugs}
+ CurrentBug={this.state.SelectedBugDir}
onOtherBugClicked={this.selectBugHandler}
+ LoadBug={this.loadBug}
/>
} else {
content =
{value}
-
+
);
}
return;
}, priority = fieldRow("Priority", this.props.Priority),
statusRow = fieldRow("Status", this.props.Status),
milestone = fieldRow("Milestone", this.props.Milestone);
+ var prevClass, nextClass;
+ if (this.props.AllBugs.length > 1 &&
+ this.props.AllBugs[0] != this.props.CurrentBug) {
+ prevClass = "previous";
+ } else {
+ prevClass = "previous disabled";
+ }
+ if (this.props.AllBugs.length > 1 &&
+ this.props.AllBugs[this.props.AllBugs.length-1] != this.props.CurrentBug) {
+ nextClass = "next";
+ } else {
+ nextClass = "next disabled";
+ }
return (
@@ -39,9 +72,9 @@ var BugPage = React.createClass({
);
From 5f310d231ca03135c85927c78fc5dd55f445e9dd Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Wed, 20 Jan 2016 21:56:01 -0500
Subject: [PATCH 18/47] Added or removed issues with the tool "bug"
---
.../issues/Description-should-be-parsed-as-markdown/Description | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bug-serve/issues/Description-should-be-parsed-as-markdown/Description
diff --git a/bug-serve/issues/Description-should-be-parsed-as-markdown/Description b/bug-serve/issues/Description-should-be-parsed-as-markdown/Description
new file mode 100644
index 0000000..e69de29
From d76a5abf4ddd7206e440e67b4ced96e97f99941f Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Thu, 21 Jan 2016 20:09:36 -0500
Subject: [PATCH 19/47] Render bug descriptions as markdown
---
bug-serve/MainPageHandler.go | 1 +
bug-serve/bindata.go | 31 ++++++++++++++++---
.../Description | 0
bug-serve/js/marked.min.js | 6 ++++
bug-serve/jsx/BugPage.js | 8 ++++-
5 files changed, 41 insertions(+), 5 deletions(-)
delete mode 100644 bug-serve/issues/Description-should-be-parsed-as-markdown/Description
create mode 100644 bug-serve/js/marked.min.js
diff --git a/bug-serve/MainPageHandler.go b/bug-serve/MainPageHandler.go
index 950a7d4..6c97aac 100644
--- a/bug-serve/MainPageHandler.go
+++ b/bug-serve/MainPageHandler.go
@@ -19,6 +19,7 @@ func (m MainPageHandler) Get(r *http.Request, p map[string]interface{}) (string,
// React
"https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
"https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
+ "/js/marked.min.js",
"/js/BugApp.js",
"/js/BugList.js",
"/js/BugPage.js",
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
index 643382b..161e775 100644
--- a/bug-serve/bindata.go
+++ b/bug-serve/bindata.go
@@ -3,6 +3,7 @@
// js/BugApp.js
// js/BugList.js
// js/BugPage.js
+// js/marked.min.js
// DO NOT EDIT!
package main
@@ -85,7 +86,7 @@ func jsBugappJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453344686, 0)}
+ info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453424896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -105,12 +106,12 @@ func jsBuglistJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453344686, 0)}
+ info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453424896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xcd\x6e\xdb\x38\x10\xbe\xfb\x29\xb8\x5a\x20\xb0\x11\xdb\x88\x83\x2c\xb0\x88\x37\x0b\x34\x6e\x0f\x05\xd2\x34\x48\x7b\x2b\x72\xa0\x25\xda\x66\x43\x93\x02\x49\xa5\x0d\x02\x5f\x7b\x2e\xfa\x04\x7d\x96\x3e\x4a\x9f\xa4\x43\x5a\x92\xf5\x43\xfd\x24\x71\x13\x97\x87\xc4\x26\x39\x33\xdf\x7c\xe2\x7c\x1c\xf9\x06\x4b\x74\x1a\xcd\x2f\xf0\x9c\xa0\x13\x74\x49\xb0\xaf\x87\xbe\x24\x58\x93\x09\xc3\x4a\x75\xef\x3a\x08\x46\x40\x55\xc8\xf0\xed\x39\x5e\x92\x63\xe4\xc5\xfb\xbd\x7e\xc7\x2e\x32\x81\x83\x0b\x49\x6e\xa8\x88\x14\x2c\x1d\xa3\x59\xc4\x7d\x4d\x05\x47\xdd\x1e\x5a\xdb\x9b\x31\x13\x12\x75\x4d\x38\x0a\x81\x46\x63\xf8\xf7\x1f\xd2\x0b\xaa\x86\xa1\x14\xa1\x1a\xbe\x60\x0c\x8c\xd5\x90\x11\x3e\xd7\x0b\xb3\xbc\x0f\xdb\xb2\x0e\xcc\x30\xf6\xd3\x68\x3e\xc1\x3c\xa0\x01\x80\x04\x57\x65\x1f\x1f\xe8\xd5\x38\x67\x45\x67\xa8\x9b\xb7\x3a\xc9\xd9\x4d\x22\x29\x09\xd7\x60\x5b\x8c\x67\x46\x66\xe3\x19\xa4\x0a\xbb\xba\xae\x98\x68\x80\x46\x57\xbd\x71\xc9\x5c\x12\x1d\x49\x9e\x9f\x5f\x75\xca\x9f\xb2\xfb\x56\xfd\x94\xd9\x73\xf2\x59\xb7\x65\xf5\xa0\x81\x55\x03\xf1\x4f\x64\x76\x7f\xeb\xcc\x02\xa8\x80\xc8\x2a\x52\x0d\x17\x33\x4a\x58\x70\x29\x3e\x01\x0f\x9b\x4d\x1c\x0a\xa0\x0f\xcb\x2c\x22\xc5\x7c\x0c\x13\xce\x85\x0d\x82\x5c\x79\xbd\x62\x64\x09\xcc\x74\x4b\x7b\xcd\xf0\x02\x7a\xe3\xf5\x9d\x4b\x77\xc8\x37\x85\x19\x97\xa2\x04\x80\x16\xa9\x97\x64\x56\x1c\xad\x63\x36\xc4\x2d\xc7\xf6\x05\x1b\x2c\x83\xc1\xa8\x32\xb4\xf5\xf8\xe3\xbb\xe7\x5c\xec\x3d\x13\xdc\x43\xc4\xf0\x94\xb0\xf5\xdf\x01\xe5\x33\x51\x8b\xdf\x3c\xf1\x9d\xc2\x7f\x84\xa6\x38\x00\xf1\xad\x03\x6d\xcf\xe1\x4e\xa1\xfe\xe7\x81\x87\xa4\x34\xdb\xab\x2a\x77\x33\x8a\x82\x50\x08\x19\x4a\x2a\x24\xd5\xb7\xa6\xa4\xe3\xea\xee\x7a\x17\xf1\xa4\xd7\xcf\xca\x51\x32\x5b\xe0\x4b\x69\xac\x23\x15\xab\x42\xea\xe2\x9d\x9d\xcd\x3b\x58\xcf\x15\xcc\x97\x94\x11\xa5\x05\x27\x39\xf3\x37\xc9\x6c\xde\x43\x3a\x9d\x49\xd9\x08\x53\x08\x57\xad\xbd\x9b\xfb\x88\xc3\xdd\x60\x3f\x6e\x76\x18\x19\xaa\xd6\xff\xff\xd1\x08\xed\xed\xb9\x84\xfd\xe0\x0a\xfd\xd5\x52\xb9\x53\x00\x90\x85\x17\xc6\x17\xbf\x97\x61\x1d\x11\xa6\x48\x1b\x23\xd3\x57\xe0\x29\x23\x41\xd6\xfa\xd1\xa9\xd4\x5e\x7f\xed\xd3\x4c\xc9\x35\x88\xcd\x97\xa6\x14\x4b\x06\xf5\xe9\xb5\xbd\x13\x1c\xe5\xc6\x23\xc6\xf2\x33\xad\x0a\xb8\xa2\x70\x9d\x05\xfb\x2f\xf2\x05\xd7\x98\x72\x22\x9d\xa5\xbb\xfd\xab\xec\x63\xb4\x9c\x0a\x2d\xe1\x9a\x85\x86\x42\x45\xcb\x25\x96\xb7\x5b\xba\xd5\x16\x87\x35\x7a\x55\x26\x33\x3b\x32\x47\xe5\x3d\xd5\xec\xd9\x54\xb5\x35\xca\x97\x44\xf9\x92\x86\xa6\x5f\x69\x2b\xa9\x4f\xf1\x74\xad\xdc\xa9\xca\xe7\x99\x48\xb3\x7b\x35\x95\x5d\xf7\x72\x2a\xab\xe5\xd4\x3a\x35\x89\x6e\xbd\x66\x8e\x5a\x57\x0a\xc8\xcd\x19\x55\xba\x0f\x7e\xec\xa9\x02\x1f\x6f\xf5\x82\x48\xf4\x5a\xa9\x88\xa8\x0a\x46\x8d\x94\x1d\x3b\x14\xcf\xbd\x5b\x70\x58\x9b\x30\xea\x5f\x93\x20\x67\x25\xb8\x8d\xb5\x59\x2d\x99\xaf\x9e\x96\xb7\xd1\xe1\x23\x25\x26\x62\xad\xce\x60\x08\x2f\xad\x6e\x35\xbb\x57\x38\x1b\x92\xd1\xb6\x2d\xd0\xe6\xe6\xab\xe9\x80\xee\x15\xdc\x02\xc0\x35\xf1\xd7\x18\x16\x92\xcc\x20\xeb\xbf\xa1\xad\x10\xdc\x3e\xea\xf8\x18\x14\x5e\xd8\xeb\x70\x3d\x08\x9b\xc5\xa7\x42\xcc\x1b\x20\xae\x61\x7a\x58\x52\x3c\x58\xd0\x20\x20\xdc\x03\xbc\x5a\x46\xf5\xdd\x6d\x1a\xe2\xe7\x97\xaf\xee\xb6\x31\x19\x15\xba\x9c\x3a\x40\x09\x0b\xd5\x6e\xca\x72\x59\xe3\xf8\x77\x1d\x21\x6f\xdd\x2b\xd4\xb2\xf2\xa4\x27\x28\x11\x92\x53\xec\x5f\x37\x3d\x2a\xef\x72\xdd\xe8\x68\x81\x18\x68\xde\x8e\x53\xbd\x69\xe2\x76\x85\xeb\xcc\x8f\x40\x8d\x54\x9b\x7d\xa8\x21\xd4\x0e\x97\xf3\xb7\x86\x72\xbe\xef\xd1\x69\xea\x07\xd2\x6f\xf1\x2b\xd6\xaa\xb3\xea\x8d\x7f\x05\x00\x00\xff\xff\x20\x81\xd8\x6b\x12\x15\x00\x00")
+var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xdd\x4e\x23\x37\x14\xbe\xcf\x53\xb8\x53\x09\x4d\x44\x12\x11\x44\xa5\x8a\x94\x4a\x25\x54\x6a\x25\xa0\x88\xd2\xab\x8a\x0b\x67\xc6\x49\x5c\x3c\xf6\xc8\xf6\xd0\x22\x94\xdb\x5e\xaf\xf6\x09\xf6\x59\xf6\x51\xf6\x49\xf6\xd8\x93\x99\xcc\xff\x0c\x10\x20\xeb\x0b\x48\xec\xf3\xfb\x8d\xcf\x77\xce\xe4\x1e\x4b\x74\x1a\x2d\xae\xf0\x82\xa0\x13\x74\x4d\xb0\xa7\x47\x9e\x24\x58\x93\x29\xc3\x4a\xb9\x8f\x3d\x04\xcb\xa7\x2a\x64\xf8\xe1\x12\x07\xe4\x18\x39\x6b\x79\x67\xd0\xb3\x87\x9e\x08\x42\xc1\x09\xd7\x67\xd4\xbf\x10\x11\xd7\xc7\x68\x1e\x71\x4f\x53\xc1\x91\xdb\x47\xb1\x05\xb3\xf4\x92\xaa\x91\x24\x73\x35\xf2\x89\xf2\x46\x94\x73\x22\x7f\xbb\xb9\x38\x07\xc7\x01\x96\x77\xc4\x77\xad\x44\x28\x45\xa8\x46\x67\x20\x22\x69\x68\xac\xf4\x27\xd6\xc4\x6a\x50\x72\xf7\x57\xe8\x43\xa4\xaf\xeb\x8f\x09\xec\x5f\x49\x72\x4f\x45\xa4\x20\xf3\x3a\x67\x73\x21\x91\x6b\xd0\xa4\x60\x7e\x3c\x81\x7f\x3f\xa1\x8c\xf9\x5f\x18\x03\x65\x35\x62\x84\x2f\xf4\xd2\x1c\xef\x83\x58\xd6\x80\x59\x46\x7f\x16\x2d\xa6\x98\xfb\xd4\x64\x06\xa6\xca\x36\xfe\xa6\xb7\x93\x9c\x16\x9d\x23\x37\xaf\x75\x92\xd3\x9b\x46\x52\x02\x5e\xa0\x5b\xf4\x97\xa2\x14\x0b\x9e\x43\xaa\x20\xe5\x56\xf9\x44\x43\x34\xbe\xed\x4f\x4a\xea\x92\xe8\x48\xf2\xfc\xfe\xaa\x57\xfe\x94\x95\xcb\x20\x7b\x49\xfe\xd3\x5d\x51\x3d\x68\x41\xd5\x84\xf8\x2d\x22\xbb\xbf\x75\x64\x21\x28\x9f\xc8\x3a\x50\x0d\x16\x73\x4a\x98\x7f\x2d\xfe\x05\x1c\x36\x42\x1c\xea\x7b\x00\xc7\x2c\x22\xc5\x7c\x0c\x12\x95\x07\x9b\x08\x72\xec\xf1\x2b\x23\x01\x20\xe3\x96\x64\xcd\x72\x7c\x7a\xef\x0c\x2a\x8f\x1e\x91\x67\x78\x67\xcd\x34\x12\x02\xb4\x91\x3a\x49\x66\xc5\xd5\xd9\x67\x8b\xdf\xb2\x6f\x4f\xb0\x61\xe0\x0f\xc7\xb5\xae\xad\xc5\xcf\x9f\x9c\xca\xc3\xfe\x3b\x85\x7b\x88\x18\x9e\x11\x16\xff\x1d\x52\x3e\x17\x8d\xf1\x9b\x27\xbe\x53\xf1\x1f\xa1\x19\xf6\xa1\xb7\x34\x05\x6d\xef\xe1\x4e\x45\xfd\xc3\x33\x2f\x49\x69\xb7\x5f\x57\xee\x66\x15\x09\xa1\xe0\x32\x94\x54\x48\xaa\x1f\x4c\x49\xaf\xab\xdb\x75\xae\xd6\x9b\xce\x20\x4b\x47\xc9\x6e\x01\x2f\xa5\xb1\x8e\xd4\x9a\x15\x52\x13\x7f\xda\xdd\xbc\x81\x78\xaf\xa0\x1e\x50\x46\x94\x86\xde\x9c\x53\xbf\x48\x76\xf3\x16\xd2\xed\x4c\xca\x86\x98\x42\x68\xb5\x76\xf4\x18\x20\x0e\xbd\xc1\x7e\xdc\x48\x18\x1a\xaa\xe7\xff\x9f\xd1\x18\xed\xed\x55\x11\xfb\xc1\x2d\xfa\xae\x23\x73\xa7\x01\x40\x16\x4e\xb8\x6e\xfc\x4e\x06\x75\x44\x98\x22\x5d\x94\xcc\xd8\x84\x67\x8c\xf8\x59\xed\x17\xa7\xd2\xd8\xfe\xba\xa7\x99\x82\x6b\x22\x36\x5f\xda\x52\x2c\x29\x34\xa7\xd7\xb5\x27\x54\x94\x1b\x8f\x18\xcb\xef\x74\x2a\xe0\x9a\xc2\xad\x2c\xd8\x1f\x61\x8c\xe4\x1a\x53\x98\x08\x2b\x4b\x77\xfb\xad\xec\x9f\x28\x98\x09\x2d\xa1\xcd\xc2\x40\xa1\xa2\x00\x26\xd0\x87\x2d\x75\xb5\xe5\x61\x03\x5f\x95\xc1\xcc\xae\xcc\x55\xb9\xa1\x9a\xbd\x23\xab\xc2\x9c\x0e\x28\x99\x41\xbd\x91\x4b\xab\x27\xf6\xae\xec\xfa\x16\x0f\xda\x32\x9f\xaa\x4d\x22\x61\xe9\xea\xd3\x94\x81\xab\x8f\x53\x86\x2d\xa7\xd6\x6b\x48\x74\xeb\xe5\x73\xd4\xb9\x68\x80\x79\xce\xa9\xd2\x03\xb0\x63\x2f\x18\xd8\xf8\x43\x2f\x89\x44\xbf\x2b\x15\x11\x55\x83\xa8\x61\xb5\xe3\x0a\xf2\xab\x96\x16\x1c\xce\xa6\x8c\x7a\xf0\x4a\x97\xd3\x12\xdc\xfa\xda\x9c\x96\xd4\x57\x6f\x8b\xdb\xf8\xf0\x85\x6c\x13\xb1\x4e\x77\x30\x84\xd7\xf3\x6a\x62\x7b\x92\x3b\xeb\x92\xd1\xae\xd3\xd0\xa6\x09\x36\x14\xf0\x93\x9c\xdb\x00\x70\x83\xff\x38\x86\x65\x4c\x1e\xdf\xc3\x84\x21\xb8\x7d\xd4\xeb\x6b\x50\x78\x77\x6f\x8a\xeb\x59\xb1\xd9\xf8\x54\x88\x79\x4b\x88\x71\x98\x0e\x96\x14\x0f\x97\xd4\xf7\x09\x77\x20\x5e\x2d\xa3\xe6\x41\x37\x75\xf1\xe5\xff\x0f\xd5\x13\x64\xb2\x6a\x28\x3a\x35\x80\x12\x14\xea\xcd\x94\xe9\xb2\xc1\xf0\x6b\x5d\x21\x27\x1e\x1b\x1a\x51\x79\xd3\x1b\x94\x10\xc9\x29\xf6\xee\xda\x1e\x95\x73\x1d\xcf\x3c\x5a\x20\x06\x9c\xb7\xe3\x50\x6f\xe6\xb9\x5d\xc1\x3a\xf3\x7b\x50\x2b\xd4\x46\x0e\xb5\xb8\xda\xe1\x72\xfe\xd8\x52\xce\x4f\xbd\x3a\x6d\xf3\x40\xfa\x2d\xf9\x6d\xb3\xb7\xea\x4f\xbe\x06\x00\x00\xff\xff\xf4\x90\x3c\x91\xfc\x15\x00\x00")
func jsBugpageJsBytes() ([]byte, error) {
return bindataRead(
@@ -125,7 +126,27 @@ func jsBugpageJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugPage.js", size: 5394, mode: os.FileMode(436), modTime: time.Unix(1453344687, 0)}
+ info := bindataFileInfo{name: "js/BugPage.js", size: 5628, mode: os.FileMode(436), modTime: time.Unix(1453424896, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _jsMarkedMinJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xec\x3c\x4d\x73\xe3\x46\x76\xf7\xfd\x15\x10\xc6\x45\x01\x24\x48\x4a\x33\x8e\x93\x90\x82\xe8\xad\xa9\x3d\x38\x35\x5b\x76\xad\x9d\x13\x41\x69\x40\x12\x22\xa1\x01\x01\x1a\x00\x47\x52\x08\x4c\xed\x7f\x48\x0e\x49\x55\x72\xcd\x0f\xdb\x5f\x92\xf7\xd1\x0d\x74\x83\x20\x25\x79\x67\x2f\xa9\xb5\x4b\x24\xd0\xfd\xbe\xfb\xf5\xeb\xd7\xaf\x9b\x33\xec\x76\x7f\x67\x74\x8d\x8d\x9f\x7e\x0a\x96\x46\xdf\xf0\xe9\x71\x99\x3c\xc4\xc6\xd6\x4f\xb3\x20\xc5\xde\xf7\xc9\xf6\x29\x0d\x57\xeb\xdc\xb0\x16\xb6\xf1\xf6\xe2\xf2\xb2\x0f\x1f\xdf\x3a\xc6\xfb\x75\x1a\x66\x79\xb2\x5d\x07\xa9\xf1\x2f\xc1\xdd\x5d\x1a\x3c\x0d\x0c\xeb\x8f\x3f\xfc\x62\x7c\x08\x17\x41\x9c\x05\x4b\x1b\xf1\xd7\x79\xbe\xcd\x46\xc3\xe1\x2a\xcc\xd7\xbb\xf9\x60\x91\x6c\x86\x8b\xf5\xfd\xfd\x90\xb9\x02\xc4\xf0\x77\xd6\xdd\x2e\x5e\xe4\x61\x12\x5b\xf6\xfe\xb3\x9f\x1a\xf3\x28\x59\x7c\x72\xf7\x71\xf0\x10\x85\x71\x30\x1a\xde\x78\x71\x6f\xe8\x2c\x92\x25\x3e\x5b\xc6\xfe\xdb\x72\x0a\x4d\xb3\x9e\x17\x77\x6d\xe8\xb8\x0b\xe2\x45\x90\x8d\xe2\x24\xd9\x3a\xeb\x94\x40\xba\xd3\x7e\xf7\x76\x66\xef\xdf\x39\xa5\xd1\xb5\x26\x23\x20\x50\x7c\x63\x0f\x9d\x75\xe0\x2f\xc3\x78\x05\x30\xd0\xfc\x66\x7f\xe9\x7c\x57\xda\xf0\xc4\xe4\x26\xf0\xf8\xa6\xab\xc1\xc7\xdb\xdc\x9f\x47\x01\xd3\x8e\x6a\x6c\x81\x61\x7b\x31\x80\xbb\x45\xdf\xde\xbf\x6d\x70\x22\x1d\x7e\xdd\x25\x39\xcb\xdc\xbd\x66\x0c\xcb\x8b\xad\xc9\xd9\x32\xb8\xb3\x05\x85\xae\x50\x22\x02\x5b\x32\xa4\x6d\xcd\x77\x51\x64\x1b\x53\x2f\xf3\x7e\x06\xa9\x80\xe8\x3a\x2d\x00\xa5\xf0\x62\x64\x03\xf8\x86\x0d\x1f\xde\x25\xc2\x19\x20\x43\xb7\xf0\xb2\x2e\xa9\x97\x6f\x22\xd6\x6d\x32\x02\x43\x6f\x82\x38\x17\x42\x31\x44\xb1\x88\x12\x18\x17\xd1\x86\xc4\x94\x76\xd0\xec\xa0\x03\x68\x02\x63\x22\xe9\x4d\x51\xe9\x19\x2a\x3d\x1b\x19\xdd\xab\x09\xbe\x66\xd7\xf0\x7e\x8d\x22\x1a\xbd\xa9\x69\xcd\xa4\x5d\xa6\xa6\x3d\xb3\x27\x9a\x41\x14\x43\x82\x73\xf9\xab\xd4\xdf\xae\x51\x61\x00\x91\xa3\x09\x74\xce\x40\x55\x61\xe6\x42\xda\xbb\xa8\x6d\x59\xe4\xfe\x0a\x4d\x61\xdb\x68\xfb\x2e\x50\x0d\x1e\xd1\x6c\x4c\x61\x58\x8e\x09\x74\x80\x86\x09\x72\x77\x88\xb4\xbb\xbd\xfe\xac\xf0\x96\x3d\x6f\x60\x0f\x45\x77\x98\x07\x1b\x57\xb7\x35\xe2\xb3\xb4\x8a\x65\xb9\xd5\xee\x6a\x78\x69\xb0\x8d\xfc\x45\x60\xd5\x4d\x8e\xb9\xda\x98\xb6\x35\x44\xa4\xe1\xca\x51\x45\xb0\x2d\x5b\xe0\xe2\xf8\x36\x70\xb1\xe9\x18\x9a\xb9\x4e\x4d\xc7\xf4\xc0\x78\xd6\xc4\xf5\xbc\x4b\x34\x31\xf9\x34\xc8\x8c\x5e\x8d\xa2\xb2\x65\x6d\x60\x6d\x82\x49\x6a\x70\xb3\xc7\xb4\xa0\x71\x90\x25\xbb\x74\x11\xf4\x4c\x84\x92\xa2\xd4\xe6\x6c\x08\x54\x77\x48\x92\x15\xa1\x1a\xfb\x16\x86\xc0\x35\xc1\x4a\x20\x82\xd9\x33\xfd\x22\xd8\x14\x59\x9e\x26\x30\x4e\xd9\xc6\x8f\xa2\x22\x2b\x16\x60\x95\xe2\xd7\x62\x79\x17\x17\xfe\x7c\x0e\xbe\xeb\xe7\x7e\x91\x87\x9b\xa0\xc0\x39\x0c\x48\x05\xcc\xf2\x22\xf3\x37\xdb\xe2\xd3\x7c\x59\x64\xbb\x39\xfc\x6d\x8b\xb0\x98\x17\xbb\x02\xe3\x42\x91\xee\xe6\x4f\x45\x9a\x17\xe9\xb6\x98\x2f\xa1\x7d\x99\x20\x56\xb6\xf5\xe3\x02\xe8\x3d\xc0\x5f\x18\x67\xe0\x08\x51\x11\x6e\x56\xb6\xe7\xcd\xe1\xef\x01\x74\x3f\x1b\x0d\x0b\x18\x35\xef\xc1\xf3\xb2\xef\x67\xdd\xef\xb1\xcb\x14\x82\xe3\xe4\x68\x28\x8c\x4d\xa0\xaa\x98\x2a\xa6\x33\xbc\x3a\xeb\xf7\x79\xde\x75\x27\xfd\xfe\xf5\x10\x3b\x69\xca\x60\x9f\x05\x9a\xdb\x72\x56\x5e\x79\x43\xef\xb2\x02\x00\x2f\x45\x08\x00\x40\xab\x4c\x6f\xcc\x59\xd7\x2c\xce\xa7\x37\xe7\xb3\xee\x39\x08\x74\x6e\x5e\xcf\xec\xee\x04\xc1\x87\x00\x53\x8d\x36\xda\xb2\xb6\x6c\x35\x2d\x1a\x52\x56\xed\xc2\x2d\x84\xec\x29\xbe\xf2\x0c\xa9\xda\xf8\x15\x3a\xa2\x46\x4f\x54\x77\xd5\xa3\x2c\x3b\xb5\x71\x07\x91\xc0\x95\xae\xa4\x13\xb1\x88\x47\xbd\x21\x4e\x52\x18\x74\x77\x13\xa4\xab\xc0\xda\x97\x0c\x22\x3b\x57\x77\x9b\x46\x8f\x80\x77\xf6\x22\x66\x53\xac\xfa\x88\x0e\x5d\x7c\xc1\x4f\x7b\x6a\x78\x03\x98\x88\xde\xcf\x3d\x0c\x1f\x30\x1b\xe5\x68\xd8\x10\x8f\xbc\x4b\x2d\xa2\xa8\x61\xe4\x48\x68\xef\x1d\x0d\xed\xa5\x22\xe4\x8b\x2c\x0f\xce\x05\x76\xc1\xcf\x5e\x8d\xc8\x6a\x88\x59\x36\x90\xc8\x30\x11\x2f\x69\x3a\xbe\x35\x6d\x70\x5b\x89\x80\xf3\xfd\x28\xe8\x3b\x06\xad\x2d\x4b\xf1\x32\x6b\xda\x0f\x98\x3a\x7b\xb9\x2a\x91\xaa\xde\xcf\x83\xae\x57\x0c\xba\xbc\x16\x4d\xfb\xa3\x59\x0f\x0c\x57\x4c\xfb\x85\x31\x9a\x61\x2b\x46\x58\x06\xe1\x95\x00\x42\x46\x57\x04\xcf\x8a\x8a\x57\x58\x03\x5e\xcd\xe0\x09\x57\x4f\xa0\xa2\x53\x30\xda\x28\x80\x11\xe5\xd2\x6d\x7c\x08\x1e\x83\xd4\x4a\xb6\xf8\x92\xd9\xfb\x7c\x1d\x66\x83\x3c\xf9\x04\x89\x80\x3b\x9d\x8d\x95\x57\xb0\x43\xfc\x29\x73\xf7\x25\x37\x0a\x0c\x57\x7c\x17\x05\x27\x06\xe8\x66\xfe\x2e\xca\x33\x86\x4a\x77\x68\x0c\xd5\x87\xc6\xe1\x9d\xa5\x12\x40\xd3\xd8\xfb\x66\x23\x5b\x51\x88\xa3\x12\xe1\x8e\x32\x88\xb2\xe0\xb0\x13\x48\x95\x65\x49\x1a\xa9\xed\x63\x6e\x89\x82\x47\xb7\xca\x58\xb2\x74\xe1\x54\x4a\x63\xf2\x12\x21\x8c\x0b\xb9\x4b\xc3\x22\xe3\x34\xc8\x77\x69\xcc\xfd\x48\x03\x51\xed\x52\xd0\xdc\xa6\x49\x9e\xe4\x4f\xdb\xe0\x80\xba\xbd\x87\x0f\x17\xfe\x2a\x9f\x19\x7a\x29\x2e\xe8\x29\x84\x11\xd3\x8b\x4d\x5b\xe9\xc8\xb1\xcd\x80\xff\xb4\xd6\xdd\xc5\x85\x7f\x41\x3d\x7a\xf3\xdb\x6f\xdf\x7e\x2b\x89\x48\xf1\xea\x81\x22\xd5\xf2\x74\x17\xb4\x08\x49\x00\xba\x11\x20\x13\x74\xe6\xbf\xb2\x0d\x0e\x24\xbe\x31\x7a\xdf\x0c\x57\xb0\x52\x9a\xb6\x13\xc3\x92\xed\x44\x09\x44\x55\x67\xe1\x03\x0e\xac\x78\xce\xdc\xa1\x85\x14\x02\xfc\x22\x70\x42\x27\x1a\x3f\xac\xc3\x28\x60\xf5\x61\x48\x01\xce\xad\x07\x69\x20\x12\xc3\x01\x08\xb5\x20\x98\xda\x46\xb0\x96\xc0\x62\x04\x71\x00\x71\xa6\x17\x33\x30\x67\xbc\xca\xd7\xf6\x98\xa9\xd4\x2d\xd7\x97\x9a\x8f\x0e\xb6\xbb\x6c\x6d\xed\x51\xb9\x91\x49\x62\x98\xa5\x5d\x96\x87\xbc\x71\x05\x7b\x15\x63\xc4\x17\x4d\x8a\x39\x20\x87\x15\xf6\x18\x1f\x93\x82\xd6\x4a\x4e\x70\xce\x34\x9f\xde\x06\x4b\x3f\xce\xc3\xc5\x04\xc8\x2a\xc3\x19\x83\x89\x91\xe0\x08\x9a\x61\x62\x2e\x12\x80\x89\x77\x41\x8b\x0e\x22\x6a\xbd\x46\x8b\xd3\x42\x46\x3e\x04\x5e\xc4\x78\x3b\x63\x81\xf1\xf9\xdd\xac\x28\x4c\xf3\xb4\x24\x22\x68\x7f\x15\x51\xaa\x15\x6f\x19\x6c\xf3\x35\x89\x70\x29\xb1\x6a\xa9\xde\xce\x1a\x12\x81\xdf\x76\x3a\x07\x1e\xc6\x11\x56\x91\xeb\x25\x2e\x86\xe9\xa1\x10\x86\xd0\x4d\x5a\x94\x82\x54\xca\xa2\x8c\x7f\xb7\xc0\x80\x6a\x74\xbf\xc1\xf9\x07\xb3\x32\xdb\x46\x61\x6e\x0d\xb9\x71\x68\x3b\x7e\x14\xae\x62\x21\xb0\x8e\x77\x0a\x6b\x11\x44\x51\x26\x8c\xaf\x7a\x06\x3b\x86\x00\xa7\xe9\x5e\x8e\xef\x92\xd4\x0a\xdd\x8b\x71\x78\x85\x72\x0f\x88\xa1\x50\x65\x1c\xf6\x7a\x34\xef\x90\x61\xbf\x37\x42\x86\x83\x3c\xc8\x72\xab\x06\x9d\x86\x33\xb0\x89\xf6\xee\x9a\xb4\x4f\x34\x29\xa8\x1a\x02\x7d\xf4\x1a\x7c\xd8\x36\xe6\x41\x7a\x40\xe0\xc5\xf8\x51\x70\x27\xd8\x37\x7a\x62\x08\x32\x65\xd9\x50\x99\xac\xa5\xab\x5c\x35\x23\x92\xf6\xd6\xb4\x75\x79\xe0\x86\x08\x7e\xd2\xd9\xa3\xbf\xb1\xb7\xbf\x9d\xb9\xae\x6b\xba\xe6\xe4\x72\xf4\xb6\x76\xf8\xcb\xa6\xc3\x37\xa7\x60\xfa\x75\xe4\x49\x9f\x99\xea\x75\x92\xf9\x55\xf8\xd5\xe4\x6e\xb3\xdc\x4f\x73\xe2\xde\x1a\x6a\xbb\xd7\xc6\xe4\x30\xd6\x22\x1f\x5a\xb3\x68\x85\x7b\x09\x9b\x20\x5e\x3e\xa3\x22\x25\x78\xaf\x51\x0e\xd7\x3e\x97\x87\xee\xa8\x04\x48\x54\xa8\xe8\x24\x29\x44\x93\x60\x39\x42\xbc\x6a\x1d\xd3\x15\xdf\xf8\xf9\x62\x6d\x29\x42\xb1\x5b\xe2\xa2\xeb\xde\xf9\x30\x33\xc6\xc4\xb1\x72\x7b\x98\x0e\x38\x2d\x60\x4e\x44\xf5\x1c\x20\x62\xe1\x6c\x4c\x0b\x21\xcf\x03\x09\x8f\xbd\xd4\xa0\x5a\xd8\x52\x77\xd9\x46\x8f\xa2\x0d\xae\xb8\x5f\x08\x32\x8c\x97\xc1\xe3\x8f\x77\x18\x78\x20\x01\x01\xb3\x20\xd5\xfe\x21\xd9\x23\xab\x9c\xc6\x0d\xf3\xaa\x3f\x05\xab\x3f\x3c\x6e\x2d\x13\x56\xd1\x4b\xc7\xec\x11\xb9\x9e\x59\x9a\xbc\x0f\xa7\x25\xb0\x29\x21\x00\x56\x0b\x6e\xd9\xcc\x11\x61\xdb\x9a\xe6\x1f\xc0\xcc\x59\xa7\x13\x9e\xb9\x6e\xd4\x87\xdc\x60\xee\xaa\x1b\x72\x1e\x55\xb2\x4a\xef\x72\x66\x83\xa1\x51\x3d\xec\x03\xf8\x79\xa7\x73\x66\x69\x43\xd2\xe9\xcc\xeb\x34\x83\xfd\x00\x6d\x9e\x45\x21\x88\x03\x14\xec\xc1\x7d\x12\xc6\x1c\x89\x7b\xd0\x0b\xc3\x00\x4c\xcb\x92\xb2\x22\x17\xc7\xaa\x28\x20\x6c\x73\x31\x82\x4a\x3b\x75\xf8\x23\xc3\x56\x62\xd2\xb8\x72\xa0\x5a\xfb\xe9\xef\x45\x84\x64\xde\xd0\x8f\x01\x01\x98\x20\xca\x19\x11\xb7\x6b\x16\x87\x11\x8c\x3d\x8e\x20\x26\x26\x7d\xdd\x22\x39\xe1\x7d\xc2\x15\x95\x96\x52\x9b\x50\x94\xc1\x91\x8b\x61\x1e\x78\xda\x9f\x89\x08\x4f\xa8\x63\x62\x30\xe0\xf3\x93\x0e\xf7\xf0\x5f\x23\xa2\xe8\x2e\xe1\xc7\x61\x1e\xfe\x1b\x98\xa1\xda\x02\x82\xfe\xc8\xca\x74\xb6\x69\xd0\x48\xc8\x24\x74\xca\x89\x04\x84\x5c\xb4\x3b\xc0\x99\x45\x51\xbf\x67\x8b\x34\xdc\xe6\x7a\x53\xfe\x04\x59\x82\x5d\x07\xeb\x8b\x66\xb0\x3e\x9b\xff\xda\xe9\xb4\xa6\x28\x58\xdd\x79\x55\x7a\x72\xb0\x05\x9b\x8a\xb4\x24\x4f\x3e\x24\x0f\x41\xfa\xde\xcf\x02\xcb\x9e\xb9\xfb\x75\x1a\xdc\x55\xd9\x5c\x98\xc3\x16\x91\x33\x8a\xf2\xf9\xbc\xe9\xff\x51\xd6\x24\xf6\xbc\x46\xd7\x9e\xfc\x3d\x81\xfa\x1a\x09\x94\x3a\x1e\x68\xd7\xd3\x63\xf9\x92\xfc\xaa\xd5\x05\xab\x09\xfb\xdb\x67\x87\x1a\x85\xea\xf9\xaf\xa6\x54\x32\xda\x6a\x9b\x8c\x3a\xde\x4e\x44\x3b\x07\xfc\x0b\x07\x7a\x5e\x94\x8b\x21\x87\xaf\x92\x1d\x21\x21\xf3\x44\x58\xa1\x8d\x75\xbe\x4e\x93\x07\x03\x57\xd4\x3f\xa4\x29\x8c\xac\xf9\x43\x7c\x17\x42\x24\x0b\x0c\x88\xfd\x5b\x23\x89\x8d\xf9\x53\x1e\x8c\x0c\x13\x97\x28\xd2\xf8\x3d\xec\xf6\x40\xeb\x0b\x1b\xb6\xc6\x07\xf5\x82\xac\x1c\xe3\xde\x3f\x8c\x71\x6f\xee\xee\x83\x0c\x38\xd3\xe1\x8d\x67\x4d\x3d\xef\x63\x77\x5f\x7a\x53\x6f\x66\xd9\x6f\x7a\x5e\x7f\x70\x76\x7b\x3d\xb3\x87\x8e\xbf\xcb\x13\x8c\x45\x00\x76\x65\x4d\x6f\x8c\xeb\x59\xcf\xfa\xbe\x18\x79\x43\x9b\x5f\xec\xeb\xa1\xb3\x4b\x23\x3e\x36\xc8\x7d\xac\xee\x35\x4a\xb4\xc5\xcd\x95\x37\x9c\x50\xf1\xf7\x54\xe1\xd5\x11\x5c\xce\x26\xde\xd4\x0a\xe3\x2c\x5c\x06\xb6\x37\xf3\x2c\x8c\x75\x1e\x08\x02\x5f\xed\x10\x59\x75\xf0\xd1\x85\xd7\xa1\x13\x27\x2a\x1c\xd6\xc3\xa6\xdc\xeb\xcd\xb0\xf2\x0c\x1a\xce\x6c\x86\xe4\xa2\x38\x40\xde\xde\x5a\xb2\x6a\x6c\xc3\xf3\xe4\xec\xd6\x2e\x6e\xbc\xae\xd7\xad\x9b\xe9\x0d\xd6\xfa\x2e\x88\x12\x6c\xd0\x68\xf3\x5b\x3e\x19\xb9\x9d\x15\xb7\xb7\x36\x62\x7a\x73\xc4\x22\x96\x00\x5d\x30\xae\x4d\xc8\x12\x55\x1e\x91\x7d\xec\x61\xb9\xb4\xaa\x9d\x4e\x6f\x3e\xce\xb8\x7e\x0a\x80\x1f\xf1\x70\x0a\x4f\xc9\x0c\x3c\xe6\x51\x52\x0c\xd8\x49\x48\x43\x8b\x43\x95\xea\x00\xca\x85\x01\xbc\x3a\xf3\xa6\xb7\xdd\x8f\xb3\x42\xe0\x51\x11\x75\xcc\xa3\x3d\xb8\x65\x83\xd1\x89\xcb\xa1\x41\x0a\x18\x76\xa0\x01\x2f\xd8\x6a\xe3\x81\x8a\xc4\x43\xfb\xbb\x43\x10\x00\xcf\x93\x64\xa9\x97\x0e\x94\xbc\xac\x37\x3d\x37\x67\x75\x2b\xbe\x41\x2c\xce\x6a\x6c\x1c\x89\xaa\x62\xab\xb4\xd9\x96\xc9\xf2\x98\x8e\x2e\x1f\x15\xd0\xb1\x92\xad\xb2\xc7\x92\xab\x78\x17\x5e\xd0\xa4\x29\x9a\x4f\x90\xad\x28\x34\xeb\xe1\xdc\x5c\x75\xcb\xa4\xb6\x09\x50\xd5\xc5\x55\xa7\x99\xb8\xde\xcf\x76\xa5\x3f\x3c\xeb\xce\x73\xd0\x7d\xe0\x44\x6d\x24\x2a\x0a\x6d\xf8\x02\xbb\xac\xe4\xd5\x2a\xf8\x0d\x51\xc5\x04\x6f\xd8\x8a\x5b\xc1\x54\x33\x1b\x12\xf2\x2f\xc5\x8c\x4e\x9e\x68\x12\x83\x63\xd2\x61\x30\x8c\xed\xd0\x1b\xe2\xe9\xe1\xd5\xac\x37\xbd\xb9\x1a\x38\xa3\xb1\x79\x4e\x93\x6d\x26\xdc\x70\x78\xf3\xe5\xcb\xa1\x80\x5f\xbe\x88\x03\xbf\x06\x4f\x6c\x43\x8e\x05\x72\x9c\x61\x11\xdd\xc4\xc7\x42\x70\x1b\x0e\xa9\xae\x5e\x6b\x35\x4f\x03\xff\x53\x76\xa0\x18\xd5\xd6\x61\x6a\x34\xa8\xcf\xf1\xa0\x05\x7d\x1e\x48\x76\x49\x99\x36\x19\xf0\x34\x40\xc8\xa1\xc2\xaa\x15\xf2\x1f\x08\x92\xab\xc2\x94\x80\x39\x7a\xb5\xfc\x65\x95\x70\xae\x9e\xd3\xa7\x5a\x1a\xd7\x06\x47\x74\x40\xf2\x0c\xdb\xc5\xd4\xd5\x92\x55\xd9\x5a\x14\xbc\x97\xe2\x37\x1d\xa3\x12\x45\xc5\xa4\x4d\x44\x2d\x42\xcb\xfa\xf1\x0b\x2d\x03\x86\x9f\xa6\xfe\x93\x91\x06\xbf\xee\xc2\x34\x80\x57\xe3\x23\x21\x7c\x34\xb6\x69\xb2\x0d\xd2\xfc\x69\xd0\xb2\x09\x6b\xad\xde\xf3\x40\x69\xd5\x7b\x6d\x08\x0f\xca\xf7\xf5\x60\x94\x55\x0e\xd4\xba\xab\x6c\xa3\x29\xfb\xca\x52\x19\x29\x0d\x64\xac\x76\x24\xbb\x7c\xbb\xcb\xf5\x22\x78\x63\x58\x95\xf5\x10\xcd\x74\xdc\x01\x64\xf5\x5d\x48\xc2\xa4\xc5\x01\x81\xca\xb3\xae\xc0\xb7\x70\x67\x7e\xd0\xe1\x9a\x26\x49\x42\x8e\xea\x60\x8c\xc3\x4a\xfb\xe9\x9a\x3a\xcf\xdb\x57\x25\x1f\xc0\xa9\xe7\x72\x5a\x73\x2a\xa9\x91\x6b\xfc\x6f\x29\xd7\x73\x49\xeb\x7b\x13\x86\x0b\x37\xba\x7a\xf2\xf5\x1d\xa5\x5b\x23\x73\x42\xcc\x36\x7e\xbc\x02\xf5\x64\xe6\x55\x11\xfe\x47\xdb\x1e\x1d\x02\xd8\x63\x5a\x79\xd4\x0e\x73\xe3\x87\x51\x9e\x8c\x60\x4b\x8e\xcc\x84\x6f\x21\x5b\xb6\x4d\x03\x13\x41\xc8\x02\xfa\xcc\x41\x4d\x29\xab\x70\x30\x65\xa6\x11\x68\xec\xe8\x08\x3e\x8c\x3f\x00\xe0\x61\xf6\x0a\x71\xf2\x95\x79\xeb\x29\x01\xc7\xbf\x45\xc0\x83\x2d\x9d\x56\xb0\x3c\xd0\x00\x32\x32\xdf\x18\x86\xbc\xbd\x60\xe1\x6c\x31\xbb\x18\xc4\xc5\x0a\x9b\x3e\x1b\x15\x5c\x6f\xe8\x5f\x9f\xc4\xa6\x8a\x42\xf9\x32\x67\x6c\xdf\xc3\xb7\xef\xd5\x8f\x34\x4b\x21\x46\x8a\x4d\xf1\x95\xbf\x4f\x57\xff\x5e\xe9\xe3\x4d\x1b\xa9\x3a\xd0\xec\xc6\x1e\xaa\x53\x1e\xdf\x92\xeb\x54\xb8\xc0\xa7\xca\xd8\x14\x52\xa4\x32\x8a\x9c\x45\x71\x70\xf8\xd1\x9c\xae\x2f\xd0\x85\xd2\x26\x31\x65\x65\x85\x43\x3d\x6b\xcc\x7a\xe2\xfc\x91\x21\xeb\x65\x64\x4a\xbc\xf4\x12\x04\x97\xab\xa0\xbd\x28\xe8\x6b\x40\x69\xda\xbe\x8a\x37\x17\x55\x08\xb8\xb0\xc7\xa2\xb8\x86\x8d\xb5\x74\x97\x5c\x56\xab\x2c\xf1\x72\x53\x53\xa2\xf7\x8c\x51\x1b\xf6\xe2\x9c\xed\xf5\xa1\x53\x9f\x97\x4c\xc5\x52\x64\x6a\x9a\xf3\xe4\x34\x85\x9d\xf6\x5f\x29\x40\xb0\xf9\xcd\xcc\x5f\x7d\x28\xda\xc2\x1e\x69\xe0\x05\x1f\x4b\x99\x78\xe8\xed\x58\x9e\x3f\x7d\xb0\xf0\xba\x03\x8c\x16\xd6\xf3\xd4\x3a\xc9\x01\x32\xd2\xbf\x96\x05\x90\x38\xb0\xee\x73\x56\x7d\x75\x35\xa0\x85\x2f\xd2\x90\x16\xa5\x1e\x2a\x76\x3f\x81\x9d\xf3\xac\x8a\xb7\x7f\xab\xda\x00\xc8\x73\x3a\x7d\xe1\xf9\x25\x53\x98\x6a\xfa\x51\x1e\x43\x8b\x98\x90\xbc\x0e\x02\x1c\xfd\x5c\x0e\x1a\xf8\x38\x51\x41\xa8\xc5\x1e\xe1\xc2\x26\x33\xaa\x66\xbc\x38\x83\x94\xe1\x4c\xa4\x0c\x2d\x6b\x22\x51\x70\xda\x46\x6a\xa4\xa3\x84\x1b\x1f\x36\x0f\x0a\x8e\xbe\x06\x1f\xcd\xdb\x14\xfb\xd7\x9a\xd3\x22\x5c\x2f\xad\xda\xc1\x04\xc3\xda\xb2\xdc\x82\xab\xba\xf2\x5c\x87\xd8\x7e\xbf\x8f\x21\xf6\x2f\x7f\xfe\x0f\xf5\x92\x87\x6c\xfc\x77\xb5\xd1\xba\x29\xa6\x7d\x6f\x87\xd7\x78\x87\x96\x37\xdd\x9b\xb8\xf1\x3a\x47\xc0\x6f\x2e\xff\xf2\xe7\xff\x54\x41\xcf\x19\xfd\xbf\x4e\xa1\xd3\xe3\x3f\x21\x0d\x53\xd2\xf8\x6f\x15\xde\x64\x1a\xff\xa3\x5d\x3e\x19\xec\xdf\x95\xdc\xfe\xbf\xe6\x51\x63\x71\x66\xf6\xac\x9d\x18\x4c\x33\x91\x9a\x09\x53\x2a\x24\x2f\x02\x84\xee\x85\xb3\x58\x37\xce\xbc\x16\x6b\x86\x51\xfc\x38\xa4\x1c\xf4\x8f\x7e\xbe\x1e\xa4\x7e\xbc\x4c\x36\x96\x7d\x3d\xf8\x07\x02\x35\x1f\xcd\xde\x62\x0d\x6b\xd6\xcf\x62\xb1\xf9\xce\xe6\x4c\xd0\xec\xbc\xc1\x9e\x9e\x39\x36\xb5\x29\x50\xed\x00\xe5\x6e\xcb\x7a\x66\xe3\xb7\x2f\x4b\x09\xaa\x58\x03\x23\xa4\x32\x5b\xe0\x8d\x2e\x5e\x08\xcf\x5b\x1e\x6e\x9f\xd6\xe1\x6a\x1d\x61\x45\xb9\xde\x19\xb4\xf7\xd7\xc4\x48\x6b\x00\x3c\xa3\x8a\x6f\xa7\x43\x8f\x2e\x76\xdb\x62\xc3\xbf\xe4\x05\x94\x84\x41\xed\x28\xa7\x25\xd4\x3d\xeb\x6c\x5e\x6d\xd3\xe0\xfa\x0a\x01\xae\xcd\x9e\x08\x3e\xcb\x09\xd5\xa6\xe4\x24\x41\x76\x1c\xd9\x7b\xa6\x17\x5f\x0d\x09\xf8\x6a\x88\x88\xd2\x74\xe7\x35\x19\x63\x11\xf9\x59\xe6\x9a\xe7\x3d\x4d\x7c\x64\xfa\x13\x4c\xc0\xf0\xb1\x27\x83\x00\x9a\x83\xe8\xf6\xce\xcd\xeb\xf3\xd7\x33\xf7\x62\xb3\x1c\xb7\x98\x5e\xb9\x32\x5b\x0d\x00\x5f\x98\xac\x94\xae\x41\x90\x4a\x8f\x9e\x7a\xe6\xd5\x50\x6f\x6f\xa5\x4e\x37\x53\x2b\xba\x74\x29\x55\x90\x35\xf0\xa5\x1d\x87\xcf\xff\xf5\xb9\xe1\x44\xc1\xe7\x20\x72\x52\xff\xa1\x96\x6b\x6d\xf6\xa8\xb5\x77\x6e\x84\xcb\x03\x1b\xf2\x51\x8b\xb0\x22\xe0\xe9\x99\x58\x3d\x5f\xa7\x37\xde\xc3\x8c\x72\xb8\xbe\x29\x8c\x8b\x0c\x51\xc1\x8a\x81\x79\x5c\xc1\xd4\x55\xae\xf8\xab\x95\x63\x29\xc7\x23\x2a\x3a\x01\x69\xd3\x21\x52\x19\xe1\xd3\x51\x72\x74\x97\xba\x22\x38\x4f\x96\x4f\xf2\x64\x9c\x1d\x1d\x81\x5c\xd1\x32\x31\x93\x08\xc8\xed\x22\x73\x2c\x2d\x62\xf6\x10\x80\xc5\xed\x21\x36\x6a\xa1\x36\x1e\x65\x4a\x67\x55\x8d\x68\x24\xa9\x46\x21\x78\xbb\xb4\x09\xbc\x1c\xa3\x53\xdf\x35\x3d\x42\x68\xab\xd0\xd9\x1e\x25\x43\x47\x65\x8a\xd3\xd0\x38\x3a\xa8\x4d\x4d\x89\x60\x48\x4b\x78\x46\x08\x7a\x66\x50\xa4\x5e\xb7\x41\x3f\xa2\x6a\x16\xa9\x5b\xf0\x45\x92\x3a\x2e\x0c\x24\x0c\x6a\x74\x8a\xf3\x20\x56\xb4\xca\x69\x38\x7b\xa2\x9d\x48\x1e\x1f\x60\xa2\x87\x07\x47\x07\x04\x9d\xbb\xc8\x5f\x65\xca\x30\xd3\xbb\x70\xe3\x89\x99\xe3\x31\x6d\xbe\x34\x29\xfe\xe3\x45\x75\xee\xa6\x63\xac\x49\x35\xf2\xe7\x06\x1d\xbc\xba\x74\x4c\xd2\xe7\x43\xc3\xf3\x9e\x02\x4a\x0e\x3e\x52\x3c\xc5\xac\xd6\x5c\x7f\xa5\xea\xf0\xac\xd7\x70\x56\x7f\x6c\xa8\xb9\x57\x19\x6f\xd9\xd0\x4a\xeb\xb8\xef\x05\x1b\x85\x06\xbe\xb4\xe2\xcb\x0c\xfb\x18\x15\x11\xb1\x25\x1d\x7e\x6d\x0f\x87\x2f\x9e\xcf\x73\x98\xcf\x38\x9b\xe7\xe9\x11\x52\x90\x18\x1f\x93\x07\xba\x14\x71\xe8\xed\xc8\xcc\x54\xb3\x48\x35\x8d\x93\xe9\x42\xeb\x56\x1f\x16\xdf\xf4\x89\x1c\x09\x49\xb9\xcb\x00\x15\xfe\xd7\x3f\xfd\xf0\x3e\xd9\x6c\x93\x18\x06\xd8\xda\xc5\x62\xc9\xa0\xd4\xb3\x11\x0d\x47\x33\x71\x70\xa9\x45\xcc\x72\x41\xf7\x6f\xea\x75\xc1\xc4\xf5\x11\x19\xd4\xd7\x60\xee\xfd\xcf\x3e\x5f\x06\x18\x99\x58\xc2\xba\x28\x0a\x1d\xe0\xf3\x5c\xeb\x56\x68\x95\x72\x1d\x3f\xbf\xf2\x39\x43\x86\x80\x8e\xdf\xe0\xb1\xe7\x74\x23\x9a\x32\x60\xde\x2a\x9f\x1b\x9c\x2c\x63\xcc\xc7\x07\x84\x11\x89\x8a\x62\x57\xbf\x76\x6e\x4a\x56\x5a\x0c\x4c\xb9\xee\x09\x0b\xd7\x42\x85\x9b\x15\x5d\xfe\xad\xa5\x32\xfc\x28\x27\x09\x90\xdd\xab\x84\x6c\xf3\x27\x72\xa6\xe7\x05\xa6\xa2\x58\xab\x57\x51\x76\xa8\x64\x64\x3f\xd1\xef\xdc\x5e\x70\x6d\x9d\xf2\xa1\xd7\xdc\x58\x6f\xd6\xdb\x5f\x5f\x85\x6f\xc7\x78\x41\xa5\xbe\x64\xad\x06\xf4\x23\xbe\xd6\xab\xea\x8e\xc4\xe7\xc1\xe3\x5f\xfb\x51\x8d\x5a\x37\x48\x0d\x27\x4d\xbe\x55\x48\x8b\x02\xb5\xe4\xa6\x2e\x71\x0d\xbe\x55\x49\xaf\xb5\x16\x8e\x5b\x48\xae\x87\xab\x5a\x38\x9a\xa2\xda\x59\xb7\xb8\x5c\xfe\x39\x40\x21\x6c\x25\xd9\x17\x35\x6e\x02\xc5\x3b\x4e\x96\x2d\xdc\x4c\x22\xc3\x0c\x55\x7d\xe7\x40\xf4\x58\xf3\x1c\x3d\xb6\xb1\x1f\x68\x47\xee\xc9\xd6\x6a\x35\x40\x10\x7c\x3a\x49\x25\x9b\x6a\xb7\x71\xc4\xf5\x81\x59\x51\x5c\x1c\x33\xe7\x2f\x0d\xc1\xe8\x77\x92\xb0\x40\x2b\xf2\x90\xdb\xab\x16\x40\x31\x20\x89\xa3\x75\xd2\xe5\xd5\xce\xb4\xf7\xb4\xbe\xd3\x35\x85\x9e\x62\x27\x42\xd6\x0e\xf5\xf5\xb3\x08\xca\x2c\x5a\x84\x03\xce\xaa\x58\xd9\x43\x58\xdd\x3f\x14\x42\x01\x14\x6c\x9b\x20\x3a\x8a\x7b\xf5\xa3\x3a\x9c\x51\xeb\x3a\xad\x9a\x0c\xdd\xb7\xd7\x29\x05\x54\x84\x11\xb7\x5d\x8f\x01\x72\xb7\xd5\x22\x77\xc3\x3c\xb6\xa3\x34\xd0\xd5\x59\xa7\x09\xc1\x1c\xe9\x62\xfb\x11\x76\xd8\xd7\x24\xac\x92\xe1\x6d\x48\xfd\x2e\x37\x68\x4c\x99\x2f\x39\x8d\xb8\xc8\x41\x79\x0b\xee\x52\x69\x2c\xe1\x3b\x74\x20\x8f\xa2\x2b\x49\x9c\xea\x38\xf7\x63\x4a\x84\xc0\xb7\xeb\xdb\x37\x0a\x6d\xa6\xa0\x5d\xc2\x21\x3c\x77\x2f\x6e\x51\xe1\x4e\x47\x5c\x8c\x52\xd0\xe4\xc5\x9e\x92\xa8\x1f\x54\x8d\x64\xfe\xf5\x8c\x45\x99\x05\xde\x24\x72\x5e\xc8\xce\x2e\x45\xfa\xd9\xc6\x11\x34\xb7\x90\xab\xdd\xae\xea\xe1\x75\x23\x4c\x39\x9b\x00\x78\x6f\x55\xb5\xd8\x3d\x90\xb9\xbf\x02\x48\x89\x79\x4f\x3b\xfe\xd7\x6a\x0d\x04\xa6\xf7\x8a\x9e\x7c\xd1\xf1\x88\xa2\xf7\xa8\x28\xcf\xb3\x53\x6a\x96\xad\xde\x45\x30\x5a\x42\xcf\x7e\x73\x70\xe3\x79\x54\x07\x81\xb6\xc8\x47\x33\x0f\xcb\x5d\x8d\x3b\xcc\x32\x02\x1c\x86\xc4\x46\x55\xb4\x42\xb3\x14\x29\x94\xeb\xc8\x1a\x7f\xb9\x03\x53\xc7\x43\x34\x9d\x10\xad\xba\xe3\xf9\x52\xa1\x10\x41\xdf\xf1\x29\x62\xa9\x97\x55\x5f\x68\x1b\xfd\x36\x6a\x53\x0a\x11\xbe\xaa\xe0\xc9\x65\xc3\x2a\x1e\x5b\xf6\xe8\x25\xf2\x22\x79\xcd\x84\x07\x37\x6b\xbf\x8a\xb0\xaf\x11\x81\x6e\xb2\x8a\x10\x84\xc5\x87\x33\x45\xe3\x6d\x1a\x74\x3a\x47\xee\x62\xbf\x20\xc0\x8e\x9a\x0b\x52\x7b\xc4\x06\xae\x5c\xe9\x60\x81\x94\x6b\xb6\xed\x31\xb7\x02\x78\x49\x90\x97\x91\x16\xc7\xec\x65\xf4\x94\x31\xb5\xcb\x52\x49\x10\xe5\x0e\x00\x44\x75\x82\x98\x0b\x61\x4a\x6d\xa6\xda\x13\x9c\x71\xe7\x64\xd8\xb1\x26\x67\x6f\xf0\x42\xda\xd8\x1e\xae\x46\xc3\x0e\xee\x12\x3a\xfe\x66\x3b\x56\xcb\x9f\x57\xd4\x1a\xe5\x5a\xe3\x35\x35\xae\xf4\x46\x2a\x9e\x76\x70\x1a\x8e\x0f\xea\xb2\x9d\x37\xef\xfe\x19\x5a\xcb\x4a\xd8\x7a\xc3\xd2\xac\x21\xd5\x98\x1d\x6b\xfa\x06\x6b\x39\xf6\x18\x48\x54\x2b\xf7\xad\x13\xdb\x7b\x48\x72\xf5\xdd\x0c\x26\xeb\x31\x7a\xff\x22\x89\x92\xd8\x14\x15\x56\x48\xc1\xa9\xa3\x2e\xaa\x23\xc8\x1b\xb3\x62\x58\xf5\xf0\x85\xc8\x47\x73\xc2\x95\xd2\xc1\x5d\x9a\x6c\xde\x8b\x1a\xab\x45\x26\xff\x01\xb6\x59\xb1\x72\xa2\xf1\xd6\x76\x2e\xbf\xb3\xed\x51\x1b\x42\x2f\xd6\x4e\xf8\xa4\xbb\xe3\x6f\xcc\x6a\x13\x48\x3d\xd3\x60\x15\x3c\x62\xba\x8b\x52\xc1\xa3\x4b\x9f\xe2\xe7\xb7\x63\x68\xc7\xf4\x1d\x7f\xa0\x26\xfd\xb3\xa2\x90\x05\x11\x28\xe7\x6f\x02\xe7\xb3\x1f\x71\xb5\x19\xdf\x64\x79\x59\xf9\x05\x42\xcd\x03\x52\xd0\xc8\x85\x3f\x41\xbf\x28\xe0\xb9\x6a\xd3\x0a\xe7\x78\x09\xce\xf6\x6e\xb8\x50\x4e\x3f\xbb\xac\x85\xab\x7e\xe4\x20\x99\x4b\xd9\x50\xa4\xb2\xd6\x11\x2f\xe9\x41\xae\x55\xe2\x37\x1d\x10\xb9\xf8\x54\xfb\x2c\x5f\x6c\x4a\xe6\xf7\xe2\x06\x8a\x7b\xe9\x40\x9c\x59\x05\xb9\xf3\x29\x78\x92\xa5\x6f\x68\xd8\xe1\xaf\xde\xf5\x15\x95\xe1\xdc\xaa\x13\x57\x53\x44\x00\x44\x23\xc4\xf2\x07\x76\x93\x51\x7e\x9c\xdf\x07\x8b\x5c\x2d\xf2\xf9\xd9\x8f\x0f\xf1\x4f\xf2\x8e\xcf\xc2\xc7\x85\xb4\x62\x8b\x89\xf8\xfc\x7e\x0a\x4f\x33\x97\x5b\xe9\xb9\xac\x0f\x8b\xe6\xf7\xb5\x86\xbc\xa3\x92\x3b\x16\x07\x69\xcd\xfd\xc5\x27\x71\x71\x85\x5f\x8a\x02\xd9\x26\x77\x06\x0e\x26\xb8\x99\x44\x36\x79\xcc\x6a\x1c\xf9\x84\x23\x4e\x23\x4f\x97\x99\xf1\xa1\xba\x01\xd6\xd8\xc1\x39\xe4\x1b\xfb\x92\xb7\x16\x55\x99\x1c\x09\xd4\x45\x73\x87\xb3\x77\x67\x0b\x21\x05\x3c\x12\x4f\x16\xc6\x58\x51\x10\x5b\x94\x0f\xea\xef\x7c\xc9\x49\x9a\xb5\x01\x43\x0a\x06\x4d\xa5\xa0\xe2\x6a\x5b\x02\x62\xbf\x4c\x62\x65\x33\x15\xa4\x29\xe9\x47\xdf\x9a\x3c\x6e\xf5\x34\x3e\xa0\x0f\xc0\xb2\x74\x40\x32\xe2\x6e\x49\xdd\x24\x5a\x42\x17\x5d\x4c\x40\x73\x83\xf2\x19\x26\x00\x34\xd1\x18\x8d\xaa\x37\xba\x60\x02\xac\x60\xdf\x80\x23\x52\xa1\x16\x45\xf5\x28\x14\xbd\x7a\x57\x19\x05\xd5\x85\xa5\x6c\x19\x44\x41\x1e\x18\x1a\x73\xa2\x22\x0c\x65\x6b\xe0\xd2\xa9\x75\xeb\x91\x47\xd7\xff\xb8\x0c\x75\x72\x3d\xa8\x5a\xda\xcf\x28\xb8\x41\xaa\x2f\xf9\xf7\xfb\x82\x41\x51\x08\x49\x64\x14\xad\x0e\x4b\xd4\xa4\xbf\xce\xf7\xd5\x11\x72\x78\x9d\x10\xc3\xa4\x4a\x8a\xef\x74\xb9\x09\x8f\x4f\xc8\x11\x8b\x82\x9f\x5d\x65\xfd\x3a\x2a\x4b\x0d\x43\x67\x32\x63\x6d\x7f\xc1\x07\x33\x87\x48\xf0\xbf\x18\x5f\xcc\xd4\x85\x3e\x25\xba\x01\x9e\xf5\xc0\x88\x3f\x37\x15\xaa\x38\xa4\xb9\xcc\xa1\x83\x37\xdd\x67\xb0\x09\xb2\xcc\x5f\x05\xb4\xdb\xfc\x29\x0a\x60\x4d\xc1\xf8\x9c\xa4\x39\x2d\xc6\x46\x9e\x3c\xf3\xaf\x03\x0d\x68\xa1\xb1\x68\x36\x36\xe4\xb2\x07\x19\xa4\x49\xb1\x56\x37\xff\x3d\x79\x63\x02\x6e\xbe\x58\xec\xf0\x77\x72\x58\x40\xa7\x63\x24\x53\x9e\x10\xd5\x32\x41\xca\xca\x27\x45\xa6\x3c\x77\xe2\x33\xef\xa0\x2c\x05\x2b\x59\x5a\x11\xaf\x59\x90\xff\x28\x5a\xaa\xb1\xa6\xf5\x85\x4d\x77\xca\x6e\xdc\x57\x8e\x1b\x30\xee\x7e\x75\xb7\xe1\x1d\x13\xff\x73\x04\xfc\xcc\x77\x1b\xc5\x0e\x43\xa6\x5e\xe2\x55\x16\x2f\x1b\xaf\x29\x9d\x79\x3b\x7c\x10\xca\x54\xea\x5f\xb5\x49\x58\xb2\x97\x78\xa9\xbc\x99\x11\xeb\xa3\xb4\x91\x89\xcf\x7d\xd3\x51\x0e\x9f\x25\x8e\x72\x56\x34\x02\xf3\xc9\x5c\x6a\xa4\x96\xb0\x1c\xaa\xd4\x31\x46\xa5\x30\xfb\x8d\x88\x38\xb2\x71\xab\x36\xf2\x9b\xec\x92\xc4\xdc\xaa\x30\x26\x3a\xc8\xe7\x38\xb4\xca\xa6\xa8\x6e\xc2\x67\xd9\xac\xd4\x97\x5c\xe5\x59\x76\x87\xed\xdd\x22\xa1\xd4\x44\x14\xe3\x4f\x85\x4b\x5e\x70\x36\xc9\x72\x17\x51\xe8\xd8\x81\x78\x77\x80\xbc\x34\x3b\x1d\xd1\x19\x3c\xa2\x83\x67\xb8\x22\x25\xb4\x44\x42\x68\x61\x84\x81\xec\x12\xee\x50\x5d\x89\x63\x44\xa6\xa4\xad\x64\x9d\x0e\x37\x0e\xfc\xcd\xd2\xde\xf3\xb3\x75\x58\x57\x12\xf4\x6c\xe5\x3a\x2c\x37\x49\x4e\xa5\xcd\xcb\x71\x7b\x49\xaa\x28\xa4\x08\x0f\x61\xbc\x4c\x1e\x74\xc5\x26\xdc\x38\x5a\x45\xc9\x1c\x52\x92\x12\x12\xe4\xf1\xff\x05\x00\x00\xff\xff\x4c\x86\x22\xfc\x39\x4c\x00\x00")
+
+func jsMarkedMinJsBytes() ([]byte, error) {
+ return bindataRead(
+ _jsMarkedMinJs,
+ "js/marked.min.js",
+ )
+}
+
+func jsMarkedMinJs() (*asset, error) {
+ bytes, err := jsMarkedMinJsBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "js/marked.min.js", size: 19513, mode: os.FileMode(436), modTime: time.Unix(1453423957, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -185,6 +206,7 @@ var _bindata = map[string]func() (*asset, error){
"js/BugApp.js": jsBugappJs,
"js/BugList.js": jsBuglistJs,
"js/BugPage.js": jsBugpageJs,
+ "js/marked.min.js": jsMarkedMinJs,
}
// AssetDir returns the file names below a certain
@@ -231,6 +253,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
"BugList.js": &bintree{jsBuglistJs, map[string]*bintree{}},
"BugPage.js": &bintree{jsBugpageJs, map[string]*bintree{}},
+ "marked.min.js": &bintree{jsMarkedMinJs, map[string]*bintree{}},
}},
}}
diff --git a/bug-serve/issues/Description-should-be-parsed-as-markdown/Description b/bug-serve/issues/Description-should-be-parsed-as-markdown/Description
deleted file mode 100644
index e69de29..0000000
diff --git a/bug-serve/js/marked.min.js b/bug-serve/js/marked.min.js
new file mode 100644
index 0000000..555c1dc
--- /dev/null
+++ b/bug-serve/js/marked.min.js
@@ -0,0 +1,6 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i.5){ch="x"+ch.toString(16)}out+=""+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return""+(escaped?code:escape(code,true))+"\n
"}return''+(escaped?code:escape(code,true))+"\n
\n"};Renderer.prototype.blockquote=function(quote){return"\n"+quote+"
\n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"
\n":"
\n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+""+type+">\n"};Renderer.prototype.listitem=function(text){return""+text+"\n"};Renderer.prototype.paragraph=function(text){return""+text+"
\n"};Renderer.prototype.table=function(header,body){return"\n"+"\n"+header+"\n"+"\n"+body+"\n"+"
\n"};Renderer.prototype.tablerow=function(content){return"\n"+content+"
\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+""+type+">\n"};Renderer.prototype.strong=function(text){return""+text+""};Renderer.prototype.em=function(text){return""+text+""};Renderer.prototype.codespan=function(text){return""+text+"
"};Renderer.prototype.br=function(){return this.options.xhtml?"
":"
"};Renderer.prototype.del=function(text){return""+text+""};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='"+text+"";return out};Renderer.prototype.image=function(href,title,text){var out='":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i/g,">").replace(/"/g,""").replace(/'/g,"'")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;iAn error occured:
"+escape(e.message+"",true)+"
"}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
\ No newline at end of file
diff --git a/bug-serve/jsx/BugPage.js b/bug-serve/jsx/BugPage.js
index 9b2a4ba..95ffd64 100644
--- a/bug-serve/jsx/BugPage.js
+++ b/bug-serve/jsx/BugPage.js
@@ -1,4 +1,10 @@
var BugPage = React.createClass({
+ componentDidMount: function() {
+ this.refs.desc.innerHTML = marked(this.props.Description)
+ },
+ componentDidUpdate: function() {
+ this.refs.desc.innerHTML = marked(this.props.Description)
+ },
loadPreviousBug: function() {
for(var i = 1; i < this.props.AllBugs.length; i += 1) {
var bugCandidate = this.props.AllBugs[i];
@@ -56,7 +62,7 @@ var BugPage = React.createClass({
{this.props.Title}
-
{this.props.Description}
+
{this.props.Description}
{priority}
From 1e7b3d55aa0ba28723b41e1662c1e508057540cc Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Thu, 21 Jan 2016 20:22:54 -0500
Subject: [PATCH 20/47] Added or removed issues with the tool "bug"
---
bug-serve/issues/Add-ability-to-edit-bugs/Description | 2 ++
.../Description | 2 ++
bug-serve/issues/Implement-save-and-Cancel/Description | 2 ++
issues/Roadmap.md | 3 +++
4 files changed, 9 insertions(+)
create mode 100644 bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description
create mode 100644 bug-serve/issues/Implement-save-and-Cancel/Description
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Description b/bug-serve/issues/Add-ability-to-edit-bugs/Description
index e850106..0968669 100644
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Description
+++ b/bug-serve/issues/Add-ability-to-edit-bugs/Description
@@ -1 +1,3 @@
You should be able to edit bugs via AJAX in bug-serve
+
+And you should be able to edit them with markdown.
diff --git a/bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description b/bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description
new file mode 100644
index 0000000..f0e1dd5
--- /dev/null
+++ b/bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description
@@ -0,0 +1,2 @@
+When you click on a bug to edit it, the description doesn't
+get updated to the new bug if you click on another bug
diff --git a/bug-serve/issues/Implement-save-and-Cancel/Description b/bug-serve/issues/Implement-save-and-Cancel/Description
new file mode 100644
index 0000000..d8c6608
--- /dev/null
+++ b/bug-serve/issues/Implement-save-and-Cancel/Description
@@ -0,0 +1,2 @@
+The GUI currently updates as if it'll let you edit a bug,
+but the save and cancel buttons don't do anything useful.
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index 0a5848c..f46abde 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -3,3 +3,6 @@
## v0.4:
- bug-serve should have feature parity with bug
- Implement golang io interfaces in Bug class
+
+## No milestone set:
+- Add constructor method
From 256b1618c519f81db58166877eb359dcfa3c3d63 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Thu, 21 Jan 2016 20:23:36 -0500
Subject: [PATCH 21/47] Began implementing UI for editing bugs
---
bug-serve/bindata.go | 8 +--
.../Description | 2 -
bug-serve/jsx/BugPage.js | 50 +++++++++++++++++--
3 files changed, 50 insertions(+), 10 deletions(-)
delete mode 100644 bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
index 161e775..02bff09 100644
--- a/bug-serve/bindata.go
+++ b/bug-serve/bindata.go
@@ -86,7 +86,7 @@ func jsBugappJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453424896, 0)}
+ info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453426695, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -106,12 +106,12 @@ func jsBuglistJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453424896, 0)}
+ info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453426696, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xdd\x4e\x23\x37\x14\xbe\xcf\x53\xb8\x53\x09\x4d\x44\x12\x11\x44\xa5\x8a\x94\x4a\x25\x54\x6a\x25\xa0\x88\xd2\xab\x8a\x0b\x67\xc6\x49\x5c\x3c\xf6\xc8\xf6\xd0\x22\x94\xdb\x5e\xaf\xf6\x09\xf6\x59\xf6\x51\xf6\x49\xf6\xd8\x93\x99\xcc\xff\x0c\x10\x20\xeb\x0b\x48\xec\xf3\xfb\x8d\xcf\x77\xce\xe4\x1e\x4b\x74\x1a\x2d\xae\xf0\x82\xa0\x13\x74\x4d\xb0\xa7\x47\x9e\x24\x58\x93\x29\xc3\x4a\xb9\x8f\x3d\x04\xcb\xa7\x2a\x64\xf8\xe1\x12\x07\xe4\x18\x39\x6b\x79\x67\xd0\xb3\x87\x9e\x08\x42\xc1\x09\xd7\x67\xd4\xbf\x10\x11\xd7\xc7\x68\x1e\x71\x4f\x53\xc1\x91\xdb\x47\xb1\x05\xb3\xf4\x92\xaa\x91\x24\x73\x35\xf2\x89\xf2\x46\x94\x73\x22\x7f\xbb\xb9\x38\x07\xc7\x01\x96\x77\xc4\x77\xad\x44\x28\x45\xa8\x46\x67\x20\x22\x69\x68\xac\xf4\x27\xd6\xc4\x6a\x50\x72\xf7\x57\xe8\x43\xa4\xaf\xeb\x8f\x09\xec\x5f\x49\x72\x4f\x45\xa4\x20\xf3\x3a\x67\x73\x21\x91\x6b\xd0\xa4\x60\x7e\x3c\x81\x7f\x3f\xa1\x8c\xf9\x5f\x18\x03\x65\x35\x62\x84\x2f\xf4\xd2\x1c\xef\x83\x58\xd6\x80\x59\x46\x7f\x16\x2d\xa6\x98\xfb\xd4\x64\x06\xa6\xca\x36\xfe\xa6\xb7\x93\x9c\x16\x9d\x23\x37\xaf\x75\x92\xd3\x9b\x46\x52\x02\x5e\xa0\x5b\xf4\x97\xa2\x14\x0b\x9e\x43\xaa\x20\xe5\x56\xf9\x44\x43\x34\xbe\xed\x4f\x4a\xea\x92\xe8\x48\xf2\xfc\xfe\xaa\x57\xfe\x94\x95\xcb\x20\x7b\x49\xfe\xd3\x5d\x51\x3d\x68\x41\xd5\x84\xf8\x2d\x22\xbb\xbf\x75\x64\x21\x28\x9f\xc8\x3a\x50\x0d\x16\x73\x4a\x98\x7f\x2d\xfe\x05\x1c\x36\x42\x1c\xea\x7b\x00\xc7\x2c\x22\xc5\x7c\x0c\x12\x95\x07\x9b\x08\x72\xec\xf1\x2b\x23\x01\x20\xe3\x96\x64\xcd\x72\x7c\x7a\xef\x0c\x2a\x8f\x1e\x91\x67\x78\x67\xcd\x34\x12\x02\xb4\x91\x3a\x49\x66\xc5\xd5\xd9\x67\x8b\xdf\xb2\x6f\x4f\xb0\x61\xe0\x0f\xc7\xb5\xae\xad\xc5\xcf\x9f\x9c\xca\xc3\xfe\x3b\x85\x7b\x88\x18\x9e\x11\x16\xff\x1d\x52\x3e\x17\x8d\xf1\x9b\x27\xbe\x53\xf1\x1f\xa1\x19\xf6\xa1\xb7\x34\x05\x6d\xef\xe1\x4e\x45\xfd\xc3\x33\x2f\x49\x69\xb7\x5f\x57\xee\x66\x15\x09\xa1\xe0\x32\x94\x54\x48\xaa\x1f\x4c\x49\xaf\xab\xdb\x75\xae\xd6\x9b\xce\x20\x4b\x47\xc9\x6e\x01\x2f\xa5\xb1\x8e\xd4\x9a\x15\x52\x13\x7f\xda\xdd\xbc\x81\x78\xaf\xa0\x1e\x50\x46\x94\x86\xde\x9c\x53\xbf\x48\x76\xf3\x16\xd2\xed\x4c\xca\x86\x98\x42\x68\xb5\x76\xf4\x18\x20\x0e\xbd\xc1\x7e\xdc\x48\x18\x1a\xaa\xe7\xff\x9f\xd1\x18\xed\xed\x55\x11\xfb\xc1\x2d\xfa\xae\x23\x73\xa7\x01\x40\x16\x4e\xb8\x6e\xfc\x4e\x06\x75\x44\x98\x22\x5d\x94\xcc\xd8\x84\x67\x8c\xf8\x59\xed\x17\xa7\xd2\xd8\xfe\xba\xa7\x99\x82\x6b\x22\x36\x5f\xda\x52\x2c\x29\x34\xa7\xd7\xb5\x27\x54\x94\x1b\x8f\x18\xcb\xef\x74\x2a\xe0\x9a\xc2\xad\x2c\xd8\x1f\x61\x8c\xe4\x1a\x53\x98\x08\x2b\x4b\x77\xfb\xad\xec\x9f\x28\x98\x09\x2d\xa1\xcd\xc2\x40\xa1\xa2\x00\x26\xd0\x87\x2d\x75\xb5\xe5\x61\x03\x5f\x95\xc1\xcc\xae\xcc\x55\xb9\xa1\x9a\xbd\x23\xab\xc2\x9c\x0e\x28\x99\x41\xbd\x91\x4b\xab\x27\xf6\xae\xec\xfa\x16\x0f\xda\x32\x9f\xaa\x4d\x22\x61\xe9\xea\xd3\x94\x81\xab\x8f\x53\x86\x2d\xa7\xd6\x6b\x48\x74\xeb\xe5\x73\xd4\xb9\x68\x80\x79\xce\xa9\xd2\x03\xb0\x63\x2f\x18\xd8\xf8\x43\x2f\x89\x44\xbf\x2b\x15\x11\x55\x83\xa8\x61\xb5\xe3\x0a\xf2\xab\x96\x16\x1c\xce\xa6\x8c\x7a\xf0\x4a\x97\xd3\x12\xdc\xfa\xda\x9c\x96\xd4\x57\x6f\x8b\xdb\xf8\xf0\x85\x6c\x13\xb1\x4e\x77\x30\x84\xd7\xf3\x6a\x62\x7b\x92\x3b\xeb\x92\xd1\xae\xd3\xd0\xa6\x09\x36\x14\xf0\x93\x9c\xdb\x00\x70\x83\xff\x38\x86\x65\x4c\x1e\xdf\xc3\x84\x21\xb8\x7d\xd4\xeb\x6b\x50\x78\x77\x6f\x8a\xeb\x59\xb1\xd9\xf8\x54\x88\x79\x4b\x88\x71\x98\x0e\x96\x14\x0f\x97\xd4\xf7\x09\x77\x20\x5e\x2d\xa3\xe6\x41\x37\x75\xf1\xe5\xff\x0f\xd5\x13\x64\xb2\x6a\x28\x3a\x35\x80\x12\x14\xea\xcd\x94\xe9\xb2\xc1\xf0\x6b\x5d\x21\x27\x1e\x1b\x1a\x51\x79\xd3\x1b\x94\x10\xc9\x29\xf6\xee\xda\x1e\x95\x73\x1d\xcf\x3c\x5a\x20\x06\x9c\xb7\xe3\x50\x6f\xe6\xb9\x5d\xc1\x3a\xf3\x7b\x50\x2b\xd4\x46\x0e\xb5\xb8\xda\xe1\x72\xfe\xd8\x52\xce\x4f\xbd\x3a\x6d\xf3\x40\xfa\x2d\xf9\x6d\xb3\xb7\xea\x4f\xbe\x06\x00\x00\xff\xff\xf4\x90\x3c\x91\xfc\x15\x00\x00")
+var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xdb\x6e\xdb\xb6\x1b\xbf\xcf\x53\xf0\xaf\x3f\x50\xd8\xa8\x6d\x24\x59\x07\x0c\xf1\x3a\x60\x75\x0a\xac\x40\xd2\x05\x49\xb7\x9b\x21\x17\xb4\x44\xdb\x5c\x29\x4a\x20\x29\x6f\x41\xe0\xdb\x5d\x0f\x7b\x82\x3d\xcb\x1e\x65\x4f\xb2\x8f\x94\x2c\x8b\x22\x75\x48\xe2\x64\x1e\x2f\xda\x98\xfc\xce\xfc\x0e\x3f\x6a\x8d\x05\x7a\x97\x2d\xaf\xf0\x92\xa0\xb7\xe8\x9a\xe0\x50\x4d\x42\x41\xb0\x22\x33\x86\xa5\x1c\xdc\x1f\x21\x58\x11\x95\x29\xc3\x77\x1f\x71\x4c\xce\x50\x50\xd0\x07\xa3\x23\x73\x18\x26\x71\x9a\x70\xc2\xd5\x39\x8d\x2e\x93\x8c\xab\x33\xb4\xc8\x78\xa8\x68\xc2\xd1\x60\x88\x72\x09\x7a\xd1\x05\x1a\xa8\x15\x95\x13\x41\x16\x72\x12\x11\x19\x56\x4f\xf5\xb2\x4f\x27\x94\x73\x22\xbe\xfb\x74\x79\x01\xa6\xc5\x58\x7c\x26\x51\xce\x9f\x8a\x24\x95\x93\x73\x20\x11\x34\xd5\x7a\x86\xd3\x52\xcc\xe6\xc8\x12\x26\x89\xba\x51\xe0\xcd\xc0\x56\x14\xbc\x8f\xa8\xa2\x7c\x19\x80\xad\x98\x49\xb2\x63\x2f\x44\x6d\x46\x8e\x6f\x3f\xa4\x11\x08\x3a\x00\xe7\x0a\xdb\x58\x82\xa3\x2b\x41\xd6\x34\xc9\x24\x5c\x49\x93\x61\x8b\x44\xa0\x81\xbe\x66\x0a\x8a\x4e\xa6\xf0\xdf\xd7\xa8\xa2\xe8\x5b\xc6\x80\x59\x4e\x18\xe1\x4b\xb5\xd2\xc7\xaf\x81\xac\x6e\xbb\xe6\x9f\x67\xcb\x19\xe6\x11\xd5\x51\x00\x51\xae\x8c\x9f\xe8\xed\xd4\xe2\xd2\x31\xb1\xb9\xde\x5a\x7c\xb3\x4c\x08\x88\x2d\xf0\xd6\xf5\x95\xf1\xca\x09\x2f\xc0\x55\xa0\x1a\xf8\x74\xa2\x31\x3a\xb9\x1d\x4e\x1d\x76\x41\x54\x26\xb8\xbd\xbf\xf1\xa4\x49\x95\xae\x12\xd9\x8f\xe4\x57\xd5\x37\xaa\xc7\x1d\x51\xd5\x26\xfe\x17\x23\xfb\x7a\xef\x91\x5d\x12\xf5\x81\x43\xe5\x61\x66\xaa\xb2\x29\xba\x39\x27\xea\x5b\xb3\x96\x0a\x02\x54\x3b\xf7\x9b\x34\xf4\x6c\x0e\x4a\x64\xcd\xbd\x01\xf3\x90\x30\x4d\xab\x89\x9f\xa8\xa8\xb5\x0b\x25\xfc\x7b\xb5\x22\x02\xdc\x99\x31\x1a\x42\xa7\xa8\x2a\x23\x7b\xd1\x66\x4b\xc8\x13\xc1\x51\x0b\xba\x2c\xbb\x20\xc6\x11\x11\x4d\x9e\xeb\xcc\x5e\x50\xc2\xa2\xeb\xe4\x17\xc8\xea\x1d\x11\x87\x31\x32\x82\x63\x96\x91\x7a\x76\xea\xbc\xf6\x1e\xe4\xea\x4c\x56\x54\x87\xd4\x7b\x46\x62\xb8\xe8\x81\x43\x6b\x1c\x8e\xe8\x3a\x18\x79\x8f\xee\x51\xa8\xc7\x5b\x31\xd0\x04\x18\x68\x2c\x0d\xb6\x9e\xd5\x57\x6f\x9d\x1d\x7a\x5d\xdd\x61\xc2\xc6\x71\x34\x3e\x69\x54\x6d\x24\xfe\xf5\x67\xe0\x3d\x1c\xfe\x4b\xe6\x9e\x22\x86\xe7\x84\xe5\xff\x8e\x29\x5f\x24\xad\xf6\xeb\x1b\x3f\x28\xfb\xdf\xa0\x39\x8e\x00\xc2\xb4\x19\x6d\xf2\xf0\xa0\xac\xfe\xf2\x91\x49\xe2\xec\x0e\x9b\x9a\xb7\x5e\xf5\xf6\x5e\x53\x99\x0a\x9a\x08\xaa\xee\x74\x49\x17\xd5\x3d\x08\xae\x8a\xcd\x60\x54\x6d\x20\xdb\xdd\x5a\xbc\x24\x34\xa7\x4c\x16\x5d\xa1\x14\x71\x63\x76\x6d\x01\xf9\x5e\x8d\x3d\xa6\x8c\x48\x05\xa8\xcc\x62\xbf\xdc\xee\xda\x12\xca\xed\x8a\xcb\xba\x31\xa5\x00\x9c\x0c\xc2\x1d\x21\x0e\x93\xde\xfc\x39\x75\xc1\x9c\x77\x9a\x7f\x83\x4e\xd0\xab\x57\xbe\x31\x7d\x7c\x8b\xfe\xd7\x73\x0e\x97\x06\x80\x17\x41\x5a\xc0\xb8\xa0\x12\x75\x44\xa0\x47\xf7\x61\xd2\xe8\x1c\xcf\x19\x89\x02\x1f\x0a\x7e\xac\x2b\xad\x60\xa6\xbf\x9b\x65\x70\xb5\xc5\xfa\x47\x97\x8b\x0e\x83\xdf\x3d\xeb\x32\x35\x9e\x3e\xa7\x6b\xcf\xfd\xe9\x54\x23\x93\x62\xf0\xe5\x20\x49\xb8\xc3\xa5\xe0\xaf\x3d\x80\x1a\x4b\xb8\xa1\x74\x79\xc6\x98\xbb\xeb\x93\x18\x28\xf0\x0b\xc3\x16\xe4\xaa\x7f\x1a\x9c\xc2\x09\x4c\x25\x09\x5b\x5f\x1c\xc3\xdf\x11\x59\xe0\x8c\xa9\x1f\x75\x4b\x3a\x43\xfe\x77\x02\xcc\xf1\x7e\xea\x9f\x3c\x2c\xf7\x34\x26\xe7\x99\x82\xca\x6c\x69\x82\xfe\x88\x96\xfc\x37\x78\x4d\x9e\x71\x2c\x76\x9a\x77\x0f\xc0\xcc\x20\xa3\xe2\x46\x6c\x40\xd8\xda\xaa\x67\x86\xb4\x77\xbb\xb6\x76\x86\x1d\x15\xb4\x9f\x6c\xbe\x87\x39\xb0\x80\xeb\xd6\xd2\x20\x01\x6d\x4f\x6d\x8c\xed\xf3\xd4\x9f\xa2\x8d\x7e\xd4\x91\x7f\xa7\xe5\x1e\xab\xdd\x6c\x79\x9a\xff\x9e\xba\xfc\x0a\x85\x09\x57\x98\xc2\xcb\xdd\x5b\x03\xfb\xaf\xb6\x9f\xb3\x78\x9e\x28\x01\xd5\x0d\xcf\x3d\x99\xc5\x31\x16\x77\x7b\x2a\xbf\xd5\xe9\xa3\x4b\xaf\x72\xbb\x9f\xa8\x62\x0f\x42\x49\x45\x7a\xba\x49\xfe\x12\xe1\x34\x78\x41\x36\x06\x70\x8b\x6d\xfc\xa7\x25\x6e\xf1\x1f\x97\xb8\xa4\xab\x7e\x9f\x39\x49\xdf\xf4\x4e\x4d\xa8\xdd\x0b\x2a\x95\x1e\x42\xe6\x1a\x41\x86\x79\xf1\xa1\x0f\x52\x66\x44\x36\x44\x54\x63\x81\x33\x0f\x64\xf0\x53\x27\xbc\xfa\x6c\x35\x5c\xce\xbb\xd2\x61\xdc\xbc\x6c\xc4\x60\xdc\x3e\xad\x9a\x33\xd6\x2b\xfb\x52\xbc\x6c\x68\x1c\x0f\x52\x67\x54\x32\xda\xf7\xf5\xb0\x03\x8d\x2d\x13\xe9\x41\xca\x8d\x01\xb8\x45\x7f\x6e\xc3\x2a\x9f\x20\xff\x77\xc6\x47\xed\xcb\x65\x9b\x5d\x8f\xb2\xcd\xd8\x27\x53\xdc\x36\xbc\x77\x66\x06\x58\x50\x3c\x5e\xd1\x28\x22\x3c\x00\x7b\x35\x42\x6c\x7d\x68\x95\x2a\xfe\xfe\xed\x77\xff\x08\xdf\xae\x86\x16\x58\x0a\x40\xdb\x28\x34\x8b\x71\xd1\x40\x8b\xe0\xe7\x4a\xa1\x20\x1f\xcb\xad\x51\x79\xd1\x0c\xda\x7e\xa0\x7a\x87\xc3\xcf\x5d\x57\x15\x5c\xe7\x98\x42\x25\x88\x41\xb7\x3b\xf0\x50\xef\xde\x3f\x87\x12\xeb\xca\xd7\xf0\xce\x50\x6b\x3a\xd4\xa1\xea\x80\xcb\xf9\x8f\x8e\x72\x7e\x68\xea\x74\x21\x81\xf2\xd7\xf6\xbb\xea\xd1\x66\x38\xfd\x27\x00\x00\xff\xff\x75\x5d\xdc\xb5\x93\x1b\x00\x00")
func jsBugpageJsBytes() ([]byte, error) {
return bindataRead(
@@ -126,7 +126,7 @@ func jsBugpageJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugPage.js", size: 5628, mode: os.FileMode(436), modTime: time.Unix(1453424896, 0)}
+ info := bindataFileInfo{name: "js/BugPage.js", size: 7059, mode: os.FileMode(436), modTime: time.Unix(1453426696, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
diff --git a/bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description b/bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description
deleted file mode 100644
index f0e1dd5..0000000
--- a/bug-serve/issues/Description-does-not-change-when-in-editing-mode/Description
+++ /dev/null
@@ -1,2 +0,0 @@
-When you click on a bug to edit it, the description doesn't
-get updated to the new bug if you click on another bug
diff --git a/bug-serve/jsx/BugPage.js b/bug-serve/jsx/BugPage.js
index 95ffd64..8b5d595 100644
--- a/bug-serve/jsx/BugPage.js
+++ b/bug-serve/jsx/BugPage.js
@@ -1,9 +1,16 @@
var BugPage = React.createClass({
componentDidMount: function() {
- this.refs.desc.innerHTML = marked(this.props.Description)
+ if(this.refs.desc) {
+ this.refs.desc.innerHTML = marked(this.props.Description)
+ }
+ this.setState({
+ "Editing" : false
+ });
},
componentDidUpdate: function() {
- this.refs.desc.innerHTML = marked(this.props.Description)
+ if(this.refs.desc) {
+ this.refs.desc.innerHTML = marked(this.props.Description)
+ }
},
loadPreviousBug: function() {
for(var i = 1; i < this.props.AllBugs.length; i += 1) {
@@ -24,6 +31,28 @@ var BugPage = React.createClass({
}
}
return;
+ },
+ getInitialState: function() {
+ return {
+ "Editing" : false
+ }
+ },
+ editCurrentBug: function() {
+ this.setState({
+ "Editing" : true
+ });
+ },
+ cancelEditting: function() {
+ this.setState({
+ "Editing" : false
+ });
+ },
+ onOtherBugClicked: function(e) {
+ this.setState({
+ "Editing" : false
+ });
+
+ this.props.onOtherBugClicked(e)
},
render: function() {
var fieldRow = function(name, value) {
@@ -57,12 +86,25 @@ var BugPage = React.createClass({
} else {
nextClass = "next disabled";
}
+
+ var descDiv;
+ if (this.state.Editing === true) {
+ descDiv = ();
+ } else {
+ descDiv = {this.props.Description}
+ }
return (
{this.props.Title}
-
{this.props.Description}
+ {descDiv}
{priority}
@@ -73,7 +115,7 @@ var BugPage = React.createClass({
From e10aaaca4d2bcc28d88590c5f03610017bdf4c4d Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 15:14:19 -0500
Subject: [PATCH 22/47] Improved testing coverage of scm package
---
issues/Roadmap.md | 3 ---
scm/GitManager.go | 7 ++---
scm/GitManager_test.go | 59 +++++++++++++++++++++++++++++++++++++++++-
scm/HgManager_test.go | 30 ++++++++++++++++++++-
4 files changed, 91 insertions(+), 8 deletions(-)
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index f46abde..0a5848c 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -3,6 +3,3 @@
## v0.4:
- bug-serve should have feature parity with bug
- Implement golang io interfaces in Bug class
-
-## No milestone set:
-- Add constructor method
diff --git a/scm/GitManager.go b/scm/GitManager.go
index 7681438..bb94654 100644
--- a/scm/GitManager.go
+++ b/scm/GitManager.go
@@ -38,11 +38,12 @@ func (a GitManager) getDeletedIdentifiers(dir bugs.Directory) []string {
continue
}
if file[0:1] == "D" && strings.HasSuffix(file, "Identifier") {
- ghRegex := regexp.MustCompile("(?im)^-Github:(\\s*)(.*)(\\s*)$^")
+ ghRegex := regexp.MustCompile("(?im)^-Github:(.*)$")
diff := exec.Command("git", "diff", "--staged", "--", file[3:])
diffout, _ := diff.CombinedOutput()
- if matches := ghRegex.FindStringSubmatch(string(diffout)); len(matches) > 2 {
- retVal = append(retVal, matches[2])
+ //fmt.Printf("Output: %s", diffout)
+ if matches := ghRegex.FindStringSubmatch(string(diffout)); len(matches) > 1 {
+ retVal = append(retVal, strings.TrimSpace(matches[1]))
}
}
}
diff --git a/scm/GitManager_test.go b/scm/GitManager_test.go
index 16d3269..33912ff 100644
--- a/scm/GitManager_test.go
+++ b/scm/GitManager_test.go
@@ -2,6 +2,7 @@ package scm
import (
"fmt"
+ "github.com/driusan/bug/bugs"
"io/ioutil"
"os"
"strings"
@@ -23,6 +24,10 @@ func (c GitCommit) Diff() (string, error) {
return runCmd("git", "show", "--pretty=format:%b", c.CommitID())
}
+func (c GitCommit) CommitMessage() (string, error) {
+ return runCmd("git", "show", "--pretty=format:%B", "--quiet", c.CommitID())
+}
+
type GitTester struct {
handler SCMHandler
workdir string
@@ -82,7 +87,6 @@ func (t *GitTester) Setup() error {
return err
}
- t.handler = GitManager{}
return nil
}
func (t GitTester) TearDown() {
@@ -150,3 +154,56 @@ func TestGitManagerPurge(t *testing.T) {
gm.handler = GitManager{}
runtestPurgeFiles(&gm, t)
}
+
+func TestGitManagerAutoclosingGitHub(t *testing.T) {
+ // This test is specific to gitmanager, since GitHub
+ // only supports git..
+ tester := GitTester{}
+ tester.handler = GitManager{Autoclose: true}
+
+ err := tester.Setup()
+ if err != nil {
+ panic("Something went wrong trying to initialize git:" + err.Error())
+ }
+ defer tester.TearDown()
+ m := tester.GetManager()
+ if m == nil {
+ t.Error("Could not get manager")
+ return
+ }
+ os.Mkdir("issues", 0755)
+ runCmd("bug", "create", "-n", "Test", "bug")
+ runCmd("bug", "create", "-n", "Test", "Another", "bug")
+ if err = ioutil.WriteFile("issues/Test-bug/Identifier", []byte("\n\nGitHub:#TestBug"), 0644); err != nil {
+ t.Error("Could not write Identifier file")
+ return
+ }
+ if err = ioutil.WriteFile("issues/Test-Another-bug/Identifier", []byte("\n\nGITHuB: #Whitespace "), 0644); err != nil {
+ t.Error("Could not write Identifier file")
+ return
+ }
+
+ // Commit the file, so that we can close it..
+ m.Commit(bugs.Directory(tester.GetWorkDir()+"/issues"), "Adding commit")
+ // Delete the bug
+ os.RemoveAll(tester.GetWorkDir() + "/issues/Test-bug")
+ os.RemoveAll(tester.GetWorkDir() + "/issues/Test-Another-bug")
+ m.Commit(bugs.Directory(tester.GetWorkDir()+"/issues"), "Removal commit")
+
+ commits, err := tester.GetLogs()
+ if len(commits) != 2 || err != nil {
+ t.Error("Error getting git logs while attempting to test GitHub autoclosing")
+ return
+ }
+ if msg, err := commits[1].(GitCommit).CommitMessage(); err != nil {
+ t.Error("Error getting git logs while attempting to test GitHub autoclosing")
+ } else {
+ if msg != `Removal commit
+
+Closes #Whitespace, closes #TestBug
+` {
+ fmt.Printf("%s\n", msg)
+ t.Error("GitManager did not autoclose Github issues")
+ }
+ }
+}
diff --git a/scm/HgManager_test.go b/scm/HgManager_test.go
index f3e828a..9ccef98 100644
--- a/scm/HgManager_test.go
+++ b/scm/HgManager_test.go
@@ -124,6 +124,34 @@ deleted file mode 100644
}
func TestHgFilesOutsideOfBugNotCommited(t *testing.T) {
tester := HgTester{}
- tester.handler = GitManager{}
+ tester.handler = HgManager{}
runtestCommitDirtyTree(&tester, t)
}
+
+func TestHgGetType(t *testing.T) {
+ m := HgManager{}
+
+ if m.GetSCMType() != "hg" {
+ t.Error("Incorrect type for HgManager")
+ }
+}
+
+func TestHgPurge(t *testing.T) {
+ // This should eventually be replaced by something more
+ // like:
+ // m := HgTester{}
+ // m.handler = HgManager{}
+ // runtestPurgeFiles(&m, t)
+ // but since the current behaviour is to return a not
+ // supported error, that would evidently fail..
+ m := HgManager{}
+ err := m.Purge("/tmp/imaginaryHgRepo")
+
+ switch err.(type) {
+ case UnsupportedType:
+ // This is valid, do nothing.
+ default:
+ t.Error("Unexpected return value for Hg purge function.")
+ }
+
+}
From 9f2bbf2e9e142338878b13aef96e9c9102950f63 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 16:55:08 -0500
Subject: [PATCH 23/47] Fixed Travis by using Trusty Tahr instead of Precise
Penguin
The problems seem to be related to the git version, and this
is the only way I can find to upgrade the version of git on
Travis.
---
.travis.yml | 10 ++++++++--
scm/GitManager_test.go | 9 +++------
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 9f0068e..dd5e501 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,10 @@
language: go
-sudo: false
+sudo: required
+dist: trusty
+ # Trusty Tahr seems to be the only way to get
+ # a modern version of git on Travis. Once they've
+ # upgraded with non-beta, this can be removed along
+ # with sudo: required..
os:
- linux
- osx
@@ -8,10 +13,11 @@ go:
addons:
apt:
packages:
- - git-2.0
+ - git
before_install:
+ - git config -l
- git --version
- hg --version
diff --git a/scm/GitManager_test.go b/scm/GitManager_test.go
index 33912ff..5fdb791 100644
--- a/scm/GitManager_test.go
+++ b/scm/GitManager_test.go
@@ -36,7 +36,8 @@ type GitTester struct {
func (t GitTester) GetLogs() ([]Commit, error) {
logs, err := runCmd("git", "log", "--oneline", "--reverse", "-z")
if err != nil {
- fmt.Fprintf(os.Stderr, "Error retrieving git logs: %s", logs)
+ wd, _ := os.Getwd()
+ fmt.Fprintf(os.Stderr, "Error retrieving git logs: %s in directory %s\n", logs, wd)
return nil, err
}
logMsgs := strings.Split(logs, "\000")
@@ -81,7 +82,7 @@ func (t *GitTester) Setup() error {
return err
}
- out, err := runCmd("git", "init", ".")
+ out, err := runCmd("git", "init")
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing git: %s", out)
return err
@@ -111,10 +112,6 @@ func (m GitTester) GetManager() SCMHandler {
}
func TestGitBugRenameCommits(t *testing.T) {
- if os.Getenv("TRAVIS") == "true" && os.Getenv("TRAVIS_OS_NAME") == "linux" {
- t.Skip("Skipping test which fails only under Travis for unknown reasons..")
- return
- }
gm := GitTester{}
gm.handler = GitManager{}
From 56884aeff38ad9d2293ff9138f3e5554621173cc Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 19:32:21 -0500
Subject: [PATCH 24/47] Added tests for DetectSCM
---
scm/Detect_test.go | 104 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
create mode 100644 scm/Detect_test.go
diff --git a/scm/Detect_test.go b/scm/Detect_test.go
new file mode 100644
index 0000000..7f4ba38
--- /dev/null
+++ b/scm/Detect_test.go
@@ -0,0 +1,104 @@
+package scm
+
+import (
+ "github.com/driusan/bug/bugs"
+ "io/ioutil"
+ "os"
+ "testing"
+)
+
+func TestDetectGit(t *testing.T) {
+ var gdir string
+ gdir, err := ioutil.TempDir("", "gitdetect")
+ if err == nil {
+ os.Chdir(gdir)
+ defer os.RemoveAll(gdir)
+ } else {
+ t.Error("Failed creating temporary directory for detect")
+ return
+ }
+ // Fake a git repo
+ os.Mkdir(".git", 0755)
+
+ options := make(map[string]bool)
+ handler, dir, err := DetectSCM(options)
+ if err != nil {
+ t.Error("Unexpected while detecting repo type: " + err.Error())
+ }
+ if dir != bugs.Directory(gdir+"/.git") {
+ t.Error("Unexpected directory found when trying to detect git repo" + dir)
+ }
+ switch handler.(type) {
+ case GitManager:
+ // GitManager is what we expect, don't fall through
+ // to the error
+ default:
+ t.Error("Unexpected SCMHandler found for Git")
+ }
+
+ // Go somewhere higher in the tree and do it again
+ os.MkdirAll("tmp/abc/hello", 0755)
+ os.Chdir("tmp/abc/hello")
+ handler, dir, err = DetectSCM(options)
+ if err != nil {
+ t.Error("Unexpected while detecting repo type: " + err.Error())
+ }
+ if dir != bugs.Directory(gdir+"/.git") {
+ t.Error("Unexpected directory found when trying to detect git repo" + dir)
+ }
+ switch handler.(type) {
+ case GitManager:
+ // GitManager is what we expect, don't fall through
+ // to the error
+ default:
+ t.Error("Unexpected SCMHandler found for Git")
+ }
+}
+
+func TestDetectHg(t *testing.T) {
+ var gdir string
+ gdir, err := ioutil.TempDir("", "hgdetect")
+ if err == nil {
+ os.Chdir(gdir)
+ defer os.RemoveAll(gdir)
+ } else {
+ t.Error("Failed creating temporary directory for detect")
+ return
+ }
+ // Fake a git repo
+ os.Mkdir(".hg", 0755)
+
+ options := make(map[string]bool)
+ handler, dir, err := DetectSCM(options)
+ if err != nil {
+ t.Error("Unexpected while detecting repo type: " + err.Error())
+ }
+ if dir != bugs.Directory(gdir+"/.hg") {
+ t.Error("Unexpected directory found when trying to detect git repo" + dir)
+ }
+ switch handler.(type) {
+ case HgManager:
+ // HgManager is what we expect, don't fall through
+ // to the error
+ default:
+ t.Error("Unexpected SCMHandler found for Mercurial")
+ }
+
+ // Go somewhere higher in the tree and do it again
+ os.MkdirAll("tmp/abc/hello", 0755)
+ os.Chdir("tmp/abc/hello")
+ handler, dir, err = DetectSCM(options)
+ if err != nil {
+ t.Error("Unexpected while detecting repo type: " + err.Error())
+ }
+ if dir != bugs.Directory(gdir+"/.hg") {
+ t.Error("Unexpected directory found when trying to detect git repo" + dir)
+ }
+ switch handler.(type) {
+ case HgManager:
+ // GitManager is what we expect, don't fall through
+ // to the error
+ default:
+ t.Error("Unexpected SCMHandler found for Mercurial")
+ }
+}
From 588d8361da31f5eaa8ead2990837de030b734a43 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 19:39:02 -0500
Subject: [PATCH 25/47] Added hack to try and fix OS X tests
---
scm/Detect_test.go | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/scm/Detect_test.go b/scm/Detect_test.go
index 7f4ba38..354099a 100644
--- a/scm/Detect_test.go
+++ b/scm/Detect_test.go
@@ -12,6 +12,9 @@ func TestDetectGit(t *testing.T) {
gdir, err := ioutil.TempDir("", "gitdetect")
if err == nil {
os.Chdir(gdir)
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
defer os.RemoveAll(gdir)
} else {
t.Error("Failed creating temporary directory for detect")
@@ -60,6 +63,9 @@ func TestDetectHg(t *testing.T) {
gdir, err := ioutil.TempDir("", "hgdetect")
if err == nil {
os.Chdir(gdir)
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
defer os.RemoveAll(gdir)
} else {
t.Error("Failed creating temporary directory for detect")
From c9ca855d811b76b185f6b4e994518d20861f2739 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 19:58:10 -0500
Subject: [PATCH 26/47] Added "New" constructor for Bug class
---
bugs/Bug.go | 9 +++++++++
bugs/Bug_test.go | 25 +++++++++++++++++++++++++
bugs/IO_test.go | 9 +++++----
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/bugs/Bug.go b/bugs/Bug.go
index c0ed495..f396d7a 100644
--- a/bugs/Bug.go
+++ b/bugs/Bug.go
@@ -254,3 +254,12 @@ func (b Bug) Identifier() string {
func (b Bug) SetIdentifier(newValue string) error {
return b.setField("Identifier", newValue)
}
+
+func New(title string) (*Bug, error) {
+ expectedDir := GetIssuesDir() + TitleToDir(title)
+ err := os.Mkdir(string(expectedDir), 0755)
+ if err != nil {
+ return nil, err
+ }
+ return &Bug{Dir: expectedDir}, nil
+}
diff --git a/bugs/Bug_test.go b/bugs/Bug_test.go
index 76edfbb..9dc52dc 100644
--- a/bugs/Bug_test.go
+++ b/bugs/Bug_test.go
@@ -2,6 +2,8 @@ package bugs
import (
"fmt"
+ "io/ioutil"
+ "os"
"testing"
)
@@ -37,3 +39,26 @@ func TestTitleToDirectory(t *testing.T) {
assertDirectory("Test --WithSpace", "Test_--WithSpace")
assertDirectory("Test - What", "Test_-_What")
}
+
+func TestNewBug(t *testing.T) {
+ var gdir string
+ gdir, err := ioutil.TempDir("", "newbug")
+ if err == nil {
+ os.Chdir(gdir)
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
+ defer os.RemoveAll(gdir)
+ } else {
+ t.Error("Failed creating temporary directory for detect")
+ return
+ }
+ os.Mkdir("issues", 0755)
+ b, err := New("I am a test")
+ if err != nil || b == nil {
+ t.Error("Unexpected error when creating New bug" + err.Error())
+ }
+ if b.Dir != GetIssuesDir()+TitleToDir("I am a test") {
+ t.Error("Unexpected directory when creating New bug")
+ }
+}
diff --git a/bugs/IO_test.go b/bugs/IO_test.go
index 9b101ee..f91ec86 100644
--- a/bugs/IO_test.go
+++ b/bugs/IO_test.go
@@ -1,6 +1,7 @@
package bugs
import (
+ bugs "."
"fmt"
"io/ioutil"
"os"
@@ -41,8 +42,8 @@ func TestBugWrite(t *testing.T) {
}
func ExampleBugWriter() {
- b := &Bug{Dir: "/path/to/log/bug/issues/Bug-Title"}
-
- fmt.Fprintf(b, "This is a bug report.\n")
- fmt.Fprintf(b, "The bug will be created as necessary.\n")
+ if b, err := bugs.New("Bug Title"); err != nil {
+ fmt.Fprintf(b, "This is a bug report.\n")
+ fmt.Fprintf(b, "The bug will be created as necessary.\n")
+ }
}
From f0b6bc6d313d2ffd4cf2fbbc5e3602c4a93da687 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 20:10:23 -0500
Subject: [PATCH 27/47] Improved test coverage of bug package
---
bugs/Bug_test.go | 15 --------
bugs/Directory_test.go | 84 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+), 15 deletions(-)
create mode 100644 bugs/Directory_test.go
diff --git a/bugs/Bug_test.go b/bugs/Bug_test.go
index 9dc52dc..3cd393f 100644
--- a/bugs/Bug_test.go
+++ b/bugs/Bug_test.go
@@ -7,21 +7,6 @@ import (
"testing"
)
-func TestDirectoryToTitle(t *testing.T) {
- var assertTitle = func(directory, title string) {
- dir := Directory(directory)
- if dir.ToTitle() != title {
- t.Error("Failed on " + directory + ": got " + dir.ToTitle() + " but expected " + title)
- }
- }
- assertTitle("Test", "Test")
- assertTitle("Test-Multiword", "Test Multiword")
- assertTitle("Test--Dash", "Test-Dash")
- assertTitle("Test---Dash", "Test--Dash")
- assertTitle("Test_--TripleDash", "Test --TripleDash")
- assertTitle("Test_-_What", "Test - What")
-}
-
func TestTitleToDirectory(t *testing.T) {
var assertDirectory = func(title, directory string) {
titleStr := TitleToDir(title)
diff --git a/bugs/Directory_test.go b/bugs/Directory_test.go
new file mode 100644
index 0000000..388a7f8
--- /dev/null
+++ b/bugs/Directory_test.go
@@ -0,0 +1,84 @@
+package bugs
+
+import (
+ "io/ioutil"
+ "os"
+ "testing"
+)
+
+func TestGetRootDirWithEnvironmentVariable(t *testing.T) {
+ var gdir string
+ gdir, err := ioutil.TempDir("", "rootdirbug")
+ if err == nil {
+ os.Chdir(gdir)
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
+ defer os.RemoveAll(gdir)
+ } else {
+ t.Error("Failed creating temporary directory")
+ return
+ }
+ os.Mkdir("issues", 0755)
+ os.Setenv("PMIT", "/tmp/abc")
+ dir := GetRootDir()
+ if dir != Directory("/tmp/abc") {
+ t.Error("Did not get proper directory according to environment variable")
+ }
+}
+func TestGetRootDirFromDirectoryTree(t *testing.T) {
+ var gdir string
+ gdir, err := ioutil.TempDir("", "rootdirbug")
+ if err == nil {
+ os.Chdir(gdir)
+ os.Unsetenv("PMIT")
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
+ defer os.RemoveAll(gdir)
+ } else {
+ t.Error("Failed creating temporary directory")
+ return
+ }
+ // Make sure we get the right directory from the top level
+ os.Mkdir("issues", 0755)
+ dir := GetRootDir()
+ if dir != Directory(gdir) {
+ t.Error("Did not get proper directory according to walking the tree:" + dir)
+ }
+ // Now go deeper into the tree and try the same thing..
+ os.Mkdir("abc/123", 0755)
+ os.Chdir("abc/123")
+ dir = GetRootDir()
+ if dir != Directory(gdir) {
+ t.Error("Did not get proper directory according to walking the tree:" + dir)
+ }
+}
+
+func TestGetIssuesDir(t *testing.T) {
+ os.Setenv("PMIT", "/tmp/abc")
+ dir := GetIssuesDir()
+ if dir != "/tmp/abc/issues/" {
+ t.Error("Did not get correct issues directory")
+ }
+}
+func TestShortName(t *testing.T) {
+ var dir Directory = "/hello/i/am/a/test"
+ if short := dir.GetShortName(); short != Directory("test") {
+ t.Error("Unexpected short name: " + string(short))
+ }
+}
+func TestDirectoryToTitle(t *testing.T) {
+ var assertTitle = func(directory, title string) {
+ dir := Directory(directory)
+ if dir.ToTitle() != title {
+ t.Error("Failed on " + directory + ": got " + dir.ToTitle() + " but expected " + title)
+ }
+ }
+ assertTitle("Test", "Test")
+ assertTitle("Test-Multiword", "Test Multiword")
+ assertTitle("Test--Dash", "Test-Dash")
+ assertTitle("Test---Dash", "Test--Dash")
+ assertTitle("Test_--TripleDash", "Test --TripleDash")
+ assertTitle("Test_-_What", "Test - What")
+}
From ac15394b4765d83b4f54d916d0860b493bb60b4f Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 20:27:01 -0500
Subject: [PATCH 28/47] Improved coverage of Directory.go file
---
bugs/Directory.go | 4 ++++
bugs/Directory_test.go | 51 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/bugs/Directory.go b/bugs/Directory.go
index 050a856..39ab837 100644
--- a/bugs/Directory.go
+++ b/bugs/Directory.go
@@ -32,6 +32,10 @@ func GetRootDir() Directory {
}
func GetIssuesDir() Directory {
+ root := GetRootDir()
+ if root == "" {
+ return root
+ }
return GetRootDir() + "/issues/"
}
diff --git a/bugs/Directory_test.go b/bugs/Directory_test.go
index 388a7f8..6348b99 100644
--- a/bugs/Directory_test.go
+++ b/bugs/Directory_test.go
@@ -21,6 +21,7 @@ func TestGetRootDirWithEnvironmentVariable(t *testing.T) {
}
os.Mkdir("issues", 0755)
os.Setenv("PMIT", "/tmp/abc")
+ defer os.Unsetenv("PMIT")
dir := GetRootDir()
if dir != Directory("/tmp/abc") {
t.Error("Did not get proper directory according to environment variable")
@@ -47,21 +48,67 @@ func TestGetRootDirFromDirectoryTree(t *testing.T) {
t.Error("Did not get proper directory according to walking the tree:" + dir)
}
// Now go deeper into the tree and try the same thing..
- os.Mkdir("abc/123", 0755)
- os.Chdir("abc/123")
+ err = os.MkdirAll("abc/123", 0755)
+ if err != nil {
+ t.Error("Could not make directory for testing")
+ }
+ err = os.Chdir("abc/123")
+ if err != nil {
+ t.Error("Could not change directory for testing")
+ }
dir = GetRootDir()
if dir != Directory(gdir) {
t.Error("Did not get proper directory according to walking the tree:" + dir)
}
}
+func TestNoRoot(t *testing.T) {
+ var gdir string
+ gdir, err := ioutil.TempDir("", "rootdirbug")
+ if err == nil {
+ os.Chdir(gdir)
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
+ defer os.RemoveAll(gdir)
+ } else {
+ t.Error("Failed creating temporary directory")
+ return
+ }
+ // Don't create an issues directory. Just try and get the directory
+ if dir := GetRootDir(); dir != "" {
+ t.Error("Found unexpected issues directory." + string(dir))
+ }
+
+}
+
func TestGetIssuesDir(t *testing.T) {
os.Setenv("PMIT", "/tmp/abc")
+ defer os.Unsetenv("PMIT")
dir := GetIssuesDir()
if dir != "/tmp/abc/issues/" {
t.Error("Did not get correct issues directory")
}
}
+func TestGetNoIssuesDir(t *testing.T) {
+ var gdir string
+ gdir, err := ioutil.TempDir("", "rootdirbug")
+ if err == nil {
+ os.Chdir(gdir)
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
+ defer os.RemoveAll(gdir)
+ } else {
+ t.Error("Failed creating temporary directory")
+ return
+ }
+ // Don't create an issues directory. Just try and get the directory
+ if dir := GetIssuesDir(); dir != "" {
+ t.Error("Found unexpected issues directory." + string(dir))
+ }
+
+}
func TestShortName(t *testing.T) {
var dir Directory = "/hello/i/am/a/test"
if short := dir.GetShortName(); short != Directory("test") {
From d4cb7fe03ee4edacaccf532fd64952d17867b673 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sat, 23 Jan 2016 20:43:02 -0500
Subject: [PATCH 29/47] Added tests for bug descriptions
---
bugs/Bug_test.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/bugs/Bug_test.go b/bugs/Bug_test.go
index 3cd393f..d704e56 100644
--- a/bugs/Bug_test.go
+++ b/bugs/Bug_test.go
@@ -7,6 +7,34 @@ import (
"testing"
)
+type tester struct {
+ dir string
+ bug *Bug
+}
+
+func (t *tester) Setup() {
+ gdir, err := ioutil.TempDir("", "issuetest")
+ if err == nil {
+ os.Chdir(gdir)
+ t.dir = gdir
+ os.Unsetenv("PMIT")
+ // Hack to get around the fact that /tmp is a symlink on
+ // OS X, and it causes the directory checks to fail..
+ gdir, _ = os.Getwd()
+ } else {
+ panic("Failed creating temporary directory")
+ }
+ // Make sure we get the right directory from the top level
+ os.Mkdir("issues", 0755)
+ b, err := New("Test Bug")
+ if err != nil {
+ panic("Unexpected error creating Test Bug")
+ }
+ t.bug = b
+}
+func (t *tester) Teardown() {
+ os.RemoveAll(t.dir)
+}
func TestTitleToDirectory(t *testing.T) {
var assertDirectory = func(title, directory string) {
titleStr := TitleToDir(title)
@@ -47,3 +75,36 @@ func TestNewBug(t *testing.T) {
t.Error("Unexpected directory when creating New bug")
}
}
+
+func TestSetDescription(t *testing.T) {
+ test := tester{}
+ test.Setup()
+ defer test.Teardown()
+
+ b := test.bug
+
+ b.SetDescription("Hello, I am a bug.")
+ val, err := ioutil.ReadFile(string(b.GetDirectory()) + "/Description")
+ if err != nil {
+ t.Error("Could not read Description file")
+ }
+
+ if string(val) != "Hello, I am a bug." {
+ t.Error("Unexpected description after SetDescription")
+ }
+}
+
+func TestDescription(t *testing.T) {
+ test := tester{}
+ test.Setup()
+ defer test.Teardown()
+
+ b := test.bug
+
+ desc := "I am yet another bug.\nWith Two Lines."
+ b.SetDescription(desc)
+
+ if b.Description() != desc {
+ t.Error("Unexpected result from bug.Description()")
+ }
+}
From b4a63774c924df3242edd751ea743e75eeddb04c Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 24 Jan 2016 10:24:10 -0500
Subject: [PATCH 30/47] Added or removed issues with the tool "bug"
---
.../Description | 15 ---------------
.../Milestone | 1 -
.../Status | 1 -
issues/Roadmap.md | 1 -
4 files changed, 18 deletions(-)
delete mode 100644 issues/Implement-golang-io-interfaces-in-Bug-class/Description
delete mode 100644 issues/Implement-golang-io-interfaces-in-Bug-class/Milestone
delete mode 100644 issues/Implement-golang-io-interfaces-in-Bug-class/Status
diff --git a/issues/Implement-golang-io-interfaces-in-Bug-class/Description b/issues/Implement-golang-io-interfaces-in-Bug-class/Description
deleted file mode 100644
index 2314c16..0000000
--- a/issues/Implement-golang-io-interfaces-in-Bug-class/Description
+++ /dev/null
@@ -1,15 +0,0 @@
-The bugs.Bug class should implement some common
-go interfaces so that you can easily intergrate
-bug with other programs/libraries. In particular,
-the interfaces:
-
-1. io.Writer should append to the bug description
-2. io.WriterAt should modify the description
-3. io.Reader should print either the bug description
- or the full bug list BugIdx style output (not sure
- which, maybe have a flag in the bug struct to modify
- the two.)
-
-This would make it much easier to integrate bugs
-with logging systems when errors are encounterd by using
-ie. io.MultiWriter
diff --git a/issues/Implement-golang-io-interfaces-in-Bug-class/Milestone b/issues/Implement-golang-io-interfaces-in-Bug-class/Milestone
deleted file mode 100644
index 866c31a..0000000
--- a/issues/Implement-golang-io-interfaces-in-Bug-class/Milestone
+++ /dev/null
@@ -1 +0,0 @@
-v0.4
\ No newline at end of file
diff --git a/issues/Implement-golang-io-interfaces-in-Bug-class/Status b/issues/Implement-golang-io-interfaces-in-Bug-class/Status
deleted file mode 100644
index 4866642..0000000
--- a/issues/Implement-golang-io-interfaces-in-Bug-class/Status
+++ /dev/null
@@ -1 +0,0 @@
-In Progress on branch IOInterfaces
\ No newline at end of file
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index 0a5848c..156dd3e 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -2,4 +2,3 @@
## v0.4:
- bug-serve should have feature parity with bug
-- Implement golang io interfaces in Bug class
From ee56a034d6fdec69210a6fea084708219b9c1119 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 24 Jan 2016 16:25:36 -0500
Subject: [PATCH 31/47] Added If-Modified-Since handling
---
bug-serve/BugPageHandler.go | 94 -----------
bug-serve/MainPageHandler.go | 2 +-
bug-serve/RestfulBugHandler.go | 147 ++++++++++++++++++
bug-serve/bindata.go | 22 +--
.../Add-ability-to-edit-bugs/Description | 1 +
.../Add-ability-to-edit-bugs/Identifier | 3 +-
.../PUT-should-create-an-issue/Description | 3 +
.../Description | 3 +
.../Description | 1 -
bug-serve/jsx/BugPage.js | 2 +-
bugs/Directory.go | 34 ++++
bugs/Formats.go | 31 ++++
12 files changed, 234 insertions(+), 109 deletions(-)
delete mode 100644 bug-serve/BugPageHandler.go
create mode 100644 bug-serve/RestfulBugHandler.go
create mode 100644 bug-serve/issues/PUT-should-create-an-issue/Description
create mode 100644 bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description
delete mode 100644 bug-serve/issues/Send-Unmodified-header-when-appropriate/Description
create mode 100644 bugs/Formats.go
diff --git a/bug-serve/BugPageHandler.go b/bug-serve/BugPageHandler.go
deleted file mode 100644
index 5a8ac48..0000000
--- a/bug-serve/BugPageHandler.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package main
-
-import (
- "encoding/json"
- "github.com/driusan/GoWebapp/HTMLPageRenderer"
- "github.com/driusan/GoWebapp/URLHandler"
- "github.com/driusan/bug/bugs"
- "io/ioutil"
- "net/http"
- "strings"
-)
-
-type BugRenderer struct {
- HTMLPageRenderer.ReactPage
- Bug bugs.Bug
-}
-type BugPageHandler struct {
- URLHandler.DefaultHandler
-}
-
-func getBugList() (string, error) {
- issues, _ := ioutil.ReadDir(string(bugs.GetRootDir()) + "/issues")
-
- var issuesSlice []string
-
- for _, issue := range issues {
- if issue.IsDir() {
- issuesSlice = append(issuesSlice, issue.Name())
- }
- }
-
- retVal, _ := json.Marshal(issuesSlice)
- return string(retVal), nil
-}
-
-func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (string, error) {
- if r.URL.Path == "/issues" || r.URL.Path == "/issues/" {
- return getBugList()
- }
- // Strip off the "/issues/"
- bugURL := r.URL.Path[8:]
-
- // See if we're getting the whole bug JSON or
- // a field from it.
- pieces := strings.Split(bugURL, "/")
-
- b, err := bugs.LoadBugByDirectory(pieces[0])
- if err != nil {
- return "", URLHandler.NotFoundError{}
- }
-
- bJSONStruct := struct {
- Identifier string `json:",omitempty"`
- Title string
- Description string
- Status string `json:",omitempty"`
- Priority string `json:",omitempty"`
- Milestone string `json:",omitempty"`
- Tags []string `json:",omitempty"`
- }{
- Identifier: b.Identifier(),
- Title: b.Title(""),
- Description: b.Description(),
- Status: b.Status(),
- Priority: b.Priority(),
- Milestone: b.Milestone(),
- Tags: b.StringTags(),
- }
-
- bJSON, _ := json.Marshal(bJSONStruct)
- return string(bJSON), nil
- /*
- switch r.URL.Query().Get("format") {
- case "json":
- default:
- page := BugRenderer{Bug: b}
- page.RootElement = "RBugPage"
- page.Title = b.Title("")
- page.JSFiles = []string{
- // Bootstrap JS
- //"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
- // React JS
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
- "/js/BugPage.js",
- }
- page.CSSFiles = []string{
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css"}
- return HTMLPageRenderer.Render(page), nil
- }
- */
-
-}
diff --git a/bug-serve/MainPageHandler.go b/bug-serve/MainPageHandler.go
index 6c97aac..29f595e 100644
--- a/bug-serve/MainPageHandler.go
+++ b/bug-serve/MainPageHandler.go
@@ -19,7 +19,7 @@ func (m MainPageHandler) Get(r *http.Request, p map[string]interface{}) (string,
// React
"https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
"https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
- "/js/marked.min.js",
+ "/js/marked.min.js",
"/js/BugApp.js",
"/js/BugList.js",
"/js/BugPage.js",
diff --git a/bug-serve/RestfulBugHandler.go b/bug-serve/RestfulBugHandler.go
new file mode 100644
index 0000000..9528df5
--- /dev/null
+++ b/bug-serve/RestfulBugHandler.go
@@ -0,0 +1,147 @@
+package main
+
+import (
+ "crypto/sha1"
+ "encoding/json"
+ "fmt"
+ "github.com/driusan/GoWebapp/URLHandler"
+ "github.com/driusan/bug/bugs"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+ "time"
+)
+
+type BugPageHandler struct {
+ URLHandler.DefaultHandler
+}
+
+func getBugList() (string, error) {
+ issues, _ := ioutil.ReadDir(string(bugs.GetRootDir()) + "/issues")
+
+ var issuesSlice []string
+
+ for _, issue := range issues {
+ if issue.IsDir() {
+ issuesSlice = append(issuesSlice, issue.Name())
+ }
+ }
+
+ retVal, _ := json.Marshal(issuesSlice)
+ return string(retVal), nil
+}
+func parseURL(u *url.URL) []string {
+ if u.Path == "/issues" || u.Path == "/issues/" {
+ return []string{}
+ }
+ bugURL := strings.TrimPrefix(u.Path, "/issues/")
+ bugURL = strings.TrimRight(bugURL, "/")
+
+ return strings.Split(bugURL, "/")
+
+}
+
+func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (string, error) {
+ switch urlChunks := parseURL(r.URL); len(urlChunks) {
+ case 0:
+ return getBugList()
+ case 1:
+ b, err := bugs.LoadBugByDirectory(urlChunks[0])
+ if err != nil {
+ return "", URLHandler.NotFoundError{}
+ }
+ return b.ToJSONString()
+ default:
+ // Must be > 1, so check what field we're editing..
+ // Need to load the bug since this is a different
+ // case statement..
+ b, err := bugs.LoadBugByDirectory(urlChunks[0])
+ if err != nil {
+ return "", URLHandler.NotFoundError{}
+ }
+ switch urlChunks[1] {
+ case "Description":
+ return b.Description(), nil
+ default:
+ // No known field, so return a 404 error.
+ return "", URLHandler.NotFoundError{}
+ }
+ }
+ return "", URLHandler.NotFoundError{}
+}
+func (m BugPageHandler) Put(r *http.Request, extras map[string]interface{}) (string, error) {
+ urlChunks := parseURL(r.URL)
+ switch len(urlChunks) {
+ case 0:
+ return "", URLHandler.BadRequestError{}
+ case 1:
+ // This should eventually be supported if a JSON string
+ // is PUT, but for now we only support PUT to a specific
+ // field
+ return "", URLHandler.BadRequestError{}
+ }
+
+ b, err := bugs.LoadBugByDirectory(urlChunks[0])
+ if err != nil {
+ // This should create the issue instead, but for now
+ // only updating fields is supported
+ return "", URLHandler.BadRequestError{}
+ }
+ switch urlChunks[1] {
+ case "Description":
+ if val, err := ioutil.ReadAll(r.Body); err == nil {
+ b.SetDescription(string(val))
+ } else {
+ panic(err.Error())
+ }
+
+ }
+ return "", URLHandler.BadRequestError{}
+}
+
+func (m BugPageHandler) ETag(u *url.URL, o map[string]interface{}) (URLHandler.ETag, error) {
+ return "", nil
+ urlChunks := parseURL(u)
+ if len(urlChunks) == 0 {
+ return URLHandler.ETag(""), nil
+ }
+
+ b, err := bugs.LoadBugByDirectory(urlChunks[0])
+ if err != nil {
+ // If the bug doesn't exist, it's not an error, but there
+ // shouldn't be an ETag either..
+ return "", nil
+ }
+
+ h := sha1.New()
+ io.WriteString(h, b.Title(""))
+ io.WriteString(h, "--")
+ io.WriteString(h, b.Description())
+ io.WriteString(h, "--")
+ io.WriteString(h, b.Identifier())
+ io.WriteString(h, "--")
+ io.WriteString(h, b.Status())
+ io.WriteString(h, "--")
+ io.WriteString(h, b.Milestone())
+ io.WriteString(h, "--")
+ io.WriteString(h, b.Priority())
+ io.WriteString(h, "--")
+ io.WriteString(h, b.GetDirectory().LastModified().Format(time.UnixDate))
+ return URLHandler.ETag(fmt.Sprintf("%x", h.Sum(nil))), nil
+}
+
+func (m BugPageHandler) LastModified(u *url.URL, o map[string]interface{}) time.Time {
+ urlChunks := parseURL(u)
+ if len(urlChunks) == 0 {
+ return URLHandler.UnknownMTime
+ }
+
+ b, err := bugs.LoadBugByDirectory(urlChunks[0])
+ if err != nil {
+ return URLHandler.UnknownMTime
+ }
+ return b.GetDirectory().LastModified()
+
+}
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
index 02bff09..c8157ba 100644
--- a/bug-serve/bindata.go
+++ b/bug-serve/bindata.go
@@ -86,7 +86,7 @@ func jsBugappJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453426695, 0)}
+ info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453649978, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -106,12 +106,12 @@ func jsBuglistJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453426696, 0)}
+ info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453649979, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xdb\x6e\xdb\xb6\x1b\xbf\xcf\x53\xf0\xaf\x3f\x50\xd8\xa8\x6d\x24\x59\x07\x0c\xf1\x3a\x60\x75\x0a\xac\x40\xd2\x05\x49\xb7\x9b\x21\x17\xb4\x44\xdb\x5c\x29\x4a\x20\x29\x6f\x41\xe0\xdb\x5d\x0f\x7b\x82\x3d\xcb\x1e\x65\x4f\xb2\x8f\x94\x2c\x8b\x22\x75\x48\xe2\x64\x1e\x2f\xda\x98\xfc\xce\xfc\x0e\x3f\x6a\x8d\x05\x7a\x97\x2d\xaf\xf0\x92\xa0\xb7\xe8\x9a\xe0\x50\x4d\x42\x41\xb0\x22\x33\x86\xa5\x1c\xdc\x1f\x21\x58\x11\x95\x29\xc3\x77\x1f\x71\x4c\xce\x50\x50\xd0\x07\xa3\x23\x73\x18\x26\x71\x9a\x70\xc2\xd5\x39\x8d\x2e\x93\x8c\xab\x33\xb4\xc8\x78\xa8\x68\xc2\xd1\x60\x88\x72\x09\x7a\xd1\x05\x1a\xa8\x15\x95\x13\x41\x16\x72\x12\x11\x19\x56\x4f\xf5\xb2\x4f\x27\x94\x73\x22\xbe\xfb\x74\x79\x01\xa6\xc5\x58\x7c\x26\x51\xce\x9f\x8a\x24\x95\x93\x73\x20\x11\x34\xd5\x7a\x86\xd3\x52\xcc\xe6\xc8\x12\x26\x89\xba\x51\xe0\xcd\xc0\x56\x14\xbc\x8f\xa8\xa2\x7c\x19\x80\xad\x98\x49\xb2\x63\x2f\x44\x6d\x46\x8e\x6f\x3f\xa4\x11\x08\x3a\x00\xe7\x0a\xdb\x58\x82\xa3\x2b\x41\xd6\x34\xc9\x24\x5c\x49\x93\x61\x8b\x44\xa0\x81\xbe\x66\x0a\x8a\x4e\xa6\xf0\xdf\xd7\xa8\xa2\xe8\x5b\xc6\x80\x59\x4e\x18\xe1\x4b\xb5\xd2\xc7\xaf\x81\xac\x6e\xbb\xe6\x9f\x67\xcb\x19\xe6\x11\xd5\x51\x00\x51\xae\x8c\x9f\xe8\xed\xd4\xe2\xd2\x31\xb1\xb9\xde\x5a\x7c\xb3\x4c\x08\x88\x2d\xf0\xd6\xf5\x95\xf1\xca\x09\x2f\xc0\x55\xa0\x1a\xf8\x74\xa2\x31\x3a\xb9\x1d\x4e\x1d\x76\x41\x54\x26\xb8\xbd\xbf\xf1\xa4\x49\x95\xae\x12\xd9\x8f\xe4\x57\xd5\x37\xaa\xc7\x1d\x51\xd5\x26\xfe\x17\x23\xfb\x7a\xef\x91\x5d\x12\xf5\x81\x43\xe5\x61\x66\xaa\xb2\x29\xba\x39\x27\xea\x5b\xb3\x96\x0a\x02\x54\x3b\xf7\x9b\x34\xf4\x6c\x0e\x4a\x64\xcd\xbd\x01\xf3\x90\x30\x4d\xab\x89\x9f\xa8\xa8\xb5\x0b\x25\xfc\x7b\xb5\x22\x02\xdc\x99\x31\x1a\x42\xa7\xa8\x2a\x23\x7b\xd1\x66\x4b\xc8\x13\xc1\x51\x0b\xba\x2c\xbb\x20\xc6\x11\x11\x4d\x9e\xeb\xcc\x5e\x50\xc2\xa2\xeb\xe4\x17\xc8\xea\x1d\x11\x87\x31\x32\x82\x63\x96\x91\x7a\x76\xea\xbc\xf6\x1e\xe4\xea\x4c\x56\x54\x87\xd4\x7b\x46\x62\xb8\xe8\x81\x43\x6b\x1c\x8e\xe8\x3a\x18\x79\x8f\xee\x51\xa8\xc7\x5b\x31\xd0\x04\x18\x68\x2c\x0d\xb6\x9e\xd5\x57\x6f\x9d\x1d\x7a\x5d\xdd\x61\xc2\xc6\x71\x34\x3e\x69\x54\x6d\x24\xfe\xf5\x67\xe0\x3d\x1c\xfe\x4b\xe6\x9e\x22\x86\xe7\x84\xe5\xff\x8e\x29\x5f\x24\xad\xf6\xeb\x1b\x3f\x28\xfb\xdf\xa0\x39\x8e\x00\xc2\xb4\x19\x6d\xf2\xf0\xa0\xac\xfe\xf2\x91\x49\xe2\xec\x0e\x9b\x9a\xb7\x5e\xf5\xf6\x5e\x53\x99\x0a\x9a\x08\xaa\xee\x74\x49\x17\xd5\x3d\x08\xae\x8a\xcd\x60\x54\x6d\x20\xdb\xdd\x5a\xbc\x24\x34\xa7\x4c\x16\x5d\xa1\x14\x71\x63\x76\x6d\x01\xf9\x5e\x8d\x3d\xa6\x8c\x48\x05\xa8\xcc\x62\xbf\xdc\xee\xda\x12\xca\xed\x8a\xcb\xba\x31\xa5\x00\x9c\x0c\xc2\x1d\x21\x0e\x93\xde\xfc\x39\x75\xc1\x9c\x77\x9a\x7f\x83\x4e\xd0\xab\x57\xbe\x31\x7d\x7c\x8b\xfe\xd7\x73\x0e\x97\x06\x80\x17\x41\x5a\xc0\xb8\xa0\x12\x75\x44\xa0\x47\xf7\x61\xd2\xe8\x1c\xcf\x19\x89\x02\x1f\x0a\x7e\xac\x2b\xad\x60\xa6\xbf\x9b\x65\x70\xb5\xc5\xfa\x47\x97\x8b\x0e\x83\xdf\x3d\xeb\x32\x35\x9e\x3e\xa7\x6b\xcf\xfd\xe9\x54\x23\x93\x62\xf0\xe5\x20\x49\xb8\xc3\xa5\xe0\xaf\x3d\x80\x1a\x4b\xb8\xa1\x74\x79\xc6\x98\xbb\xeb\x93\x18\x28\xf0\x0b\xc3\x16\xe4\xaa\x7f\x1a\x9c\xc2\x09\x4c\x25\x09\x5b\x5f\x1c\xc3\xdf\x11\x59\xe0\x8c\xa9\x1f\x75\x4b\x3a\x43\xfe\x77\x02\xcc\xf1\x7e\xea\x9f\x3c\x2c\xf7\x34\x26\xe7\x99\x82\xca\x6c\x69\x82\xfe\x88\x96\xfc\x37\x78\x4d\x9e\x71\x2c\x76\x9a\x77\x0f\xc0\xcc\x20\xa3\xe2\x46\x6c\x40\xd8\xda\xaa\x67\x86\xb4\x77\xbb\xb6\x76\x86\x1d\x15\xb4\x9f\x6c\xbe\x87\x39\xb0\x80\xeb\xd6\xd2\x20\x01\x6d\x4f\x6d\x8c\xed\xf3\xd4\x9f\xa2\x8d\x7e\xd4\x91\x7f\xa7\xe5\x1e\xab\xdd\x6c\x79\x9a\xff\x9e\xba\xfc\x0a\x85\x09\x57\x98\xc2\xcb\xdd\x5b\x03\xfb\xaf\xb6\x9f\xb3\x78\x9e\x28\x01\xd5\x0d\xcf\x3d\x99\xc5\x31\x16\x77\x7b\x2a\xbf\xd5\xe9\xa3\x4b\xaf\x72\xbb\x9f\xa8\x62\x0f\x42\x49\x45\x7a\xba\x49\xfe\x12\xe1\x34\x78\x41\x36\x06\x70\x8b\x6d\xfc\xa7\x25\x6e\xf1\x1f\x97\xb8\xa4\xab\x7e\x9f\x39\x49\xdf\xf4\x4e\x4d\xa8\xdd\x0b\x2a\x95\x1e\x42\xe6\x1a\x41\x86\x79\xf1\xa1\x0f\x52\x66\x44\x36\x44\x54\x63\x81\x33\x0f\x64\xf0\x53\x27\xbc\xfa\x6c\x35\x5c\xce\xbb\xd2\x61\xdc\xbc\x6c\xc4\x60\xdc\x3e\xad\x9a\x33\xd6\x2b\xfb\x52\xbc\x6c\x68\x1c\x0f\x52\x67\x54\x32\xda\xf7\xf5\xb0\x03\x8d\x2d\x13\xe9\x41\xca\x8d\x01\xb8\x45\x7f\x6e\xc3\x2a\x9f\x20\xff\x77\xc6\x47\xed\xcb\x65\x9b\x5d\x8f\xb2\xcd\xd8\x27\x53\xdc\x36\xbc\x77\x66\x06\x58\x50\x3c\x5e\xd1\x28\x22\x3c\x00\x7b\x35\x42\x6c\x7d\x68\x95\x2a\xfe\xfe\xed\x77\xff\x08\xdf\xae\x86\x16\x58\x0a\x40\xdb\x28\x34\x8b\x71\xd1\x40\x8b\xe0\xe7\x4a\xa1\x20\x1f\xcb\xad\x51\x79\xd1\x0c\xda\x7e\xa0\x7a\x87\xc3\xcf\x5d\x57\x15\x5c\xe7\x98\x42\x25\x88\x41\xb7\x3b\xf0\x50\xef\xde\x3f\x87\x12\xeb\xca\xd7\xf0\xce\x50\x6b\x3a\xd4\xa1\xea\x80\xcb\xf9\x8f\x8e\x72\x7e\x68\xea\x74\x21\x81\xf2\xd7\xf6\xbb\xea\xd1\x66\x38\xfd\x27\x00\x00\xff\xff\x75\x5d\xdc\xb5\x93\x1b\x00\x00")
+var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xdb\x6e\xdb\x36\x18\xbe\xcf\x53\x70\x1a\x50\xd8\xa8\x63\xd4\x41\x37\x0c\xf1\x3a\x60\x75\x0a\xac\x40\xd2\x05\x49\xb7\x9b\x21\x17\xb4\x44\xdb\x5c\x29\x4a\x20\x29\x6f\x41\xe0\xdb\x5d\x0f\x7b\x82\x3d\xcb\x1e\x65\x4f\xb2\x9f\x94\x2c\x8b\x22\x75\x48\xe2\x64\x2e\x2f\xda\x98\xfc\xcf\xfc\x0f\x1f\xb5\xc6\x02\xbd\xcd\x96\x97\x78\x49\xd0\x1b\x74\x45\x70\xa8\xc6\xa1\x20\x58\x91\x19\xc3\x52\x0e\xee\x8e\x10\xac\x88\xca\x94\xe1\xdb\x0f\x38\x26\xa7\x28\x28\xe8\x83\xd1\x91\x39\x0c\x93\x38\x4d\x38\xe1\xea\x8c\x46\x17\x49\xc6\xd5\x29\x5a\x64\x3c\x54\x34\xe1\x68\x30\x44\xb9\x04\xbd\xe8\x02\x0d\xd4\x8a\xca\xb1\x20\x0b\x39\x8e\x88\x0c\xab\xa7\x7a\xd9\xa7\x63\xca\x39\x11\x3f\x7c\xbc\x38\x07\xd3\x62\x2c\x3e\x91\x28\xe7\x4f\x45\x92\xca\xf1\x19\x90\x08\x9a\x6a\x3d\xc3\x69\x29\x66\x73\x64\x09\x93\x44\x5d\x2b\xf0\x66\x60\x2b\x0a\xde\x45\x54\x51\xbe\x0c\xc0\x56\xcc\x24\xd9\xb1\x17\xa2\x36\x23\xc7\xb7\x9f\xd2\x08\x04\x1d\x80\x73\x85\x6d\x2c\xc1\xd1\xa5\x20\x6b\x9a\x64\x12\xae\xa4\xc9\xb0\x45\x22\xd0\x40\x5f\x33\x05\x45\x93\x29\xfc\xf7\x2d\xaa\x28\xfa\x9e\x31\x60\x96\x63\x46\xf8\x52\xad\xf4\xf1\x4b\x20\xab\xdb\xae\xf9\xe7\xd9\x72\x86\x79\x44\x75\x14\x40\x94\x2b\xe3\x17\x7a\x33\xb5\xb8\x74\x4c\x6c\xae\x37\x16\xdf\x2c\x13\x02\x62\x0b\xbc\x75\x7d\x65\xbc\x72\xc2\x73\x70\x15\xa8\x06\x3e\x9d\xe8\x18\x4d\x6e\x86\x53\x87\x5d\x10\x95\x09\x6e\xef\x6f\x3c\x69\x52\xa5\xab\x44\xf6\x03\xf9\x5d\xf5\x8d\xea\xab\x8e\xa8\x6a\x13\x3f\xc7\xc8\xbe\xdc\x7b\x64\x97\x44\xbd\xe7\x50\x79\x98\x99\xaa\x6c\x8a\x6e\xce\x89\xfa\xd6\xac\xa5\x82\x00\xd5\xce\xfd\x26\x0d\x3d\x9b\x83\x12\x59\x73\x6f\xc0\x3c\x24\x4c\xd3\x6a\xe2\x47\x2a\x6a\xed\x42\x09\xff\x51\xad\x88\x00\x77\x66\x8c\x86\xd0\x29\xaa\xca\xc8\x5e\xb4\xd9\x12\xf2\x44\x70\xd4\x82\x2e\xcb\x2e\x88\x71\x44\x44\x93\xe7\x3a\xb3\x17\x94\xb0\xe8\x2a\xf9\x0d\xb2\x7a\x47\xc4\x61\x8c\x8c\xe0\x98\x65\xa4\x9e\x9d\x3a\xaf\xbd\x07\xb9\x3a\x93\x15\xd5\x21\xf5\x8e\x91\x18\x2e\x7a\xe0\xd0\x1a\x87\x23\xba\x0e\x46\xde\xa3\x3b\x14\xea\xf1\x56\x0c\x34\x01\x06\x1a\x4b\x83\xad\x67\xf5\xd5\x5b\x67\x87\x5e\x57\x77\x98\xb0\xe3\x38\x3a\x9e\x34\xaa\x36\x12\xff\xf9\x3b\xf0\x1e\x0e\xff\x27\x73\x4f\x10\xc3\x73\xc2\xf2\x7f\x8f\x29\x5f\x24\xad\xf6\xeb\x1b\x3f\x28\xfb\x5f\xa3\x39\x8e\x00\xc2\xb4\x19\x6d\xf2\xf0\xa0\xac\xfe\xea\x81\x49\xe2\xec\x0e\x9b\x9a\xb7\x5e\xf5\xf6\x5e\x53\x99\x0a\x9a\x08\xaa\x6e\x75\x49\x17\xd5\x3d\x08\x2e\x8b\xcd\x60\x54\x6d\x20\xdb\xdd\x5a\xbc\x24\x34\xa7\x4c\x16\x5d\xa1\x14\x71\x6d\x76\x6d\x01\xf9\x5e\x8d\x3d\xa6\x8c\x48\x05\xa8\xcc\x62\xbf\xd8\xee\xda\x12\xca\xed\x8a\xcb\xba\x31\xa5\x00\x9c\x0c\xc2\x1d\x21\x0e\x93\xde\xfc\x39\x75\xc1\x9c\x77\x9a\x7f\x87\x26\xe8\xc5\x0b\xdf\x98\x7e\x75\x83\xbe\xe8\x39\x87\x4b\x03\xc0\x8b\x20\x2d\x60\x5c\x50\x89\x3a\x22\xd0\xa3\xfb\x30\x69\x74\x8e\xe7\x8c\x44\x81\x0f\x05\x3f\xd4\x95\x56\x30\xd3\xdf\xcd\x32\xb8\xda\x62\xfd\xa3\xcb\x45\x87\xc1\xef\x9e\x75\x99\x1a\x4f\x9f\xd1\xb5\xe7\xfe\x74\xaa\x91\x71\x31\xf8\x72\x90\x24\xdc\xe1\x52\xf0\xd7\x1e\x40\x8d\x25\xdc\x50\xba\x3c\x63\xcc\xdd\xf5\x49\x0c\x14\xf8\x85\x61\x0b\x72\xd5\x3f\x0d\x4e\xe0\x04\xa6\x92\x84\xad\xc9\xd7\xf0\x77\x44\x16\x38\x63\xea\x67\xdd\x92\x4e\x91\xff\x9d\x00\x73\xbc\x9f\xfa\x47\x0f\xcb\x3d\x8d\xc9\x79\xa6\xa0\x32\x5b\x9a\xa0\x3f\xa2\x25\xff\x35\x5e\x93\x27\x1c\x8b\x9d\xe6\xdd\x01\x30\x33\xc8\xa8\xb8\x11\x1b\x10\xb6\xb6\xea\x99\x21\xed\xdd\xae\xad\x9d\x61\x47\x05\xed\x27\x9b\xef\x60\x0e\x2c\xe0\xba\xb5\x34\x48\x40\xdb\x53\x1b\x63\xfb\x3c\xf5\xa7\x68\xa3\x1f\x75\xe4\xdf\x69\xb9\xc7\x6a\x37\x5b\x1e\xe7\xbf\xa7\x2e\xbf\x41\x61\xc2\x15\xa6\xf0\x72\xf7\xd6\xc0\xfe\xab\xed\xd7\x2c\x9e\x27\x4a\x40\x75\xc3\x73\x4f\x66\x71\x8c\xc5\xed\x9e\xca\x6f\x75\xf2\xe0\xd2\xab\xdc\xee\x47\xaa\xd8\xbd\x50\x52\x91\x9e\x6e\x92\x3f\x47\x38\x0d\x5e\x90\x8d\x01\xdc\x62\x1b\xff\x69\x89\x5b\xfc\xc7\x25\x2e\xe9\xaa\xdf\x27\x4e\xd2\xd7\xbd\x53\x13\x6a\xf7\x9c\x4a\xa5\x87\x90\xb9\x46\x90\x61\x5e\x7c\xe8\xbd\x94\x19\x91\x0d\x11\xd5\x58\xe0\xd4\x03\x19\xfc\xd4\x09\xaf\x3e\x5b\x0d\x97\xf3\xae\x74\x18\x37\xcf\x1b\x31\x18\xb7\x8f\xab\xe6\x8c\xf5\xca\xbe\x14\x2f\x1b\x1a\xc7\xbd\xd4\x19\x95\x8c\xf6\x7d\x3d\xec\x40\x63\xcb\x44\xba\x97\x72\x63\x00\x6e\xd1\x9f\xdb\xb0\xca\x27\xc8\x97\xce\xf8\xa8\x7d\xb9\x6c\xb3\xeb\x41\xb6\x19\xfb\x64\x8a\xdb\x86\xf7\xce\xcc\x00\x0b\x8a\x8f\x57\x34\x8a\x08\x0f\xc0\x5e\x8d\x10\x5b\x1f\x5a\xa5\x8a\x7f\xff\xf8\xd3\x3f\xc2\xb7\xab\xa1\x05\x96\x02\xd0\x36\x0a\xcd\x62\x5c\x34\xd0\x22\xf8\xa9\x52\x28\xc8\xc7\x72\x6b\x54\x9e\x35\x83\xb6\x1f\xa8\xde\xe2\xf0\x53\xd7\x55\x05\x57\x39\xa6\x50\x09\x62\xd0\xed\x0e\x3c\xd4\xbb\xf7\xcf\xa1\xc4\xba\xf2\x35\xbc\x33\xd4\x9a\x0e\x75\xa8\x3a\xe0\x72\xfe\xab\xa3\x9c\xef\x9b\x3a\x5d\x48\xa0\xfc\xb5\xfd\xae\x7a\xb4\x19\x4e\xff\x0b\x00\x00\xff\xff\xef\xd8\x7e\x42\x93\x1b\x00\x00")
func jsBugpageJsBytes() ([]byte, error) {
return bindataRead(
@@ -126,7 +126,7 @@ func jsBugpageJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugPage.js", size: 7059, mode: os.FileMode(436), modTime: time.Unix(1453426696, 0)}
+ info := bindataFileInfo{name: "js/BugPage.js", size: 7059, mode: os.FileMode(436), modTime: time.Unix(1453649979, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -203,9 +203,9 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
- "js/BugApp.js": jsBugappJs,
- "js/BugList.js": jsBuglistJs,
- "js/BugPage.js": jsBugpageJs,
+ "js/BugApp.js": jsBugappJs,
+ "js/BugList.js": jsBuglistJs,
+ "js/BugPage.js": jsBugpageJs,
"js/marked.min.js": jsMarkedMinJs,
}
@@ -248,11 +248,12 @@ type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
+
var _bintree = &bintree{nil, map[string]*bintree{
"js": &bintree{nil, map[string]*bintree{
- "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
- "BugList.js": &bintree{jsBuglistJs, map[string]*bintree{}},
- "BugPage.js": &bintree{jsBugpageJs, map[string]*bintree{}},
+ "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
+ "BugList.js": &bintree{jsBuglistJs, map[string]*bintree{}},
+ "BugPage.js": &bintree{jsBugpageJs, map[string]*bintree{}},
"marked.min.js": &bintree{jsMarkedMinJs, map[string]*bintree{}},
}},
}}
@@ -303,4 +304,3 @@ func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
-
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Description b/bug-serve/issues/Add-ability-to-edit-bugs/Description
index 0968669..5ba8744 100644
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Description
+++ b/bug-serve/issues/Add-ability-to-edit-bugs/Description
@@ -1,3 +1,4 @@
You should be able to edit bugs via AJAX in bug-serve
And you should be able to edit them with markdown.
+
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Identifier b/bug-serve/issues/Add-ability-to-edit-bugs/Identifier
index 0c05f99..9910222 100644
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Identifier
+++ b/bug-serve/issues/Add-ability-to-edit-bugs/Identifier
@@ -1 +1,2 @@
-editbug
\ No newline at end of file
+editbug
+
diff --git a/bug-serve/issues/PUT-should-create-an-issue/Description b/bug-serve/issues/PUT-should-create-an-issue/Description
new file mode 100644
index 0000000..6842253
--- /dev/null
+++ b/bug-serve/issues/PUT-should-create-an-issue/Description
@@ -0,0 +1,3 @@
+When PUTing a description to a field that doesn't exist,
+the issue should be created instead of returning a 400
+error.
diff --git a/bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description b/bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description
new file mode 100644
index 0000000..61776b8
--- /dev/null
+++ b/bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description
@@ -0,0 +1,3 @@
+A PUT of valid JSON to /issues/Bug-Title should create
+Bug-Title if it doesn't exist, and overwrite Bug-Title
+if the JSON is valid and ETag matches
diff --git a/bug-serve/issues/Send-Unmodified-header-when-appropriate/Description b/bug-serve/issues/Send-Unmodified-header-when-appropriate/Description
deleted file mode 100644
index 7db570e..0000000
--- a/bug-serve/issues/Send-Unmodified-header-when-appropriate/Description
+++ /dev/null
@@ -1 +0,0 @@
-Everything responds with a 200 or 404 now.
diff --git a/bug-serve/jsx/BugPage.js b/bug-serve/jsx/BugPage.js
index 8b5d595..f64c3bc 100644
--- a/bug-serve/jsx/BugPage.js
+++ b/bug-serve/jsx/BugPage.js
@@ -90,7 +90,7 @@ var BugPage = React.createClass({
var descDiv;
if (this.state.Editing === true) {
descDiv = (
-
+
diff --git a/bugs/Directory.go b/bugs/Directory.go
index 39ab837..c31b30c 100644
--- a/bugs/Directory.go
+++ b/bugs/Directory.go
@@ -1,6 +1,7 @@
package bugs
import (
+ "time"
"os"
"regexp"
"strings"
@@ -59,3 +60,36 @@ func (d Directory) ToTitle() string {
return strings.Replace(match, "_", " ", -1)
})
}
+
+func (d Directory) LastModified() time.Time {
+ var t time.Time
+ stat, err := os.Stat(string(d))
+ if err != nil {
+ panic("Directory " + string(d) + " is not a directory.")
+ }
+
+ if stat.IsDir() == false {
+ return stat.ModTime()
+ }
+
+ dir, _ := os.Open(string(d))
+ files, _ := dir.Readdir(-1)
+ if len(files) == 0 {
+ t = stat.ModTime()
+ }
+ for _, file := range files {
+ if file.IsDir() {
+ mtime := (d +"/" + Directory(file.Name())).LastModified()
+ if mtime.After(t) {
+ t = mtime
+ }
+ } else {
+ mtime := file.ModTime()
+ if mtime.After(t) {
+ t = mtime
+ }
+
+ }
+ }
+ return t
+}
diff --git a/bugs/Formats.go b/bugs/Formats.go
new file mode 100644
index 0000000..d3bd69d
--- /dev/null
+++ b/bugs/Formats.go
@@ -0,0 +1,31 @@
+package bugs
+import (
+ "encoding/json"
+)
+
+
+func (b Bug) ToJSONString() (string, error) {
+ bJSONStruct := struct {
+ Identifier string `json:",omitempty"`
+ Title string
+ Description string
+ Status string `json:",omitempty"`
+ Priority string `json:",omitempty"`
+ Milestone string `json:",omitempty"`
+ Tags []string `json:",omitempty"`
+ }{
+ Identifier: b.Identifier(),
+ Title: b.Title(""),
+ Description: b.Description(),
+ Status: b.Status(),
+ Priority: b.Priority(),
+ Milestone: b.Milestone(),
+ Tags: b.StringTags(),
+ }
+
+ bJSON, err := json.Marshal(bJSONStruct)
+ if err != nil {
+ return "", err
+ }
+ return string(bJSON), nil
+}
From 7b3c1c9b20d3281dbb15476a0ec7d17606d82680 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Tue, 26 Jan 2016 19:27:26 -0500
Subject: [PATCH 32/47] Added or removed issues with the tool "bug"
---
.../Bug.Close-should-be-able-to-notify-people/Description | 6 ++++++
issues/Bug.Close-should-be-able-to-notify-people/Milestone | 1 +
issues/Roadmap.md | 3 +++
3 files changed, 10 insertions(+)
create mode 100644 issues/Bug.Close-should-be-able-to-notify-people/Description
create mode 100644 issues/Bug.Close-should-be-able-to-notify-people/Milestone
diff --git a/issues/Bug.Close-should-be-able-to-notify-people/Description b/issues/Bug.Close-should-be-able-to-notify-people/Description
new file mode 100644
index 0000000..d6aa579
--- /dev/null
+++ b/issues/Bug.Close-should-be-able-to-notify-people/Description
@@ -0,0 +1,6 @@
+When a bug is closed with bug.Close(), instead of
+just closing the file descriptor, there should
+be a method of notifying things other than the VCS
+that a bug was created (ie. email, send a post
+to a url, etc) so make it more useful to embed
+the bugs library into other applications.
diff --git a/issues/Bug.Close-should-be-able-to-notify-people/Milestone b/issues/Bug.Close-should-be-able-to-notify-people/Milestone
new file mode 100644
index 0000000..4ea1309
--- /dev/null
+++ b/issues/Bug.Close-should-be-able-to-notify-people/Milestone
@@ -0,0 +1 @@
+v0.5
\ No newline at end of file
diff --git a/issues/Roadmap.md b/issues/Roadmap.md
index 156dd3e..b7af0ec 100644
--- a/issues/Roadmap.md
+++ b/issues/Roadmap.md
@@ -1,4 +1,7 @@
# Roadmap for bug
+## v0.5:
+- Bug.Close should be able to notify people
+
## v0.4:
- bug-serve should have feature parity with bug
From a0d9fcbc9c848ea4a2fef5203ad23bac07e2775e Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Tue, 26 Jan 2016 21:14:58 -0500
Subject: [PATCH 33/47] Implemented editing and deleting of bugs in bug-serve
---
bug-serve/RestfulBugHandler.go | 20 +++++-
bug-serve/bindata.go | 10 +--
.../Add-ability-to-edit-bugs/Description | 4 --
.../Add-ability-to-edit-bugs/Identifier | 2 -
.../issues/Add-ability-to-edit-bugs/Milestone | 1 -
.../issues/Add-ability-to-edit-bugs/Priority | 1 -
.../issues/Add-ability-to-edit-bugs/Status | 1 -
.../issues/Add-ability-to-edit-bugs/tags/test | 0
.../issues/Add-ability-to-edit-bugs/tags/whee | 0
.../Implement-save-and-Cancel/Description | 2 -
bug-serve/jsx/BugApp.js | 62 +++++++++++++++++--
bug-serve/jsx/BugPage.js | 40 +++++++++++-
bugs/Bug.go | 1 +
bugs/Directory.go | 56 ++++++++---------
bugs/Formats.go | 10 +--
bugs/IO.go | 8 +++
16 files changed, 159 insertions(+), 59 deletions(-)
delete mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Description
delete mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Identifier
delete mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Milestone
delete mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Priority
delete mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/Status
delete mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/tags/test
delete mode 100644 bug-serve/issues/Add-ability-to-edit-bugs/tags/whee
delete mode 100644 bug-serve/issues/Implement-save-and-Cancel/Description
diff --git a/bug-serve/RestfulBugHandler.go b/bug-serve/RestfulBugHandler.go
index 9528df5..fb655fe 100644
--- a/bug-serve/RestfulBugHandler.go
+++ b/bug-serve/RestfulBugHandler.go
@@ -71,6 +71,7 @@ func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (str
}
return "", URLHandler.NotFoundError{}
}
+
func (m BugPageHandler) Put(r *http.Request, extras map[string]interface{}) (string, error) {
urlChunks := parseURL(r.URL)
switch len(urlChunks) {
@@ -93,6 +94,7 @@ func (m BugPageHandler) Put(r *http.Request, extras map[string]interface{}) (str
case "Description":
if val, err := ioutil.ReadAll(r.Body); err == nil {
b.SetDescription(string(val))
+ return "", nil
} else {
panic(err.Error())
}
@@ -101,9 +103,25 @@ func (m BugPageHandler) Put(r *http.Request, extras map[string]interface{}) (str
return "", URLHandler.BadRequestError{}
}
-func (m BugPageHandler) ETag(u *url.URL, o map[string]interface{}) (URLHandler.ETag, error) {
+func (m BugPageHandler) Delete(r *http.Request, extras map[string]interface{}) (string, error) {
+ urlChunks := parseURL(r.URL)
+ if len(urlChunks) != 1 {
+ return "", URLHandler.BadRequestError{}
+ }
+
+ b, err := bugs.LoadBugByDirectory(urlChunks[0])
+ if err != nil {
+ return "", URLHandler.NotFoundError{}
+ }
+
+ if err := b.Remove(); err != nil {
+ panic("Could not delete bug.")
+ }
return "", nil
+}
+func (m BugPageHandler) ETag(u *url.URL, o map[string]interface{}) (URLHandler.ETag, error) {
urlChunks := parseURL(u)
+ fmt.Printf("Calculating ETag for %s => %s\n", u, urlChunks)
if len(urlChunks) == 0 {
return URLHandler.ETag(""), nil
}
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
index c8157ba..77d17f6 100644
--- a/bug-serve/bindata.go
+++ b/bug-serve/bindata.go
@@ -71,7 +71,7 @@ func (fi bindataFileInfo) Sys() interface{} {
return nil
}
-var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x55\xcf\x4f\xe3\x3a\x10\x3e\xa7\x7f\x85\x5f\x0e\x28\xe8\x55\x81\xf7\xb4\xa7\xa2\x1e\xa0\x20\x60\xc5\x2f\x41\x0f\x2b\xad\xf6\x60\x92\x69\xeb\xc5\x75\xb2\xb6\xc3\x82\x50\xff\xf7\x1d\x7b\x9c\xc6\x85\x66\x81\x4b\xa5\x8e\xbf\x6f\xe6\x9b\x9f\x79\xe4\x9a\x1d\x35\xf3\xc3\xba\x66\x63\x76\x0b\xbc\xb0\x79\xa1\x81\x5b\x98\x48\x6e\x4c\xf6\x32\x48\x4a\x61\x6a\xc9\x9f\xaf\xf8\x12\x46\x2c\x25\x6c\x3a\x1c\x0c\x92\xa2\x5a\xd6\x95\x02\x65\x8f\x45\x79\x59\x35\xca\x8e\xd8\xac\x51\x85\x15\x95\x62\xd9\x2e\x43\x6a\xe2\xbc\xdb\x05\xb7\xe8\xdb\x2e\x84\x39\x40\xd3\xe1\x4f\xfe\x74\x0a\x36\x4b\xf7\x84\x31\x0d\x98\xbd\x74\x18\xd1\x34\x18\xf4\x69\x80\xe8\x89\xe3\xe6\x06\xec\x9d\x45\x45\x99\x37\x25\x4e\x82\x49\x47\xec\xeb\xdd\xf5\x55\x5e\x73\x6d\xa0\x63\x39\xc0\x6a\xd7\x85\xa1\xdf\x2e\x18\x3a\xb1\x42\x21\xf1\xb3\xd1\xee\x5a\xe2\x87\x22\xae\x86\x83\x64\x0e\xf6\x5c\x09\x2b\xb8\xf4\x8e\xde\x56\x45\x83\x6d\xb4\xa2\x98\xb1\xff\x17\xc7\x46\xd3\x54\x58\x09\xf8\x3f\xbd\xae\x41\xb1\x73\x5f\xa6\x94\x9e\x42\xee\xdf\x7f\x0c\x03\x59\x42\x61\xa1\x44\x33\x5a\x55\x23\xe5\x1b\xfb\xb1\xd0\xce\x55\xea\x14\x06\x81\xb2\xe2\xee\x25\x16\x76\xdf\xcc\x3f\xd1\x31\xf6\x2f\x43\x02\xfe\xa6\x9f\xee\x5e\xa4\x6c\x7b\x41\x87\x6d\xd9\x5f\x65\x80\x01\xb7\xd4\xda\x78\x18\x82\xce\xb8\x2a\x25\xe8\x38\xa7\x20\x03\xf2\x5a\xc3\xa3\x1b\x53\x98\xf1\x46\xda\xcc\x7b\x70\xc9\xe5\xa1\x10\x19\xe4\x45\xa3\x35\x42\xa6\x5c\x63\xf7\x72\x0b\x4f\x76\x52\x29\x8b\x96\x36\x10\xea\xc3\x44\x82\xa8\xb7\x2d\xf5\xee\xba\x54\xd9\x96\xce\xb0\x55\xe7\x4b\x95\x9b\x52\xbb\xda\x17\x14\xd6\x49\x14\x33\x96\x91\x5f\xe7\x34\x8f\x3c\xb2\x7f\xc6\xde\x65\xa8\x73\xe0\xbc\x5a\xe0\x13\x09\x4b\xb4\x66\x88\xbf\xe1\x73\x18\x12\x36\xf1\xc3\x35\x62\xdb\x1d\xe7\xfe\x95\x5a\x70\x0c\xa6\xd0\xa2\x76\x02\x7b\xe1\x11\x86\x48\x97\x42\x82\xb1\x78\x15\x7a\x29\x6b\x04\x11\x5c\xc1\x1a\xd3\x8b\xa6\x67\x82\xde\x68\x51\x69\x61\x9f\x7b\xc1\x2d\x80\xe0\xe7\x25\x66\x2f\x66\xc2\x55\xba\x87\xd0\x41\x88\x32\xe5\xf3\x7e\x29\xee\x91\x60\x95\x3a\xe2\xc5\x43\x00\x6e\x0c\x06\xbd\x1f\x4a\xe9\xf6\x74\xc3\x93\x33\xd0\xeb\x84\x46\xcd\x2f\xc0\xf6\x50\x38\xf0\x6d\xa0\x6b\xbb\x00\x8d\xa6\x89\x14\xc5\x83\x1b\xbc\x30\x68\x9b\x53\x4f\xe8\x8b\x76\xad\xe3\xd9\x8e\x76\x86\x81\x34\xf0\xc1\x89\xb9\x10\xc6\xf6\x4f\x4c\x34\x25\x7f\x49\x14\xcb\xf4\x9e\xf0\x48\x5d\x77\x17\xb7\x49\xf2\x57\xad\x14\x8f\x74\x06\xd7\x87\xae\x0f\x9a\xa4\x8b\xff\x08\xda\x61\x93\x94\x2e\x29\x9b\x55\x38\x11\xe1\x75\xa3\x01\x74\x88\x29\x3b\xf7\xba\xfb\x4e\x8c\xb5\x9e\x28\x48\xa8\xac\xa7\xe3\x8f\x5f\xf9\x81\x4b\x71\xe0\xb6\x3b\x9c\x52\xac\x7b\xb7\xfb\x8d\x96\x43\x56\x70\x29\xef\x71\xa8\xfc\x46\x3b\xe4\xd3\x52\x2e\xac\x75\x1f\x65\x05\xbf\xd9\xb7\xcb\x8b\x33\xfc\x77\x0b\xbf\x30\x01\xba\x60\x01\x90\x57\x0a\x95\x95\xcf\x3e\x87\x62\xc1\xd5\x1c\x36\xbc\xd3\x89\x58\x9f\x12\x8f\xf5\x47\x8a\x8d\xc7\x63\xf6\x85\xed\xec\x74\xcd\x6b\x0c\x1a\xd9\xff\xfb\xfb\xed\x5d\x09\xa2\x5a\x2a\x5d\xe8\x29\x1e\xc7\xb6\x65\xab\x58\x08\x7e\xac\xb2\xf4\xf4\x64\x8a\x9f\x04\x9f\x93\xd5\x0d\xc4\x4a\x0d\x9e\x3d\x27\x7d\x75\xf0\x27\x00\x00\xff\xff\xb1\x0c\x38\xdf\x75\x08\x00\x00")
+var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xdc\x56\x4d\x6f\xe3\x36\x10\x3d\xdb\xbf\x82\xd5\x61\xa1\xa0\xaa\x76\xfb\x71\x4a\xeb\x02\xd9\xd8\xd8\xa4\x48\x36\x41\xe2\x02\x05\x8a\x1e\xb8\xd2\xd8\x66\x97\x91\x5c\x72\x94\x26\x58\xe4\xbf\x77\xc8\xa1\x2c\x2a\x96\xf2\x71\x28\x0a\xf4\x62\xc0\x9c\x37\xc3\x37\x8f\x8f\x43\xdd\x4a\x23\xde\x37\xeb\xa3\xed\x56\xcc\xc4\x15\xc8\x02\xf3\xc2\x80\x44\x38\xd6\xd2\xda\xf4\xcb\x74\x52\x2a\xbb\xd5\xf2\xfe\xa3\xbc\x81\x43\x91\x30\x36\xc9\xa6\xd3\x89\x01\x5d\xcb\xf2\xd4\xda\x06\xec\xa1\x58\x35\x55\x81\xaa\xae\x44\x7a\x20\x28\x6b\xe2\x0a\xe3\x46\x22\x95\xc5\x8d\xb2\x3f\xd2\xd2\xd1\x9f\xf2\xee\x03\x60\x9a\xbc\x55\x3e\xe9\x6d\x92\x45\x69\x06\xec\xb6\xae\x2c\x70\xfa\xc4\xe5\xe6\x16\xf0\x1a\x89\x4c\xea\x97\x26\x6e\x77\x9b\x1c\x8a\x5f\xae\x2f\x3e\xe6\x5b\x69\x2c\x74\x59\x0e\xf0\x70\xe0\xb6\xf1\xbf\x0f\x59\x4b\xf0\x1a\x10\x55\xb5\x7e\x2d\x45\x1b\xd2\x5e\xcd\xb1\xdd\xef\xe5\x3c\x8b\xfa\x86\x62\x50\xe1\x5c\x95\xe7\x75\x53\xe1\x3e\x55\xc7\x2f\x8f\x05\x4f\x7d\x89\x68\xb9\xdd\x36\x6d\xab\xae\x01\x4f\x2b\x85\x4a\x6a\x4f\x6f\xbf\xa6\x01\x6c\x4c\xc5\x9d\xc4\xac\xbf\xb8\x6c\x5a\x5a\x2a\xd4\x40\xff\x93\x8b\x2d\x54\x82\xb7\x4d\x38\x14\xce\xe1\xf7\x3f\xb2\x90\xac\xa1\x40\x28\x69\x99\x56\xab\x46\xeb\xbd\xf5\xb9\x32\xae\x54\xe2\xfa\x0e\x04\x1d\x6b\x8a\xc4\xc4\x3e\x35\xeb\x57\xb8\x47\x7c\x2d\x28\x81\x7e\x93\x61\x27\x65\x62\x23\xab\x52\x83\x79\xfa\xb8\x62\xee\x43\x27\x96\xed\x01\x17\x4b\xe9\xc0\xa1\x7a\x4e\x4a\x5f\x05\xf0\x09\xc8\x12\x4c\x9a\x78\xc4\x40\x26\xcb\x40\xac\x07\x6c\x60\x3d\x8c\x40\x27\x5c\x37\x16\x26\x38\x0e\xf2\xad\x81\x5b\xe7\x14\x58\xc9\x46\x63\xe4\x82\xa0\x66\x0a\x79\xd1\x18\x43\x90\xa5\x34\x44\x2c\x47\xb8\xc3\xe3\xba\x42\x5a\xe9\xee\x85\x13\x21\x90\x1a\xf1\x5a\x27\x93\x78\xc9\xf1\x06\x45\x9e\x38\x7a\x17\xea\x5f\x4e\xda\xc2\xf9\x68\xd4\xec\x11\xc9\x3d\xb7\x47\x97\x80\x8b\x55\x65\x5f\xb0\xce\x46\x05\x37\xef\x0a\xa8\x95\x48\xb9\x3b\xd7\x5a\x1e\x71\x14\x5f\xcd\x3c\xc3\xe0\x94\x90\xf3\x68\x24\x2e\x34\xdc\xd0\x6a\x4a\xf8\x4b\xb9\x26\x7b\xb1\x85\xfc\x3d\x39\x14\xc3\x85\x73\x1f\x65\x23\xcc\xc1\x16\x46\x6d\x1d\xc1\x51\x78\x84\xe1\xa4\x73\xa5\xc1\x22\x8d\x87\xd1\x94\x1d\x82\x13\xdc\xb1\x35\x76\x14\xcd\x61\x86\x5e\x1a\x55\x1b\x85\xf7\xa3\xe0\x16\xc0\xf0\xd3\x92\xba\x57\x2b\xe5\x94\x1e\x49\xe8\x20\x9c\x42\xb6\x18\xa7\xe2\x82\x0c\xab\xab\xf7\xb2\xf8\x1c\x80\xbd\x93\x6f\xe3\x73\xfa\x8f\x10\x23\x9c\x77\x38\x7a\xa4\x35\x1b\x29\xda\xa7\x8b\x1e\xf3\x75\xf0\x93\x66\x98\x08\x19\xb4\x07\x75\x66\x1e\xc3\xba\x58\xcb\xe9\x02\x37\x60\x68\xed\x58\xab\xe2\xb3\xbb\x49\xe1\xe6\xf4\xaf\x31\xa3\xcf\xda\x61\x17\x5f\xd6\x68\x08\x08\xd0\x16\x5e\x68\xbe\x33\x65\x71\xdc\x7c\x91\xe1\x9e\x50\x85\x14\x7f\x8e\x78\xc4\xae\x7b\x2d\x86\x28\xf9\x0b\x5f\xaa\x5b\x7e\x1c\x76\x33\x60\x0c\x3a\x49\x36\xdf\x32\xb4\xc3\x4e\x12\xbe\xd1\x62\x55\x93\xb9\x42\xb4\x77\x02\xfc\x3c\x71\x77\x2e\x7a\xf0\xcc\x1e\x3b\x3e\xd1\x26\x41\x59\x9f\x4e\x3f\x7e\x7a\x4c\x5d\x8b\x53\x37\x28\xc2\x03\x43\xba\x77\x63\xa4\x31\x3a\x13\x85\xd4\xfa\x13\xf9\xd3\x0f\x07\x87\xbc\xbb\xd1\x1b\x44\xf7\xc5\x54\xc1\xdf\xe2\xb7\xf3\xb3\x13\xfa\x77\x05\x7f\x51\x03\x3c\x92\x03\x20\xaf\x2b\x62\x56\xde\xfb\x1e\x0a\x7a\x2e\xd6\xd0\xab\xce\xd3\x66\x37\x95\x3c\xd6\x4f\x5d\x31\x9b\xcd\xc4\x0f\xe2\xcd\x9b\xee\xf0\x1a\x4b\x8b\xe2\xbb\x77\xef\xda\x11\x15\x48\xb5\xa9\xfc\xfe\x2c\x69\xda\x67\x3e\xa9\x3d\xb8\x87\x98\x0e\x3d\xe4\x69\xf2\x61\xb1\xa4\xe7\xd2\x77\x86\xa6\x81\x98\xaf\xa5\x39\xea\x1a\x78\x88\x24\xb9\x6c\x06\x24\x29\x25\xca\x4e\x98\x4c\x00\xca\xf5\x7f\x2d\xcf\xcf\x5e\x9e\xc7\xab\x3f\x89\xef\x5f\xa0\xd9\xb8\x5a\x97\xbf\xee\xa9\xe5\x18\xed\x1a\x8e\xb4\xc3\xd0\x63\xfb\x11\x70\xba\xfa\xe6\x5c\x62\xb1\x49\x82\x3e\xde\x6e\x7d\xad\x9d\x8e\xfb\x7a\xbb\xaf\x90\xe7\x34\xf7\x9b\x07\x3c\xc7\xfd\xb7\x8b\x45\x43\xf7\x44\xad\xee\xb9\x74\x84\xef\xef\xc2\xf3\x74\xdc\xeb\xff\xe7\x23\x9d\x2f\xce\x16\xcb\xc5\xbf\x78\xaa\x5e\xeb\x7f\x02\x00\x00\xff\xff\x17\x7e\x3a\xfe\x5a\x0d\x00\x00")
func jsBugappJsBytes() ([]byte, error) {
return bindataRead(
@@ -86,7 +86,7 @@ func jsBugappJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugApp.js", size: 2165, mode: os.FileMode(436), modTime: time.Unix(1453649978, 0)}
+ info := bindataFileInfo{name: "js/BugApp.js", size: 3418, mode: os.FileMode(436), modTime: time.Unix(1453860464, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -106,12 +106,12 @@ func jsBuglistJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453649979, 0)}
+ info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453860464, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x58\xdb\x6e\xdb\x36\x18\xbe\xcf\x53\x70\x1a\x50\xd8\xa8\x63\xd4\x41\x37\x0c\xf1\x3a\x60\x75\x0a\xac\x40\xd2\x05\x49\xb7\x9b\x21\x17\xb4\x44\xdb\x5c\x29\x4a\x20\x29\x6f\x41\xe0\xdb\x5d\x0f\x7b\x82\x3d\xcb\x1e\x65\x4f\xb2\x9f\x94\x2c\x8b\x22\x75\x48\xe2\x64\x2e\x2f\xda\x98\xfc\xcf\xfc\x0f\x1f\xb5\xc6\x02\xbd\xcd\x96\x97\x78\x49\xd0\x1b\x74\x45\x70\xa8\xc6\xa1\x20\x58\x91\x19\xc3\x52\x0e\xee\x8e\x10\xac\x88\xca\x94\xe1\xdb\x0f\x38\x26\xa7\x28\x28\xe8\x83\xd1\x91\x39\x0c\x93\x38\x4d\x38\xe1\xea\x8c\x46\x17\x49\xc6\xd5\x29\x5a\x64\x3c\x54\x34\xe1\x68\x30\x44\xb9\x04\xbd\xe8\x02\x0d\xd4\x8a\xca\xb1\x20\x0b\x39\x8e\x88\x0c\xab\xa7\x7a\xd9\xa7\x63\xca\x39\x11\x3f\x7c\xbc\x38\x07\xd3\x62\x2c\x3e\x91\x28\xe7\x4f\x45\x92\xca\xf1\x19\x90\x08\x9a\x6a\x3d\xc3\x69\x29\x66\x73\x64\x09\x93\x44\x5d\x2b\xf0\x66\x60\x2b\x0a\xde\x45\x54\x51\xbe\x0c\xc0\x56\xcc\x24\xd9\xb1\x17\xa2\x36\x23\xc7\xb7\x9f\xd2\x08\x04\x1d\x80\x73\x85\x6d\x2c\xc1\xd1\xa5\x20\x6b\x9a\x64\x12\xae\xa4\xc9\xb0\x45\x22\xd0\x40\x5f\x33\x05\x45\x93\x29\xfc\xf7\x2d\xaa\x28\xfa\x9e\x31\x60\x96\x63\x46\xf8\x52\xad\xf4\xf1\x4b\x20\xab\xdb\xae\xf9\xe7\xd9\x72\x86\x79\x44\x75\x14\x40\x94\x2b\xe3\x17\x7a\x33\xb5\xb8\x74\x4c\x6c\xae\x37\x16\xdf\x2c\x13\x02\x62\x0b\xbc\x75\x7d\x65\xbc\x72\xc2\x73\x70\x15\xa8\x06\x3e\x9d\xe8\x18\x4d\x6e\x86\x53\x87\x5d\x10\x95\x09\x6e\xef\x6f\x3c\x69\x52\xa5\xab\x44\xf6\x03\xf9\x5d\xf5\x8d\xea\xab\x8e\xa8\x6a\x13\x3f\xc7\xc8\xbe\xdc\x7b\x64\x97\x44\xbd\xe7\x50\x79\x98\x99\xaa\x6c\x8a\x6e\xce\x89\xfa\xd6\xac\xa5\x82\x00\xd5\xce\xfd\x26\x0d\x3d\x9b\x83\x12\x59\x73\x6f\xc0\x3c\x24\x4c\xd3\x6a\xe2\x47\x2a\x6a\xed\x42\x09\xff\x51\xad\x88\x00\x77\x66\x8c\x86\xd0\x29\xaa\xca\xc8\x5e\xb4\xd9\x12\xf2\x44\x70\xd4\x82\x2e\xcb\x2e\x88\x71\x44\x44\x93\xe7\x3a\xb3\x17\x94\xb0\xe8\x2a\xf9\x0d\xb2\x7a\x47\xc4\x61\x8c\x8c\xe0\x98\x65\xa4\x9e\x9d\x3a\xaf\xbd\x07\xb9\x3a\x93\x15\xd5\x21\xf5\x8e\x91\x18\x2e\x7a\xe0\xd0\x1a\x87\x23\xba\x0e\x46\xde\xa3\x3b\x14\xea\xf1\x56\x0c\x34\x01\x06\x1a\x4b\x83\xad\x67\xf5\xd5\x5b\x67\x87\x5e\x57\x77\x98\xb0\xe3\x38\x3a\x9e\x34\xaa\x36\x12\xff\xf9\x3b\xf0\x1e\x0e\xff\x27\x73\x4f\x10\xc3\x73\xc2\xf2\x7f\x8f\x29\x5f\x24\xad\xf6\xeb\x1b\x3f\x28\xfb\x5f\xa3\x39\x8e\x00\xc2\xb4\x19\x6d\xf2\xf0\xa0\xac\xfe\xea\x81\x49\xe2\xec\x0e\x9b\x9a\xb7\x5e\xf5\xf6\x5e\x53\x99\x0a\x9a\x08\xaa\x6e\x75\x49\x17\xd5\x3d\x08\x2e\x8b\xcd\x60\x54\x6d\x20\xdb\xdd\x5a\xbc\x24\x34\xa7\x4c\x16\x5d\xa1\x14\x71\x6d\x76\x6d\x01\xf9\x5e\x8d\x3d\xa6\x8c\x48\x05\xa8\xcc\x62\xbf\xd8\xee\xda\x12\xca\xed\x8a\xcb\xba\x31\xa5\x00\x9c\x0c\xc2\x1d\x21\x0e\x93\xde\xfc\x39\x75\xc1\x9c\x77\x9a\x7f\x87\x26\xe8\xc5\x0b\xdf\x98\x7e\x75\x83\xbe\xe8\x39\x87\x4b\x03\xc0\x8b\x20\x2d\x60\x5c\x50\x89\x3a\x22\xd0\xa3\xfb\x30\x69\x74\x8e\xe7\x8c\x44\x81\x0f\x05\x3f\xd4\x95\x56\x30\xd3\xdf\xcd\x32\xb8\xda\x62\xfd\xa3\xcb\x45\x87\xc1\xef\x9e\x75\x99\x1a\x4f\x9f\xd1\xb5\xe7\xfe\x74\xaa\x91\x71\x31\xf8\x72\x90\x24\xdc\xe1\x52\xf0\xd7\x1e\x40\x8d\x25\xdc\x50\xba\x3c\x63\xcc\xdd\xf5\x49\x0c\x14\xf8\x85\x61\x0b\x72\xd5\x3f\x0d\x4e\xe0\x04\xa6\x92\x84\xad\xc9\xd7\xf0\x77\x44\x16\x38\x63\xea\x67\xdd\x92\x4e\x91\xff\x9d\x00\x73\xbc\x9f\xfa\x47\x0f\xcb\x3d\x8d\xc9\x79\xa6\xa0\x32\x5b\x9a\xa0\x3f\xa2\x25\xff\x35\x5e\x93\x27\x1c\x8b\x9d\xe6\xdd\x01\x30\x33\xc8\xa8\xb8\x11\x1b\x10\xb6\xb6\xea\x99\x21\xed\xdd\xae\xad\x9d\x61\x47\x05\xed\x27\x9b\xef\x60\x0e\x2c\xe0\xba\xb5\x34\x48\x40\xdb\x53\x1b\x63\xfb\x3c\xf5\xa7\x68\xa3\x1f\x75\xe4\xdf\x69\xb9\xc7\x6a\x37\x5b\x1e\xe7\xbf\xa7\x2e\xbf\x41\x61\xc2\x15\xa6\xf0\x72\xf7\xd6\xc0\xfe\xab\xed\xd7\x2c\x9e\x27\x4a\x40\x75\xc3\x73\x4f\x66\x71\x8c\xc5\xed\x9e\xca\x6f\x75\xf2\xe0\xd2\xab\xdc\xee\x47\xaa\xd8\xbd\x50\x52\x91\x9e\x6e\x92\x3f\x47\x38\x0d\x5e\x90\x8d\x01\xdc\x62\x1b\xff\x69\x89\x5b\xfc\xc7\x25\x2e\xe9\xaa\xdf\x27\x4e\xd2\xd7\xbd\x53\x13\x6a\xf7\x9c\x4a\xa5\x87\x90\xb9\x46\x90\x61\x5e\x7c\xe8\xbd\x94\x19\x91\x0d\x11\xd5\x58\xe0\xd4\x03\x19\xfc\xd4\x09\xaf\x3e\x5b\x0d\x97\xf3\xae\x74\x18\x37\xcf\x1b\x31\x18\xb7\x8f\xab\xe6\x8c\xf5\xca\xbe\x14\x2f\x1b\x1a\xc7\xbd\xd4\x19\x95\x8c\xf6\x7d\x3d\xec\x40\x63\xcb\x44\xba\x97\x72\x63\x00\x6e\xd1\x9f\xdb\xb0\xca\x27\xc8\x97\xce\xf8\xa8\x7d\xb9\x6c\xb3\xeb\x41\xb6\x19\xfb\x64\x8a\xdb\x86\xf7\xce\xcc\x00\x0b\x8a\x8f\x57\x34\x8a\x08\x0f\xc0\x5e\x8d\x10\x5b\x1f\x5a\xa5\x8a\x7f\xff\xf8\xd3\x3f\xc2\xb7\xab\xa1\x05\x96\x02\xd0\x36\x0a\xcd\x62\x5c\x34\xd0\x22\xf8\xa9\x52\x28\xc8\xc7\x72\x6b\x54\x9e\x35\x83\xb6\x1f\xa8\xde\xe2\xf0\x53\xd7\x55\x05\x57\x39\xa6\x50\x09\x62\xd0\xed\x0e\x3c\xd4\xbb\xf7\xcf\xa1\xc4\xba\xf2\x35\xbc\x33\xd4\x9a\x0e\x75\xa8\x3a\xe0\x72\xfe\xab\xa3\x9c\xef\x9b\x3a\x5d\x48\xa0\xfc\xb5\xfd\xae\x7a\xb4\x19\x4e\xff\x0b\x00\x00\xff\xff\xef\xd8\x7e\x42\x93\x1b\x00\x00")
+var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x59\xdd\x6e\xdb\x36\x14\xbe\xcf\x53\x70\x1a\x50\xd8\xa8\xed\xc4\x41\x37\x0c\xf1\x3a\xa0\x4d\x02\xac\x40\xd2\x05\x49\xb6\x9b\x21\x17\xb4\x44\xdb\x6c\x69\x4a\x20\x29\x2f\x41\xe0\xdb\x5d\x0f\x7b\x82\x3d\xcb\x1e\x65\x4f\xb2\x43\xea\xc7\xa2\x44\xfd\x38\x71\x17\x8f\x40\x1b\x9b\xe4\xf9\x3f\x3c\xe7\x23\xbd\xc2\x02\xbd\x8f\xe7\x57\x78\x4e\xd0\x5b\x74\x4d\xb0\xaf\x46\xbe\x20\x58\x91\x53\x86\xa5\xec\x3d\x1e\x20\x18\x01\x95\x11\xc3\x0f\x1f\xf1\x92\x9c\x20\x2f\xdd\xef\x0d\x0e\xcc\xa2\x1f\x2e\xa3\x90\x13\xae\xce\x68\x70\x19\xc6\x5c\x9d\xa0\x59\xcc\x7d\x45\x43\x8e\x7a\x7d\x94\x70\xd0\x83\xce\x50\x4f\x2d\xa8\x1c\x09\x32\x93\xa3\x80\x48\xbf\xb8\xaa\x87\xbd\x3a\xa2\x9c\x13\xf1\xe3\xed\xe5\x05\xa8\xb6\xc4\xe2\x33\x09\x12\xfa\x48\x84\x91\x1c\x9d\xc1\x16\x41\x23\x2d\xa7\x3f\xc9\xd9\xac\x0f\x2c\x66\x92\xa8\x1b\x05\xd6\xf4\x6c\x41\xde\x79\x40\x15\xe5\x73\x0f\x74\xc5\x4c\x92\x0d\x79\xca\x6a\x3d\xa8\xd8\xf6\x73\x14\x00\xa3\x3d\x30\x2e\xd5\x8d\x85\x38\xb8\x12\x64\x45\xc3\x58\x42\x48\xea\x14\x9b\x85\x02\xf5\x74\x98\x29\x08\x1a\x4f\xe0\xcf\xf7\xa8\x20\xe8\x1d\x63\x40\x2c\x47\x8c\xf0\xb9\x5a\xe8\xe5\xd7\xb0\xad\xac\xbb\xa6\x9f\xc6\xf3\x53\xcc\x03\xaa\xbd\x00\xac\xaa\x3c\x7e\xa5\x77\x13\x8b\x4a\xfb\xc4\xa6\x7a\x6b\xd1\x9d\xc6\x42\x80\x6f\x81\xb6\x2c\x2f\xf7\x57\xb2\xf1\x02\x4c\x85\x5d\x3d\x97\x4c\x34\x44\xe3\xbb\xfe\xa4\x42\x2e\x88\x8a\x05\xb7\xe7\xd7\x8e\x34\x29\xee\x2b\x78\xf6\x23\xb9\x57\x5d\xbd\x7a\xd4\xe2\x55\xad\xe2\xff\xd1\xb3\xaf\x77\xee\xd9\x39\x51\x1f\x38\x9c\x3c\xcc\xcc\xa9\xac\xf3\x6e\x42\x89\xba\x9e\x59\x4b\x04\x81\x5d\x1b\xf3\xeb\x24\x74\x2c\x0e\x4a\xc4\xf5\xb5\x01\x73\x9f\x30\xbd\x57\x6f\x7e\xa6\xa0\xc6\x2a\x24\xf1\x8a\xb8\x4d\x22\x45\x51\x3a\x95\x8c\xf5\x2c\x94\xb1\xd0\x99\xb4\xd9\xe8\xab\xfb\x72\x26\xa4\x4e\xae\x61\x96\x0d\x20\x2c\xa8\x5f\x51\x39\x57\xb5\x4c\x63\xa7\xd7\x66\xa6\x90\x99\xa5\x0c\x9a\x94\x03\xaa\xc7\xbb\x4f\xf8\xfe\x2a\x56\x3d\xef\x90\x4a\x19\x13\x79\xe8\x41\x56\x3a\x13\x1d\xe6\xbd\xc3\x42\xd9\xf4\x06\x85\x8a\xab\xdd\x62\xaa\xee\x0a\xb3\x98\x0c\x8a\x6e\x32\xa9\xdf\x1f\x38\x98\x9e\xdf\xe2\xb9\x1d\x88\x80\x30\xa2\x6a\x42\x51\x8e\x84\x5a\x60\x95\x1e\x66\xdb\x9c\x33\xc3\xa4\x83\x45\x83\x1a\xee\x7a\x24\xed\x06\xab\x94\x28\xe4\x09\x57\xf7\x69\xaf\x6c\xeb\x95\x7d\xbf\x71\x7d\x37\x47\x84\xfc\x27\xb5\x20\x02\x94\x3c\x65\xd4\x87\xde\x55\x9b\x94\x4f\xce\x7f\x9b\x43\xa6\x7f\x49\x2c\xc8\xb2\xf4\x02\x6d\x03\x22\x9a\xc2\x32\xa3\x84\x05\xd7\xe1\x6f\xd6\xe9\xe0\x00\x6c\x06\xc8\xe4\x86\xcb\xd1\xce\x85\x44\x9c\x39\x42\x45\xd8\x74\xce\xc8\x12\x5c\xd6\xab\xec\x35\x06\x07\x74\xe5\x0d\x9c\x4b\x8f\xc8\xd7\x80\x2b\x85\x58\x02\x14\x34\x9a\x7a\x99\x65\xe5\xd1\x59\x66\x8b\xdc\xaa\x6c\x3f\x64\xc3\x65\x30\x1c\xd7\x8a\x36\x1c\xff\xfe\xcb\x73\x2e\xf6\x5f\x48\xdd\x63\xc4\xf0\x94\xb0\xe4\xff\x21\xe5\xb3\xb0\x51\x7f\x1d\xf1\xbd\xd2\xff\x0d\x9a\xe2\x00\x40\x75\x93\xd2\x26\x0f\xf7\x4a\xeb\x6f\x9e\x98\x24\x95\xd9\xda\x82\xa4\x47\x19\x70\x94\x44\x46\x82\x86\x82\xaa\x07\x7d\xa4\xd3\xd3\xdd\xf3\xae\xd2\x49\xcf\x2a\x68\xd9\x6c\xc9\x5f\x12\x8a\x53\x2c\xd3\xaa\x90\xb3\xb8\x31\xb3\x36\x83\x64\xae\x44\xbe\xa4\x8c\x48\x05\xf7\x04\x8b\xfc\x32\x9b\xb5\x39\xe4\xd3\x05\x93\x75\x61\x8a\x00\xca\x9b\x3b\xd7\x00\x71\xc0\x9e\xe6\xe3\xa4\x7a\xbd\x70\xe2\xcb\x1f\xd0\x18\xbd\x7a\xe5\x02\x8e\x47\x77\xe8\xab\x8e\xc8\x30\x57\x00\xac\xf0\xa2\xf4\x62\xe1\x15\xbc\x8e\x88\x6e\xf8\x1d\x88\xf4\x7d\x11\x4f\x19\x09\x3c\xd7\xbd\xec\xa9\xa6\x34\xc2\xeb\xee\x66\xe6\xce\xd5\x1a\xeb\x2f\x6d\x26\x56\x08\xdc\xe6\x59\xc1\xd4\x58\xe3\x8c\xae\x1c\xf1\xd3\xa9\x46\x46\x69\xe3\x4b\x60\xbb\xa8\x36\x97\x94\xbe\x74\x25\xaf\x3d\xc2\x35\x47\x97\xc7\x8c\x55\x67\xbf\x48\xb7\xda\xaa\x4f\x79\x0a\xbc\x88\x61\x0a\x4e\x86\xbb\xf7\x1c\xc3\x0a\x70\x95\x30\x35\xfe\x16\x3e\x07\x64\x86\x63\xa6\x7e\xd1\x05\xf0\x04\xb9\xef\xc9\x40\x41\x66\x40\x90\x61\x3d\x50\xc9\x51\x67\xf6\xd1\x1f\xbb\xed\xdb\x47\x8d\x35\x79\x2b\xf9\x46\x87\x69\xac\x94\x86\xd3\x8d\xbb\x6c\x55\xa6\x8a\x23\xf8\x37\x4c\xc3\x06\x01\x0c\xb9\x41\x6c\x69\xec\xec\x0b\x4d\x93\xba\x46\x83\x1b\xd8\xee\x6e\x24\x7a\xd4\xf4\xbe\xbd\x31\xd6\xbe\x27\xb6\x1a\x7b\x6a\xb6\x37\x98\xbb\x57\x00\xe0\xf8\x65\x92\xcd\xf6\x70\xf9\x5a\x36\x68\x8a\x0f\x9a\xb3\x87\x68\x41\x7d\xc0\xfd\xf9\xa7\xa1\x20\xcb\x70\xd5\x0c\xbe\x8c\x7a\xc9\xf5\x69\xeb\xe0\x54\xcb\x90\x35\xd3\x6f\xe9\x40\xbb\xe9\x06\x8f\x69\x7d\x34\xb5\xb1\x9c\xa4\xf6\xab\x89\xcb\x0f\xee\xa2\x5b\x6b\x47\xf9\x2d\xa7\x55\x73\x87\xd6\xd5\xfe\xf5\x3c\xfb\x1d\xf9\xfb\x1d\x82\xf0\x2b\x4c\x39\x11\xce\xe8\xef\xbe\x39\x7c\x8a\x97\xd3\x50\x09\x48\xbf\x29\x40\x98\x78\xb9\xc4\xe2\x61\x47\xdd\x62\x71\xdc\x70\x70\xdc\x60\x20\x1b\x85\xe8\xde\x52\xc5\xb6\xba\x65\xa4\xe9\xf9\x32\xbd\xd6\xe0\x6d\x59\xeb\xc0\xec\x6e\xe0\x5e\xcd\x71\xbf\x7b\x39\xc7\xf5\x6d\xe7\xf7\x0b\x27\xe9\x9b\xce\xa9\x09\x67\xf7\x82\x4a\xa5\x61\x95\x09\x23\xf0\x30\x2f\x26\xe8\x83\x79\x6b\xaa\xf1\xa8\xc6\xd2\x27\x0e\xc8\xed\xde\x1d\xf2\xe2\xb3\x8f\xa1\xaa\xbc\xcb\x54\x08\xd7\xff\xad\xc7\xc6\xee\xbe\xd4\x3d\xfd\x62\xd6\x29\xfb\x22\x3c\xaf\x29\x1c\x5b\x89\x33\x22\x19\xed\xda\x7c\x37\x97\xae\x9d\xf6\x5e\xdc\xda\x76\x17\x49\x07\xf9\xba\xd2\x3e\x4a\xbf\x45\xb5\xf5\xd1\xad\x75\x33\xfa\xc9\x08\xb7\x21\x83\x44\x4d\x0f\x0b\x8a\x87\x0b\x1a\x04\x84\x7b\xa0\xaf\xbe\x61\xb5\xf6\x76\x23\xe2\x9f\xdf\xff\xa8\x6f\xee\x7a\x34\x80\x4d\xc3\x00\x65\x5e\x78\x11\x00\xd7\x3d\x85\xbc\xa4\x2d\xef\x18\xbd\x3d\x23\x83\xb2\x07\xde\xf7\xd8\xff\xdc\x0a\xc3\xae\x13\x4c\xa1\x42\xc4\xa0\xda\xed\xb9\xab\x37\xef\x07\xfb\xe2\xeb\xc2\xef\x9b\xad\xae\xd6\xfb\x50\x8b\xa8\x3d\x3e\xce\x7f\xb6\x1c\xe7\x5d\x23\xf9\xfc\x5b\xf6\xbb\xc4\xc1\xba\x3f\xf9\x37\x00\x00\xff\xff\x48\xfb\x65\x1f\x65\x21\x00\x00")
func jsBugpageJsBytes() ([]byte, error) {
return bindataRead(
@@ -126,7 +126,7 @@ func jsBugpageJs() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "js/BugPage.js", size: 7059, mode: os.FileMode(436), modTime: time.Unix(1453649979, 0)}
+ info := bindataFileInfo{name: "js/BugPage.js", size: 8549, mode: os.FileMode(436), modTime: time.Unix(1453860464, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Description b/bug-serve/issues/Add-ability-to-edit-bugs/Description
deleted file mode 100644
index 5ba8744..0000000
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Description
+++ /dev/null
@@ -1,4 +0,0 @@
-You should be able to edit bugs via AJAX in bug-serve
-
-And you should be able to edit them with markdown.
-
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Identifier b/bug-serve/issues/Add-ability-to-edit-bugs/Identifier
deleted file mode 100644
index 9910222..0000000
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Identifier
+++ /dev/null
@@ -1,2 +0,0 @@
-editbug
-
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Milestone b/bug-serve/issues/Add-ability-to-edit-bugs/Milestone
deleted file mode 100644
index 866c31a..0000000
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Milestone
+++ /dev/null
@@ -1 +0,0 @@
-v0.4
\ No newline at end of file
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Priority b/bug-serve/issues/Add-ability-to-edit-bugs/Priority
deleted file mode 100644
index bf0d87a..0000000
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Priority
+++ /dev/null
@@ -1 +0,0 @@
-4
\ No newline at end of file
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/Status b/bug-serve/issues/Add-ability-to-edit-bugs/Status
deleted file mode 100644
index fa1c255..0000000
--- a/bug-serve/issues/Add-ability-to-edit-bugs/Status
+++ /dev/null
@@ -1 +0,0 @@
-Up next
\ No newline at end of file
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/tags/test b/bug-serve/issues/Add-ability-to-edit-bugs/tags/test
deleted file mode 100644
index e69de29..0000000
diff --git a/bug-serve/issues/Add-ability-to-edit-bugs/tags/whee b/bug-serve/issues/Add-ability-to-edit-bugs/tags/whee
deleted file mode 100644
index e69de29..0000000
diff --git a/bug-serve/issues/Implement-save-and-Cancel/Description b/bug-serve/issues/Implement-save-and-Cancel/Description
deleted file mode 100644
index d8c6608..0000000
--- a/bug-serve/issues/Implement-save-and-Cancel/Description
+++ /dev/null
@@ -1,2 +0,0 @@
-The GUI currently updates as if it'll let you edit a bug,
-but the save and cancel buttons don't do anything useful.
diff --git a/bug-serve/jsx/BugApp.js b/bug-serve/jsx/BugApp.js
index 431c101..ac59eeb 100644
--- a/bug-serve/jsx/BugApp.js
+++ b/bug-serve/jsx/BugApp.js
@@ -1,16 +1,23 @@
var BugApp = React.createClass({
- componentDidMount: function() {
- var that = this;
+ reloadIssues: function() {
+ var that = this;
AjaxGet("/issues/", function(response) {
that.setState({
"Bugs" : JSON.parse(response)
});
});
+ },
+ reloadSettings: function() {
+ var that = this;
AjaxGet("/settings", function(response) {
that.setState({
"Settings" : JSON.parse(response)
});
})
+ },
+ componentDidMount: function() {
+ this.reloadIssues();
+ this.reloadSettings();
},
getInitialState : function() {
return {
@@ -23,9 +30,10 @@ var BugApp = React.createClass({
},
loadBug: function(bug) {
var that = this;
- AjaxGet("/issues/" + bug + "/", function(response) {
+ AjaxGet("/issues/" + bug + "/", function(response, handler) {
that.setState({
- SelectedBug : JSON.parse(response),
+ "SelectedBug" : JSON.parse(response),
+ "SelectedBugETag" : handler.getResponseHeader("ETag"),
"SelectedBugDir" : bug
});
});
@@ -35,8 +43,15 @@ var BugApp = React.createClass({
this.loadBug(e.currentTarget.textContent);
},
resetSelected: function() {
- this.setState({ "SelectedBug" : null});
+ this.setState({ "SelectedBug" : null,
+ "SelectedBugETag" : null,
+ "SelectedBugDir" : null
+ });
},
+ resetBugs: function() {
+ this.resetSelected();
+ this.reloadIssues();
+ },
render: function() {
var content;
if(this.state.SelectedBug != null) {
@@ -49,8 +64,10 @@ var BugApp = React.createClass({
Identifier={this.state.SelectedBug.Identifier}
Tags={this.state.SelectedBug.Tags}
onBack={this.resetSelected}
+ onDelete={this.resetBugs}
AllBugs={this.state.Bugs}
CurrentBug={this.state.SelectedBugDir}
+ CurrentETag={this.state.SelectedBugETag}
onOtherBugClicked={this.selectBugHandler}
LoadBug={this.loadBug}
/>
@@ -74,9 +91,42 @@ var AjaxGet = function(url, callback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status == 200) {
- callback(this.responseText)
+ callback(this.responseText, this)
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send()
}
+
+
+var AjaxPut = function(url, data, callback, etag) {
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ if (this.readyState === 4 && (this.status >= 200 && this.status < 300)) {
+ callback(this.responseText)
+ }
+ }
+ xmlhttp.open("PUT", url, true);
+ if (etag) {
+ xmlhttp.setRequestHeader("If-Match", etag)
+ }
+ xmlhttp.send(data)
+}
+
+var AjaxPutJSON = function(url, data, callback) {
+ AjaxPut(url, JSON.stringify(data), callback);
+}
+
+var AjaxDelete = function(url, callback, etag) {
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ if (this.readyState === 4 && (this.status >= 200 && this.status < 300)) {
+ callback(this.responseText)
+ }
+ }
+ xmlhttp.open("DELETE", url, true);
+ if (etag) {
+ xmlhttp.setRequestHeader("If-Match", etag)
+ }
+ xmlhttp.send()
+}
diff --git a/bug-serve/jsx/BugPage.js b/bug-serve/jsx/BugPage.js
index f64c3bc..e8de522 100644
--- a/bug-serve/jsx/BugPage.js
+++ b/bug-serve/jsx/BugPage.js
@@ -47,6 +47,33 @@ var BugPage = React.createClass({
"Editing" : false
});
},
+ saveCurrentBug: function(e) {
+ var editClosure = function(ctx) {
+ return function(e) {
+ ctx.setState({"Editing" : false});
+ ctx.props.LoadBug(ctx.props.CurrentBug);
+ }
+ }
+ AjaxPut(
+ "/issues/" + this.props.CurrentBug + "/Description",
+ this.refs.editdesc.value,
+ editClosure(this),
+ this.props.CurrentETag
+ );
+
+ },
+ deleteCurrentBug: function() {
+ var that = this;
+ AjaxDelete(
+ "/issues/" + this.props.CurrentBug,
+ function() {
+ if (that.props.onDelete) {
+ that.props.onDelete();
+ }
+ },
+ this.props.CurrentETag
+ );
+ },
onOtherBugClicked: function(e) {
this.setState({
"Editing" : false
@@ -90,10 +117,17 @@ var BugPage = React.createClass({
var descDiv;
if (this.state.Editing === true) {
descDiv = (
-
-
-
+
+
+
+
+
+
+
+
+
+
);
} else {
diff --git a/bugs/Bug.go b/bugs/Bug.go
index f396d7a..3057e2b 100644
--- a/bugs/Bug.go
+++ b/bugs/Bug.go
@@ -10,6 +10,7 @@ import (
)
var NoDescriptionError = errors.New("No description provided")
+var NotFoundError = errors.New("Could not find bug")
type Bug struct {
Dir Directory
diff --git a/bugs/Directory.go b/bugs/Directory.go
index c31b30c..611a062 100644
--- a/bugs/Directory.go
+++ b/bugs/Directory.go
@@ -1,10 +1,10 @@
package bugs
import (
- "time"
"os"
"regexp"
"strings"
+ "time"
)
func GetRootDir() Directory {
@@ -62,34 +62,34 @@ func (d Directory) ToTitle() string {
}
func (d Directory) LastModified() time.Time {
- var t time.Time
- stat, err := os.Stat(string(d))
- if err != nil {
- panic("Directory " + string(d) + " is not a directory.")
- }
+ var t time.Time
+ stat, err := os.Stat(string(d))
+ if err != nil {
+ panic("Directory " + string(d) + " is not a directory.")
+ }
- if stat.IsDir() == false {
- return stat.ModTime()
- }
+ if stat.IsDir() == false {
+ return stat.ModTime()
+ }
- dir, _ := os.Open(string(d))
- files, _ := dir.Readdir(-1)
- if len(files) == 0 {
- t = stat.ModTime()
- }
- for _, file := range files {
- if file.IsDir() {
- mtime := (d +"/" + Directory(file.Name())).LastModified()
- if mtime.After(t) {
- t = mtime
- }
- } else {
- mtime := file.ModTime()
- if mtime.After(t) {
- t = mtime
- }
+ dir, _ := os.Open(string(d))
+ files, _ := dir.Readdir(-1)
+ if len(files) == 0 {
+ t = stat.ModTime()
+ }
+ for _, file := range files {
+ if file.IsDir() {
+ mtime := (d + "/" + Directory(file.Name())).LastModified()
+ if mtime.After(t) {
+ t = mtime
+ }
+ } else {
+ mtime := file.ModTime()
+ if mtime.After(t) {
+ t = mtime
+ }
- }
- }
- return t
+ }
+ }
+ return t
}
diff --git a/bugs/Formats.go b/bugs/Formats.go
index d3bd69d..41f161b 100644
--- a/bugs/Formats.go
+++ b/bugs/Formats.go
@@ -1,9 +1,9 @@
package bugs
+
import (
- "encoding/json"
+ "encoding/json"
)
-
func (b Bug) ToJSONString() (string, error) {
bJSONStruct := struct {
Identifier string `json:",omitempty"`
@@ -24,8 +24,8 @@ func (b Bug) ToJSONString() (string, error) {
}
bJSON, err := json.Marshal(bJSONStruct)
- if err != nil {
- return "", err
- }
+ if err != nil {
+ return "", err
+ }
return string(bJSON), nil
}
diff --git a/bugs/IO.go b/bugs/IO.go
index aa4f97a..3eb3d73 100644
--- a/bugs/IO.go
+++ b/bugs/IO.go
@@ -54,3 +54,11 @@ func (b Bug) Close() error {
}
return nil
}
+
+func (b *Bug) Remove() error {
+ dir := b.GetDirectory()
+ if dir != "" {
+ return os.RemoveAll(string(dir))
+ }
+ return NotFoundError
+}
From bbbb444f4c307dbfef3a599eb40d4752cc7eadf9 Mon Sep 17 00:00:00 2001
From: Koo
Date: Mon, 15 Feb 2016 21:49:55 +0100
Subject: [PATCH 34/47] Add coverage related files to .gitignore
---
.gitignore | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.gitignore b/.gitignore
index ff3c350..a7dd4a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,6 @@ _testmain.go
*.test
*.prof
*.un~
+
+coverage.txt
+profile.out
From 145025d046d53f91fc27146521a0d4c01ee481fc Mon Sep 17 00:00:00 2001
From: Koo
Date: Mon, 15 Feb 2016 21:54:35 +0100
Subject: [PATCH 35/47] Stop writing to nonexisting temp file
We should early return when /tmp folder is not accessible.
---
scm/GitManager.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scm/GitManager.go b/scm/GitManager.go
index bb94654..5fc2e7c 100644
--- a/scm/GitManager.go
+++ b/scm/GitManager.go
@@ -70,7 +70,8 @@ func (a GitManager) Commit(dir bugs.Directory, commitMsg string) error {
}
file, err := ioutil.TempFile("", "bugCommit")
if err != nil {
- fmt.Fprintf(os.Stderr, "Could not create file for commit message.\n")
+ fmt.Fprintf(os.Stderr, "Could not create temporary file.\nNothing commited.\n")
+ return err
}
defer func() {
os.Remove(file.Name())
From 4e1f3bc3facba563e6d5af253b5a7a0c1028288f Mon Sep 17 00:00:00 2001
From: Koo
Date: Mon, 15 Feb 2016 22:14:21 +0100
Subject: [PATCH 36/47] Add help for newbies with clean repo
When there is no `issues' directory `bug help' command is not available.
It is nice to provide some help for newbies in those situation.
---
main.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/main.go b/main.go
index 7b91b49..9759ea6 100644
--- a/main.go
+++ b/main.go
@@ -15,6 +15,7 @@ func main() {
if bugs.GetRootDir() == "" {
fmt.Printf("Could not find issues directory.\n")
fmt.Printf("Make sure either the PMIT environment variable is set, or a parent directory of your working directory has an issues folder.\n")
+ fmt.Println("(If you just started new repo, you probably want to create directory named `issues`).")
fmt.Printf("Aborting.\n")
os.Exit(2)
}
From 5a6159c3942a96d1741c6b06eb3fdad655f03be5 Mon Sep 17 00:00:00 2001
From: Koo
Date: Tue, 16 Feb 2016 00:47:30 +0100
Subject: [PATCH 37/47] Apply minor refactoring
---
bugs/Bug.go | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/bugs/Bug.go b/bugs/Bug.go
index 3057e2b..b300a8c 100644
--- a/bugs/Bug.go
+++ b/bugs/Bug.go
@@ -58,24 +58,24 @@ func (b *Bug) LoadBug(dir Directory) {
}
func (b Bug) Title(options string) string {
- var checkOption = func(o string) bool {
+ var hasOption = func(o string) bool {
return strings.Contains(options, o)
}
title := b.Dir.GetShortName().ToTitle()
- if id := b.Identifier(); checkOption("identifier") && id != "" {
+ if id := b.Identifier(); hasOption("identifier") && id != "" {
title = fmt.Sprintf("(%s) %s", id, title)
}
- if strings.Contains(options, "tags") {
+ if hasOption("tags") {
tags := b.StringTags()
if len(tags) > 0 {
title += fmt.Sprintf(" (%s)", strings.Join(tags, ", "))
}
}
- priority := checkOption("priority") && b.Priority() != ""
- status := checkOption("status") && b.Status() != ""
+ priority := hasOption("priority") && b.Priority() != ""
+ status := hasOption("status") && b.Status() != ""
if options == "" {
priority = false
status = false
From d80a7475180b1835a8d92e55ff44d1165d55d3ca Mon Sep 17 00:00:00 2001
From: Koo
Date: Mon, 15 Feb 2016 21:51:04 +0100
Subject: [PATCH 38/47] Refactor GitManager to be simpler/more idiomatic
Logic/behaviour not changed.
---
scm/GitManager.go | 41 +++++++++++++++++------------------------
1 file changed, 17 insertions(+), 24 deletions(-)
diff --git a/scm/GitManager.go b/scm/GitManager.go
index bb94654..d0a1b70 100644
--- a/scm/GitManager.go
+++ b/scm/GitManager.go
@@ -20,25 +20,21 @@ func (a GitManager) Purge(dir bugs.Directory) error {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
- err := cmd.Run()
-
- if err != nil {
- return err
- }
- return nil
+ return cmd.Run()
}
-func (a GitManager) getDeletedIdentifiers(dir bugs.Directory) []string {
+func (a GitManager) closedGithubIssues(dir bugs.Directory) []string {
+ ghRegex := regexp.MustCompile("(?im)^-Github:(.*)$")
cmd := exec.Command("git", "status", "-z", "--porcelain", string(dir))
out, _ := cmd.CombinedOutput()
files := strings.Split(string(out), "\000")
- retVal := []string{}
+ var retVal []string
for _, file := range files {
if file == "" {
continue
}
- if file[0:1] == "D" && strings.HasSuffix(file, "Identifier") {
- ghRegex := regexp.MustCompile("(?im)^-Github:(.*)$")
+
+ if file[:1] == "D" && strings.HasSuffix(file, "Identifier") {
diff := exec.Command("git", "diff", "--staged", "--", file[3:])
diffout, _ := diff.CombinedOutput()
//fmt.Printf("Output: %s", diffout)
@@ -49,6 +45,7 @@ func (a GitManager) getDeletedIdentifiers(dir bugs.Directory) []string {
}
return retVal
}
+
func (a GitManager) Commit(dir bugs.Directory, commitMsg string) error {
cmd := exec.Command("git", "add", "-A", string(dir))
if err := cmd.Run(); err != nil {
@@ -57,25 +54,21 @@ func (a GitManager) Commit(dir bugs.Directory, commitMsg string) error {
}
- var deletedIdentifiers []string
- if a.Autoclose == true {
- deletedIdentifiers = a.getDeletedIdentifiers(dir)
- } else {
- deletedIdentifiers = []string{}
- }
- if len(deletedIdentifiers) > 0 {
- commitMsg = fmt.Sprintf("%s\n\nCloses %s\n", commitMsg, strings.Join(a.getDeletedIdentifiers(dir), ", closes "))
- } else {
- commitMsg = fmt.Sprintf("%s\n", commitMsg)
+ var closesGH string
+ if a.Autoclose {
+ ci := a.closedGithubIssues(dir)
+ if len(ci) > 0 {
+ closesGH = fmt.Sprintf("\nCloses %s\n", strings.Join(ci, ", closes "))
+ }
}
+
file, err := ioutil.TempFile("", "bugCommit")
if err != nil {
fmt.Fprintf(os.Stderr, "Could not create file for commit message.\n")
}
- defer func() {
- os.Remove(file.Name())
- }()
- file.WriteString(commitMsg)
+ defer os.Remove(file.Name())
+
+ fmt.Fprintf(file, "%s\n%s", commitMsg, closesGH)
cmd = exec.Command("git", "commit", "-o", string(dir), "-F", file.Name(), "-q")
if err := cmd.Run(); err != nil {
// If nothing was added commit will have an error,
From f63ce1af2de6893a6c87755f84e2f2481b2dc4d6 Mon Sep 17 00:00:00 2001
From: Koo
Date: Tue, 16 Feb 2016 00:42:12 +0100
Subject: [PATCH 39/47] Add information about new/closed/updated issues to
commit msg in git
Instead of always-the-same commit message we can contain information
about what was changed.
Test updated to support both old and new format (simple/rich ?).
---
scm/GitManager.go | 146 +++++++++++++++++++++++++++++++++++-----
scm/GitManager_test.go | 9 +--
scm/TestHelpers_test.go | 22 ++++--
3 files changed, 151 insertions(+), 26 deletions(-)
diff --git a/scm/GitManager.go b/scm/GitManager.go
index d0a1b70..fcb6e5a 100644
--- a/scm/GitManager.go
+++ b/scm/GitManager.go
@@ -1,6 +1,7 @@
package scm
import (
+ "bytes"
"fmt"
"github.com/driusan/bug/bugs"
"io/ioutil"
@@ -23,30 +24,142 @@ func (a GitManager) Purge(dir bugs.Directory) error {
return cmd.Run()
}
-func (a GitManager) closedGithubIssues(dir bugs.Directory) []string {
+type issueStatus struct {
+ a, d, m bool // Added, Deleted, Modified
+}
+type issuesStatus map[string]issueStatus
+
+// Get list of created, updated, closed and closed-on-github issues.
+//
+// In general following rules to categorize issues are applied:
+// * closed if Description file is deleted (D);
+// * created if Description file is created (A) (TODO: handle issue renamings);
+// * closed issue will also close issue on GH when Autoclose is true (see Identifier example);
+// * updated if Description file is modified (M);
+// * updated if Description is unchanged but any other files are touched. (' '+x)
+//
+// eg output from `from git status --porcelain`, appendix mine
+// note that `git add -A issues` was invoked before
+//
+// D issues/First-GH-issue/Description issue closed (GH issues are also here)
+// D issues/First-GH-issue/Identifier maybe it is GH issue, maybe not
+// M issues/issue--2/Description desc updated
+// A issues/issue--2/Status new field added (status); considered as update unless Description is also created
+// D issues/issue1/Description issue closed
+// A issues/issue3/Description new issue, description field is mandatory for rich format
+func (a GitManager) currentStatus(dir bugs.Directory) (closedOnGitHub []string, _ issuesStatus) {
ghRegex := regexp.MustCompile("(?im)^-Github:(.*)$")
+ closesGH := func(file string) (issue string, ok bool) {
+ if !a.Autoclose {
+ return "", false
+ }
+ if !strings.HasSuffix(file, "Identifier") {
+ return "", false
+ }
+ diff := exec.Command("git", "diff", "--staged", "--", file)
+ diffout, _ := diff.CombinedOutput()
+ matches := ghRegex.FindStringSubmatch(string(diffout))
+ if len(matches) > 1 {
+ return strings.TrimSpace(matches[1]), true
+ }
+ return "", false
+ }
+ short := func(path string) string {
+ b := strings.Index(path, "/")
+ e := strings.LastIndex(path, "/")
+ if b+1 >= e {
+ return "???"
+ }
+ return path[b+1 : e]
+ }
+
cmd := exec.Command("git", "status", "-z", "--porcelain", string(dir))
out, _ := cmd.CombinedOutput()
files := strings.Split(string(out), "\000")
- var retVal []string
+
+ issues := issuesStatus{}
+ var ghClosed []string
+ const minLineLen = 3 /*for path*/ + 2 /*for issues dir with path sep*/ + 3 /*for issue name, path sep and any file under issue dir*/
for _, file := range files {
- if file == "" {
+ if len(file) < minLineLen {
continue
}
- if file[:1] == "D" && strings.HasSuffix(file, "Identifier") {
- diff := exec.Command("git", "diff", "--staged", "--", file[3:])
- diffout, _ := diff.CombinedOutput()
- //fmt.Printf("Output: %s", diffout)
- if matches := ghRegex.FindStringSubmatch(string(diffout)); len(matches) > 1 {
- retVal = append(retVal, strings.TrimSpace(matches[1]))
+ // TODO: check if path starts with $issues
+ path := file[3:]
+ op := file[0]
+ desc := strings.HasSuffix(path, "/Description")
+ name := short(path)
+ issue := issues[name]
+
+ switch {
+ case desc && op == 'D':
+ issue.d = true
+ case desc && op == 'A':
+ issue.a = true
+ default:
+ issue.m = true
+ if op == 'D' {
+ if ghIssue, ok := closesGH(path); ok {
+ ghClosed = append(ghClosed, ghIssue)
+ issue.d = true // to be sure
+ }
}
}
+
+ issues[name] = issue
+ }
+ return ghClosed, issues
+}
+
+// Create commit message by iterate over issues in order:
+// closed issues are most important (something is DONE, ok? ;), those issues will also become hidden)
+// new issues are next, with just updates at the end
+// TODO: do something if this message will be too long
+func (a GitManager) commitMsg(dir bugs.Directory) []byte {
+ ghClosed, issues := a.currentStatus(dir)
+
+ done, add, update, together := &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}
+ var cntd, cnta, cntu int
+
+ for issue, state := range issues {
+ if state.d {
+ fmt.Fprintf(done, ", %q", issue)
+ cntd++
+ } else if state.a {
+ fmt.Fprintf(add, ", %q", issue)
+ cnta++
+ } else if state.m {
+ fmt.Fprintf(update, ", %q", issue)
+ cntu++
+ }
}
- return retVal
+
+ f := func(b *bytes.Buffer, what string, many bool) {
+ if b.Len() == 0 {
+ return
+ }
+ var m string
+ if many {
+ m = "s:"
+ }
+ s := b.Bytes()[2:]
+ fmt.Fprintf(together, "%s issue%s %s; ", what, m, s)
+ }
+ f(done, "Close", cntd > 1)
+ f(add, "Create", cnta > 1)
+ f(update, "Update", cntu > 1)
+ if l := together.Len(); l > 0 {
+ together.Truncate(l - 2) // "; " from last applied f()
+ }
+
+ if len(ghClosed) > 0 {
+ fmt.Fprintf(together, "\n\nCloses %s\n", strings.Join(ghClosed, ", closes "))
+ }
+ return together.Bytes()
}
-func (a GitManager) Commit(dir bugs.Directory, commitMsg string) error {
+func (a GitManager) Commit(dir bugs.Directory, backupCommitMsg string) error {
cmd := exec.Command("git", "add", "-A", string(dir))
if err := cmd.Run(); err != nil {
fmt.Printf("Could not add issues to be commited: %s?\n", err.Error())
@@ -54,12 +167,9 @@ func (a GitManager) Commit(dir bugs.Directory, commitMsg string) error {
}
- var closesGH string
- if a.Autoclose {
- ci := a.closedGithubIssues(dir)
- if len(ci) > 0 {
- closesGH = fmt.Sprintf("\nCloses %s\n", strings.Join(ci, ", closes "))
- }
+ msg := a.commitMsg(dir)
+ if len(msg) == 0 {
+ msg = []byte(backupCommitMsg)
}
file, err := ioutil.TempFile("", "bugCommit")
@@ -68,7 +178,7 @@ func (a GitManager) Commit(dir bugs.Directory, commitMsg string) error {
}
defer os.Remove(file.Name())
- fmt.Fprintf(file, "%s\n%s", commitMsg, closesGH)
+ fmt.Fprintf(file, "%s\n", msg)
cmd = exec.Command("git", "commit", "-o", string(dir), "-F", file.Name(), "-q")
if err := cmd.Run(); err != nil {
// If nothing was added commit will have an error,
diff --git a/scm/GitManager_test.go b/scm/GitManager_test.go
index 5fdb791..d7d8f0f 100644
--- a/scm/GitManager_test.go
+++ b/scm/GitManager_test.go
@@ -195,10 +195,11 @@ func TestGitManagerAutoclosingGitHub(t *testing.T) {
if msg, err := commits[1].(GitCommit).CommitMessage(); err != nil {
t.Error("Error getting git logs while attempting to test GitHub autoclosing")
} else {
- if msg != `Removal commit
-
-Closes #Whitespace, closes #TestBug
-` {
+ closing := func(issue string) bool {
+ return strings.Contains(msg, "Closes #"+issue) ||
+ strings.Contains(msg, ", closes #"+issue)
+ }
+ if !closing("Whitespace") || !closing("TestBug") {
fmt.Printf("%s\n", msg)
t.Error("GitManager did not autoclose Github issues")
}
diff --git a/scm/TestHelpers_test.go b/scm/TestHelpers_test.go
index 97f1abb..f3a9823 100644
--- a/scm/TestHelpers_test.go
+++ b/scm/TestHelpers_test.go
@@ -33,7 +33,7 @@ func runCmd(cmd string, options ...string) (string, error) {
return string(out), err
}
-func assertLogs(tester ManagerTester, t *testing.T, titles []string, diffs []string) {
+func assertLogs(tester ManagerTester, t *testing.T, titles []map[string]bool, diffs []string) {
logs, err := tester.GetLogs()
if err != nil {
t.Error("Could not get scm logs" + err.Error())
@@ -50,7 +50,7 @@ func assertLogs(tester ManagerTester, t *testing.T, titles []string, diffs []str
}
for i, _ := range titles {
- if titles[i] != logs[i].LogMsg() {
+ if _, ok := titles[i][logs[i].LogMsg()]; !ok {
t.Error("Unexpected commit message:" + logs[i].LogMsg())
}
@@ -58,7 +58,14 @@ func assertLogs(tester ManagerTester, t *testing.T, titles []string, diffs []str
t.Error("Could not get diff of commit")
} else {
if diff != diffs[i] {
- t.Error("Incorrect diff for " + titles[i])
+ // get shortest commit msg to keep errors simple
+ var s string
+ for k := range titles[i] {
+ if len(s) == 0 || len(k) < len(s) {
+ s = k
+ }
+ }
+ t.Error(fmt.Sprintf("Incorrect diff for i=%d, title=%s", i, s))
fmt.Fprintf(os.Stderr, "Got %s, expected %s", diff, diffs[i])
}
}
@@ -86,7 +93,14 @@ func runtestRenameCommitsHelper(tester ManagerTester, t *testing.T, expectedDiff
tester.AssertCleanTree(t)
- assertLogs(tester, t, []string{"Initial commit", "This is a test rename"}, expectedDiffs)
+ assertLogs(tester, t, []map[string]bool{{
+ "Initial commit": true, // simple format
+ `Create issue "Test-bug"`: true, // rich format
+ }, {
+ "This is a test rename": true, // simple format
+ `Update issues: "Test-bug", "Renamed-bug"`: true, // rich format
+ `Update issues: "Renamed-bug", "Test-bug"`: true, // has two alternatives equally good
+ }}, expectedDiffs)
}
func runtestCommitDirtyTree(tester ManagerTester, t *testing.T) {
From dea117d23f0cb01a47ea3918e2ee172a93dbd66a Mon Sep 17 00:00:00 2001
From: Przemek Komosa
Date: Wed, 24 Feb 2016 15:11:06 +0100
Subject: [PATCH 40/47] Add 'bug: ' prefix to commit subjects with issues
management
Those commits will be easily distinguishable when rebasing.
---
bugapp/Commit.go | 1 +
scm/Detect.go | 10 +++++++---
scm/GitManager.go | 17 +++++++++++------
3 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/bugapp/Commit.go b/bugapp/Commit.go
index 2d8944d..1a917e1 100644
--- a/bugapp/Commit.go
+++ b/bugapp/Commit.go
@@ -13,6 +13,7 @@ func Commit(args ArgumentList) {
} else {
options["autoclose"] = false
}
+ options["use_bug_prefix"] = true // SCM will ignore this option if it doesn't know it
scm, _, err := scm.DetectSCM(options)
if err != nil {
diff --git a/scm/Detect.go b/scm/Detect.go
index 927d23a..b089389 100644
--- a/scm/Detect.go
+++ b/scm/Detect.go
@@ -38,10 +38,14 @@ func DetectSCM(options map[string]bool) (SCMHandler, bugs.Directory, error) {
dirFound, scmtype := walkAndSearch(wd, []string{".git", ".hg"})
if dirFound != "" && scmtype == ".git" {
- if val, exists := options["autoclose"]; exists && val == true {
- return GitManager{Autoclose: true}, bugs.Directory(dirFound), nil
+ var gm GitManager
+ if val, ok := options["autoclose"]; ok {
+ gm.Autoclose = val
}
- return GitManager{Autoclose: false}, bugs.Directory(dirFound), nil
+ if val, ok := options["use_bug_prefix"]; ok {
+ gm.UseBugPrefix = val
+ }
+ return gm, bugs.Directory(dirFound), nil
}
if dirFound != "" && scmtype == ".hg" {
return HgManager{}, bugs.Directory(dirFound), nil
diff --git a/scm/GitManager.go b/scm/GitManager.go
index fcb6e5a..96bfcce 100644
--- a/scm/GitManager.go
+++ b/scm/GitManager.go
@@ -12,7 +12,8 @@ import (
)
type GitManager struct {
- Autoclose bool
+ Autoclose bool
+ UseBugPrefix bool
}
func (a GitManager) Purge(dir bugs.Directory) error {
@@ -85,7 +86,6 @@ func (a GitManager) currentStatus(dir bugs.Directory) (closedOnGitHub []string,
continue
}
- // TODO: check if path starts with $issues
path := file[3:]
op := file[0]
desc := strings.HasSuffix(path, "/Description")
@@ -168,9 +168,6 @@ func (a GitManager) Commit(dir bugs.Directory, backupCommitMsg string) error {
}
msg := a.commitMsg(dir)
- if len(msg) == 0 {
- msg = []byte(backupCommitMsg)
- }
file, err := ioutil.TempFile("", "bugCommit")
if err != nil {
@@ -178,7 +175,15 @@ func (a GitManager) Commit(dir bugs.Directory, backupCommitMsg string) error {
}
defer os.Remove(file.Name())
- fmt.Fprintf(file, "%s\n", msg)
+ if len(msg) == 0 {
+ fmt.Fprintf(file, "%s\n", backupCommitMsg)
+ } else {
+ var pref string
+ if a.UseBugPrefix {
+ pref = "bug: "
+ }
+ fmt.Fprintf(file, "%s%s\n", pref, msg)
+ }
cmd = exec.Command("git", "commit", "-o", string(dir), "-F", file.Name(), "-q")
if err := cmd.Run(); err != nil {
// If nothing was added commit will have an error,
From 01fff53ca6dd63eed3be89cacebf245a753b6386 Mon Sep 17 00:00:00 2001
From: driusan
Date: Sun, 28 Feb 2016 15:56:01 -0500
Subject: [PATCH 41/47] Remove attempt to autopage with less
Bug was previously trying to autopage output that is longer
than 1 screen long. This was causing issues with people who
prefer other pagers, and with systems where less isn't installed.
(ie. Plan9) or on dumb terminals.
It now doesn't try and guess at all, bug requires the user to manually
pipe through their favourite pager. Ths should cause fewer issues
in weird configurations.
---
bugapp/List.go | 2 +-
main.go | 42 +-----------------------------------------
2 files changed, 2 insertions(+), 42 deletions(-)
diff --git a/bugapp/List.go b/bugapp/List.go
index 5c4ad1d..b43806a 100644
--- a/bugapp/List.go
+++ b/bugapp/List.go
@@ -26,7 +26,7 @@ func listTags(files []os.FileInfo, args ArgumentList) {
}
}
}
-func List(args ArgumentList, stdout *os.File) {
+func List(args ArgumentList) {
issues, _ := ioutil.ReadDir(string(bugs.GetIssuesDir()))
var wantTags bool = false
diff --git a/main.go b/main.go
index 9759ea6..b7661a0 100644
--- a/main.go
+++ b/main.go
@@ -5,10 +5,6 @@ import (
"github.com/driusan/bug/bugapp"
"github.com/driusan/bug/bugs"
"os"
- "os/exec"
- "runtime"
- // "bytes"
- // "io"
)
func main() {
@@ -20,49 +16,18 @@ func main() {
os.Exit(2)
}
- // Create a pipe for a pager to use
- r, w, err := os.Pipe()
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- }
- // Capture STDOUT for the Pager
- stdout := os.Stdout
-
- // Don't capture the output on MacOS, because for some reason
- // it doesn't work and results in nothing getting printed
- if runtime.GOOS != "darwin" {
- os.Stdout = w
- }
-
- // Invoke less -RF attached to the pipe
- // we created
- cmd := exec.Command("less", "-RF")
- cmd.Stdin = r
- cmd.Stdout = stdout
- cmd.Stderr = os.Stderr
- // Make sure the pipe is closed after we
- // finish, then restore STDOUT
- defer func() {
- w.Close()
- if err := cmd.Run(); err != nil {
- fmt.Fprintln(os.Stderr, err)
- }
- os.Stdout = stdout
- }()
-
if len(os.Args) > 1 {
if len(os.Args) >= 3 && os.Args[2] == "--help" {
os.Args[1], os.Args[2] = "help", os.Args[1]
}
switch os.Args[1] {
case "add", "new", "create":
- os.Stdout = stdout
bugapp.Create(os.Args[2:])
case "view", "list":
// bug list with no parameters shouldn't autopage,
// bug list with bugs to view should. So the original
// stdout is passed as a parameter.
- bugapp.List(os.Args[2:], stdout)
+ bugapp.List(os.Args[2:])
case "priority":
bugapp.Priority(os.Args[2:])
case "status":
@@ -76,15 +41,10 @@ func main() {
case "mv", "rename", "retitle", "relabel":
bugapp.Relabel(os.Args[2:])
case "purge":
- // This shouldn't autopage
- os.Stdout = stdout
bugapp.Purge()
case "rm", "close":
bugapp.Close(os.Args[2:])
case "edit":
- // Edit needs the original Stdout since it
- // invokes an editor
- os.Stdout = stdout
bugapp.Edit(os.Args[2:])
case "--version", "version":
bugapp.Version()
From bf915ad1c9cd4751d57d13b1331ff922217613e6 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 28 Feb 2016 16:08:37 -0500
Subject: [PATCH 42/47] bug: Create issues:
"Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory",
"bug--create-lets-you-create-an-unnamed-bug",
"Feature-request:-arg-for-bug--create-to-use-a-generated-identifier"; Update
issues:
"Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/tags",
"bug--create-lets-you-create-an-unnamed-bug/tags",
"Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/tags"
---
.../Description | 0
.../Identifier | 3 +++
.../tags/enhancement | 0
.../Description | 0
.../Identifier | 3 +++
.../tags/bug | 0
issues/bug--create-lets-you-create-an-unnamed-bug/Description | 4 ++++
issues/bug--create-lets-you-create-an-unnamed-bug/Identifier | 3 +++
issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug | 0
9 files changed, 13 insertions(+)
create mode 100644 issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Description
create mode 100644 issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier
create mode 100644 issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/tags/enhancement
create mode 100644 issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Description
create mode 100644 issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier
create mode 100644 issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/tags/bug
create mode 100644 issues/bug--create-lets-you-create-an-unnamed-bug/Description
create mode 100644 issues/bug--create-lets-you-create-an-unnamed-bug/Identifier
create mode 100644 issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug
diff --git a/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Description b/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Description
new file mode 100644
index 0000000..e69de29
diff --git a/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier b/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier
new file mode 100644
index 0000000..25d970f
--- /dev/null
+++ b/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier
@@ -0,0 +1,3 @@
+
+
+GitHub:driusan/bug#11
diff --git a/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/tags/enhancement b/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/tags/enhancement
new file mode 100644
index 0000000..e69de29
diff --git a/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Description b/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Description
new file mode 100644
index 0000000..e69de29
diff --git a/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier b/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier
new file mode 100644
index 0000000..03c7d1c
--- /dev/null
+++ b/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier
@@ -0,0 +1,3 @@
+
+
+GitHub:driusan/bug#12
diff --git a/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/tags/bug b/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/tags/bug
new file mode 100644
index 0000000..e69de29
diff --git a/issues/bug--create-lets-you-create-an-unnamed-bug/Description b/issues/bug--create-lets-you-create-an-unnamed-bug/Description
new file mode 100644
index 0000000..0a0b6b2
--- /dev/null
+++ b/issues/bug--create-lets-you-create-an-unnamed-bug/Description
@@ -0,0 +1,4 @@
+$ bug create --status open --priority 0 --identifier 1
+Created issue:
+$ ls issues
+Description Identifier Priority Status
\ No newline at end of file
diff --git a/issues/bug--create-lets-you-create-an-unnamed-bug/Identifier b/issues/bug--create-lets-you-create-an-unnamed-bug/Identifier
new file mode 100644
index 0000000..ca20ffc
--- /dev/null
+++ b/issues/bug--create-lets-you-create-an-unnamed-bug/Identifier
@@ -0,0 +1,3 @@
+
+
+GitHub:driusan/bug#13
diff --git a/issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug b/issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug
new file mode 100644
index 0000000..e69de29
From 52aef574dc9dcf9c4e49b9bcb01e199b72557f4f Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 28 Feb 2016 16:09:14 -0500
Subject: [PATCH 43/47] Fixed bug where you could create an empty title
Closes driusan/bug#11
---
bugapp/Create.go | 7 +++++++
.../Description | 0
.../Identifier | 3 ---
.../tags/enhancement | 0
.../bug--create-lets-you-create-an-unnamed-bug/Description | 4 ----
.../bug--create-lets-you-create-an-unnamed-bug/Identifier | 3 ---
issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug | 0
7 files changed, 7 insertions(+), 10 deletions(-)
delete mode 100644 issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Description
delete mode 100644 issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier
delete mode 100644 issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/tags/enhancement
delete mode 100644 issues/bug--create-lets-you-create-an-unnamed-bug/Description
delete mode 100644 issues/bug--create-lets-you-create-an-unnamed-bug/Identifier
delete mode 100644 issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug
diff --git a/bugapp/Create.go b/bugapp/Create.go
index 027cc85..cc5fafe 100644
--- a/bugapp/Create.go
+++ b/bugapp/Create.go
@@ -45,6 +45,13 @@ func Create(Args ArgumentList) {
identifier = generateID(strings.Join(Args, " "))
}
+ // It's possible there were arguments provided, but still no title
+ // included. Do another check before trying to create the bug.
+ if strings.TrimSpace(strings.Join(Args, " ")) == "" {
+ fmt.Fprintf(os.Stderr, "Usage: %s create [-n] Bug Description\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "\nNo Bug Description provided.\n")
+ return
+ }
var bug bugs.Bug
bug = bugs.Bug{
Dir: bugs.GetIssuesDir() + bugs.TitleToDir(strings.Join(Args, " ")),
diff --git a/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Description b/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Description
deleted file mode 100644
index e69de29..0000000
diff --git a/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier b/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier
deleted file mode 100644
index 25d970f..0000000
--- a/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/Identifier
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-GitHub:driusan/bug#11
diff --git a/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/tags/enhancement b/issues/Feature-request:-arg-for-bug--create-to-use-a-generated-identifier/tags/enhancement
deleted file mode 100644
index e69de29..0000000
diff --git a/issues/bug--create-lets-you-create-an-unnamed-bug/Description b/issues/bug--create-lets-you-create-an-unnamed-bug/Description
deleted file mode 100644
index 0a0b6b2..0000000
--- a/issues/bug--create-lets-you-create-an-unnamed-bug/Description
+++ /dev/null
@@ -1,4 +0,0 @@
-$ bug create --status open --priority 0 --identifier 1
-Created issue:
-$ ls issues
-Description Identifier Priority Status
\ No newline at end of file
diff --git a/issues/bug--create-lets-you-create-an-unnamed-bug/Identifier b/issues/bug--create-lets-you-create-an-unnamed-bug/Identifier
deleted file mode 100644
index ca20ffc..0000000
--- a/issues/bug--create-lets-you-create-an-unnamed-bug/Identifier
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-GitHub:driusan/bug#13
diff --git a/issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug b/issues/bug--create-lets-you-create-an-unnamed-bug/tags/bug
deleted file mode 100644
index e69de29..0000000
From a53d621f0a4c1f1a7d951d7763ff2eecc423a1bd Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 28 Feb 2016 16:24:55 -0500
Subject: [PATCH 44/47] Fixed bug where help was unavailable if there is no
issues directory
Closes driusan/bug#12
---
.../Description | 0
.../Identifier | 3 ---
.../tags/bug | 0
main.go | 17 ++++++++++++++++-
4 files changed, 16 insertions(+), 4 deletions(-)
delete mode 100644 issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Description
delete mode 100644 issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier
delete mode 100644 issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/tags/bug
diff --git a/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Description b/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Description
deleted file mode 100644
index e69de29..0000000
diff --git a/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier b/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier
deleted file mode 100644
index 03c7d1c..0000000
--- a/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/Identifier
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-GitHub:driusan/bug#12
diff --git a/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/tags/bug b/issues/Unable-to-use_--help-or-help-to-examine-usage-if-there's-no-issues-directory/tags/bug
deleted file mode 100644
index e69de29..0000000
diff --git a/main.go b/main.go
index b7661a0..f5da8cd 100644
--- a/main.go
+++ b/main.go
@@ -8,12 +8,27 @@ import (
)
func main() {
- if bugs.GetRootDir() == "" {
+ var skipRootCheck bool = false
+ switch len(os.Args) {
+ case 0, 1:
+ skipRootCheck = true
+ case 2:
+ if os.Args[1] == "help" {
+ skipRootCheck = true
+ }
+ case 3:
+ if os.Args[2] == "--help" {
+ skipRootCheck = true
+ }
+
+ }
+ if skipRootCheck == false && bugs.GetRootDir() == "" {
fmt.Printf("Could not find issues directory.\n")
fmt.Printf("Make sure either the PMIT environment variable is set, or a parent directory of your working directory has an issues folder.\n")
fmt.Println("(If you just started new repo, you probably want to create directory named `issues`).")
fmt.Printf("Aborting.\n")
os.Exit(2)
+
}
if len(os.Args) > 1 {
From 80f8fa9dcb7a0403973edf7a95e2c94b6c8a41d2 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 28 Feb 2016 16:36:51 -0500
Subject: [PATCH 45/47] Included help for bug create --generate-id option.
The option was already there, but there was no way for people
to know about it.
Closes driusan/bug#11
---
bugapp/Help.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/bugapp/Help.go b/bugapp/Help.go
index 4fa7192..3055559 100644
--- a/bugapp/Help.go
+++ b/bugapp/Help.go
@@ -35,6 +35,7 @@ time as creating it. Valid options are:
--priority Sets the priority to the next parameter
--milestone Sets the milestone to the next parameter
--identifier Sets the identifier to the next parameter
+ --generate-id Automatically generate a stable bug identifier
`, os.Args[0])
case "list":
fmt.Printf("Usage: " + os.Args[0] + " list [BugIDs]\n")
From 9fda82f45f6fb31e2302b726168b768472494813 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 28 Feb 2016 16:46:38 -0500
Subject: [PATCH 46/47] Removed bug-serve to move to a different repository
The bug-serve code isn't as mature as the bug code, and
is pretty much a completely independent codebase. It was
never include in any releases unless installed with `go get`.
Being in a separate repository (https://github.com/driusan/bug-serve)
allows development of both bug and bug-serve to move faster.
---
bug-serve/JSAssetHandler.go | 19 --
bug-serve/MainPageHandler.go | 35 --
bug-serve/Makefile | 16 -
bug-serve/README.md | 7 -
bug-serve/RestfulBugHandler.go | 165 ----------
bug-serve/SettingsHandler.go | 21 --
bug-serve/bindata.go | 306 ------------------
.../Implement-HTML5-history-API/Description | 0
.../PUT-should-create-an-issue/Description | 3 -
.../Description | 3 -
.../Should-include-REST-API/Description | 2 -
.../Description | 2 -
bug-serve/js/marked.min.js | 6 -
bug-serve/jsx/BugApp.js | 132 --------
bug-serve/jsx/BugList.js | 24 --
bug-serve/jsx/BugPage.js | 164 ----------
bug-serve/main.go | 17 -
.../Description | 3 -
.../Milestone | 1 -
.../Status | 0
.../tags/feature | 0
21 files changed, 926 deletions(-)
delete mode 100644 bug-serve/JSAssetHandler.go
delete mode 100644 bug-serve/MainPageHandler.go
delete mode 100644 bug-serve/Makefile
delete mode 100644 bug-serve/README.md
delete mode 100644 bug-serve/RestfulBugHandler.go
delete mode 100644 bug-serve/SettingsHandler.go
delete mode 100644 bug-serve/bindata.go
delete mode 100644 bug-serve/issues/Implement-HTML5-history-API/Description
delete mode 100644 bug-serve/issues/PUT-should-create-an-issue/Description
delete mode 100644 bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description
delete mode 100644 bug-serve/issues/Should-include-REST-API/Description
delete mode 100644 bug-serve/issues/Should-titles-instead-of-directories/Description
delete mode 100644 bug-serve/js/marked.min.js
delete mode 100644 bug-serve/jsx/BugApp.js
delete mode 100644 bug-serve/jsx/BugList.js
delete mode 100644 bug-serve/jsx/BugPage.js
delete mode 100644 bug-serve/main.go
delete mode 100644 issues/bug--serve-should-have-feature-parity-with-bug/Description
delete mode 100644 issues/bug--serve-should-have-feature-parity-with-bug/Milestone
delete mode 100644 issues/bug--serve-should-have-feature-parity-with-bug/Status
delete mode 100644 issues/bug--serve-should-have-feature-parity-with-bug/tags/feature
diff --git a/bug-serve/JSAssetHandler.go b/bug-serve/JSAssetHandler.go
deleted file mode 100644
index 6de9204..0000000
--- a/bug-serve/JSAssetHandler.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package main
-
-import (
- "github.com/driusan/GoWebapp/URLHandler"
- "net/http"
-)
-
-type JSAssetHandler struct {
- URLHandler.DefaultHandler
-}
-
-func (s JSAssetHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
- data, err := Asset(r.URL.Path[1:])
- if err == nil {
- return string(data), nil
-
- }
- return "File Not found", URLHandler.NotFoundError{}
-}
diff --git a/bug-serve/MainPageHandler.go b/bug-serve/MainPageHandler.go
deleted file mode 100644
index 29f595e..0000000
--- a/bug-serve/MainPageHandler.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package main
-
-import (
- "github.com/driusan/GoWebapp/HTMLPageRenderer"
- "github.com/driusan/GoWebapp/URLHandler"
- "net/http"
-)
-
-type MainPageHandler struct {
- URLHandler.DefaultHandler
-}
-
-func (m MainPageHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
- page := HTMLPageRenderer.ReactPage{
- Title: "Open Issues",
- JSFiles: []string{
- // Bootstrap
- //"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
- // React
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js",
- "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js",
- "/js/marked.min.js",
- "/js/BugApp.js",
- "/js/BugList.js",
- "/js/BugPage.js",
- },
- CSSFiles: []string{
- // Bootstrap
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
- "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css",
- },
- RootElement: "BugApp",
- }
- return HTMLPageRenderer.Render(page), nil
-}
diff --git a/bug-serve/Makefile b/bug-serve/Makefile
deleted file mode 100644
index 6300594..0000000
--- a/bug-serve/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-all: Generate Go serve
-
-Generate:
- go generate
-Go:
- go build .
-
-js: React
-
-jsx: React
-
-React:
- babel --out-dir=js jsx
-
-serve:
- ./bug-serve
diff --git a/bug-serve/README.md b/bug-serve/README.md
deleted file mode 100644
index 8284fb5..0000000
--- a/bug-serve/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# bug-serve
-
-This directory contains an application to serve a issues/
-directory managed by bug over HTTP using React.JS and
-Bootstrap.
-
-It's not as mature as the bug code.
diff --git a/bug-serve/RestfulBugHandler.go b/bug-serve/RestfulBugHandler.go
deleted file mode 100644
index fb655fe..0000000
--- a/bug-serve/RestfulBugHandler.go
+++ /dev/null
@@ -1,165 +0,0 @@
-package main
-
-import (
- "crypto/sha1"
- "encoding/json"
- "fmt"
- "github.com/driusan/GoWebapp/URLHandler"
- "github.com/driusan/bug/bugs"
- "io"
- "io/ioutil"
- "net/http"
- "net/url"
- "strings"
- "time"
-)
-
-type BugPageHandler struct {
- URLHandler.DefaultHandler
-}
-
-func getBugList() (string, error) {
- issues, _ := ioutil.ReadDir(string(bugs.GetRootDir()) + "/issues")
-
- var issuesSlice []string
-
- for _, issue := range issues {
- if issue.IsDir() {
- issuesSlice = append(issuesSlice, issue.Name())
- }
- }
-
- retVal, _ := json.Marshal(issuesSlice)
- return string(retVal), nil
-}
-func parseURL(u *url.URL) []string {
- if u.Path == "/issues" || u.Path == "/issues/" {
- return []string{}
- }
- bugURL := strings.TrimPrefix(u.Path, "/issues/")
- bugURL = strings.TrimRight(bugURL, "/")
-
- return strings.Split(bugURL, "/")
-
-}
-
-func (m BugPageHandler) Get(r *http.Request, extras map[string]interface{}) (string, error) {
- switch urlChunks := parseURL(r.URL); len(urlChunks) {
- case 0:
- return getBugList()
- case 1:
- b, err := bugs.LoadBugByDirectory(urlChunks[0])
- if err != nil {
- return "", URLHandler.NotFoundError{}
- }
- return b.ToJSONString()
- default:
- // Must be > 1, so check what field we're editing..
- // Need to load the bug since this is a different
- // case statement..
- b, err := bugs.LoadBugByDirectory(urlChunks[0])
- if err != nil {
- return "", URLHandler.NotFoundError{}
- }
- switch urlChunks[1] {
- case "Description":
- return b.Description(), nil
- default:
- // No known field, so return a 404 error.
- return "", URLHandler.NotFoundError{}
- }
- }
- return "", URLHandler.NotFoundError{}
-}
-
-func (m BugPageHandler) Put(r *http.Request, extras map[string]interface{}) (string, error) {
- urlChunks := parseURL(r.URL)
- switch len(urlChunks) {
- case 0:
- return "", URLHandler.BadRequestError{}
- case 1:
- // This should eventually be supported if a JSON string
- // is PUT, but for now we only support PUT to a specific
- // field
- return "", URLHandler.BadRequestError{}
- }
-
- b, err := bugs.LoadBugByDirectory(urlChunks[0])
- if err != nil {
- // This should create the issue instead, but for now
- // only updating fields is supported
- return "", URLHandler.BadRequestError{}
- }
- switch urlChunks[1] {
- case "Description":
- if val, err := ioutil.ReadAll(r.Body); err == nil {
- b.SetDescription(string(val))
- return "", nil
- } else {
- panic(err.Error())
- }
-
- }
- return "", URLHandler.BadRequestError{}
-}
-
-func (m BugPageHandler) Delete(r *http.Request, extras map[string]interface{}) (string, error) {
- urlChunks := parseURL(r.URL)
- if len(urlChunks) != 1 {
- return "", URLHandler.BadRequestError{}
- }
-
- b, err := bugs.LoadBugByDirectory(urlChunks[0])
- if err != nil {
- return "", URLHandler.NotFoundError{}
- }
-
- if err := b.Remove(); err != nil {
- panic("Could not delete bug.")
- }
- return "", nil
-}
-func (m BugPageHandler) ETag(u *url.URL, o map[string]interface{}) (URLHandler.ETag, error) {
- urlChunks := parseURL(u)
- fmt.Printf("Calculating ETag for %s => %s\n", u, urlChunks)
- if len(urlChunks) == 0 {
- return URLHandler.ETag(""), nil
- }
-
- b, err := bugs.LoadBugByDirectory(urlChunks[0])
- if err != nil {
- // If the bug doesn't exist, it's not an error, but there
- // shouldn't be an ETag either..
- return "", nil
- }
-
- h := sha1.New()
- io.WriteString(h, b.Title(""))
- io.WriteString(h, "--")
- io.WriteString(h, b.Description())
- io.WriteString(h, "--")
- io.WriteString(h, b.Identifier())
- io.WriteString(h, "--")
- io.WriteString(h, b.Status())
- io.WriteString(h, "--")
- io.WriteString(h, b.Milestone())
- io.WriteString(h, "--")
- io.WriteString(h, b.Priority())
- io.WriteString(h, "--")
- io.WriteString(h, b.GetDirectory().LastModified().Format(time.UnixDate))
- return URLHandler.ETag(fmt.Sprintf("%x", h.Sum(nil))), nil
-}
-
-func (m BugPageHandler) LastModified(u *url.URL, o map[string]interface{}) time.Time {
- urlChunks := parseURL(u)
- if len(urlChunks) == 0 {
- return URLHandler.UnknownMTime
- }
-
- b, err := bugs.LoadBugByDirectory(urlChunks[0])
- if err != nil {
- return URLHandler.UnknownMTime
- }
- return b.GetDirectory().LastModified()
-
-}
diff --git a/bug-serve/SettingsHandler.go b/bug-serve/SettingsHandler.go
deleted file mode 100644
index d20fa66..0000000
--- a/bug-serve/SettingsHandler.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package main
-
-import (
- "encoding/json"
- "github.com/driusan/GoWebapp/URLHandler"
- "github.com/driusan/bug/bugs"
- "net/http"
-)
-
-type SettingsHandler struct {
- URLHandler.DefaultHandler
-}
-
-func (s SettingsHandler) Get(r *http.Request, p map[string]interface{}) (string, error) {
- settings := struct {
- Title string
- Directory string
- }{bugs.GetRootDir().GetShortName().ToTitle(), string(bugs.GetRootDir())}
- retVal, _ := json.Marshal(settings)
- return string(retVal), nil
-}
diff --git a/bug-serve/bindata.go b/bug-serve/bindata.go
deleted file mode 100644
index 77d17f6..0000000
--- a/bug-serve/bindata.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Code generated by go-bindata.
-// sources:
-// js/BugApp.js
-// js/BugList.js
-// js/BugPage.js
-// js/marked.min.js
-// DO NOT EDIT!
-
-package main
-
-import (
- "bytes"
- "compress/gzip"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "time"
-)
-
-func bindataRead(data []byte, name string) ([]byte, error) {
- gz, err := gzip.NewReader(bytes.NewBuffer(data))
- if err != nil {
- return nil, fmt.Errorf("Read %q: %v", name, err)
- }
-
- var buf bytes.Buffer
- _, err = io.Copy(&buf, gz)
- clErr := gz.Close()
-
- if err != nil {
- return nil, fmt.Errorf("Read %q: %v", name, err)
- }
- if clErr != nil {
- return nil, err
- }
-
- return buf.Bytes(), nil
-}
-
-type asset struct {
- bytes []byte
- info os.FileInfo
-}
-
-type bindataFileInfo struct {
- name string
- size int64
- mode os.FileMode
- modTime time.Time
-}
-
-func (fi bindataFileInfo) Name() string {
- return fi.name
-}
-func (fi bindataFileInfo) Size() int64 {
- return fi.size
-}
-func (fi bindataFileInfo) Mode() os.FileMode {
- return fi.mode
-}
-func (fi bindataFileInfo) ModTime() time.Time {
- return fi.modTime
-}
-func (fi bindataFileInfo) IsDir() bool {
- return false
-}
-func (fi bindataFileInfo) Sys() interface{} {
- return nil
-}
-
-var _jsBugappJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xdc\x56\x4d\x6f\xe3\x36\x10\x3d\xdb\xbf\x82\xd5\x61\xa1\xa0\xaa\x76\xfb\x71\x4a\xeb\x02\xd9\xd8\xd8\xa4\x48\x36\x41\xe2\x02\x05\x8a\x1e\xb8\xd2\xd8\x66\x97\x91\x5c\x72\x94\x26\x58\xe4\xbf\x77\xc8\xa1\x2c\x2a\x96\xf2\x71\x28\x0a\xf4\x62\xc0\x9c\x37\xc3\x37\x8f\x8f\x43\xdd\x4a\x23\xde\x37\xeb\xa3\xed\x56\xcc\xc4\x15\xc8\x02\xf3\xc2\x80\x44\x38\xd6\xd2\xda\xf4\xcb\x74\x52\x2a\xbb\xd5\xf2\xfe\xa3\xbc\x81\x43\x91\x30\x36\xc9\xa6\xd3\x89\x01\x5d\xcb\xf2\xd4\xda\x06\xec\xa1\x58\x35\x55\x81\xaa\xae\x44\x7a\x20\x28\x6b\xe2\x0a\xe3\x46\x22\x95\xc5\x8d\xb2\x3f\xd2\xd2\xd1\x9f\xf2\xee\x03\x60\x9a\xbc\x55\x3e\xe9\x6d\x92\x45\x69\x06\xec\xb6\xae\x2c\x70\xfa\xc4\xe5\xe6\x16\xf0\x1a\x89\x4c\xea\x97\x26\x6e\x77\x9b\x1c\x8a\x5f\xae\x2f\x3e\xe6\x5b\x69\x2c\x74\x59\x0e\xf0\x70\xe0\xb6\xf1\xbf\x0f\x59\x4b\xf0\x1a\x10\x55\xb5\x7e\x2d\x45\x1b\xd2\x5e\xcd\xb1\xdd\xef\xe5\x3c\x8b\xfa\x86\x62\x50\xe1\x5c\x95\xe7\x75\x53\xe1\x3e\x55\xc7\x2f\x8f\x05\x4f\x7d\x89\x68\xb9\xdd\x36\x6d\xab\xae\x01\x4f\x2b\x85\x4a\x6a\x4f\x6f\xbf\xa6\x01\x6c\x4c\xc5\x9d\xc4\xac\xbf\xb8\x6c\x5a\x5a\x2a\xd4\x40\xff\x93\x8b\x2d\x54\x82\xb7\x4d\x38\x14\xce\xe1\xf7\x3f\xb2\x90\xac\xa1\x40\x28\x69\x99\x56\xab\x46\xeb\xbd\xf5\xb9\x32\xae\x54\xe2\xfa\x0e\x04\x1d\x6b\x8a\xc4\xc4\x3e\x35\xeb\x57\xb8\x47\x7c\x2d\x28\x81\x7e\x93\x61\x27\x65\x62\x23\xab\x52\x83\x79\xfa\xb8\x62\xee\x43\x27\x96\xed\x01\x17\x4b\xe9\xc0\xa1\x7a\x4e\x4a\x5f\x05\xf0\x09\xc8\x12\x4c\x9a\x78\xc4\x40\x26\xcb\x40\xac\x07\x6c\x60\x3d\x8c\x40\x27\x5c\x37\x16\x26\x38\x0e\xf2\xad\x81\x5b\xe7\x14\x58\xc9\x46\x63\xe4\x82\xa0\x66\x0a\x79\xd1\x18\x43\x90\xa5\x34\x44\x2c\x47\xb8\xc3\xe3\xba\x42\x5a\xe9\xee\x85\x13\x21\x90\x1a\xf1\x5a\x27\x93\x78\xc9\xf1\x06\x45\x9e\x38\x7a\x17\xea\x5f\x4e\xda\xc2\xf9\x68\xd4\xec\x11\xc9\x3d\xb7\x47\x97\x80\x8b\x55\x65\x5f\xb0\xce\x46\x05\x37\xef\x0a\xa8\x95\x48\xb9\x3b\xd7\x5a\x1e\x71\x14\x5f\xcd\x3c\xc3\xe0\x94\x90\xf3\x68\x24\x2e\x34\xdc\xd0\x6a\x4a\xf8\x4b\xb9\x26\x7b\xb1\x85\xfc\x3d\x39\x14\xc3\x85\x73\x1f\x65\x23\xcc\xc1\x16\x46\x6d\x1d\xc1\x51\x78\x84\xe1\xa4\x73\xa5\xc1\x22\x8d\x87\xd1\x94\x1d\x82\x13\xdc\xb1\x35\x76\x14\xcd\x61\x86\x5e\x1a\x55\x1b\x85\xf7\xa3\xe0\x16\xc0\xf0\xd3\x92\xba\x57\x2b\xe5\x94\x1e\x49\xe8\x20\x9c\x42\xb6\x18\xa7\xe2\x82\x0c\xab\xab\xf7\xb2\xf8\x1c\x80\xbd\x93\x6f\xe3\x73\xfa\x8f\x10\x23\x9c\x77\x38\x7a\xa4\x35\x1b\x29\xda\xa7\x8b\x1e\xf3\x75\xf0\x93\x66\x98\x08\x19\xb4\x07\x75\x66\x1e\xc3\xba\x58\xcb\xe9\x02\x37\x60\x68\xed\x58\xab\xe2\xb3\xbb\x49\xe1\xe6\xf4\xaf\x31\xa3\xcf\xda\x61\x17\x5f\xd6\x68\x08\x08\xd0\x16\x5e\x68\xbe\x33\x65\x71\xdc\x7c\x91\xe1\x9e\x50\x85\x14\x7f\x8e\x78\xc4\xae\x7b\x2d\x86\x28\xf9\x0b\x5f\xaa\x5b\x7e\x1c\x76\x33\x60\x0c\x3a\x49\x36\xdf\x32\xb4\xc3\x4e\x12\xbe\xd1\x62\x55\x93\xb9\x42\xb4\x77\x02\xfc\x3c\x71\x77\x2e\x7a\xf0\xcc\x1e\x3b\x3e\xd1\x26\x41\x59\x9f\x4e\x3f\x7e\x7a\x4c\x5d\x8b\x53\x37\x28\xc2\x03\x43\xba\x77\x63\xa4\x31\x3a\x13\x85\xd4\xfa\x13\xf9\xd3\x0f\x07\x87\xbc\xbb\xd1\x1b\x44\xf7\xc5\x54\xc1\xdf\xe2\xb7\xf3\xb3\x13\xfa\x77\x05\x7f\x51\x03\x3c\x92\x03\x20\xaf\x2b\x62\x56\xde\xfb\x1e\x0a\x7a\x2e\xd6\xd0\xab\xce\xd3\x66\x37\x95\x3c\xd6\x4f\x5d\x31\x9b\xcd\xc4\x0f\xe2\xcd\x9b\xee\xf0\x1a\x4b\x8b\xe2\xbb\x77\xef\xda\x11\x15\x48\xb5\xa9\xfc\xfe\x2c\x69\xda\x67\x3e\xa9\x3d\xb8\x87\x98\x0e\x3d\xe4\x69\xf2\x61\xb1\xa4\xe7\xd2\x77\x86\xa6\x81\x98\xaf\xa5\x39\xea\x1a\x78\x88\x24\xb9\x6c\x06\x24\x29\x25\xca\x4e\x98\x4c\x00\xca\xf5\x7f\x2d\xcf\xcf\x5e\x9e\xc7\xab\x3f\x89\xef\x5f\xa0\xd9\xb8\x5a\x97\xbf\xee\xa9\xe5\x18\xed\x1a\x8e\xb4\xc3\xd0\x63\xfb\x11\x70\xba\xfa\xe6\x5c\x62\xb1\x49\x82\x3e\xde\x6e\x7d\xad\x9d\x8e\xfb\x7a\xbb\xaf\x90\xe7\x34\xf7\x9b\x07\x3c\xc7\xfd\xb7\x8b\x45\x43\xf7\x44\xad\xee\xb9\x74\x84\xef\xef\xc2\xf3\x74\xdc\xeb\xff\xe7\x23\x9d\x2f\xce\x16\xcb\xc5\xbf\x78\xaa\x5e\xeb\x7f\x02\x00\x00\xff\xff\x17\x7e\x3a\xfe\x5a\x0d\x00\x00")
-
-func jsBugappJsBytes() ([]byte, error) {
- return bindataRead(
- _jsBugappJs,
- "js/BugApp.js",
- )
-}
-
-func jsBugappJs() (*asset, error) {
- bytes, err := jsBugappJsBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "js/BugApp.js", size: 3418, mode: os.FileMode(436), modTime: time.Unix(1453860464, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-var _jsBuglistJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x91\x3f\x6b\xf3\x30\x10\xc6\x67\xf9\x53\x1c\x7a\x17\x9b\x37\x78\xe8\xe8\xd0\xa5\x69\x87\x42\x29\xa5\x74\x2b\x1d\x84\x7d\x89\x45\x64\xd9\x48\xb2\x21\x04\x7f\xf7\x9e\xfe\xb8\x31\x84\x90\xe5\x38\x9d\x4e\xbf\x7b\x9e\xd3\x24\x0c\x3c\x8d\x87\x37\x69\x1d\x3c\xc2\x27\x8a\xda\x95\xb5\x41\xe1\x70\xa7\x84\xb5\xf9\x39\x63\x8d\xb4\x83\x12\xa7\x77\xd1\x61\x05\x3c\x35\xf3\x4d\x96\xb1\x03\xba\x67\xdc\x8b\x51\xb9\x0f\xd3\x0f\xb6\x82\xfd\xa8\x6b\x27\x7b\x0d\x79\x01\xf4\x92\x19\x74\xa3\xd1\x21\x65\xfc\x4b\x3a\x85\x3c\x22\x2c\xbd\xf7\xb5\x90\x56\xf0\xfd\x13\x8e\xbd\xa6\xf3\x4e\xc9\xfa\x88\xcd\x1a\x86\x91\xc6\x18\x96\x83\xc1\x09\xf5\x32\x36\x2f\xb6\x71\xc4\xd6\x5f\xcf\x14\x66\xca\x66\x82\x19\xd4\x0d\x9a\x6b\x45\xde\xaf\x6b\x85\x37\xeb\x5a\x69\xb7\xa9\x84\x0a\x3b\xc2\xda\x54\xa6\x31\xe4\xa7\xf4\xea\xca\x4e\x0c\xf9\x85\x32\x09\x95\xc4\x24\x6f\xeb\x95\xbd\x44\x4a\x1e\xb4\x72\x25\xa3\x49\x76\x86\x23\x9e\x2e\xab\x7b\x75\xd8\x71\xf8\x0f\x84\x82\x39\x76\xdc\x84\x30\x2e\x12\x84\x28\xad\xc1\x3d\x61\xfe\xf1\x0d\xf4\x3a\xac\xa9\x0a\x5e\x92\xda\xf5\xf6\x16\x30\x99\x53\x21\x29\x7c\x2c\xbc\xdd\x39\xc4\x3b\xea\x79\x23\xa7\x38\x58\x8f\x4a\x85\xe4\xb6\xd1\xf6\x21\x69\xfc\xeb\x65\xab\x25\x86\x6f\x0f\xd3\xef\x60\x7a\x75\x85\x59\xbe\x25\x4b\x0e\xbc\xf4\x39\x23\x07\xbf\x01\x00\x00\xff\xff\xc0\x85\x8c\x9c\xb7\x02\x00\x00")
-
-func jsBuglistJsBytes() ([]byte, error) {
- return bindataRead(
- _jsBuglistJs,
- "js/BugList.js",
- )
-}
-
-func jsBuglistJs() (*asset, error) {
- bytes, err := jsBuglistJsBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "js/BugList.js", size: 695, mode: os.FileMode(436), modTime: time.Unix(1453860464, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-var _jsBugpageJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x59\xdd\x6e\xdb\x36\x14\xbe\xcf\x53\x70\x1a\x50\xd8\xa8\xed\xc4\x41\x37\x0c\xf1\x3a\xa0\x4d\x02\xac\x40\xd2\x05\x49\xb6\x9b\x21\x17\xb4\x44\xdb\x6c\x69\x4a\x20\x29\x2f\x41\xe0\xdb\x5d\x0f\x7b\x82\x3d\xcb\x1e\x65\x4f\xb2\x43\xea\xc7\xa2\x44\xfd\x38\x71\x17\x8f\x40\x1b\x9b\xe4\xf9\x3f\x3c\xe7\x23\xbd\xc2\x02\xbd\x8f\xe7\x57\x78\x4e\xd0\x5b\x74\x4d\xb0\xaf\x46\xbe\x20\x58\x91\x53\x86\xa5\xec\x3d\x1e\x20\x18\x01\x95\x11\xc3\x0f\x1f\xf1\x92\x9c\x20\x2f\xdd\xef\x0d\x0e\xcc\xa2\x1f\x2e\xa3\x90\x13\xae\xce\x68\x70\x19\xc6\x5c\x9d\xa0\x59\xcc\x7d\x45\x43\x8e\x7a\x7d\x94\x70\xd0\x83\xce\x50\x4f\x2d\xa8\x1c\x09\x32\x93\xa3\x80\x48\xbf\xb8\xaa\x87\xbd\x3a\xa2\x9c\x13\xf1\xe3\xed\xe5\x05\xa8\xb6\xc4\xe2\x33\x09\x12\xfa\x48\x84\x91\x1c\x9d\xc1\x16\x41\x23\x2d\xa7\x3f\xc9\xd9\xac\x0f\x2c\x66\x92\xa8\x1b\x05\xd6\xf4\x6c\x41\xde\x79\x40\x15\xe5\x73\x0f\x74\xc5\x4c\x92\x0d\x79\xca\x6a\x3d\xa8\xd8\xf6\x73\x14\x00\xa3\x3d\x30\x2e\xd5\x8d\x85\x38\xb8\x12\x64\x45\xc3\x58\x42\x48\xea\x14\x9b\x85\x02\xf5\x74\x98\x29\x08\x1a\x4f\xe0\xcf\xf7\xa8\x20\xe8\x1d\x63\x40\x2c\x47\x8c\xf0\xb9\x5a\xe8\xe5\xd7\xb0\xad\xac\xbb\xa6\x9f\xc6\xf3\x53\xcc\x03\xaa\xbd\x00\xac\xaa\x3c\x7e\xa5\x77\x13\x8b\x4a\xfb\xc4\xa6\x7a\x6b\xd1\x9d\xc6\x42\x80\x6f\x81\xb6\x2c\x2f\xf7\x57\xb2\xf1\x02\x4c\x85\x5d\x3d\x97\x4c\x34\x44\xe3\xbb\xfe\xa4\x42\x2e\x88\x8a\x05\xb7\xe7\xd7\x8e\x34\x29\xee\x2b\x78\xf6\x23\xb9\x57\x5d\xbd\x7a\xd4\xe2\x55\xad\xe2\xff\xd1\xb3\xaf\x77\xee\xd9\x39\x51\x1f\x38\x9c\x3c\xcc\xcc\xa9\xac\xf3\x6e\x42\x89\xba\x9e\x59\x4b\x04\x81\x5d\x1b\xf3\xeb\x24\x74\x2c\x0e\x4a\xc4\xf5\xb5\x01\x73\x9f\x30\xbd\x57\x6f\x7e\xa6\xa0\xc6\x2a\x24\xf1\x8a\xb8\x4d\x22\x45\x51\x3a\x95\x8c\xf5\x2c\x94\xb1\xd0\x99\xb4\xd9\xe8\xab\xfb\x72\x26\xa4\x4e\xae\x61\x96\x0d\x20\x2c\xa8\x5f\x51\x39\x57\xb5\x4c\x63\xa7\xd7\x66\xa6\x90\x99\xa5\x0c\x9a\x94\x03\xaa\xc7\xbb\x4f\xf8\xfe\x2a\x56\x3d\xef\x90\x4a\x19\x13\x79\xe8\x41\x56\x3a\x13\x1d\xe6\xbd\xc3\x42\xd9\xf4\x06\x85\x8a\xab\xdd\x62\xaa\xee\x0a\xb3\x98\x0c\x8a\x6e\x32\xa9\xdf\x1f\x38\x98\x9e\xdf\xe2\xb9\x1d\x88\x80\x30\xa2\x6a\x42\x51\x8e\x84\x5a\x60\x95\x1e\x66\xdb\x9c\x33\xc3\xa4\x83\x45\x83\x1a\xee\x7a\x24\xed\x06\xab\x94\x28\xe4\x09\x57\xf7\x69\xaf\x6c\xeb\x95\x7d\xbf\x71\x7d\x37\x47\x84\xfc\x27\xb5\x20\x02\x94\x3c\x65\xd4\x87\xde\x55\x9b\x94\x4f\xce\x7f\x9b\x43\xa6\x7f\x49\x2c\xc8\xb2\xf4\x02\x6d\x03\x22\x9a\xc2\x32\xa3\x84\x05\xd7\xe1\x6f\xd6\xe9\xe0\x00\x6c\x06\xc8\xe4\x86\xcb\xd1\xce\x85\x44\x9c\x39\x42\x45\xd8\x74\xce\xc8\x12\x5c\xd6\xab\xec\x35\x06\x07\x74\xe5\x0d\x9c\x4b\x8f\xc8\xd7\x80\x2b\x85\x58\x02\x14\x34\x9a\x7a\x99\x65\xe5\xd1\x59\x66\x8b\xdc\xaa\x6c\x3f\x64\xc3\x65\x30\x1c\xd7\x8a\x36\x1c\xff\xfe\xcb\x73\x2e\xf6\x5f\x48\xdd\x63\xc4\xf0\x94\xb0\xe4\xff\x21\xe5\xb3\xb0\x51\x7f\x1d\xf1\xbd\xd2\xff\x0d\x9a\xe2\x00\x40\x75\x93\xd2\x26\x0f\xf7\x4a\xeb\x6f\x9e\x98\x24\x95\xd9\xda\x82\xa4\x47\x19\x70\x94\x44\x46\x82\x86\x82\xaa\x07\x7d\xa4\xd3\xd3\xdd\xf3\xae\xd2\x49\xcf\x2a\x68\xd9\x6c\xc9\x5f\x12\x8a\x53\x2c\xd3\xaa\x90\xb3\xb8\x31\xb3\x36\x83\x64\xae\x44\xbe\xa4\x8c\x48\x05\xf7\x04\x8b\xfc\x32\x9b\xb5\x39\xe4\xd3\x05\x93\x75\x61\x8a\x00\xca\x9b\x3b\xd7\x00\x71\xc0\x9e\xe6\xe3\xa4\x7a\xbd\x70\xe2\xcb\x1f\xd0\x18\xbd\x7a\xe5\x02\x8e\x47\x77\xe8\xab\x8e\xc8\x30\x57\x00\xac\xf0\xa2\xf4\x62\xe1\x15\xbc\x8e\x88\x6e\xf8\x1d\x88\xf4\x7d\x11\x4f\x19\x09\x3c\xd7\xbd\xec\xa9\xa6\x34\xc2\xeb\xee\x66\xe6\xce\xd5\x1a\xeb\x2f\x6d\x26\x56\x08\xdc\xe6\x59\xc1\xd4\x58\xe3\x8c\xae\x1c\xf1\xd3\xa9\x46\x46\x69\xe3\x4b\x60\xbb\xa8\x36\x97\x94\xbe\x74\x25\xaf\x3d\xc2\x35\x47\x97\xc7\x8c\x55\x67\xbf\x48\xb7\xda\xaa\x4f\x79\x0a\xbc\x88\x61\x0a\x4e\x86\xbb\xf7\x1c\xc3\x0a\x70\x95\x30\x35\xfe\x16\x3e\x07\x64\x86\x63\xa6\x7e\xd1\x05\xf0\x04\xb9\xef\xc9\x40\x41\x66\x40\x90\x61\x3d\x50\xc9\x51\x67\xf6\xd1\x1f\xbb\xed\xdb\x47\x8d\x35\x79\x2b\xf9\x46\x87\x69\xac\x94\x86\xd3\x8d\xbb\x6c\x55\xa6\x8a\x23\xf8\x37\x4c\xc3\x06\x01\x0c\xb9\x41\x6c\x69\xec\xec\x0b\x4d\x93\xba\x46\x83\x1b\xd8\xee\x6e\x24\x7a\xd4\xf4\xbe\xbd\x31\xd6\xbe\x27\xb6\x1a\x7b\x6a\xb6\x37\x98\xbb\x57\x00\xe0\xf8\x65\x92\xcd\xf6\x70\xf9\x5a\x36\x68\x8a\x0f\x9a\xb3\x87\x68\x41\x7d\xc0\xfd\xf9\xa7\xa1\x20\xcb\x70\xd5\x0c\xbe\x8c\x7a\xc9\xf5\x69\xeb\xe0\x54\xcb\x90\x35\xd3\x6f\xe9\x40\xbb\xe9\x06\x8f\x69\x7d\x34\xb5\xb1\x9c\xa4\xf6\xab\x89\xcb\x0f\xee\xa2\x5b\x6b\x47\xf9\x2d\xa7\x55\x73\x87\xd6\xd5\xfe\xf5\x3c\xfb\x1d\xf9\xfb\x1d\x82\xf0\x2b\x4c\x39\x11\xce\xe8\xef\xbe\x39\x7c\x8a\x97\xd3\x50\x09\x48\xbf\x29\x40\x98\x78\xb9\xc4\xe2\x61\x47\xdd\x62\x71\xdc\x70\x70\xdc\x60\x20\x1b\x85\xe8\xde\x52\xc5\xb6\xba\x65\xa4\xe9\xf9\x32\xbd\xd6\xe0\x6d\x59\xeb\xc0\xec\x6e\xe0\x5e\xcd\x71\xbf\x7b\x39\xc7\xf5\x6d\xe7\xf7\x0b\x27\xe9\x9b\xce\xa9\x09\x67\xf7\x82\x4a\xa5\x61\x95\x09\x23\xf0\x30\x2f\x26\xe8\x83\x79\x6b\xaa\xf1\xa8\xc6\xd2\x27\x0e\xc8\xed\xde\x1d\xf2\xe2\xb3\x8f\xa1\xaa\xbc\xcb\x54\x08\xd7\xff\xad\xc7\xc6\xee\xbe\xd4\x3d\xfd\x62\xd6\x29\xfb\x22\x3c\xaf\x29\x1c\x5b\x89\x33\x22\x19\xed\xda\x7c\x37\x97\xae\x9d\xf6\x5e\xdc\xda\x76\x17\x49\x07\xf9\xba\xd2\x3e\x4a\xbf\x45\xb5\xf5\xd1\xad\x75\x33\xfa\xc9\x08\xb7\x21\x83\x44\x4d\x0f\x0b\x8a\x87\x0b\x1a\x04\x84\x7b\xa0\xaf\xbe\x61\xb5\xf6\x76\x23\xe2\x9f\xdf\xff\xa8\x6f\xee\x7a\x34\x80\x4d\xc3\x00\x65\x5e\x78\x11\x00\xd7\x3d\x85\xbc\xa4\x2d\xef\x18\xbd\x3d\x23\x83\xb2\x07\xde\xf7\xd8\xff\xdc\x0a\xc3\xae\x13\x4c\xa1\x42\xc4\xa0\xda\xed\xb9\xab\x37\xef\x07\xfb\xe2\xeb\xc2\xef\x9b\xad\xae\xd6\xfb\x50\x8b\xa8\x3d\x3e\xce\x7f\xb6\x1c\xe7\x5d\x23\xf9\xfc\x5b\xf6\xbb\xc4\xc1\xba\x3f\xf9\x37\x00\x00\xff\xff\x48\xfb\x65\x1f\x65\x21\x00\x00")
-
-func jsBugpageJsBytes() ([]byte, error) {
- return bindataRead(
- _jsBugpageJs,
- "js/BugPage.js",
- )
-}
-
-func jsBugpageJs() (*asset, error) {
- bytes, err := jsBugpageJsBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "js/BugPage.js", size: 8549, mode: os.FileMode(436), modTime: time.Unix(1453860464, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-var _jsMarkedMinJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xec\x3c\x4d\x73\xe3\x46\x76\xf7\xfd\x15\x10\xc6\x45\x01\x24\x48\x4a\x33\x8e\x93\x90\x82\xe8\xad\xa9\x3d\x38\x35\x5b\x76\xad\x9d\x13\x41\x69\x40\x12\x22\xa1\x01\x01\x1a\x00\x47\x52\x08\x4c\xed\x7f\x48\x0e\x49\x55\x72\xcd\x0f\xdb\x5f\x92\xf7\xd1\x0d\x74\x83\x20\x25\x79\x67\x2f\xa9\xb5\x4b\x24\xd0\xfd\xbe\xfb\xf5\xeb\xd7\xaf\x9b\x33\xec\x76\x7f\x67\x74\x8d\x8d\x9f\x7e\x0a\x96\x46\xdf\xf0\xe9\x71\x99\x3c\xc4\xc6\xd6\x4f\xb3\x20\xc5\xde\xf7\xc9\xf6\x29\x0d\x57\xeb\xdc\xb0\x16\xb6\xf1\xf6\xe2\xf2\xb2\x0f\x1f\xdf\x3a\xc6\xfb\x75\x1a\x66\x79\xb2\x5d\x07\xa9\xf1\x2f\xc1\xdd\x5d\x1a\x3c\x0d\x0c\xeb\x8f\x3f\xfc\x62\x7c\x08\x17\x41\x9c\x05\x4b\x1b\xf1\xd7\x79\xbe\xcd\x46\xc3\xe1\x2a\xcc\xd7\xbb\xf9\x60\x91\x6c\x86\x8b\xf5\xfd\xfd\x90\xb9\x02\xc4\xf0\x77\xd6\xdd\x2e\x5e\xe4\x61\x12\x5b\xf6\xfe\xb3\x9f\x1a\xf3\x28\x59\x7c\x72\xf7\x71\xf0\x10\x85\x71\x30\x1a\xde\x78\x71\x6f\xe8\x2c\x92\x25\x3e\x5b\xc6\xfe\xdb\x72\x0a\x4d\xb3\x9e\x17\x77\x6d\xe8\xb8\x0b\xe2\x45\x90\x8d\xe2\x24\xd9\x3a\xeb\x94\x40\xba\xd3\x7e\xf7\x76\x66\xef\xdf\x39\xa5\xd1\xb5\x26\x23\x20\x50\x7c\x63\x0f\x9d\x75\xe0\x2f\xc3\x78\x05\x30\xd0\xfc\x66\x7f\xe9\x7c\x57\xda\xf0\xc4\xe4\x26\xf0\xf8\xa6\xab\xc1\xc7\xdb\xdc\x9f\x47\x01\xd3\x8e\x6a\x6c\x81\x61\x7b\x31\x80\xbb\x45\xdf\xde\xbf\x6d\x70\x22\x1d\x7e\xdd\x25\x39\xcb\xdc\xbd\x66\x0c\xcb\x8b\xad\xc9\xd9\x32\xb8\xb3\x05\x85\xae\x50\x22\x02\x5b\x32\xa4\x6d\xcd\x77\x51\x64\x1b\x53\x2f\xf3\x7e\x06\xa9\x80\xe8\x3a\x2d\x00\xa5\xf0\x62\x64\x03\xf8\x86\x0d\x1f\xde\x25\xc2\x19\x20\x43\xb7\xf0\xb2\x2e\xa9\x97\x6f\x22\xd6\x6d\x32\x02\x43\x6f\x82\x38\x17\x42\x31\x44\xb1\x88\x12\x18\x17\xd1\x86\xc4\x94\x76\xd0\xec\xa0\x03\x68\x02\x63\x22\xe9\x4d\x51\xe9\x19\x2a\x3d\x1b\x19\xdd\xab\x09\xbe\x66\xd7\xf0\x7e\x8d\x22\x1a\xbd\xa9\x69\xcd\xa4\x5d\xa6\xa6\x3d\xb3\x27\x9a\x41\x14\x43\x82\x73\xf9\xab\xd4\xdf\xae\x51\x61\x00\x91\xa3\x09\x74\xce\x40\x55\x61\xe6\x42\xda\xbb\xa8\x6d\x59\xe4\xfe\x0a\x4d\x61\xdb\x68\xfb\x2e\x50\x0d\x1e\xd1\x6c\x4c\x61\x58\x8e\x09\x74\x80\x86\x09\x72\x77\x88\xb4\xbb\xbd\xfe\xac\xf0\x96\x3d\x6f\x60\x0f\x45\x77\x98\x07\x1b\x57\xb7\x35\xe2\xb3\xb4\x8a\x65\xb9\xd5\xee\x6a\x78\x69\xb0\x8d\xfc\x45\x60\xd5\x4d\x8e\xb9\xda\x98\xb6\x35\x44\xa4\xe1\xca\x51\x45\xb0\x2d\x5b\xe0\xe2\xf8\x36\x70\xb1\xe9\x18\x9a\xb9\x4e\x4d\xc7\xf4\xc0\x78\xd6\xc4\xf5\xbc\x4b\x34\x31\xf9\x34\xc8\x8c\x5e\x8d\xa2\xb2\x65\x6d\x60\x6d\x82\x49\x6a\x70\xb3\xc7\xb4\xa0\x71\x90\x25\xbb\x74\x11\xf4\x4c\x84\x92\xa2\xd4\xe6\x6c\x08\x54\x77\x48\x92\x15\xa1\x1a\xfb\x16\x86\xc0\x35\xc1\x4a\x20\x82\xd9\x33\xfd\x22\xd8\x14\x59\x9e\x26\x30\x4e\xd9\xc6\x8f\xa2\x22\x2b\x16\x60\x95\xe2\xd7\x62\x79\x17\x17\xfe\x7c\x0e\xbe\xeb\xe7\x7e\x91\x87\x9b\xa0\xc0\x39\x0c\x48\x05\xcc\xf2\x22\xf3\x37\xdb\xe2\xd3\x7c\x59\x64\xbb\x39\xfc\x6d\x8b\xb0\x98\x17\xbb\x02\xe3\x42\x91\xee\xe6\x4f\x45\x9a\x17\xe9\xb6\x98\x2f\xa1\x7d\x99\x20\x56\xb6\xf5\xe3\x02\xe8\x3d\xc0\x5f\x18\x67\xe0\x08\x51\x11\x6e\x56\xb6\xe7\xcd\xe1\xef\x01\x74\x3f\x1b\x0d\x0b\x18\x35\xef\xc1\xf3\xb2\xef\x67\xdd\xef\xb1\xcb\x14\x82\xe3\xe4\x68\x28\x8c\x4d\xa0\xaa\x98\x2a\xa6\x33\xbc\x3a\xeb\xf7\x79\xde\x75\x27\xfd\xfe\xf5\x10\x3b\x69\xca\x60\x9f\x05\x9a\xdb\x72\x56\x5e\x79\x43\xef\xb2\x02\x00\x2f\x45\x08\x00\x40\xab\x4c\x6f\xcc\x59\xd7\x2c\xce\xa7\x37\xe7\xb3\xee\x39\x08\x74\x6e\x5e\xcf\xec\xee\x04\xc1\x87\x00\x53\x8d\x36\xda\xb2\xb6\x6c\x35\x2d\x1a\x52\x56\xed\xc2\x2d\x84\xec\x29\xbe\xf2\x0c\xa9\xda\xf8\x15\x3a\xa2\x46\x4f\x54\x77\xd5\xa3\x2c\x3b\xb5\x71\x07\x91\xc0\x95\xae\xa4\x13\xb1\x88\x47\xbd\x21\x4e\x52\x18\x74\x77\x13\xa4\xab\xc0\xda\x97\x0c\x22\x3b\x57\x77\x9b\x46\x8f\x80\x77\xf6\x22\x66\x53\xac\xfa\x88\x0e\x5d\x7c\xc1\x4f\x7b\x6a\x78\x03\x98\x88\xde\xcf\x3d\x0c\x1f\x30\x1b\xe5\x68\xd8\x10\x8f\xbc\x4b\x2d\xa2\xa8\x61\xe4\x48\x68\xef\x1d\x0d\xed\xa5\x22\xe4\x8b\x2c\x0f\xce\x05\x76\xc1\xcf\x5e\x8d\xc8\x6a\x88\x59\x36\x90\xc8\x30\x11\x2f\x69\x3a\xbe\x35\x6d\x70\x5b\x89\x80\xf3\xfd\x28\xe8\x3b\x06\xad\x2d\x4b\xf1\x32\x6b\xda\x0f\x98\x3a\x7b\xb9\x2a\x91\xaa\xde\xcf\x83\xae\x57\x0c\xba\xbc\x16\x4d\xfb\xa3\x59\x0f\x0c\x57\x4c\xfb\x85\x31\x9a\x61\x2b\x46\x58\x06\xe1\x95\x00\x42\x46\x57\x04\xcf\x8a\x8a\x57\x58\x03\x5e\xcd\xe0\x09\x57\x4f\xa0\xa2\x53\x30\xda\x28\x80\x11\xe5\xd2\x6d\x7c\x08\x1e\x83\xd4\x4a\xb6\xf8\x92\xd9\xfb\x7c\x1d\x66\x83\x3c\xf9\x04\x89\x80\x3b\x9d\x8d\x95\x57\xb0\x43\xfc\x29\x73\xf7\x25\x37\x0a\x0c\x57\x7c\x17\x05\x27\x06\xe8\x66\xfe\x2e\xca\x33\x86\x4a\x77\x68\x0c\xd5\x87\xc6\xe1\x9d\xa5\x12\x40\xd3\xd8\xfb\x66\x23\x5b\x51\x88\xa3\x12\xe1\x8e\x32\x88\xb2\xe0\xb0\x13\x48\x95\x65\x49\x1a\xa9\xed\x63\x6e\x89\x82\x47\xb7\xca\x58\xb2\x74\xe1\x54\x4a\x63\xf2\x12\x21\x8c\x0b\xb9\x4b\xc3\x22\xe3\x34\xc8\x77\x69\xcc\xfd\x48\x03\x51\xed\x52\xd0\xdc\xa6\x49\x9e\xe4\x4f\xdb\xe0\x80\xba\xbd\x87\x0f\x17\xfe\x2a\x9f\x19\x7a\x29\x2e\xe8\x29\x84\x11\xd3\x8b\x4d\x5b\xe9\xc8\xb1\xcd\x80\xff\xb4\xd6\xdd\xc5\x85\x7f\x41\x3d\x7a\xf3\xdb\x6f\xdf\x7e\x2b\x89\x48\xf1\xea\x81\x22\xd5\xf2\x74\x17\xb4\x08\x49\x00\xba\x11\x20\x13\x74\xe6\xbf\xb2\x0d\x0e\x24\xbe\x31\x7a\xdf\x0c\x57\xb0\x52\x9a\xb6\x13\xc3\x92\xed\x44\x09\x44\x55\x67\xe1\x03\x0e\xac\x78\xce\xdc\xa1\x85\x14\x02\xfc\x22\x70\x42\x27\x1a\x3f\xac\xc3\x28\x60\xf5\x61\x48\x01\xce\xad\x07\x69\x20\x12\xc3\x01\x08\xb5\x20\x98\xda\x46\xb0\x96\xc0\x62\x04\x71\x00\x71\xa6\x17\x33\x30\x67\xbc\xca\xd7\xf6\x98\xa9\xd4\x2d\xd7\x97\x9a\x8f\x0e\xb6\xbb\x6c\x6d\xed\x51\xb9\x91\x49\x62\x98\xa5\x5d\x96\x87\xbc\x71\x05\x7b\x15\x63\xc4\x17\x4d\x8a\x39\x20\x87\x15\xf6\x18\x1f\x93\x82\xd6\x4a\x4e\x70\xce\x34\x9f\xde\x06\x4b\x3f\xce\xc3\xc5\x04\xc8\x2a\xc3\x19\x83\x89\x91\xe0\x08\x9a\x61\x62\x2e\x12\x80\x89\x77\x41\x8b\x0e\x22\x6a\xbd\x46\x8b\xd3\x42\x46\x3e\x04\x5e\xc4\x78\x3b\x63\x81\xf1\xf9\xdd\xac\x28\x4c\xf3\xb4\x24\x22\x68\x7f\x15\x51\xaa\x15\x6f\x19\x6c\xf3\x35\x89\x70\x29\xb1\x6a\xa9\xde\xce\x1a\x12\x81\xdf\x76\x3a\x07\x1e\xc6\x11\x56\x91\xeb\x25\x2e\x86\xe9\xa1\x10\x86\xd0\x4d\x5a\x94\x82\x54\xca\xa2\x8c\x7f\xb7\xc0\x80\x6a\x74\xbf\xc1\xf9\x07\xb3\x32\xdb\x46\x61\x6e\x0d\xb9\x71\x68\x3b\x7e\x14\xae\x62\x21\xb0\x8e\x77\x0a\x6b\x11\x44\x51\x26\x8c\xaf\x7a\x06\x3b\x86\x00\xa7\xe9\x5e\x8e\xef\x92\xd4\x0a\xdd\x8b\x71\x78\x85\x72\x0f\x88\xa1\x50\x65\x1c\xf6\x7a\x34\xef\x90\x61\xbf\x37\x42\x86\x83\x3c\xc8\x72\xab\x06\x9d\x86\x33\xb0\x89\xf6\xee\x9a\xb4\x4f\x34\x29\xa8\x1a\x02\x7d\xf4\x1a\x7c\xd8\x36\xe6\x41\x7a\x40\xe0\xc5\xf8\x51\x70\x27\xd8\x37\x7a\x62\x08\x32\x65\xd9\x50\x99\xac\xa5\xab\x5c\x35\x23\x92\xf6\xd6\xb4\x75\x79\xe0\x86\x08\x7e\xd2\xd9\xa3\xbf\xb1\xb7\xbf\x9d\xb9\xae\x6b\xba\xe6\xe4\x72\xf4\xb6\x76\xf8\xcb\xa6\xc3\x37\xa7\x60\xfa\x75\xe4\x49\x9f\x99\xea\x75\x92\xf9\x55\xf8\xd5\xe4\x6e\xb3\xdc\x4f\x73\xe2\xde\x1a\x6a\xbb\xd7\xc6\xe4\x30\xd6\x22\x1f\x5a\xb3\x68\x85\x7b\x09\x9b\x20\x5e\x3e\xa3\x22\x25\x78\xaf\x51\x0e\xd7\x3e\x97\x87\xee\xa8\x04\x48\x54\xa8\xe8\x24\x29\x44\x93\x60\x39\x42\xbc\x6a\x1d\xd3\x15\xdf\xf8\xf9\x62\x6d\x29\x42\xb1\x5b\xe2\xa2\xeb\xde\xf9\x30\x33\xc6\xc4\xb1\x72\x7b\x98\x0e\x38\x2d\x60\x4e\x44\xf5\x1c\x20\x62\xe1\x6c\x4c\x0b\x21\xcf\x03\x09\x8f\xbd\xd4\xa0\x5a\xd8\x52\x77\xd9\x46\x8f\xa2\x0d\xae\xb8\x5f\x08\x32\x8c\x97\xc1\xe3\x8f\x77\x18\x78\x20\x01\x01\xb3\x20\xd5\xfe\x21\xd9\x23\xab\x9c\xc6\x0d\xf3\xaa\x3f\x05\xab\x3f\x3c\x6e\x2d\x13\x56\xd1\x4b\xc7\xec\x11\xb9\x9e\x59\x9a\xbc\x0f\xa7\x25\xb0\x29\x21\x00\x56\x0b\x6e\xd9\xcc\x11\x61\xdb\x9a\xe6\x1f\xc0\xcc\x59\xa7\x13\x9e\xb9\x6e\xd4\x87\xdc\x60\xee\xaa\x1b\x72\x1e\x55\xb2\x4a\xef\x72\x66\x83\xa1\x51\x3d\xec\x03\xf8\x79\xa7\x73\x66\x69\x43\xd2\xe9\xcc\xeb\x34\x83\xfd\x00\x6d\x9e\x45\x21\x88\x03\x14\xec\xc1\x7d\x12\xc6\x1c\x89\x7b\xd0\x0b\xc3\x00\x4c\xcb\x92\xb2\x22\x17\xc7\xaa\x28\x20\x6c\x73\x31\x82\x4a\x3b\x75\xf8\x23\xc3\x56\x62\xd2\xb8\x72\xa0\x5a\xfb\xe9\xef\x45\x84\x64\xde\xd0\x8f\x01\x01\x98\x20\xca\x19\x11\xb7\x6b\x16\x87\x11\x8c\x3d\x8e\x20\x26\x26\x7d\xdd\x22\x39\xe1\x7d\xc2\x15\x95\x96\x52\x9b\x50\x94\xc1\x91\x8b\x61\x1e\x78\xda\x9f\x89\x08\x4f\xa8\x63\x62\x30\xe0\xf3\x93\x0e\xf7\xf0\x5f\x23\xa2\xe8\x2e\xe1\xc7\x61\x1e\xfe\x1b\x98\xa1\xda\x02\x82\xfe\xc8\xca\x74\xb6\x69\xd0\x48\xc8\x24\x74\xca\x89\x04\x84\x5c\xb4\x3b\xc0\x99\x45\x51\xbf\x67\x8b\x34\xdc\xe6\x7a\x53\xfe\x04\x59\x82\x5d\x07\xeb\x8b\x66\xb0\x3e\x9b\xff\xda\xe9\xb4\xa6\x28\x58\xdd\x79\x55\x7a\x72\xb0\x05\x9b\x8a\xb4\x24\x4f\x3e\x24\x0f\x41\xfa\xde\xcf\x02\xcb\x9e\xb9\xfb\x75\x1a\xdc\x55\xd9\x5c\x98\xc3\x16\x91\x33\x8a\xf2\xf9\xbc\xe9\xff\x51\xd6\x24\xf6\xbc\x46\xd7\x9e\xfc\x3d\x81\xfa\x1a\x09\x94\x3a\x1e\x68\xd7\xd3\x63\xf9\x92\xfc\xaa\xd5\x05\xab\x09\xfb\xdb\x67\x87\x1a\x85\xea\xf9\xaf\xa6\x54\x32\xda\x6a\x9b\x8c\x3a\xde\x4e\x44\x3b\x07\xfc\x0b\x07\x7a\x5e\x94\x8b\x21\x87\xaf\x92\x1d\x21\x21\xf3\x44\x58\xa1\x8d\x75\xbe\x4e\x93\x07\x03\x57\xd4\x3f\xa4\x29\x8c\xac\xf9\x43\x7c\x17\x42\x24\x0b\x0c\x88\xfd\x5b\x23\x89\x8d\xf9\x53\x1e\x8c\x0c\x13\x97\x28\xd2\xf8\x3d\xec\xf6\x40\xeb\x0b\x1b\xb6\xc6\x07\xf5\x82\xac\x1c\xe3\xde\x3f\x8c\x71\x6f\xee\xee\x83\x0c\x38\xd3\xe1\x8d\x67\x4d\x3d\xef\x63\x77\x5f\x7a\x53\x6f\x66\xd9\x6f\x7a\x5e\x7f\x70\x76\x7b\x3d\xb3\x87\x8e\xbf\xcb\x13\x8c\x45\x00\x76\x65\x4d\x6f\x8c\xeb\x59\xcf\xfa\xbe\x18\x79\x43\x9b\x5f\xec\xeb\xa1\xb3\x4b\x23\x3e\x36\xc8\x7d\xac\xee\x35\x4a\xb4\xc5\xcd\x95\x37\x9c\x50\xf1\xf7\x54\xe1\xd5\x11\x5c\xce\x26\xde\xd4\x0a\xe3\x2c\x5c\x06\xb6\x37\xf3\x2c\x8c\x75\x1e\x08\x02\x5f\xed\x10\x59\x75\xf0\xd1\x85\xd7\xa1\x13\x27\x2a\x1c\xd6\xc3\xa6\xdc\xeb\xcd\xb0\xf2\x0c\x1a\xce\x6c\x86\xe4\xa2\x38\x40\xde\xde\x5a\xb2\x6a\x6c\xc3\xf3\xe4\xec\xd6\x2e\x6e\xbc\xae\xd7\xad\x9b\xe9\x0d\xd6\xfa\x2e\x88\x12\x6c\xd0\x68\xf3\x5b\x3e\x19\xb9\x9d\x15\xb7\xb7\x36\x62\x7a\x73\xc4\x22\x96\x00\x5d\x30\xae\x4d\xc8\x12\x55\x1e\x91\x7d\xec\x61\xb9\xb4\xaa\x9d\x4e\x6f\x3e\xce\xb8\x7e\x0a\x80\x1f\xf1\x70\x0a\x4f\xc9\x0c\x3c\xe6\x51\x52\x0c\xd8\x49\x48\x43\x8b\x43\x95\xea\x00\xca\x85\x01\xbc\x3a\xf3\xa6\xb7\xdd\x8f\xb3\x42\xe0\x51\x11\x75\xcc\xa3\x3d\xb8\x65\x83\xd1\x89\xcb\xa1\x41\x0a\x18\x76\xa0\x01\x2f\xd8\x6a\xe3\x81\x8a\xc4\x43\xfb\xbb\x43\x10\x00\xcf\x93\x64\xa9\x97\x0e\x94\xbc\xac\x37\x3d\x37\x67\x75\x2b\xbe\x41\x2c\xce\x6a\x6c\x1c\x89\xaa\x62\xab\xb4\xd9\x96\xc9\xf2\x98\x8e\x2e\x1f\x15\xd0\xb1\x92\xad\xb2\xc7\x92\xab\x78\x17\x5e\xd0\xa4\x29\x9a\x4f\x90\xad\x28\x34\xeb\xe1\xdc\x5c\x75\xcb\xa4\xb6\x09\x50\xd5\xc5\x55\xa7\x99\xb8\xde\xcf\x76\xa5\x3f\x3c\xeb\xce\x73\xd0\x7d\xe0\x44\x6d\x24\x2a\x0a\x6d\xf8\x02\xbb\xac\xe4\xd5\x2a\xf8\x0d\x51\xc5\x04\x6f\xd8\x8a\x5b\xc1\x54\x33\x1b\x12\xf2\x2f\xc5\x8c\x4e\x9e\x68\x12\x83\x63\xd2\x61\x30\x8c\xed\xd0\x1b\xe2\xe9\xe1\xd5\xac\x37\xbd\xb9\x1a\x38\xa3\xb1\x79\x4e\x93\x6d\x26\xdc\x70\x78\xf3\xe5\xcb\xa1\x80\x5f\xbe\x88\x03\xbf\x06\x4f\x6c\x43\x8e\x05\x72\x9c\x61\x11\xdd\xc4\xc7\x42\x70\x1b\x0e\xa9\xae\x5e\x6b\x35\x4f\x03\xff\x53\x76\xa0\x18\xd5\xd6\x61\x6a\x34\xa8\xcf\xf1\xa0\x05\x7d\x1e\x48\x76\x49\x99\x36\x19\xf0\x34\x40\xc8\xa1\xc2\xaa\x15\xf2\x1f\x08\x92\xab\xc2\x94\x80\x39\x7a\xb5\xfc\x65\x95\x70\xae\x9e\xd3\xa7\x5a\x1a\xd7\x06\x47\x74\x40\xf2\x0c\xdb\xc5\xd4\xd5\x92\x55\xd9\x5a\x14\xbc\x97\xe2\x37\x1d\xa3\x12\x45\xc5\xa4\x4d\x44\x2d\x42\xcb\xfa\xf1\x0b\x2d\x03\x86\x9f\xa6\xfe\x93\x91\x06\xbf\xee\xc2\x34\x80\x57\xe3\x23\x21\x7c\x34\xb6\x69\xb2\x0d\xd2\xfc\x69\xd0\xb2\x09\x6b\xad\xde\xf3\x40\x69\xd5\x7b\x6d\x08\x0f\xca\xf7\xf5\x60\x94\x55\x0e\xd4\xba\xab\x6c\xa3\x29\xfb\xca\x52\x19\x29\x0d\x64\xac\x76\x24\xbb\x7c\xbb\xcb\xf5\x22\x78\x63\x58\x95\xf5\x10\xcd\x74\xdc\x01\x64\xf5\x5d\x48\xc2\xa4\xc5\x01\x81\xca\xb3\xae\xc0\xb7\x70\x67\x7e\xd0\xe1\x9a\x26\x49\x42\x8e\xea\x60\x8c\xc3\x4a\xfb\xe9\x9a\x3a\xcf\xdb\x57\x25\x1f\xc0\xa9\xe7\x72\x5a\x73\x2a\xa9\x91\x6b\xfc\x6f\x29\xd7\x73\x49\xeb\x7b\x13\x86\x0b\x37\xba\x7a\xf2\xf5\x1d\xa5\x5b\x23\x73\x42\xcc\x36\x7e\xbc\x02\xf5\x64\xe6\x55\x11\xfe\x47\xdb\x1e\x1d\x02\xd8\x63\x5a\x79\xd4\x0e\x73\xe3\x87\x51\x9e\x8c\x60\x4b\x8e\xcc\x84\x6f\x21\x5b\xb6\x4d\x03\x13\x41\xc8\x02\xfa\xcc\x41\x4d\x29\xab\x70\x30\x65\xa6\x11\x68\xec\xe8\x08\x3e\x8c\x3f\x00\xe0\x61\xf6\x0a\x71\xf2\x95\x79\xeb\x29\x01\xc7\xbf\x45\xc0\x83\x2d\x9d\x56\xb0\x3c\xd0\x00\x32\x32\xdf\x18\x86\xbc\xbd\x60\xe1\x6c\x31\xbb\x18\xc4\xc5\x0a\x9b\x3e\x1b\x15\x5c\x6f\xe8\x5f\x9f\xc4\xa6\x8a\x42\xf9\x32\x67\x6c\xdf\xc3\xb7\xef\xd5\x8f\x34\x4b\x21\x46\x8a\x4d\xf1\x95\xbf\x4f\x57\xff\x5e\xe9\xe3\x4d\x1b\xa9\x3a\xd0\xec\xc6\x1e\xaa\x53\x1e\xdf\x92\xeb\x54\xb8\xc0\xa7\xca\xd8\x14\x52\xa4\x32\x8a\x9c\x45\x71\x70\xf8\xd1\x9c\xae\x2f\xd0\x85\xd2\x26\x31\x65\x65\x85\x43\x3d\x6b\xcc\x7a\xe2\xfc\x91\x21\xeb\x65\x64\x4a\xbc\xf4\x12\x04\x97\xab\xa0\xbd\x28\xe8\x6b\x40\x69\xda\xbe\x8a\x37\x17\x55\x08\xb8\xb0\xc7\xa2\xb8\x86\x8d\xb5\x74\x97\x5c\x56\xab\x2c\xf1\x72\x53\x53\xa2\xf7\x8c\x51\x1b\xf6\xe2\x9c\xed\xf5\xa1\x53\x9f\x97\x4c\xc5\x52\x64\x6a\x9a\xf3\xe4\x34\x85\x9d\xf6\x5f\x29\x40\xb0\xf9\xcd\xcc\x5f\x7d\x28\xda\xc2\x1e\x69\xe0\x05\x1f\x4b\x99\x78\xe8\xed\x58\x9e\x3f\x7d\xb0\xf0\xba\x03\x8c\x16\xd6\xf3\xd4\x3a\xc9\x01\x32\xd2\xbf\x96\x05\x90\x38\xb0\xee\x73\x56\x7d\x75\x35\xa0\x85\x2f\xd2\x90\x16\xa5\x1e\x2a\x76\x3f\x81\x9d\xf3\xac\x8a\xb7\x7f\xab\xda\x00\xc8\x73\x3a\x7d\xe1\xf9\x25\x53\x98\x6a\xfa\x51\x1e\x43\x8b\x98\x90\xbc\x0e\x02\x1c\xfd\x5c\x0e\x1a\xf8\x38\x51\x41\xa8\xc5\x1e\xe1\xc2\x26\x33\xaa\x66\xbc\x38\x83\x94\xe1\x4c\xa4\x0c\x2d\x6b\x22\x51\x70\xda\x46\x6a\xa4\xa3\x84\x1b\x1f\x36\x0f\x0a\x8e\xbe\x06\x1f\xcd\xdb\x14\xfb\xd7\x9a\xd3\x22\x5c\x2f\xad\xda\xc1\x04\xc3\xda\xb2\xdc\x82\xab\xba\xf2\x5c\x87\xd8\x7e\xbf\x8f\x21\xf6\x2f\x7f\xfe\x0f\xf5\x92\x87\x6c\xfc\x77\xb5\xd1\xba\x29\xa6\x7d\x6f\x87\xd7\x78\x87\x96\x37\xdd\x9b\xb8\xf1\x3a\x47\xc0\x6f\x2e\xff\xf2\xe7\xff\x54\x41\xcf\x19\xfd\xbf\x4e\xa1\xd3\xe3\x3f\x21\x0d\x53\xd2\xf8\x6f\x15\xde\x64\x1a\xff\xa3\x5d\x3e\x19\xec\xdf\x95\xdc\xfe\xbf\xe6\x51\x63\x71\x66\xf6\xac\x9d\x18\x4c\x33\x91\x9a\x09\x53\x2a\x24\x2f\x02\x84\xee\x85\xb3\x58\x37\xce\xbc\x16\x6b\x86\x51\xfc\x38\xa4\x1c\xf4\x8f\x7e\xbe\x1e\xa4\x7e\xbc\x4c\x36\x96\x7d\x3d\xf8\x07\x02\x35\x1f\xcd\xde\x62\x0d\x6b\xd6\xcf\x62\xb1\xf9\xce\xe6\x4c\xd0\xec\xbc\xc1\x9e\x9e\x39\x36\xb5\x29\x50\xed\x00\xe5\x6e\xcb\x7a\x66\xe3\xb7\x2f\x4b\x09\xaa\x58\x03\x23\xa4\x32\x5b\xe0\x8d\x2e\x5e\x08\xcf\x5b\x1e\x6e\x9f\xd6\xe1\x6a\x1d\x61\x45\xb9\xde\x19\xb4\xf7\xd7\xc4\x48\x6b\x00\x3c\xa3\x8a\x6f\xa7\x43\x8f\x2e\x76\xdb\x62\xc3\xbf\xe4\x05\x94\x84\x41\xed\x28\xa7\x25\xd4\x3d\xeb\x6c\x5e\x6d\xd3\xe0\xfa\x0a\x01\xae\xcd\x9e\x08\x3e\xcb\x09\xd5\xa6\xe4\x24\x41\x76\x1c\xd9\x7b\xa6\x17\x5f\x0d\x09\xf8\x6a\x88\x88\xd2\x74\xe7\x35\x19\x63\x11\xf9\x59\xe6\x9a\xe7\x3d\x4d\x7c\x64\xfa\x13\x4c\xc0\xf0\xb1\x27\x83\x00\x9a\x83\xe8\xf6\xce\xcd\xeb\xf3\xd7\x33\xf7\x62\xb3\x1c\xb7\x98\x5e\xb9\x32\x5b\x0d\x00\x5f\x98\xac\x94\xae\x41\x90\x4a\x8f\x9e\x7a\xe6\xd5\x50\x6f\x6f\xa5\x4e\x37\x53\x2b\xba\x74\x29\x55\x90\x35\xf0\xa5\x1d\x87\xcf\xff\xf5\xb9\xe1\x44\xc1\xe7\x20\x72\x52\xff\xa1\x96\x6b\x6d\xf6\xa8\xb5\x77\x6e\x84\xcb\x03\x1b\xf2\x51\x8b\xb0\x22\xe0\xe9\x99\x58\x3d\x5f\xa7\x37\xde\xc3\x8c\x72\xb8\xbe\x29\x8c\x8b\x0c\x51\xc1\x8a\x81\x79\x5c\xc1\xd4\x55\xae\xf8\xab\x95\x63\x29\xc7\x23\x2a\x3a\x01\x69\xd3\x21\x52\x19\xe1\xd3\x51\x72\x74\x97\xba\x22\x38\x4f\x96\x4f\xf2\x64\x9c\x1d\x1d\x81\x5c\xd1\x32\x31\x93\x08\xc8\xed\x22\x73\x2c\x2d\x62\xf6\x10\x80\xc5\xed\x21\x36\x6a\xa1\x36\x1e\x65\x4a\x67\x55\x8d\x68\x24\xa9\x46\x21\x78\xbb\xb4\x09\xbc\x1c\xa3\x53\xdf\x35\x3d\x42\x68\xab\xd0\xd9\x1e\x25\x43\x47\x65\x8a\xd3\xd0\x38\x3a\xa8\x4d\x4d\x89\x60\x48\x4b\x78\x46\x08\x7a\x66\x50\xa4\x5e\xb7\x41\x3f\xa2\x6a\x16\xa9\x5b\xf0\x45\x92\x3a\x2e\x0c\x24\x0c\x6a\x74\x8a\xf3\x20\x56\xb4\xca\x69\x38\x7b\xa2\x9d\x48\x1e\x1f\x60\xa2\x87\x07\x47\x07\x04\x9d\xbb\xc8\x5f\x65\xca\x30\xd3\xbb\x70\xe3\x89\x99\xe3\x31\x6d\xbe\x34\x29\xfe\xe3\x45\x75\xee\xa6\x63\xac\x49\x35\xf2\xe7\x06\x1d\xbc\xba\x74\x4c\xd2\xe7\x43\xc3\xf3\x9e\x02\x4a\x0e\x3e\x52\x3c\xc5\xac\xd6\x5c\x7f\xa5\xea\xf0\xac\xd7\x70\x56\x7f\x6c\xa8\xb9\x57\x19\x6f\xd9\xd0\x4a\xeb\xb8\xef\x05\x1b\x85\x06\xbe\xb4\xe2\xcb\x0c\xfb\x18\x15\x11\xb1\x25\x1d\x7e\x6d\x0f\x87\x2f\x9e\xcf\x73\x98\xcf\x38\x9b\xe7\xe9\x11\x52\x90\x18\x1f\x93\x07\xba\x14\x71\xe8\xed\xc8\xcc\x54\xb3\x48\x35\x8d\x93\xe9\x42\xeb\x56\x1f\x16\xdf\xf4\x89\x1c\x09\x49\xb9\xcb\x00\x15\xfe\xd7\x3f\xfd\xf0\x3e\xd9\x6c\x93\x18\x06\xd8\xda\xc5\x62\xc9\xa0\xd4\xb3\x11\x0d\x47\x33\x71\x70\xa9\x45\xcc\x72\x41\xf7\x6f\xea\x75\xc1\xc4\xf5\x11\x19\xd4\xd7\x60\xee\xfd\xcf\x3e\x5f\x06\x18\x99\x58\xc2\xba\x28\x0a\x1d\xe0\xf3\x5c\xeb\x56\x68\x95\x72\x1d\x3f\xbf\xf2\x39\x43\x86\x80\x8e\xdf\xe0\xb1\xe7\x74\x23\x9a\x32\x60\xde\x2a\x9f\x1b\x9c\x2c\x63\xcc\xc7\x07\x84\x11\x89\x8a\x62\x57\xbf\x76\x6e\x4a\x56\x5a\x0c\x4c\xb9\xee\x09\x0b\xd7\x42\x85\x9b\x15\x5d\xfe\xad\xa5\x32\xfc\x28\x27\x09\x90\xdd\xab\x84\x6c\xf3\x27\x72\xa6\xe7\x05\xa6\xa2\x58\xab\x57\x51\x76\xa8\x64\x64\x3f\xd1\xef\xdc\x5e\x70\x6d\x9d\xf2\xa1\xd7\xdc\x58\x6f\xd6\xdb\x5f\x5f\x85\x6f\xc7\x78\x41\xa5\xbe\x64\xad\x06\xf4\x23\xbe\xd6\xab\xea\x8e\xc4\xe7\xc1\xe3\x5f\xfb\x51\x8d\x5a\x37\x48\x0d\x27\x4d\xbe\x55\x48\x8b\x02\xb5\xe4\xa6\x2e\x71\x0d\xbe\x55\x49\xaf\xb5\x16\x8e\x5b\x48\xae\x87\xab\x5a\x38\x9a\xa2\xda\x59\xb7\xb8\x5c\xfe\x39\x40\x21\x6c\x25\xd9\x17\x35\x6e\x02\xc5\x3b\x4e\x96\x2d\xdc\x4c\x22\xc3\x0c\x55\x7d\xe7\x40\xf4\x58\xf3\x1c\x3d\xb6\xb1\x1f\x68\x47\xee\xc9\xd6\x6a\x35\x40\x10\x7c\x3a\x49\x25\x9b\x6a\xb7\x71\xc4\xf5\x81\x59\x51\x5c\x1c\x33\xe7\x2f\x0d\xc1\xe8\x77\x92\xb0\x40\x2b\xf2\x90\xdb\xab\x16\x40\x31\x20\x89\xa3\x75\xd2\xe5\xd5\xce\xb4\xf7\xb4\xbe\xd3\x35\x85\x9e\x62\x27\x42\xd6\x0e\xf5\xf5\xb3\x08\xca\x2c\x5a\x84\x03\xce\xaa\x58\xd9\x43\x58\xdd\x3f\x14\x42\x01\x14\x6c\x9b\x20\x3a\x8a\x7b\xf5\xa3\x3a\x9c\x51\xeb\x3a\xad\x9a\x0c\xdd\xb7\xd7\x29\x05\x54\x84\x11\xb7\x5d\x8f\x01\x72\xb7\xd5\x22\x77\xc3\x3c\xb6\xa3\x34\xd0\xd5\x59\xa7\x09\xc1\x1c\xe9\x62\xfb\x11\x76\xd8\xd7\x24\xac\x92\xe1\x6d\x48\xfd\x2e\x37\x68\x4c\x99\x2f\x39\x8d\xb8\xc8\x41\x79\x0b\xee\x52\x69\x2c\xe1\x3b\x74\x20\x8f\xa2\x2b\x49\x9c\xea\x38\xf7\x63\x4a\x84\xc0\xb7\xeb\xdb\x37\x0a\x6d\xa6\xa0\x5d\xc2\x21\x3c\x77\x2f\x6e\x51\xe1\x4e\x47\x5c\x8c\x52\xd0\xe4\xc5\x9e\x92\xa8\x1f\x54\x8d\x64\xfe\xf5\x8c\x45\x99\x05\xde\x24\x72\x5e\xc8\xce\x2e\x45\xfa\xd9\xc6\x11\x34\xb7\x90\xab\xdd\xae\xea\xe1\x75\x23\x4c\x39\x9b\x00\x78\x6f\x55\xb5\xd8\x3d\x90\xb9\xbf\x02\x48\x89\x79\x4f\x3b\xfe\xd7\x6a\x0d\x04\xa6\xf7\x8a\x9e\x7c\xd1\xf1\x88\xa2\xf7\xa8\x28\xcf\xb3\x53\x6a\x96\xad\xde\x45\x30\x5a\x42\xcf\x7e\x73\x70\xe3\x79\x54\x07\x81\xb6\xc8\x47\x33\x0f\xcb\x5d\x8d\x3b\xcc\x32\x02\x1c\x86\xc4\x46\x55\xb4\x42\xb3\x14\x29\x94\xeb\xc8\x1a\x7f\xb9\x03\x53\xc7\x43\x34\x9d\x10\xad\xba\xe3\xf9\x52\xa1\x10\x41\xdf\xf1\x29\x62\xa9\x97\x55\x5f\x68\x1b\xfd\x36\x6a\x53\x0a\x11\xbe\xaa\xe0\xc9\x65\xc3\x2a\x1e\x5b\xf6\xe8\x25\xf2\x22\x79\xcd\x84\x07\x37\x6b\xbf\x8a\xb0\xaf\x11\x81\x6e\xb2\x8a\x10\x84\xc5\x87\x33\x45\xe3\x6d\x1a\x74\x3a\x47\xee\x62\xbf\x20\xc0\x8e\x9a\x0b\x52\x7b\xc4\x06\xae\x5c\xe9\x60\x81\x94\x6b\xb6\xed\x31\xb7\x02\x78\x49\x90\x97\x91\x16\xc7\xec\x65\xf4\x94\x31\xb5\xcb\x52\x49\x10\xe5\x0e\x00\x44\x75\x82\x98\x0b\x61\x4a\x6d\xa6\xda\x13\x9c\x71\xe7\x64\xd8\xb1\x26\x67\x6f\xf0\x42\xda\xd8\x1e\xae\x46\xc3\x0e\xee\x12\x3a\xfe\x66\x3b\x56\xcb\x9f\x57\xd4\x1a\xe5\x5a\xe3\x35\x35\xae\xf4\x46\x2a\x9e\x76\x70\x1a\x8e\x0f\xea\xb2\x9d\x37\xef\xfe\x19\x5a\xcb\x4a\xd8\x7a\xc3\xd2\xac\x21\xd5\x98\x1d\x6b\xfa\x06\x6b\x39\xf6\x18\x48\x54\x2b\xf7\xad\x13\xdb\x7b\x48\x72\xf5\xdd\x0c\x26\xeb\x31\x7a\xff\x22\x89\x92\xd8\x14\x15\x56\x48\xc1\xa9\xa3\x2e\xaa\x23\xc8\x1b\xb3\x62\x58\xf5\xf0\x85\xc8\x47\x73\xc2\x95\xd2\xc1\x5d\x9a\x6c\xde\x8b\x1a\xab\x45\x26\xff\x01\xb6\x59\xb1\x72\xa2\xf1\xd6\x76\x2e\xbf\xb3\xed\x51\x1b\x42\x2f\xd6\x4e\xf8\xa4\xbb\xe3\x6f\xcc\x6a\x13\x48\x3d\xd3\x60\x15\x3c\x62\xba\x8b\x52\xc1\xa3\x4b\x9f\xe2\xe7\xb7\x63\x68\xc7\xf4\x1d\x7f\xa0\x26\xfd\xb3\xa2\x90\x05\x11\x28\xe7\x6f\x02\xe7\xb3\x1f\x71\xb5\x19\xdf\x64\x79\x59\xf9\x05\x42\xcd\x03\x52\xd0\xc8\x85\x3f\x41\xbf\x28\xe0\xb9\x6a\xd3\x0a\xe7\x78\x09\xce\xf6\x6e\xb8\x50\x4e\x3f\xbb\xac\x85\xab\x7e\xe4\x20\x99\x4b\xd9\x50\xa4\xb2\xd6\x11\x2f\xe9\x41\xae\x55\xe2\x37\x1d\x10\xb9\xf8\x54\xfb\x2c\x5f\x6c\x4a\xe6\xf7\xe2\x06\x8a\x7b\xe9\x40\x9c\x59\x05\xb9\xf3\x29\x78\x92\xa5\x6f\x68\xd8\xe1\xaf\xde\xf5\x15\x95\xe1\xdc\xaa\x13\x57\x53\x44\x00\x44\x23\xc4\xf2\x07\x76\x93\x51\x7e\x9c\xdf\x07\x8b\x5c\x2d\xf2\xf9\xd9\x8f\x0f\xf1\x4f\xf2\x8e\xcf\xc2\xc7\x85\xb4\x62\x8b\x89\xf8\xfc\x7e\x0a\x4f\x33\x97\x5b\xe9\xb9\xac\x0f\x8b\xe6\xf7\xb5\x86\xbc\xa3\x92\x3b\x16\x07\x69\xcd\xfd\xc5\x27\x71\x71\x85\x5f\x8a\x02\xd9\x26\x77\x06\x0e\x26\xb8\x99\x44\x36\x79\xcc\x6a\x1c\xf9\x84\x23\x4e\x23\x4f\x97\x99\xf1\xa1\xba\x01\xd6\xd8\xc1\x39\xe4\x1b\xfb\x92\xb7\x16\x55\x99\x1c\x09\xd4\x45\x73\x87\xb3\x77\x67\x0b\x21\x05\x3c\x12\x4f\x16\xc6\x58\x51\x10\x5b\x94\x0f\xea\xef\x7c\xc9\x49\x9a\xb5\x01\x43\x0a\x06\x4d\xa5\xa0\xe2\x6a\x5b\x02\x62\xbf\x4c\x62\x65\x33\x15\xa4\x29\xe9\x47\xdf\x9a\x3c\x6e\xf5\x34\x3e\xa0\x0f\xc0\xb2\x74\x40\x32\xe2\x6e\x49\xdd\x24\x5a\x42\x17\x5d\x4c\x40\x73\x83\xf2\x19\x26\x00\x34\xd1\x18\x8d\xaa\x37\xba\x60\x02\xac\x60\xdf\x80\x23\x52\xa1\x16\x45\xf5\x28\x14\xbd\x7a\x57\x19\x05\xd5\x85\xa5\x6c\x19\x44\x41\x1e\x18\x1a\x73\xa2\x22\x0c\x65\x6b\xe0\xd2\xa9\x75\xeb\x91\x47\xd7\xff\xb8\x0c\x75\x72\x3d\xa8\x5a\xda\xcf\x28\xb8\x41\xaa\x2f\xf9\xf7\xfb\x82\x41\x51\x08\x49\x64\x14\xad\x0e\x4b\xd4\xa4\xbf\xce\xf7\xd5\x11\x72\x78\x9d\x10\xc3\xa4\x4a\x8a\xef\x74\xb9\x09\x8f\x4f\xc8\x11\x8b\x82\x9f\x5d\x65\xfd\x3a\x2a\x4b\x0d\x43\x67\x32\x63\x6d\x7f\xc1\x07\x33\x87\x48\xf0\xbf\x18\x5f\xcc\xd4\x85\x3e\x25\xba\x01\x9e\xf5\xc0\x88\x3f\x37\x15\xaa\x38\xa4\xb9\xcc\xa1\x83\x37\xdd\x67\xb0\x09\xb2\xcc\x5f\x05\xb4\xdb\xfc\x29\x0a\x60\x4d\xc1\xf8\x9c\xa4\x39\x2d\xc6\x46\x9e\x3c\xf3\xaf\x03\x0d\x68\xa1\xb1\x68\x36\x36\xe4\xb2\x07\x19\xa4\x49\xb1\x56\x37\xff\x3d\x79\x63\x02\x6e\xbe\x58\xec\xf0\x77\x72\x58\x40\xa7\x63\x24\x53\x9e\x10\xd5\x32\x41\xca\xca\x27\x45\xa6\x3c\x77\xe2\x33\xef\xa0\x2c\x05\x2b\x59\x5a\x11\xaf\x59\x90\xff\x28\x5a\xaa\xb1\xa6\xf5\x85\x4d\x77\xca\x6e\xdc\x57\x8e\x1b\x30\xee\x7e\x75\xb7\xe1\x1d\x13\xff\x73\x04\xfc\xcc\x77\x1b\xc5\x0e\x43\xa6\x5e\xe2\x55\x16\x2f\x1b\xaf\x29\x9d\x79\x3b\x7c\x10\xca\x54\xea\x5f\xb5\x49\x58\xb2\x97\x78\xa9\xbc\x99\x11\xeb\xa3\xb4\x91\x89\xcf\x7d\xd3\x51\x0e\x9f\x25\x8e\x72\x56\x34\x02\xf3\xc9\x5c\x6a\xa4\x96\xb0\x1c\xaa\xd4\x31\x46\xa5\x30\xfb\x8d\x88\x38\xb2\x71\xab\x36\xf2\x9b\xec\x92\xc4\xdc\xaa\x30\x26\x3a\xc8\xe7\x38\xb4\xca\xa6\xa8\x6e\xc2\x67\xd9\xac\xd4\x97\x5c\xe5\x59\x76\x87\xed\xdd\x22\xa1\xd4\x44\x14\xe3\x4f\x85\x4b\x5e\x70\x36\xc9\x72\x17\x51\xe8\xd8\x81\x78\x77\x80\xbc\x34\x3b\x1d\xd1\x19\x3c\xa2\x83\x67\xb8\x22\x25\xb4\x44\x42\x68\x61\x84\x81\xec\x12\xee\x50\x5d\x89\x63\x44\xa6\xa4\xad\x64\x9d\x0e\x37\x0e\xfc\xcd\xd2\xde\xf3\xb3\x75\x58\x57\x12\xf4\x6c\xe5\x3a\x2c\x37\x49\x4e\xa5\xcd\xcb\x71\x7b\x49\xaa\x28\xa4\x08\x0f\x61\xbc\x4c\x1e\x74\xc5\x26\xdc\x38\x5a\x45\xc9\x1c\x52\x92\x12\x12\xe4\xf1\xff\x05\x00\x00\xff\xff\x4c\x86\x22\xfc\x39\x4c\x00\x00")
-
-func jsMarkedMinJsBytes() ([]byte, error) {
- return bindataRead(
- _jsMarkedMinJs,
- "js/marked.min.js",
- )
-}
-
-func jsMarkedMinJs() (*asset, error) {
- bytes, err := jsMarkedMinJsBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "js/marked.min.js", size: 19513, mode: os.FileMode(436), modTime: time.Unix(1453423957, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-// Asset loads and returns the asset for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func Asset(name string) ([]byte, error) {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[cannonicalName]; ok {
- a, err := f()
- if err != nil {
- return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
- }
- return a.bytes, nil
- }
- return nil, fmt.Errorf("Asset %s not found", name)
-}
-
-// MustAsset is like Asset but panics when Asset would return an error.
-// It simplifies safe initialization of global variables.
-func MustAsset(name string) []byte {
- a, err := Asset(name)
- if err != nil {
- panic("asset: Asset(" + name + "): " + err.Error())
- }
-
- return a
-}
-
-// AssetInfo loads and returns the asset info for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func AssetInfo(name string) (os.FileInfo, error) {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[cannonicalName]; ok {
- a, err := f()
- if err != nil {
- return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
- }
- return a.info, nil
- }
- return nil, fmt.Errorf("AssetInfo %s not found", name)
-}
-
-// AssetNames returns the names of the assets.
-func AssetNames() []string {
- names := make([]string, 0, len(_bindata))
- for name := range _bindata {
- names = append(names, name)
- }
- return names
-}
-
-// _bindata is a table, holding each asset generator, mapped to its name.
-var _bindata = map[string]func() (*asset, error){
- "js/BugApp.js": jsBugappJs,
- "js/BugList.js": jsBuglistJs,
- "js/BugPage.js": jsBugpageJs,
- "js/marked.min.js": jsMarkedMinJs,
-}
-
-// AssetDir returns the file names below a certain
-// directory embedded in the file by go-bindata.
-// For example if you run go-bindata on data/... and data contains the
-// following hierarchy:
-// data/
-// foo.txt
-// img/
-// a.png
-// b.png
-// then AssetDir("data") would return []string{"foo.txt", "img"}
-// AssetDir("data/img") would return []string{"a.png", "b.png"}
-// AssetDir("foo.txt") and AssetDir("notexist") would return an error
-// AssetDir("") will return []string{"data"}.
-func AssetDir(name string) ([]string, error) {
- node := _bintree
- if len(name) != 0 {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- pathList := strings.Split(cannonicalName, "/")
- for _, p := range pathList {
- node = node.Children[p]
- if node == nil {
- return nil, fmt.Errorf("Asset %s not found", name)
- }
- }
- }
- if node.Func != nil {
- return nil, fmt.Errorf("Asset %s not found", name)
- }
- rv := make([]string, 0, len(node.Children))
- for childName := range node.Children {
- rv = append(rv, childName)
- }
- return rv, nil
-}
-
-type bintree struct {
- Func func() (*asset, error)
- Children map[string]*bintree
-}
-
-var _bintree = &bintree{nil, map[string]*bintree{
- "js": &bintree{nil, map[string]*bintree{
- "BugApp.js": &bintree{jsBugappJs, map[string]*bintree{}},
- "BugList.js": &bintree{jsBuglistJs, map[string]*bintree{}},
- "BugPage.js": &bintree{jsBugpageJs, map[string]*bintree{}},
- "marked.min.js": &bintree{jsMarkedMinJs, map[string]*bintree{}},
- }},
-}}
-
-// RestoreAsset restores an asset under the given directory
-func RestoreAsset(dir, name string) error {
- data, err := Asset(name)
- if err != nil {
- return err
- }
- info, err := AssetInfo(name)
- if err != nil {
- return err
- }
- err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
- if err != nil {
- return err
- }
- err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
- if err != nil {
- return err
- }
- err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
- if err != nil {
- return err
- }
- return nil
-}
-
-// RestoreAssets restores an asset under the given directory recursively
-func RestoreAssets(dir, name string) error {
- children, err := AssetDir(name)
- // File
- if err != nil {
- return RestoreAsset(dir, name)
- }
- // Dir
- for _, child := range children {
- err = RestoreAssets(dir, filepath.Join(name, child))
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func _filePath(dir, name string) string {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
-}
diff --git a/bug-serve/issues/Implement-HTML5-history-API/Description b/bug-serve/issues/Implement-HTML5-history-API/Description
deleted file mode 100644
index e69de29..0000000
diff --git a/bug-serve/issues/PUT-should-create-an-issue/Description b/bug-serve/issues/PUT-should-create-an-issue/Description
deleted file mode 100644
index 6842253..0000000
--- a/bug-serve/issues/PUT-should-create-an-issue/Description
+++ /dev/null
@@ -1,3 +0,0 @@
-When PUTing a description to a field that doesn't exist,
-the issue should be created instead of returning a 400
-error.
diff --git a/bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description b/bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description
deleted file mode 100644
index 61776b8..0000000
--- a/bug-serve/issues/PUT-should-support-JSON-to-main-bug-URL/Description
+++ /dev/null
@@ -1,3 +0,0 @@
-A PUT of valid JSON to /issues/Bug-Title should create
-Bug-Title if it doesn't exist, and overwrite Bug-Title
-if the JSON is valid and ETag matches
diff --git a/bug-serve/issues/Should-include-REST-API/Description b/bug-serve/issues/Should-include-REST-API/Description
deleted file mode 100644
index 8e17c9c..0000000
--- a/bug-serve/issues/Should-include-REST-API/Description
+++ /dev/null
@@ -1,2 +0,0 @@
-The bug-server should be redone as a more usable, well-documented
-REST API, in order to make it more useful to third parties.
diff --git a/bug-serve/issues/Should-titles-instead-of-directories/Description b/bug-serve/issues/Should-titles-instead-of-directories/Description
deleted file mode 100644
index 64e1f1b..0000000
--- a/bug-serve/issues/Should-titles-instead-of-directories/Description
+++ /dev/null
@@ -1,2 +0,0 @@
-The front end should show the pretty title, not the directory name
-of any issues
diff --git a/bug-serve/js/marked.min.js b/bug-serve/js/marked.min.js
deleted file mode 100644
index 555c1dc..0000000
--- a/bug-serve/js/marked.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * marked - a markdown parser
- * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/chjj/marked
- */
-(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i.5){ch="x"+ch.toString(16)}out+=""+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return""+(escaped?code:escape(code,true))+"\n
"}return''+(escaped?code:escape(code,true))+"\n
\n"};Renderer.prototype.blockquote=function(quote){return"\n"+quote+"
\n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"
\n":"
\n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+""+type+">\n"};Renderer.prototype.listitem=function(text){return""+text+"\n"};Renderer.prototype.paragraph=function(text){return""+text+"
\n"};Renderer.prototype.table=function(header,body){return"\n"+"\n"+header+"\n"+"\n"+body+"\n"+"
\n"};Renderer.prototype.tablerow=function(content){return"\n"+content+"
\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+""+type+">\n"};Renderer.prototype.strong=function(text){return""+text+""};Renderer.prototype.em=function(text){return""+text+""};Renderer.prototype.codespan=function(text){return""+text+"
"};Renderer.prototype.br=function(){return this.options.xhtml?"
":"
"};Renderer.prototype.del=function(text){return""+text+""};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='"+text+"";return out};Renderer.prototype.image=function(href,title,text){var out='":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i/g,">").replace(/"/g,""").replace(/'/g,"'")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;iAn error occured:"+escape(e.message+"",true)+"
"}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
\ No newline at end of file
diff --git a/bug-serve/jsx/BugApp.js b/bug-serve/jsx/BugApp.js
deleted file mode 100644
index ac59eeb..0000000
--- a/bug-serve/jsx/BugApp.js
+++ /dev/null
@@ -1,132 +0,0 @@
-var BugApp = React.createClass({
- reloadIssues: function() {
- var that = this;
- AjaxGet("/issues/", function(response) {
- that.setState({
- "Bugs" : JSON.parse(response)
- });
- });
- },
- reloadSettings: function() {
- var that = this;
- AjaxGet("/settings", function(response) {
- that.setState({
- "Settings" : JSON.parse(response)
- });
- })
- },
- componentDidMount: function() {
- this.reloadIssues();
- this.reloadSettings();
- },
- getInitialState : function() {
- return {
- "Settings" : {},
- "Title" : "Open Issues",
- "Bugs": [],
- "SelectedBug" : null,
- "SelectedBugDir" : ""
- }
- },
- loadBug: function(bug) {
- var that = this;
- AjaxGet("/issues/" + bug + "/", function(response, handler) {
- that.setState({
- "SelectedBug" : JSON.parse(response),
- "SelectedBugETag" : handler.getResponseHeader("ETag"),
- "SelectedBugDir" : bug
- });
- });
- },
- selectBugHandler: function(e) {
- e.preventDefault();
- this.loadBug(e.currentTarget.textContent);
- },
- resetSelected: function() {
- this.setState({ "SelectedBug" : null,
- "SelectedBugETag" : null,
- "SelectedBugDir" : null
- });
- },
- resetBugs: function() {
- this.resetSelected();
- this.reloadIssues();
- },
- render: function() {
- var content;
- if(this.state.SelectedBug != null) {
- content =
- } else {
- content =
- }
- return (
-
Issues for: {this.state.Settings.Title}
-
- {content}
-
-
);
- }
-});
-
-var AjaxGet = function(url, callback) {
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.onreadystatechange = function() {
- if (this.readyState === 4 && this.status == 200) {
- callback(this.responseText, this)
- }
- }
- xmlhttp.open("GET", url, true);
- xmlhttp.send()
-}
-
-
-var AjaxPut = function(url, data, callback, etag) {
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.onreadystatechange = function() {
- if (this.readyState === 4 && (this.status >= 200 && this.status < 300)) {
- callback(this.responseText)
- }
- }
- xmlhttp.open("PUT", url, true);
- if (etag) {
- xmlhttp.setRequestHeader("If-Match", etag)
- }
- xmlhttp.send(data)
-}
-
-var AjaxPutJSON = function(url, data, callback) {
- AjaxPut(url, JSON.stringify(data), callback);
-}
-
-var AjaxDelete = function(url, callback, etag) {
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.onreadystatechange = function() {
- if (this.readyState === 4 && (this.status >= 200 && this.status < 300)) {
- callback(this.responseText)
- }
- }
- xmlhttp.open("DELETE", url, true);
- if (etag) {
- xmlhttp.setRequestHeader("If-Match", etag)
- }
- xmlhttp.send()
-}
diff --git a/bug-serve/jsx/BugList.js b/bug-serve/jsx/BugList.js
deleted file mode 100644
index 9415918..0000000
--- a/bug-serve/jsx/BugList.js
+++ /dev/null
@@ -1,24 +0,0 @@
-var BugList = React.createClass({
- getDefaultProps: function() {
- return {
- "Title" : "Bugs",
- "Bugs" : [],
- onBugClicked: function(e) { e.preventDefault(); return }
- }
- },
- render: function() {
- var that = this;
- var elements = this.props.Bugs.map(function (val) {
- return (
- {val}
- );
- });
- return (
-
{this.props.Title}
-
- {elements}
-
-
- );
- }
-});
diff --git a/bug-serve/jsx/BugPage.js b/bug-serve/jsx/BugPage.js
deleted file mode 100644
index e8de522..0000000
--- a/bug-serve/jsx/BugPage.js
+++ /dev/null
@@ -1,164 +0,0 @@
-var BugPage = React.createClass({
- componentDidMount: function() {
- if(this.refs.desc) {
- this.refs.desc.innerHTML = marked(this.props.Description)
- }
- this.setState({
- "Editing" : false
- });
- },
- componentDidUpdate: function() {
- if(this.refs.desc) {
- this.refs.desc.innerHTML = marked(this.props.Description)
- }
- },
- loadPreviousBug: function() {
- for(var i = 1; i < this.props.AllBugs.length; i += 1) {
- var bugCandidate = this.props.AllBugs[i];
- if (bugCandidate === this.props.CurrentBug) {
- this.props.LoadBug(this.props.AllBugs[i-1]);
- return
- }
- }
- return;
- },
- loadNextBug: function() {
- for(var i = 0; i < this.props.AllBugs.length - 1 ; i += 1) {
- var bugCandidate = this.props.AllBugs[i];
- if (bugCandidate === this.props.CurrentBug) {
- this.props.LoadBug(this.props.AllBugs[i+1]);
- return
- }
- }
- return;
- },
- getInitialState: function() {
- return {
- "Editing" : false
- }
- },
- editCurrentBug: function() {
- this.setState({
- "Editing" : true
- });
- },
- cancelEditting: function() {
- this.setState({
- "Editing" : false
- });
- },
- saveCurrentBug: function(e) {
- var editClosure = function(ctx) {
- return function(e) {
- ctx.setState({"Editing" : false});
- ctx.props.LoadBug(ctx.props.CurrentBug);
- }
- }
- AjaxPut(
- "/issues/" + this.props.CurrentBug + "/Description",
- this.refs.editdesc.value,
- editClosure(this),
- this.props.CurrentETag
- );
-
- },
- deleteCurrentBug: function() {
- var that = this;
- AjaxDelete(
- "/issues/" + this.props.CurrentBug,
- function() {
- if (that.props.onDelete) {
- that.props.onDelete();
- }
- },
- this.props.CurrentETag
- );
- },
- onOtherBugClicked: function(e) {
- this.setState({
- "Editing" : false
- });
-
- this.props.onOtherBugClicked(e)
- },
- render: function() {
- var fieldRow = function(name, value) {
- if (value) {
- return (
-
-
-
- {name}
-
-
- {value}
-
-
-
);
- }
- return;
- }, priority = fieldRow("Priority", this.props.Priority),
- statusRow = fieldRow("Status", this.props.Status),
- milestone = fieldRow("Milestone", this.props.Milestone);
- var prevClass, nextClass;
- if (this.props.AllBugs.length > 1 &&
- this.props.AllBugs[0] != this.props.CurrentBug) {
- prevClass = "previous";
- } else {
- prevClass = "previous disabled";
- }
- if (this.props.AllBugs.length > 1 &&
- this.props.AllBugs[this.props.AllBugs.length-1] != this.props.CurrentBug) {
- nextClass = "next";
- } else {
- nextClass = "next disabled";
- }
-
- var descDiv;
- if (this.state.Editing === true) {
- descDiv = (
-
-
-
-
-
-
-
-
-
-
-
-
-
);
- } else {
- descDiv = {this.props.Description}
- }
- return (
-
-
-
-
{this.props.Title}
- {descDiv}
-
-
- {priority}
- {statusRow}
- {milestone}
-
-
-
-
-
-
-
);
- }
-});
diff --git a/bug-serve/main.go b/bug-serve/main.go
deleted file mode 100644
index e41a302..0000000
--- a/bug-serve/main.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package main
-
-import (
- "github.com/driusan/GoWebapp/URLHandler"
- "net/http"
-)
-
-func main() {
- URLHandler.RegisterHandler(MainPageHandler{}, "/")
- URLHandler.RegisterHandler(SettingsHandler{}, "/settings")
- URLHandler.RegisterHandler(BugPageHandler{}, "/issues/")
- URLHandler.RegisterHandler(JSAssetHandler{}, "/js/")
- http.ListenAndServe(":8080", nil)
-}
-
-//go:generate babel --out-dir=js jsx
-//go:generate go-bindata js/
diff --git a/issues/bug--serve-should-have-feature-parity-with-bug/Description b/issues/bug--serve-should-have-feature-parity-with-bug/Description
deleted file mode 100644
index 321bd49..0000000
--- a/issues/bug--serve-should-have-feature-parity-with-bug/Description
+++ /dev/null
@@ -1,3 +0,0 @@
-bug-serve, the HTTP implementation of bug, should
-support anything that you can do from the command
-line.
diff --git a/issues/bug--serve-should-have-feature-parity-with-bug/Milestone b/issues/bug--serve-should-have-feature-parity-with-bug/Milestone
deleted file mode 100644
index 866c31a..0000000
--- a/issues/bug--serve-should-have-feature-parity-with-bug/Milestone
+++ /dev/null
@@ -1 +0,0 @@
-v0.4
\ No newline at end of file
diff --git a/issues/bug--serve-should-have-feature-parity-with-bug/Status b/issues/bug--serve-should-have-feature-parity-with-bug/Status
deleted file mode 100644
index e69de29..0000000
diff --git a/issues/bug--serve-should-have-feature-parity-with-bug/tags/feature b/issues/bug--serve-should-have-feature-parity-with-bug/tags/feature
deleted file mode 100644
index e69de29..0000000
From cfa5f8b5c8e86358097dbb61edaae06efb87fa64 Mon Sep 17 00:00:00 2001
From: Dave MacFarlane
Date: Sun, 28 Feb 2016 16:58:12 -0500
Subject: [PATCH 47/47] Increased version number to v0.4
---
bugapp/Version.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bugapp/Version.go b/bugapp/Version.go
index bd2eb9d..39587e8 100644
--- a/bugapp/Version.go
+++ b/bugapp/Version.go
@@ -6,6 +6,6 @@ import (
)
func Version() {
- fmt.Printf("%s version 0.4-dev\n", os.Args[0])
+ fmt.Printf("%s version 0.4\n", os.Args[0])
}