Skip to content

Commit 276da34

Browse files
committed
Support editing multiple files
1 parent f13896b commit 276da34

File tree

6 files changed

+279
-95
lines changed

6 files changed

+279
-95
lines changed

agent/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (a *agent) apiHandler() http.Handler {
6262
r.Post("/api/v0/list-directory", a.HandleLS)
6363
r.Get("/api/v0/read-file", a.HandleReadFile)
6464
r.Post("/api/v0/write-file", a.HandleWriteFile)
65-
r.Post("/api/v0/edit-file", a.HandleEditFile)
65+
r.Post("/api/v0/edit-files", a.HandleEditFiles)
6666
r.Get("/debug/logs", a.HandleHTTPDebugLogs)
6767
r.Get("/debug/magicsock", a.HandleHTTPDebugMagicsock)
6868
r.Get("/debug/magicsock/debug-logging/{state}", a.HandleHTTPMagicsockDebugLoggingState)

agent/files.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -170,40 +170,51 @@ func (a *agent) writeFile(ctx context.Context, r *http.Request, path string) (HT
170170
return 0, nil
171171
}
172172

173-
func (a *agent) HandleEditFile(rw http.ResponseWriter, r *http.Request) {
173+
func (a *agent) HandleEditFiles(rw http.ResponseWriter, r *http.Request) {
174174
ctx := r.Context()
175175

176-
query := r.URL.Query()
177-
parser := httpapi.NewQueryParamParser().RequiredNotEmpty("path")
178-
path := parser.String(query, "", "path")
179-
parser.ErrorExcessParams(query)
180-
if len(parser.Errors) > 0 {
176+
var req workspacesdk.FileEditRequest
177+
if !httpapi.Read(ctx, rw, r, &req) {
178+
return
179+
}
180+
181+
if len(req.Files) == 0 {
181182
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
182-
Message: "Query parameters have invalid values.",
183-
Validations: parser.Errors,
183+
Message: "must specify at least one file",
184184
})
185185
return
186186
}
187187

188-
var edits workspacesdk.FileEditRequest
189-
if !httpapi.Read(ctx, rw, r, &edits) {
190-
return
188+
var combinedErr error
189+
status := http.StatusOK
190+
for _, edit := range req.Files {
191+
s, err := a.editFile(r.Context(), edit.Path, edit.Edits)
192+
// Keep the highest response status, so 500 will be preferred over 400, etc.
193+
if s > status {
194+
status = s
195+
}
196+
if err != nil {
197+
combinedErr = errors.Join(combinedErr, err)
198+
}
191199
}
192200

193-
status, err := a.editFile(r.Context(), path, edits.Edits)
194-
if err != nil {
201+
if combinedErr != nil {
195202
httpapi.Write(ctx, rw, status, codersdk.Response{
196-
Message: err.Error(),
203+
Message: combinedErr.Error(),
197204
})
198205
return
199206
}
200207

201208
httpapi.Write(ctx, rw, http.StatusOK, codersdk.Response{
202-
Message: fmt.Sprintf("Successfully edited %q", path),
209+
Message: "Successfully edited file(s)",
203210
})
204211
}
205212

206213
func (a *agent) editFile(ctx context.Context, path string, edits []workspacesdk.FileEdit) (int, error) {
214+
if path == "" {
215+
return http.StatusBadRequest, xerrors.New("\"path\" is required")
216+
}
217+
207218
if !filepath.IsAbs(path) {
208219
return http.StatusBadRequest, xerrors.Errorf("file path must be absolute: %q", path)
209220
}

0 commit comments

Comments
 (0)