From 7083a4c4508d68d18dc0427a0f0f86df3f1009c7 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 16 Nov 2016 00:22:22 -0500 Subject: stuff --- enhancers.txt | 31 ++++++++++----- src/edit/dir.go | 16 ++++---- src/edit/git.go | 111 ++++++++++++++++++++++++++++++++---------------------- src/edit/main.go | 3 +- src/edit/views.go | 3 +- static/style.css | 2 +- 6 files changed, 100 insertions(+), 66 deletions(-) diff --git a/enhancers.txt b/enhancers.txt index d70a5f8..842bf5b 100644 --- a/enhancers.txt +++ b/enhancers.txt @@ -1,6 +1,21 @@ --boundary X-Thing: Pattern +inode/directory +--boundary +X-Thing: Head + +--boundary +X-Thing: Tail + + +--boundary +X-Thing: Pattern + text/markdown --boundary X-Thing: Head @@ -22,21 +37,17 @@ X-Thing: Tail var tip = document.createElement('aside'); tip.innerHTML = '

Tip: To set the page title (what appears in the tab '+ - 'name/window bar), put this at the top of the page:

\n'+ + 'name/window bar), but not have it appear as a header on the page, put '+ + 'this at the top:

\n'+ '
---\ntitle: "Your Title Here"\n---\n
\n'+ - '

(I apologize that it looks funny on this page and in the '+ - 'preview.)

\n'+ - - '

Otherwise, the first line will be used as the title. This means '+ - 'that if you want the title to also appear at the top of the document, '+ - 'you can instead use:

\n'+ - '

Your Title Here\n===============\n
\n'+ - '

which will also include it as a heading at the top of the page.

'; + '

To set the page title, and have it appear as a header on the page, '+ + 'put this at the top:

\n'+ + '

