package delta import ( "net/http" "os" "path/filepath" "github.com/gin-gonic/gin" ) // Handler provides delta patch generation for JAR artefacts. type Handler struct { artefactDir string } func NewHandler(artefactDir string) *Handler { return &Handler{artefactDir: artefactDir} } // GenerateDelta creates a delta patch between two artefact versions. // POST /api/v1/delta/generate // Form fields: oldVersion, newVersion func (h *Handler) GenerateDelta(c *gin.Context) { oldVersion := c.PostForm("oldVersion") newVersion := c.PostForm("newVersion") if oldVersion == "" || newVersion == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "oldVersion and newVersion are required"}) return } oldDir := filepath.Join(h.artefactDir, oldVersion) newDir := filepath.Join(h.artefactDir, newVersion) if _, err := os.Stat(oldDir); os.IsNotExist(err) { c.JSON(http.StatusNotFound, gin.H{"error": "Old version not found: " + oldVersion}) return } if _, err := os.Stat(newDir); os.IsNotExist(err) { c.JSON(http.StatusNotFound, gin.H{"error": "New version not found: " + newVersion}) return } // Find JAR files in each version directory oldJar, err := findJarInDir(oldDir) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "No JAR found in old version: " + err.Error()}) return } newJar, err := findJarInDir(newDir) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "No JAR found in new version: " + err.Error()}) return } patchPath := filepath.Join(h.artefactDir, "patches", oldVersion+"-to-"+newVersion+".patch") if err := os.MkdirAll(filepath.Dir(patchPath), 0755); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create patch directory"}) return } if err := GenerateJarDelta(oldJar, newJar, patchPath); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Delta generation failed: " + err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "status": "generated", "patchPath": patchPath, "oldVersion": oldVersion, "newVersion": newVersion, }) } func findJarInDir(dir string) (string, error) { entries, err := os.ReadDir(dir) if err != nil { return "", err } for _, e := range entries { if !e.IsDir() && filepath.Ext(e.Name()) == ".jar" { return filepath.Join(dir, e.Name()), nil } } return "", os.ErrNotExist }