예제 #1
0
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
}
예제 #2
0
// 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
}
예제 #3
0
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
}
예제 #4
0
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
}