Your Title Here\n===============\n
\n'; container.appendChild(tip); - // bug workaround from https://github.com/codemirror/CodeMirror/issues/2143#issuecomment-140100969 + // workaround from https://github.com/codemirror/CodeMirror/issues/2143#issuecomment-140100969 var updateSectionHeaderStyles = function(cm, change) { var lines = cm.lineCount(); for (var i = Math.max(0, change.from.line-1); i <= Math.min(change.to.line+1, lines-1); i++) { diff --git a/src/edit/dir.go b/src/edit/dir.go index 8315dc0..304732e 100644 --- a/src/edit/dir.go +++ b/src/edit/dir.go @@ -18,8 +18,8 @@ func ServeGit(out http.ResponseWriter, in *http.Request) { } upath = path.Clean(upath) - errcheck(GitPull()) - tree, err := GitLsTree() + errcheck(WWW.Pull()) + tree, err := WWW.LsTree() errcheck(err) file, fileExists := tree[upath] if file.Type == "tree" && in.Method != http.MethodPut { @@ -60,7 +60,7 @@ func ServeGit(out http.ResponseWriter, in *http.Request) { } content, err := ioutil.ReadAll(in.Body) errcheck(err) - edit := Edit{ + edit := GitCommit{ UserName: userinfo.Name, UserEmail: username + "@edit.team4272.com", Time: time.Now(), @@ -69,8 +69,8 @@ func ServeGit(out http.ResponseWriter, in *http.Request) { upath[1:]: content, }, } - errcheck(GitCommit(edit)) - errcheck(GitPush()) + errcheck(WWW.Commit(edit)) + errcheck(WWW.Push()) errcheck(renderModified(out, upath)) if fileExists { out.WriteHeader(http.StatusOK) @@ -89,7 +89,7 @@ func ServeGit(out http.ResponseWriter, in *http.Request) { if msg == "" { msg = fmt.Sprintf("web edit: delete %q", upath) } - edit := Edit{ + edit := GitCommit{ UserName: userinfo.Name, UserEmail: username + "@edit.team4272.com", Time: time.Now(), @@ -98,8 +98,8 @@ func ServeGit(out http.ResponseWriter, in *http.Request) { upath[1:]: nil, }, } - errcheck(GitCommit(edit)) - errcheck(GitPush()) + errcheck(WWW.Commit(edit)) + errcheck(WWW.Push()) errcheck(renderDeleted(out, upath)) out.WriteHeader(http.StatusOK) case http.MethodOptions: diff --git a/src/edit/git.go b/src/edit/git.go index 1f8f8ba..4ced7b7 100644 --- a/src/edit/git.go +++ b/src/edit/git.go @@ -8,22 +8,73 @@ import ( "os/exec" "strconv" "time" + + "os" ) -// Use .Output() instead of .Run() so that it populates -// ExitError.Stderr. +type GitDir string + +func (dir GitDir) cmd(args ...string) *exec.Cmd { + cmd := exec.Command(args[0], args[1:]...) + cmd.Dir = string(dir) + return cmd +} + +func (dir GitDir) output(args ...string) ([]byte, error) { + return dir.cmd(args...).Output() +} -func GitPull() error { - _, err := exec.Command("git", "fetch").Output() +func (dir GitDir) run(args ...string) error { + // Use .Output() instead of .Run() so that it populates + // ExitError.Stderr. + _, err := dir.output(args...) return err +} + +func (dir GitDir) Pull() error { + return dir.run("git", "fetch") +} + +func (dir GitDir) Push() error { + return dir.run("git", "push") } -func GitPush() error { - _, err := exec.Command("git", "push").Output() +func (dir GitDir) Commit(commit GitCommit) error { + cmd := dir.cmd("git", "fast-import", "--done") + + // stdin + pw, err := cmd.StdinPipe() + if err != nil { + return err + } + + // stderr + var buf bytes.Buffer + cmd.Stderr = &buf + + // run + if err = cmd.Start(); err != nil { + return err + } + werr := commit.FastExport(pw) + if werr != nil { goto end; } + _, werr = io.WriteString(pw, "done\n") + if werr != nil { goto end; } +end: + cerr := pw.Close() + if err = cmd.Wait(); err != nil { + if ee, ok := err.(*exec.ExitError); ok { + ee.Stderr = buf.Bytes() + } + } else if werr != nil { + err = werr + } else { + err = cerr + } return err } -type Edit struct { +type GitCommit struct { UserName string UserEmail string Time time.Time @@ -35,7 +86,7 @@ func gitTime(t time.Time) string { return fmt.Sprintf("%d %s", t.Unix(), t.Format("-0700")) } -func (edit Edit) WriteTo(w io.WriteCloser) error { +func (edit GitCommit) FastExport(w io.Writer) error { var err error commit := make([]string, len(edit.Files)) i := 0 @@ -70,42 +121,11 @@ data %d } } } - _, err = fmt.Fprintf(w, "done\n") - if err != nil { - return err - } - return w.Close() -} - -func GitCommit(edit Edit) error { - cmd := exec.Command("git", "fast-import", "--done") - - // stdin - pw, err := cmd.StdinPipe() - if err != nil { - return err - } - - // stderr - var buf bytes.Buffer - cmd.Stderr = &buf - - // run - if err = cmd.Start(); err != nil { - return err - } - werr := edit.WriteTo(pw) - if err = cmd.Wait(); err != nil { - if ee, ok := err.(*exec.ExitError); ok { - ee.Stderr = buf.Bytes() - } - } else { - err = werr - } - return err + return nil } type GitFile struct { + Dir GitDir Mode int32 // 18 bits unsigned Type string Hash string @@ -113,7 +133,7 @@ type GitFile struct { } func (f GitFile) Cat() ([]byte, error) { - return exec.Command("git", "cat-file", "blob", f.Hash).Output() + return f.Dir.output("git", "cat-file", "blob", f.Hash) } type GitTree map[string]GitFile @@ -168,16 +188,16 @@ func parseGitTreeLine(line []byte) (rname string, rfile GitFile, err error) { return } -func GitLsTree() (GitTree, error) { +func (dir GitDir) LsTree() (GitTree, error) { // Get the root tree-ish - data, err := exec.Command("git", "rev-parse", "HEAD:").Output() + data, err := dir.output("git", "rev-parse", "HEAD:") if err != nil { return nil, err } treeish := string(bytes.TrimSuffix(data, []byte{'\n'})) // Recursively read said tree-ish - data, err = exec.Command("git", "ls-tree", "-trlz", treeish).Output() + data, err = dir.output("git", "ls-tree", "-trlz", treeish) if err != nil { return nil, err } @@ -203,6 +223,7 @@ func GitLsTree() (GitTree, error) { panic(err) return nil, err } + file.Dir = dir ret["/"+name] = file } return ret, nil diff --git a/src/edit/main.go b/src/edit/main.go index 5995bea..3ddb2cd 100644 --- a/src/edit/main.go +++ b/src/edit/main.go @@ -14,10 +14,11 @@ func ServeIndex(out http.ResponseWriter, in *http.Request) { http.Redirect(out, in, "/files/src/", http.StatusMovedPermanently) } +var WWW = GitDir("/srv/http/edit.team4272.com/www.git") + func main() { socket, err := util.StreamListener(os.Args[1], os.Args[2]) errcheck(err) - errcheck(os.Setenv("GIT_DIR", "/srv/http/edit.team4272.com/www.git")) http.Handle("/", util.SaneHTTPHandler{http.HandlerFunc(ServeIndex)}) http.Handle("/static/", util.SaneHTTPHandler{http.StripPrefix("/static", http.FileServer(http.Dir("static")))}) http.Handle("/files/", util.SaneHTTPHandler{http.StripPrefix("/files", http.HandlerFunc(ServeGit))}) diff --git a/src/edit/views.go b/src/edit/views.go index 3f55fa1..a080b07 100644 --- a/src/edit/views.go +++ b/src/edit/views.go @@ -57,8 +57,9 @@ func renderViewTree(w io.Writer, upath string, tree GitTree) error { if err != nil { return err } + head, tail := getEnhancer("inode/directory") // Page render - return renderPage(w, upath, "", body.String(), "") + return renderPage(w, upath, head, body.String(), tail) } func renderViewBlob(w io.Writer, upath string, file *GitFile) error { diff --git a/static/style.css b/static/style.css index 2e1db2a..31bf5aa 100644 --- a/static/style.css +++ b/static/style.css @@ -95,7 +95,7 @@ aside { background-repeat: repeat-x; } .CodeMirror .cm-spell-error:not(.cm-url):not(.cm-comment):not(.cm-tag):not(.cm-word) { - background-image: url("errline.png"); + background-image: url("errline.png") !important; background-position: bottom left !important; background-repeat: repeat-x !important; background-color: transparent !important; -- cgit v1.2.3