87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
package v1
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"sync"
|
|
|
|
"errors"
|
|
|
|
"git.dog/xx/update-api/model"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/go-git/go-git/v5"
|
|
"github.com/go-git/go-git/v5/plumbing/object"
|
|
)
|
|
|
|
var (
|
|
repos = sync.Map{}
|
|
errStop = errors.New("stopped iteration")
|
|
)
|
|
|
|
func SetRepo(repo *model.Repo) error {
|
|
repos.Store(repo.Name, repo.Plumbing)
|
|
return nil
|
|
}
|
|
|
|
func RegisterHandlers(router *gin.RouterGroup) {
|
|
router.GET("/changes/:project/head/:commit", getChanges)
|
|
}
|
|
|
|
func getChanges(c *gin.Context) {
|
|
comm := c.Param("commit")
|
|
project := c.Param("project")
|
|
|
|
repoi, ok := repos.Load(project)
|
|
|
|
if !ok {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "no such project"})
|
|
return
|
|
}
|
|
|
|
repo := repoi.(*git.Repository)
|
|
|
|
head, err := repo.Head()
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
cIter, err := repo.Log(&git.LogOptions{From: head.Hash()})
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// should probably move this logic outside of this function
|
|
// it should be called only when the repo is initialized or updated
|
|
// after that, this func should operate on a "cache"
|
|
var commits []model.Commit
|
|
err = cIter.ForEach(func(iterCommit *object.Commit) error {
|
|
commitHash := iterCommit.Hash.String()
|
|
|
|
// todo: minimum length for short hashes
|
|
if strings.HasPrefix(commitHash, comm) {
|
|
return errStop
|
|
}
|
|
|
|
// this can get very expensive if the repo is large
|
|
commits = append(commits, model.Commit{
|
|
ID: commitHash,
|
|
Description: iterCommit.Message,
|
|
})
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil && err != errStop {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, model.Changelog{
|
|
Latest: head.Hash().String(),
|
|
Changes: &commits,
|
|
})
|
|
}
|