package server import ( "errors" "fmt" "net/http" "regexp" "g.fc.run/misc/byre/internal/api" "g.fc.run/misc/byre/internal/git" ) var objectID = regexp.MustCompile(`^[0-9a-f]{40}([0-9a-f]{24})?$`) func (s *Server) GetTaskChanges(w http.ResponseWriter, r *http.Request, taskID string, params api.GetTaskChangesParams) { t, err := s.store.GetTask(r.Context(), taskID) if err != nil { writeStoreError(w, err) return } if t.Status != api.TaskStatusActive { writeError(w, http.StatusConflict, fmt.Errorf("task %s is %s and has no worktree", t.Id, t.Status)) return } p, err := s.store.GetProject(r.Context(), t.ProjectId) if err != nil { writeStoreError(w, err) return } since := "" if params.Since != nil { since = *params.Since if !objectID.MatchString(since) { writeError(w, http.StatusBadRequest, errors.New("since must be a full object id")) return } } changes, err := git.Changes(t.WorktreePath, p.DefaultBranch, since) if err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusOK, changes) } func (s *Server) GetTaskDiff(w http.ResponseWriter, r *http.Request, taskID string, params api.GetTaskDiffParams) { t, err := s.store.GetTask(r.Context(), taskID) if err != nil { writeStoreError(w, err) return } if t.Status != api.TaskStatusActive { writeError(w, http.StatusConflict, fmt.Errorf("task %s is %s and has no worktree", t.Id, t.Status)) return } if !objectID.MatchString(params.Base) || !objectID.MatchString(params.Tree) { writeError(w, http.StatusBadRequest, errors.New("base and tree must be full object ids")) return } oldPath := "" if params.OldPath != nil { oldPath = *params.OldPath } patch, err := git.FileDiff(t.WorktreePath, params.Base, params.Tree, params.Path, oldPath) if err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusOK, api.FileDiff{Path: params.Path, Patch: patch}) }