package api import ( "encoding/json" "net/http" "sync" "github.com/muyue/muyue/internal/installer" "github.com/muyue/muyue/internal/scanner" "github.com/muyue/muyue/internal/updater" ) func (s *Server) handleUpdates(w http.ResponseWriter, r *http.Request) { result := scanner.ScanSystem() statuses := updater.CheckUpdates(result) type updateInfo struct { Tool string `json:"tool"` Current string `json:"current"` Latest string `json:"latest"` NeedsUpdate bool `json:"needsUpdate"` Error string `json:"error,omitempty"` } updates := make([]updateInfo, len(statuses)) for i, u := range statuses { updates[i] = updateInfo{ Tool: u.Tool, Current: u.Current, Latest: u.Latest, NeedsUpdate: u.NeedsUpdate, Error: u.Error, } } writeJSON(w, map[string]interface{}{ "updates": updates, }) } func (s *Server) handleInstall(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { writeError(w, "POST only", http.StatusMethodNotAllowed) return } var body struct { Tools []string `json:"tools"` } if err := json.NewDecoder(r.Body).Decode(&body); err != nil { writeError(w, err.Error(), http.StatusBadRequest) return } if len(body.Tools) == 0 { writeError(w, "no tools specified", http.StatusBadRequest) return } results := make([]installer.InstallResult, len(body.Tools)) var wg sync.WaitGroup var mu sync.Mutex for i, tool := range body.Tools { wg.Add(1) go func(idx int, name string) { defer wg.Done() inst := installer.New(s.config) res := inst.InstallTool(name) mu.Lock() results[idx] = res mu.Unlock() }(i, tool) } wg.Wait() writeJSON(w, map[string]interface{}{ "status": "done", "tools": body.Tools, "results": results, }) } func (s *Server) handleRunUpdate(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { writeError(w, "POST only", http.StatusMethodNotAllowed) return } var body struct { Tool string `json:"tool"` } if err := json.NewDecoder(r.Body).Decode(&body); err != nil { writeError(w, "invalid request body", http.StatusBadRequest) return } result := scanner.ScanSystem() statuses := updater.CheckUpdates(result) if body.Tool != "" { for _, u := range statuses { if u.Tool == body.Tool && u.NeedsUpdate { updater.RunAutoUpdate([]updater.UpdateStatus{u}) } } writeJSON(w, map[string]string{"status": "ok", "tool": body.Tool}) return } needsUpdate := make([]updater.UpdateStatus, 0) for _, u := range statuses { if u.NeedsUpdate { needsUpdate = append(needsUpdate, u) } } if len(needsUpdate) > 0 { updater.RunAutoUpdate(needsUpdate) } writeJSON(w, map[string]interface{}{ "status": "ok", "updated": len(needsUpdate), }) }