This commit is contained in:
@@ -280,6 +280,96 @@ type DeleteFolderRequest struct {
|
||||
Path string `json:"path" binding:"required" example:"deploy/nginx" description:"Folder path to delete"`
|
||||
}
|
||||
|
||||
// RenameRequest is the request body for renaming a script or folder.
|
||||
type RenameRequest struct {
|
||||
OldPath string `json:"old_path" binding:"required" example:"deploy/nginx" description:"Current path"`
|
||||
NewPath string `json:"new_path" binding:"required" example:"deploy/nginx-v2" description:"New path"`
|
||||
}
|
||||
|
||||
// Rename renames a script or all scripts under a folder path.
|
||||
// @Summary Rename script or folder
|
||||
// @Description Renames a single script or all scripts under a folder prefix
|
||||
// @Tags scripts
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body RenameRequest true "Rename request"
|
||||
// @Success 200 {object} map[string]interface{} "Rename result with count of renamed scripts"
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Failure 409 {object} map[string]string
|
||||
// @Security Bearer
|
||||
// @Router /scripts/rename [post]
|
||||
func (sh *ScriptHandlersGroup) Rename(c *gin.Context) {
|
||||
var req RenameRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate new path
|
||||
if err := validateScriptPath(req.NewPath); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("invalid new path: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate old path
|
||||
if err := validateScriptPath(req.OldPath); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("invalid old path: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
// Get all scripts
|
||||
allScripts, err := sh.svc.Repo.ListScripts()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list scripts"})
|
||||
return
|
||||
}
|
||||
|
||||
// Find scripts to rename: exact match or folder prefix
|
||||
prefix := req.OldPath + "/"
|
||||
var toRename []repository.Script
|
||||
for _, script := range allScripts {
|
||||
if script.Path == req.OldPath || strings.HasPrefix(script.Path, prefix) {
|
||||
toRename = append(toRename, script)
|
||||
}
|
||||
}
|
||||
|
||||
if len(toRename) == 0 {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "no scripts found with this path"})
|
||||
return
|
||||
}
|
||||
|
||||
// Rename each script
|
||||
renamedCount := 0
|
||||
for _, script := range toRename {
|
||||
newPath := req.NewPath + strings.TrimPrefix(script.Path, req.OldPath)
|
||||
|
||||
// Check if new path already exists (excluding the scripts we're renaming)
|
||||
for _, existing := range allScripts {
|
||||
if existing.ID != script.ID && existing.Path == newPath {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": fmt.Sprintf("path '%s' already exists", newPath)})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_, err := sh.svc.Repo.UpdateScript(script.ID, repository.ScriptUpdate{
|
||||
Path: &newPath,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to rename %s: %v", script.Path, err)})
|
||||
return
|
||||
}
|
||||
renamedCount++
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "renamed",
|
||||
"old_path": req.OldPath,
|
||||
"new_path": req.NewPath,
|
||||
"renamed_count": renamedCount,
|
||||
})
|
||||
}
|
||||
|
||||
// CreateFolder creates a virtual folder in the script tree.
|
||||
// @Summary Create folder
|
||||
// @Description Creates a virtual folder by creating a placeholder script with the folder path
|
||||
|
||||
Reference in New Issue
Block a user