Author | Jakob Wakeling <[email protected]> |
Date | 2023-08-07 07:22:06 |
Commit | 0dadb00e59a08480835e2e6b9de8510d42857b64 |
Parent | b4ad3bf77335e5b65d31eac65fe46a3b6c80eeaf |
Update the repository refs page
Diffstat
M | main.go | | | 2 | +- |
M | res/index.html | | | 2 | +- |
M | res/repo/refs.html | | | 30 | +++++++++++++++++++----------- |
M | src/repo.go | | | 63 | --------------------------------------------------------------- |
A | src/repo/refs.go | | | 110 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 131 insertions, 76 deletions
diff --git a/main.go b/main.go index 6767f94..90df6ef 100644 --- a/main.go +++ b/main.go @@ -44,7 +44,7 @@ func main() { h.Path("/{repo}/tree").Methods("GET").HandlerFunc(repo.HandleTree) h.Path("/{repo}/tree/{path:.*}").Methods("GET").HandlerFunc(repo.HandleTree) h.Path("/{repo}/file/{path:.*}").Methods("GET").HandlerFunc(repo.HandleFile) - h.Path("/{repo}/refs").Methods("GET").HandlerFunc(goit.HandleRepoRefs) + h.Path("/{repo}/refs").Methods("GET").HandlerFunc(repo.HandleRefs) h.Path("/{repo}/info/refs").Methods("GET").HandlerFunc(goit.HandleInfoRefs) h.Path("/{repo}/git-upload-pack").Methods("POST").HandlerFunc(goit.HandleUploadPack) h.Path("/{repo}/git-receive-pack").Methods("POST").HandlerFunc(goit.HandleReceivePack) diff --git a/res/index.html b/res/index.html index b8ea778..df35113 100644 --- a/res/index.html +++ b/res/index.html @@ -29,7 +29,7 @@ </table> </header><hr> <main> - <table> + <table class="highlight-row"> <thead> <tr> <td><b>Name</b></td> diff --git a/res/repo/refs.html b/res/repo/refs.html index 9869b06..ac0d253 100644 --- a/res/repo/refs.html +++ b/res/repo/refs.html @@ -3,43 +3,51 @@ <body> <header>{{template "repo/header" .}}</header><hr> <main> - {{if .Branches}} <h2>Branches</h2> <table class="highlight-row"> <thead> <tr> <td><b>Name</b></td> - <td><b>Hash</b></td> + <td><b>Message</b></td> + <td><b>Author</b></td> + <td><b>Last Commit</b></td> </tr> </thead> <tbody> {{range .Branches}} <tr> - <td>{{.Name}}</a></td> - <td>{{.Hash}}</td> + <td>{{.Name}}</td> + <td><a href="/{{$.Name}}/commit/{{.Hash}}">{{.Message}}</a></td> + <td>{{.Author}}</td> + <td>{{.LastCommit}}</td> </tr> + {{else}} + <tr><td colspan="4">No branches</td></tr> {{end}} </tbody> </table> - {{end}} - {{if .Tags}} - <h2>Tags</h2> + <br><h2>Tags</h2> <table class="highlight-row"> <thead> <tr> <td><b>Name</b></td> - <td><b>Hash</b></td> + <td><b>Message</b></td> + <td><b>Author</b></td> + <td><b>Last Commit</b></td> </tr> </thead> <tbody> {{range .Tags}} <tr> - <td>{{.Name}}</a></td> - <td>{{.Hash}}</td> + <td>{{.Name}}</td> + <td><a href="/{{$.Name}}/commit/{{.Hash}}">{{.Message}}</a></td> + <td>{{.Author}}</td> + <td>{{.LastCommit}}</td> </tr> + {{else}} + <tr><td colspan="4">No tags</td></tr> {{end}} </tbody> </table> - {{end}} </main> </body> diff --git a/src/repo.go b/src/repo.go index 0200eb1..afe986a 100644 --- a/src/repo.go +++ b/src/repo.go @@ -7,15 +7,10 @@ package goit import ( "database/sql" "errors" - "log" - "net/http" "os" "strings" - "github.com/Jamozed/Goit/src/util" "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/gorilla/mux" ) type Repo struct { @@ -27,64 +22,6 @@ type Repo struct { IsPrivate bool } -func HandleRepoRefs(w http.ResponseWriter, r *http.Request) { - reponame := mux.Vars(r)["repo"] - - repo, err := GetRepoByName(reponame) - if err != nil { - HttpError(w, http.StatusInternalServerError) - return - } else if repo == nil { - HttpError(w, http.StatusNotFound) - return - } - - type bra struct{ Name, Hash string } - type tag struct{ Name, Hash string } - bras := []bra{} - tags := []tag{} - - if gr, err := git.PlainOpen(RepoPath(reponame)); err != nil { - log.Println("[Repo:Refs]", err.Error()) - HttpError(w, http.StatusInternalServerError) - return - } else if iter, err := gr.Branches(); err != nil { - log.Println("[Repo:Refs]", err.Error()) - HttpError(w, http.StatusInternalServerError) - return - } else if err := iter.ForEach(func(b *plumbing.Reference) error { - bras = append(bras, bra{b.Name().Short(), b.Hash().String()}) - return nil - }); err != nil { - log.Println("[Repo:Refs]", err.Error()) - HttpError(w, http.StatusInternalServerError) - return - } else if iter, err := gr.Tags(); err != nil { - log.Println("[Repo:Refs]", err.Error()) - HttpError(w, http.StatusInternalServerError) - return - } else if err := iter.ForEach(func(b *plumbing.Reference) error { - tags = append(tags, tag{b.Name().Short(), b.Hash().String()}) - return nil - }); err != nil { - log.Println("[Repo:Refs]", err.Error()) - HttpError(w, http.StatusInternalServerError) - return - } - - if err := Tmpl.ExecuteTemplate(w, "repo/refs", struct { - Title, Name, Description, Url string - Readme, Licence string - Branches []bra - Tags []tag - }{ - "Refs", reponame, repo.Description, util.If(Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name, - "", "", bras, tags, - }); err != nil { - log.Println("[Repo:Refs]", err.Error()) - } -} - func GetRepo(id int64) (*Repo, error) { r := &Repo{} diff --git a/src/repo/refs.go b/src/repo/refs.go new file mode 100644 index 0000000..6bff474 --- /dev/null +++ b/src/repo/refs.go @@ -0,0 +1,110 @@ +package repo + +import ( + "errors" + "log" + "net/http" + "path" + "strings" + "time" + + goit "github.com/Jamozed/Goit/src" + "github.com/Jamozed/Goit/src/util" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/gorilla/mux" +) + +func HandleRefs(w http.ResponseWriter, r *http.Request) { + auth, uid := goit.AuthCookie(w, r, true) + + repo, err := goit.GetRepoByName(mux.Vars(r)["repo"]) + if err != nil { + goit.HttpError(w, http.StatusInternalServerError) + return + } else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != uid)) { + goit.HttpError(w, http.StatusNotFound) + return + } + + type row struct{ Name, Message, Author, LastCommit, Hash string } + data := struct { + Title, Name, Description, Url string + Readme, Licence string + Branches, Tags []row + }{ + Title: repo.Name + " - References", Name: repo.Name, Description: repo.Description, + Url: util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name, + } + + gr, err := git.PlainOpen(goit.RepoPath(repo.Name)) + if err != nil { + log.Println("[/repo/refs]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + ref, err := gr.Head() + if err != nil { + if !errors.Is(err, plumbing.ErrReferenceNotFound) { + log.Println("[/repo/log]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + } else { + if readme, _ := findReadme(gr, ref); readme != "" { + data.Readme = path.Join("/", repo.Name, "file", readme) + } + if licence, _ := findLicence(gr, ref); licence != "" { + data.Licence = path.Join("/", repo.Name, "file", licence) + } + } + + if iter, err := gr.Branches(); err != nil { + log.Println("[/repo/refs]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } else if err := iter.ForEach(func(r *plumbing.Reference) error { + commit, err := gr.CommitObject(r.Hash()) + if err != nil { + return err + } + + data.Branches = append(data.Branches, row{ + Name: r.Name().Short(), Message: strings.SplitN(commit.Message, "\n", 2)[0], Author: commit.Author.Name, + LastCommit: commit.Author.When.UTC().Format(time.DateTime), Hash: r.Hash().String(), + }) + + return nil + }); err != nil { + log.Println("[/repo/refs]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + if iter, err := gr.Tags(); err != nil { + log.Println("[Repo:Refs]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } else if err := iter.ForEach(func(r *plumbing.Reference) error { + commit, err := gr.CommitObject(r.Hash()) + if err != nil { + return err + } + + data.Tags = append(data.Tags, row{ + Name: r.Name().Short(), Message: strings.SplitN(commit.Message, "\n", 2)[0], Author: commit.Author.Name, + LastCommit: commit.Author.When.UTC().Format(time.DateTime), Hash: r.Hash().String(), + }) + + return nil + }); err != nil { + log.Println("[Repo:Refs]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + if err := goit.Tmpl.ExecuteTemplate(w, "repo/refs", data); err != nil { + log.Println("[/repo/refs]", err.Error()) + } +}