func (uis *UIServer) schedulePatch(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Patch == nil { http.Error(w, "patch not found", http.StatusNotFound) return } curUser := GetUser(r) if !uis.canEditPatch(curUser, projCtx.Patch) { http.Error(w, "Not authorized to schedule patch", http.StatusUnauthorized) return } // grab patch again, as the diff was excluded var err error projCtx.Patch, err = patch.FindOne(patch.ById(projCtx.Patch.Id)) if err != nil { http.Error(w, fmt.Sprintf("error loading patch: %v", err), http.StatusInternalServerError) return } // Unmarshal the project config and set it in the project context project := &model.Project{} if err := yaml.Unmarshal([]byte(projCtx.Patch.PatchedConfig), project); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error unmarshaling project config: %v", err)) } projCtx.Project = project patchUpdateReq := patchVariantsTasksRequest{} err = util.ReadJSONInto(r.Body, &patchUpdateReq) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } var pairs []model.TVPair if len(patchUpdateReq.VariantsTasks) > 0 { pairs = model.VariantTasksToTVPairs(patchUpdateReq.VariantsTasks) } else { for _, v := range patchUpdateReq.Variants { for _, t := range patchUpdateReq.Tasks { if project.FindTaskForVariant(t, v) != nil { pairs = append(pairs, model.TVPair{v, t}) } } } } pairs = model.IncludePatchDependencies(projCtx.Project, pairs) if err = model.ValidateTVPairs(projCtx.Project, pairs); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // update the description for both reconfigured and new patches if err = projCtx.Patch.SetDescription(patchUpdateReq.Description); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting description: %v", err)) return } // update the description for both reconfigured and new patches if err = projCtx.Patch.SetVariantsTasks(model.TVPairsToVariantTasks(pairs)); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting description: %v", err)) return } if projCtx.Patch.Version != "" { projCtx.Patch.Activated = true // This patch has already been finalized, just add the new builds and tasks if projCtx.Version == nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Couldn't find patch for id %v", projCtx.Patch.Version)) return } // First add new tasks to existing builds, if necessary err = model.AddNewTasksForPatch(projCtx.Patch, projCtx.Version, projCtx.Project, pairs) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new tasks: `%v` for version `%v`", err, projCtx.Version.Id)) return } err := model.AddNewBuildsForPatch(projCtx.Patch, projCtx.Version, projCtx.Project, pairs) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new builds: `%v` for version `%v`", err, projCtx.Version.Id)) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Builds and tasks successfully added to patch.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{projCtx.Version.Id}) } else { projCtx.Patch.Activated = true err = projCtx.Patch.SetVariantsTasks(model.TVPairsToVariantTasks(pairs)) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting patch variants and tasks: %v", err)) return } ver, err := model.FinalizePatch(projCtx.Patch, &uis.Settings) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error finalizing patch: %v", err)) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Patch builds are scheduled.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{ver.Id}) } }
func (uis *UIServer) schedulePatch(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Patch == nil { http.Error(w, "patch not found", http.StatusNotFound) return } // grab patch again, as the diff was excluded var err error projCtx.Patch, err = patch.FindOne(patch.ById(projCtx.Patch.Id)) if err != nil { http.Error(w, fmt.Sprintf("error loading patch: %v", err), http.StatusInternalServerError) return } patchUpdateReq := struct { Variants []string `json:"variants"` Tasks []string `json:"tasks"` Description string `json:"description"` }{} err = util.ReadJSONInto(r.Body, &patchUpdateReq) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if projCtx.Patch.Version != "" { // This patch has already been finalized, just add the new builds and tasks if projCtx.Version == nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Couldn't find patch for id %v", projCtx.Patch.Version)) return } // First add new tasks to existing builds, if necessary if len(patchUpdateReq.Tasks) > 0 { err = model.AddNewTasksForPatch(projCtx.Patch, projCtx.Version, patchUpdateReq.Tasks) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new tasks: `%v` for version `%v`", err, projCtx.Version.Id)) return } } if len(patchUpdateReq.Variants) > 0 { _, err := model.AddNewBuildsForPatch(projCtx.Patch, projCtx.Version, patchUpdateReq.Variants) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new builds: `%v` for version `%v`", err, projCtx.Version.Id)) return } } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Builds and tasks successfully added to patch.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{projCtx.Version.Id}) } else { err = projCtx.Patch.SetVariantsAndTasks(patchUpdateReq.Variants, patchUpdateReq.Tasks) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting patch variants and tasks: %v", err)) return } if err = projCtx.Patch.SetDescription(patchUpdateReq.Description); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting description: %v", err)) return } // Unmarshal the project config and set it in the project context project := model.Project{} if err := yaml.Unmarshal([]byte(projCtx.Patch.PatchedConfig), &project); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error unmarshaling project config: %v", err)) } projCtx.Project = &project ver, err := model.FinalizePatch(projCtx.Patch, &uis.Settings) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error finalizing patch: %v", err)) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Patch builds are scheduled.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{ver.Id}) } }
func (uis *UIServer) schedulePatch(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Patch == nil { http.Error(w, "patch not found", http.StatusNotFound) return } // grab patch again, as the diff was excluded var err error projCtx.Patch, err = patch.FindOne(patch.ById(projCtx.Patch.Id)) if err != nil { http.Error(w, fmt.Sprintf("error loading patch: %v", err), http.StatusInternalServerError) return } // Unmarshal the project config and set it in the project context project := &model.Project{} if err := yaml.Unmarshal([]byte(projCtx.Patch.PatchedConfig), project); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error unmarshaling project config: %v", err)) } projCtx.Project = project patchUpdateReq := struct { Variants []string `json:"variants"` Tasks []string `json:"tasks"` Description string `json:"description"` }{} err = util.ReadJSONInto(r.Body, &patchUpdateReq) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Add all dependencies to patchUpdateReq.Tasks and add their variants to patchUpdateReq.Variants // Construct a set of variants to include in patchUpdateReq.Variants updateReqVariants := make(map[string]bool) for _, variant := range patchUpdateReq.Variants { updateReqVariants[variant] = true } // Construct a set of tasks to include in patchUpdateReq.Tasks // Add all dependencies, and add their variants to updateReqVariants updateReqTasks := make(map[string]bool) for _, v := range patchUpdateReq.Variants { for _, t := range projCtx.Project.FindTasksForVariant(v) { for _, task := range patchUpdateReq.Tasks { if t == task { deps, variants, err := getDeps(task, v, projCtx.Project) if err != nil { if err == TaskNotPatchableError { continue } else { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error getting dependencies for task: %v", err)) return } } updateReqTasks[task] = true for _, dep := range deps { updateReqTasks[dep] = true } for _, variant := range variants { updateReqVariants[variant] = true } } } } } // Reset patchUpdateReq.Tasks and patchUpdateReq.Variants patchUpdateReq.Tasks = make([]string, 0, len(updateReqTasks)) for task := range updateReqTasks { patchUpdateReq.Tasks = append(patchUpdateReq.Tasks, task) } patchUpdateReq.Variants = make([]string, 0, len(updateReqVariants)) for variant := range updateReqVariants { patchUpdateReq.Variants = append(patchUpdateReq.Variants, variant) } if projCtx.Patch.Version != "" { // This patch has already been finalized, just add the new builds and tasks if projCtx.Version == nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Couldn't find patch for id %v", projCtx.Patch.Version)) return } // First add new tasks to existing builds, if necessary if len(patchUpdateReq.Tasks) > 0 { err = model.AddNewTasksForPatch(projCtx.Patch, projCtx.Version, projCtx.Project, patchUpdateReq.Tasks) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new tasks: `%v` for version `%v`", err, projCtx.Version.Id)) return } } if len(patchUpdateReq.Variants) > 0 { _, err := model.AddNewBuildsForPatch(projCtx.Patch, projCtx.Version, projCtx.Project, patchUpdateReq.Variants) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new builds: `%v` for version `%v`", err, projCtx.Version.Id)) return } } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Builds and tasks successfully added to patch.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{projCtx.Version.Id}) } else { err = projCtx.Patch.SetVariantsAndTasks(patchUpdateReq.Variants, patchUpdateReq.Tasks) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting patch variants and tasks: %v", err)) return } if err = projCtx.Patch.SetDescription(patchUpdateReq.Description); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting description: %v", err)) return } ver, err := model.FinalizePatch(projCtx.Patch, &uis.Settings) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error finalizing patch: %v", err)) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Patch builds are scheduled.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{ver.Id}) } }