89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package api
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/syonad/clonepack/internal/core"
|
|
"github.com/syonad/clonepack/internal/store"
|
|
)
|
|
|
|
type CloneHandler struct {
|
|
svc *core.CloneService
|
|
}
|
|
|
|
func NewCloneHandler(svc *core.CloneService) *CloneHandler {
|
|
return &CloneHandler{svc: svc}
|
|
}
|
|
|
|
func (h *CloneHandler) StartClone(w http.ResponseWriter, r *http.Request) {
|
|
repoID, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
|
|
if err != nil {
|
|
Error(w, http.StatusBadRequest, "invalid id")
|
|
return
|
|
}
|
|
if err := Authorize(r.Context(), ActionCloneStart, repoID); err != nil {
|
|
Error(w, http.StatusForbidden, "forbidden")
|
|
return
|
|
}
|
|
jobID, err := h.svc.StartClone(r.Context(), repoID)
|
|
if errors.Is(err, store.ErrNotFound) {
|
|
Error(w, http.StatusNotFound, "repo not found")
|
|
return
|
|
}
|
|
if errors.Is(err, core.ErrCloneAlreadyRunning) {
|
|
Error(w, http.StatusConflict, err.Error())
|
|
return
|
|
}
|
|
if err != nil {
|
|
Error(w, http.StatusUnprocessableEntity, err.Error())
|
|
return
|
|
}
|
|
|
|
JSON(w, http.StatusAccepted, StartCloneResponse{JobID: jobID, Status: "running"})
|
|
}
|
|
|
|
func (h *CloneHandler) GetStatus(w http.ResponseWriter, r *http.Request) {
|
|
repoID, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
|
|
if err != nil {
|
|
Error(w, http.StatusBadRequest, "invalid id")
|
|
return
|
|
}
|
|
if err := Authorize(r.Context(), ActionCloneRead, repoID); err != nil {
|
|
Error(w, http.StatusForbidden, "forbidden")
|
|
return
|
|
}
|
|
job, err := h.svc.GetLatestCloneJob(r.Context(), repoID)
|
|
if errors.Is(err, store.ErrNotFound) {
|
|
Error(w, http.StatusNotFound, "no clone job found for this repo")
|
|
return
|
|
}
|
|
if err != nil {
|
|
Error(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
JSON(w, http.StatusOK, cloneJobToResponse(job))
|
|
}
|
|
|
|
func cloneJobToResponse(j *store.CloneJob) CloneStatusResponse {
|
|
resp := CloneStatusResponse{
|
|
JobID: j.ID,
|
|
RepoID: j.RepoID,
|
|
Status: string(j.Status),
|
|
Error: j.Error,
|
|
CreatedAt: j.CreatedAt.Format(time.RFC3339),
|
|
}
|
|
if j.StartedAt != nil {
|
|
s := j.StartedAt.Format(time.RFC3339)
|
|
resp.StartedAt = &s
|
|
}
|
|
if j.FinishedAt != nil {
|
|
f := j.FinishedAt.Format(time.RFC3339)
|
|
resp.FinishedAt = &f
|
|
}
|
|
return resp
|
|
}
|