0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
|
// Copyright (C) 2025, Jakob Wakeling
// All rights reserved.
package repo
import (
"errors"
"net/http"
"path/filepath"
"time"
"github.com/Jamozed/Goit/src/goit"
"github.com/Jamozed/Goit/src/util"
"github.com/go-chi/chi/v5"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
)
func HandleTag(w http.ResponseWriter, r *http.Request) {
auth, user, err := goit.Auth(w, r, true)
if err != nil {
util.PrintError(err)
goit.HttpError(w, http.StatusInternalServerError)
return
}
repo, err := goit.GetRepoByName(chi.URLParam(r, "repo"))
if err != nil {
goit.HttpError(w, http.StatusInternalServerError)
return
} else if repo == nil || !goit.IsVisible(repo, auth, user) {
goit.HttpError(w, http.StatusNotFound)
return
}
data := struct {
HeaderFields
Title string
Tag, Author, Date, Commit string
Parents []string
Message string
}{
HeaderFields: GetHeaderFields(auth, user, repo, r.Host),
Title: repo.Name + " - Tags",
}
gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
if err != nil {
util.PrintError(err)
goit.HttpError(w, http.StatusInternalServerError)
return
}
head, err := gr.Head()
if err != nil {
if !errors.Is(err, plumbing.ErrReferenceNotFound) {
util.PrintError(err)
goit.HttpError(w, http.StatusInternalServerError)
return
}
} else {
if readme, _ := findPattern(gr, head, readmePattern); readme != "" {
data.Readme = filepath.Join("/", repo.Name, "file", readme)
}
if licence, _ := findPattern(gr, head, licencePattern); licence != "" {
data.Licence = filepath.Join("/", repo.Name, "file", licence)
}
}
ref, err := gr.Tag(chi.URLParam(r, "tag"))
if errors.Is(err, plumbing.ErrReferenceNotFound) {
goit.HttpError(w, http.StatusNotFound)
return
} else if err != nil {
util.PrintError(err)
goit.HttpError(w, http.StatusInternalServerError)
return
}
data.Tag = ref.Name().Short()
var commit *object.Commit
if tag, err := gr.TagObject(ref.Hash()); err != nil {
if !errors.Is(err, plumbing.ErrObjectNotFound) {
util.PrintError(err)
goit.HttpError(w, http.StatusInternalServerError)
return
}
/* Tag is not annotated. */
if commit, err = gr.CommitObject(ref.Hash()); err != nil {
util.PrintError(err)
goit.HttpError(w, http.StatusInternalServerError)
return
}
data.Author = commit.Author.String()
data.Message = commit.Message
} else {
/* Tag is annotated. */
if commit, err = gr.CommitObject(tag.Target); err != nil {
util.PrintError(err)
goit.HttpError(w, http.StatusInternalServerError)
return
}
data.Author = tag.Tagger.String()
data.Message = tag.Message
}
data.Date = commit.Author.When.UTC().Format(time.DateTime)
data.Commit = commit.Hash.String()
if err := goit.Tmpl.ExecuteTemplate(w, "repo/tag", data); err != nil {
util.PrintError(err)
}
}
|