func getSummaries(patchContent string) ([]patch.Summary, error) { summaries := []patch.Summary{} if patchContent != "" { gitOutput, err := thirdparty.GitApplyNumstat(patchContent) if err != nil { return nil, fmt.Errorf("couldn't validate patch: %v", err) } if gitOutput == nil { return nil, fmt.Errorf("couldn't validate patch: git apply --numstat returned empty") } summaries, err = thirdparty.ParseGitSummary(gitOutput) if err != nil { return nil, fmt.Errorf("couldn't validate patch: %v", err) } } return summaries, nil }
// Validate checks an API request to see if it is safe and sane. // Returns the relevant patch metadata and any errors that occur. func (pr *PatchAPIRequest) Validate(oauthToken string) (*PatchMetadata, error) { var repoOwner, repo string var module *model.Module projectRef, err := model.FindOneProjectRef(pr.ProjectFileName) if err != nil { return nil, fmt.Errorf("Could not find project ref %v : %v", pr.ProjectFileName, err) } repoOwner = projectRef.Owner repo = projectRef.Repo // validate the project file project, err := model.FindProject("", projectRef) if err != nil { return nil, fmt.Errorf("Could not find project file %v: %v", pr.ProjectFileName, err) } if project == nil { return nil, fmt.Errorf("No such project file named %v", pr.ProjectFileName) } if pr.ModuleName != "" { // is there a module? validate it. module, err = project.GetModuleByName(pr.ModuleName) if err != nil { return nil, fmt.Errorf("could not find module %v: %v", pr.ModuleName, err) } if module == nil { return nil, fmt.Errorf("no module named %v", pr.ModuleName) } repoOwner, repo = module.GetRepoOwnerAndName() } if len(pr.Githash) != 40 { return nil, fmt.Errorf("invalid githash") } gitCommit, err := thirdparty.GetCommitEvent(oauthToken, repoOwner, repo, pr.Githash) if err != nil { return nil, fmt.Errorf("could not find base revision %v for project %v: %v", pr.Githash, projectRef.Identifier, err) } if gitCommit == nil { return nil, fmt.Errorf("commit hash %v doesn't seem to exist", pr.Githash) } gitOutput, err := thirdparty.GitApplyNumstat(pr.PatchContent) if err != nil { return nil, fmt.Errorf("couldn't validate patch: %v", err) } if gitOutput == nil { return nil, fmt.Errorf("couldn't validate patch: git apply --numstat returned empty") } summaries, err := thirdparty.ParseGitSummary(gitOutput) if err != nil { return nil, fmt.Errorf("couldn't validate patch: %v", err) } if len(pr.BuildVariants) == 0 || pr.BuildVariants[0] == "" { return nil, fmt.Errorf("no buildvariants specified") } // verify that this build variant exists for _, buildVariant := range pr.BuildVariants { if buildVariant == "all" { continue } bv := project.FindBuildVariant(buildVariant) if bv == nil { return nil, fmt.Errorf("No such buildvariant: %v", buildVariant) } } return &PatchMetadata{pr.Githash, project, module, pr.BuildVariants, summaries}, nil }
func (as *APIServer) updatePatchModule(w http.ResponseWriter, r *http.Request) { p, err := getPatchFromRequest(r) if err != nil { as.WriteJSON(w, http.StatusBadRequest, err.Error()) return } moduleName := r.FormValue("module") patchContent := r.FormValue("patch") githash := r.FormValue("githash") projectRef, err := model.FindOneProjectRef(p.Project) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error getting project ref with id %v: %v", p.Project, err)) return } project, err := model.FindProject("", projectRef) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error getting patch: %v", err)) return } if project == nil { as.LoggedError(w, r, http.StatusNotFound, fmt.Errorf("can't find project: %v", p.Project)) return } module, err := project.GetModuleByName(moduleName) if err != nil || module == nil { as.LoggedError(w, r, http.StatusBadRequest, fmt.Errorf("No such module")) return } gitOutput, err := thirdparty.GitApplyNumstat(patchContent) if err != nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("Invalid patch: %v", err)) return } if gitOutput == nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("Empty diff")) return } summaries, err := thirdparty.ParseGitSummary(gitOutput) if err != nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("Can't validate patch: %v", err)) return } repoOwner, repo := module.GetRepoOwnerAndName() commitInfo, err := thirdparty.GetCommitEvent(as.Settings.Credentials[projectRef.RepoKind], repoOwner, repo, githash) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } if commitInfo == nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("commit hash doesn't seem to exist")) return } modulePatch := patch.ModulePatch{ ModuleName: moduleName, Githash: githash, PatchSet: patch.PatchSet{ Patch: patchContent, Summary: summaries, // thirdparty.GetPatchSummary(apiRequest.PatchContent), }, } if err = p.UpdateModulePatch(modulePatch); err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } as.WriteJSON(w, http.StatusOK, "Patch module updated") return }
func (as *APIServer) updatePatchModule(w http.ResponseWriter, r *http.Request) { p, err := getPatchFromRequest(r) if err != nil { as.WriteJSON(w, http.StatusBadRequest, err.Error()) return } var moduleName, patchContent, githash string if r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" { moduleName, patchContent, githash = r.FormValue("module"), r.FormValue("patch"), r.FormValue("githash") } else { data := struct { Module string `json:"module"` Patch string `json:"patch"` Githash string `json:"githash"` }{} if err := util.ReadJSONInto(r.Body, &data); err != nil { as.LoggedError(w, r, http.StatusBadRequest, err) return } moduleName, patchContent, githash = data.Module, data.Patch, data.Githash } if len(patchContent) == 0 { as.LoggedError(w, r, http.StatusBadRequest, fmt.Errorf("Error: Patch must not be empty")) return } projectRef, err := model.FindOneProjectRef(p.Project) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error getting project ref with id %v: %v", p.Project, err)) return } project, err := model.FindProject("", projectRef) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error getting patch: %v", err)) return } if project == nil { as.LoggedError(w, r, http.StatusNotFound, fmt.Errorf("can't find project: %v", p.Project)) return } module, err := project.GetModuleByName(moduleName) if err != nil || module == nil { as.LoggedError(w, r, http.StatusBadRequest, fmt.Errorf("No such module", moduleName)) return } gitOutput, err := thirdparty.GitApplyNumstat(patchContent) if err != nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("Invalid patch: %v", err)) return } if gitOutput == nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("Empty diff")) return } summaries, err := thirdparty.ParseGitSummary(gitOutput) if err != nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("Can't validate patch: %v", err)) return } repoOwner, repo := module.GetRepoOwnerAndName() commitInfo, err := thirdparty.GetCommitEvent(as.Settings.Credentials["github"], repoOwner, repo, githash) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } if commitInfo == nil { as.WriteJSON(w, http.StatusBadRequest, fmt.Errorf("commit hash doesn't seem to exist")) return } // write the patch content into a GridFS file under a new ObjectId. patchFileId := bson.NewObjectId().Hex() err = db.WriteGridFile(patch.GridFSPrefix, patchFileId, strings.NewReader(patchContent)) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("failed to write patch file to db: %v", err)) return } modulePatch := patch.ModulePatch{ ModuleName: moduleName, Githash: githash, PatchSet: patch.PatchSet{ PatchFileId: patchFileId, Summary: summaries, }, } if err = p.UpdateModulePatch(modulePatch); err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } as.WriteJSON(w, http.StatusOK, "Patch module updated") return }