Skip to content

Commit f8b95c9

Browse files
committed
feat: add file revision API for workspaces
Signed-off-by: Donnie Adams <[email protected]>
1 parent 73a9ffe commit f8b95c9

File tree

2 files changed

+113
-7
lines changed

2 files changed

+113
-7
lines changed

pkg/sdkserver/routes.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package sdkserver
33
import (
44
"encoding/json"
55
"fmt"
6-
"io"
76
"net/http"
87
"sort"
98
"strings"
@@ -81,6 +80,9 @@ func (s *server) addRoutes(mux *http.ServeMux) {
8180
mux.HandleFunc("POST /workspaces/delete-file", s.removeFileInWorkspace)
8281
mux.HandleFunc("POST /workspaces/read-file", s.readFileInWorkspace)
8382
mux.HandleFunc("POST /workspaces/stat-file", s.statFileInWorkspace)
83+
mux.HandleFunc("POST /workspaces/list-revisions", s.listRevisions)
84+
mux.HandleFunc("POST /workspaces/get-revision", s.getRevisionForFileInWorkspace)
85+
mux.HandleFunc("POST /workspaces/delete-revision", s.deleteRevisionForFileInWorkspace)
8486
}
8587

8688
// health just provides an endpoint for checking whether the server is running and accessible.
@@ -152,14 +154,9 @@ func (s *server) listModels(w http.ResponseWriter, r *http.Request) {
152154
// Then the options and tool are passed to the process function.
153155
func (s *server) execHandler(w http.ResponseWriter, r *http.Request) {
154156
logger := gcontext.GetLogger(r.Context())
155-
body, err := io.ReadAll(r.Body)
156-
if err != nil {
157-
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to read request body: %w", err))
158-
return
159-
}
160157

161158
reqObject := new(toolOrFileRequest)
162-
if err := json.Unmarshal(body, reqObject); err != nil {
159+
if err := json.NewDecoder(r.Body).Decode(reqObject); err != nil {
163160
writeError(logger, w, http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err))
164161
return
165162
}

pkg/sdkserver/workspaces.go

+109
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,112 @@ func (s *server) statFileInWorkspace(w http.ResponseWriter, r *http.Request) {
321321

322322
writeResponse(logger, w, map[string]any{"stdout": out})
323323
}
324+
325+
type listRevisionsRequest struct {
326+
workspaceCommonRequest `json:",inline"`
327+
FilePath string `json:"filePath"`
328+
}
329+
330+
func (s *server) listRevisions(w http.ResponseWriter, r *http.Request) {
331+
logger := gcontext.GetLogger(r.Context())
332+
var reqObject listRevisionsRequest
333+
if err := json.NewDecoder(r.Body).Decode(&reqObject); err != nil {
334+
writeError(logger, w, http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err))
335+
}
336+
337+
prg, err := loader.Program(r.Context(), s.getWorkspaceTool(reqObject.workspaceCommonRequest), "List Revisions for File in Workspace", loader.Options{Cache: s.client.Cache})
338+
if err != nil {
339+
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to load program: %w", err))
340+
return
341+
}
342+
343+
out, err := s.client.Run(
344+
r.Context(),
345+
prg,
346+
s.getServerToolsEnv(reqObject.Env),
347+
fmt.Sprintf(
348+
`{"workspace_id": "%s", "file_path": "%s"}`,
349+
reqObject.ID, reqObject.FilePath,
350+
),
351+
)
352+
if err != nil {
353+
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to run program: %w", err))
354+
return
355+
}
356+
357+
writeResponse(logger, w, map[string]any{"stdout": out})
358+
}
359+
360+
type getRevisionForFileInWorkspaceRequest struct {
361+
workspaceCommonRequest `json:",inline"`
362+
FilePath string `json:"filePath"`
363+
RevisionID string `json:"revisionID"`
364+
}
365+
366+
func (s *server) getRevisionForFileInWorkspace(w http.ResponseWriter, r *http.Request) {
367+
logger := gcontext.GetLogger(r.Context())
368+
var reqObject getRevisionForFileInWorkspaceRequest
369+
if err := json.NewDecoder(r.Body).Decode(&reqObject); err != nil {
370+
writeError(logger, w, http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err))
371+
return
372+
}
373+
374+
prg, err := loader.Program(r.Context(), s.getWorkspaceTool(reqObject.workspaceCommonRequest), "Get a Revision for File in Workspace", loader.Options{Cache: s.client.Cache})
375+
if err != nil {
376+
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to load program: %w", err))
377+
return
378+
}
379+
380+
out, err := s.client.Run(
381+
r.Context(),
382+
prg,
383+
s.getServerToolsEnv(reqObject.Env),
384+
fmt.Sprintf(
385+
`{"workspace_id": "%s", "file_path": "%s", "revision_id": "%s"}`,
386+
reqObject.ID, reqObject.FilePath, reqObject.RevisionID,
387+
),
388+
)
389+
if err != nil {
390+
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to run program: %w", err))
391+
return
392+
}
393+
394+
writeResponse(logger, w, map[string]any{"stdout": out})
395+
}
396+
397+
type deleteRevisionForFileInWorkspaceRequest struct {
398+
workspaceCommonRequest `json:",inline"`
399+
FilePath string `json:"filePath"`
400+
RevisionID string `json:"revisionID"`
401+
}
402+
403+
func (s *server) deleteRevisionForFileInWorkspace(w http.ResponseWriter, r *http.Request) {
404+
logger := gcontext.GetLogger(r.Context())
405+
var reqObject deleteRevisionForFileInWorkspaceRequest
406+
if err := json.NewDecoder(r.Body).Decode(&reqObject); err != nil {
407+
writeError(logger, w, http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err))
408+
return
409+
}
410+
411+
prg, err := loader.Program(r.Context(), s.getWorkspaceTool(reqObject.workspaceCommonRequest), "Delete a Revision for File in Workspace", loader.Options{Cache: s.client.Cache})
412+
if err != nil {
413+
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to load program: %w", err))
414+
return
415+
}
416+
417+
out, err := s.client.Run(
418+
r.Context(),
419+
prg,
420+
s.getServerToolsEnv(reqObject.Env),
421+
fmt.Sprintf(
422+
`{"workspace_id": "%s", "file_path": "%s", "revision_id": "%s"}`,
423+
reqObject.ID, reqObject.FilePath, reqObject.RevisionID,
424+
),
425+
)
426+
if err != nil {
427+
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to run program: %w", err))
428+
return
429+
}
430+
431+
writeResponse(logger, w, map[string]any{"stdout": out})
432+
}

0 commit comments

Comments
 (0)