mirror of
https://github.com/harness/drone.git
synced 2025-05-04 23:22:42 +08:00
API returns status 422 in case of rule violations (#718)
This commit is contained in:
parent
02b36d0f73
commit
6ee49f9848
@ -48,22 +48,17 @@ func (c *Controller) Merge(
|
|||||||
repoRef string,
|
repoRef string,
|
||||||
pullreqNum int64,
|
pullreqNum int64,
|
||||||
in *MergeInput,
|
in *MergeInput,
|
||||||
) (types.MergeResponse, error) {
|
) (*types.MergeResponse, *types.MergeViolations, error) {
|
||||||
var (
|
|
||||||
sha string
|
|
||||||
pr *types.PullReq
|
|
||||||
)
|
|
||||||
|
|
||||||
method, ok := in.Method.Sanitize()
|
method, ok := in.Method.Sanitize()
|
||||||
if !ok {
|
if !ok {
|
||||||
return types.MergeResponse{}, usererror.BadRequest(
|
return nil, nil, usererror.BadRequest(
|
||||||
fmt.Sprintf("wrong merge method type: %s", in.Method))
|
fmt.Sprintf("wrong merge method type: %s", in.Method))
|
||||||
}
|
}
|
||||||
in.Method = method
|
in.Method = method
|
||||||
|
|
||||||
targetRepo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit)
|
targetRepo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to acquire access to target repo: %w", err)
|
return nil, nil, fmt.Errorf("failed to acquire access to target repo: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if two requests for merging comes at the same time then mutex will lock
|
// if two requests for merging comes at the same time then mutex will lock
|
||||||
@ -72,50 +67,50 @@ func (c *Controller) Merge(
|
|||||||
// pr is already merged.
|
// pr is already merged.
|
||||||
mutex, err := c.newMutexForPR(targetRepo.GitUID, 0) // 0 means locks all PRs for this repo
|
mutex, err := c.newMutexForPR(targetRepo.GitUID, 0) // 0 means locks all PRs for this repo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
err = mutex.Lock(ctx)
|
err = mutex.Lock(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = mutex.Unlock(ctx)
|
_ = mutex.Unlock(ctx)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pr, err = c.pullreqStore.FindByNumber(ctx, targetRepo.ID, pullreqNum)
|
pr, err := c.pullreqStore.FindByNumber(ctx, targetRepo.ID, pullreqNum)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to get pull request by number: %w", err)
|
return nil, nil, fmt.Errorf("failed to get pull request by number: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pr.Merged != nil {
|
if pr.Merged != nil {
|
||||||
return types.MergeResponse{}, usererror.BadRequest("Pull request already merged")
|
return nil, nil, usererror.BadRequest("Pull request already merged")
|
||||||
}
|
}
|
||||||
|
|
||||||
if pr.State != enum.PullReqStateOpen {
|
if pr.State != enum.PullReqStateOpen {
|
||||||
return types.MergeResponse{}, usererror.BadRequest("Pull request must be open")
|
return nil, nil, usererror.BadRequest("Pull request must be open")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if pr.SourceSHA != in.SourceSHA {
|
if pr.SourceSHA != in.SourceSHA {
|
||||||
return types.MergeResponse{},
|
return nil, nil,
|
||||||
usererror.BadRequest("A newer commit is available. Only the latest commit can be merged.")
|
usererror.BadRequest("A newer commit is available. Only the latest commit can be merged.")
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if pr.IsDraft {
|
if pr.IsDraft {
|
||||||
return types.MergeResponse{}, usererror.BadRequest(
|
return nil, nil, usererror.BadRequest(
|
||||||
"Draft pull requests can't be merged. Clear the draft flag first.",
|
"Draft pull requests can't be merged. Clear the draft flag first.",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
reviewers, err := c.reviewerStore.List(ctx, pr.ID)
|
reviewers, err := c.reviewerStore.List(ctx, pr.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to load list of reviwers: %w", err)
|
return nil, nil, fmt.Errorf("failed to load list of reviwers: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetWriteParams, err := controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, targetRepo)
|
targetWriteParams, err := controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, targetRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to create RPC write params: %w", err)
|
return nil, nil, fmt.Errorf("failed to create RPC write params: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceRepo := targetRepo
|
sourceRepo := targetRepo
|
||||||
@ -123,28 +118,28 @@ func (c *Controller) Merge(
|
|||||||
if pr.SourceRepoID != pr.TargetRepoID {
|
if pr.SourceRepoID != pr.TargetRepoID {
|
||||||
sourceWriteParams, err = controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, sourceRepo)
|
sourceWriteParams, err = controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, sourceRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to create RPC write params: %w", err)
|
return nil, nil, fmt.Errorf("failed to create RPC write params: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceRepo, err = c.repoStore.Find(ctx, pr.SourceRepoID)
|
sourceRepo, err = c.repoStore.Find(ctx, pr.SourceRepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to get source repository: %w", err)
|
return nil, nil, fmt.Errorf("failed to get source repository: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isSpaceOwner, err := apiauth.IsSpaceAdmin(ctx, c.authorizer, session, targetRepo)
|
isSpaceOwner, err := apiauth.IsSpaceAdmin(ctx, c.authorizer, session, targetRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to determine if the user is space admin: %w", err)
|
return nil, nil, fmt.Errorf("failed to determine if the user is space admin: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkResults, err := c.checkStore.ListResults(ctx, targetRepo.ID, pr.SourceSHA)
|
checkResults, err := c.checkStore.ListResults(ctx, targetRepo.ID, pr.SourceSHA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to list status checks: %w", err)
|
return nil, nil, fmt.Errorf("failed to list status checks: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
protectionRules, err := c.protectionManager.ForRepository(ctx, targetRepo.ID)
|
protectionRules, err := c.protectionManager.ForRepository(ctx, targetRepo.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to fetch protection rules for the repository: %w", err)
|
return nil, nil, fmt.Errorf("failed to fetch protection rules for the repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ruleOut, violations, err := protectionRules.CanMerge(ctx, protection.CanMergeInput{
|
ruleOut, violations, err := protectionRules.CanMerge(ctx, protection.CanMergeInput{
|
||||||
@ -158,10 +153,10 @@ func (c *Controller) Merge(
|
|||||||
CheckResults: checkResults,
|
CheckResults: checkResults,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to verify protection rules: %w", err)
|
return nil, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||||
}
|
}
|
||||||
if protection.IsCritical(violations) {
|
if protection.IsCritical(violations) {
|
||||||
return types.MergeResponse{RuleViolations: violations}, nil
|
return nil, &types.MergeViolations{RuleViolations: violations}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: for forking merge title might be different?
|
// TODO: for forking merge title might be different?
|
||||||
@ -192,12 +187,22 @@ func (c *Controller) Merge(
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if gitrpc.ErrorStatus(err) == gitrpc.StatusNotMergeable {
|
if gitrpc.ErrorStatus(err) == gitrpc.StatusNotMergeable {
|
||||||
return types.MergeResponse{
|
return &types.MergeResponse{
|
||||||
|
SHA: "",
|
||||||
|
BranchDeleted: false,
|
||||||
ConflictFiles: gitrpc.AsConflictFilesError(err),
|
ConflictFiles: gitrpc.AsConflictFilesError(err),
|
||||||
RuleViolations: violations,
|
RuleViolations: violations,
|
||||||
}, nil
|
}, nil, nil
|
||||||
|
// TODO: This should be the response in case of a merge conflict.
|
||||||
|
// TODO: Remove the ConflictFiles field from types.MergeResponse.
|
||||||
|
/*
|
||||||
|
return nil, &types.MergeViolations{
|
||||||
|
ConflictFiles: gitrpc.AsConflictFilesError(err),
|
||||||
|
RuleViolations: violations,
|
||||||
|
}, nil
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return types.MergeResponse{}, fmt.Errorf("merge check execution failed: %w", err)
|
return nil, nil, fmt.Errorf("merge check execution failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pr, err = c.pullreqStore.UpdateOptLock(ctx, pr, func(pr *types.PullReq) error {
|
pr, err = c.pullreqStore.UpdateOptLock(ctx, pr, func(pr *types.PullReq) error {
|
||||||
@ -219,7 +224,7 @@ func (c *Controller) Merge(
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.MergeResponse{}, fmt.Errorf("failed to update pull request: %w", err)
|
return nil, nil, fmt.Errorf("failed to update pull request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
activityPayload := &types.PullRequestActivityPayloadMerge{
|
activityPayload := &types.PullRequestActivityPayloadMerge{
|
||||||
@ -255,9 +260,9 @@ func (c *Controller) Merge(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.MergeResponse{
|
return &types.MergeResponse{
|
||||||
SHA: sha,
|
SHA: mergeOutput.MergeSHA,
|
||||||
BranchDeleted: branchDeleted,
|
BranchDeleted: branchDeleted,
|
||||||
RuleViolations: violations,
|
RuleViolations: violations,
|
||||||
}, nil
|
}, nil, nil
|
||||||
}
|
}
|
||||||
|
@ -57,20 +57,20 @@ func (c *Controller) CommitFiles(ctx context.Context,
|
|||||||
session *auth.Session,
|
session *auth.Session,
|
||||||
repoRef string,
|
repoRef string,
|
||||||
in *CommitFilesOptions,
|
in *CommitFilesOptions,
|
||||||
) (types.CommitFilesResponse, error) {
|
) (types.CommitFilesResponse, []types.RuleViolations, error) {
|
||||||
repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoPush, false)
|
repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoPush, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, err
|
return types.CommitFilesResponse{}, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
isSpaceOwner, err := apiauth.IsSpaceAdmin(ctx, c.authorizer, session, repo)
|
isSpaceOwner, err := apiauth.IsSpaceAdmin(ctx, c.authorizer, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, err
|
return types.CommitFilesResponse{}, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
protectionRules, err := c.protectionManager.ForRepository(ctx, repo.ID)
|
protectionRules, err := c.protectionManager.ForRepository(ctx, repo.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{},
|
return types.CommitFilesResponse{}, nil,
|
||||||
fmt.Errorf("failed to fetch protection rules for the repository: %w", err)
|
fmt.Errorf("failed to fetch protection rules for the repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,11 +93,11 @@ func (c *Controller) CommitFiles(ctx context.Context,
|
|||||||
RefNames: []string{branchName},
|
RefNames: []string{branchName},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, fmt.Errorf("failed to verify protection rules for git push: %w", err)
|
return types.CommitFilesResponse{}, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if protection.IsCritical(violations) {
|
if protection.IsCritical(violations) {
|
||||||
return types.CommitFilesResponse{RuleViolations: violations}, nil
|
return types.CommitFilesResponse{}, violations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
actions := make([]gitrpc.CommitFileAction, len(in.Actions))
|
actions := make([]gitrpc.CommitFileAction, len(in.Actions))
|
||||||
@ -107,7 +107,7 @@ func (c *Controller) CommitFiles(ctx context.Context,
|
|||||||
case enum.ContentEncodingTypeBase64:
|
case enum.ContentEncodingTypeBase64:
|
||||||
rawPayload, err = base64.StdEncoding.DecodeString(action.Payload)
|
rawPayload, err = base64.StdEncoding.DecodeString(action.Payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, fmt.Errorf("failed to decode base64 payload: %w", err)
|
return types.CommitFilesResponse{}, nil, fmt.Errorf("failed to decode base64 payload: %w", err)
|
||||||
}
|
}
|
||||||
case enum.ContentEncodingTypeUTF8:
|
case enum.ContentEncodingTypeUTF8:
|
||||||
fallthrough
|
fallthrough
|
||||||
@ -127,7 +127,7 @@ func (c *Controller) CommitFiles(ctx context.Context,
|
|||||||
// Create internal write params. Note: This will skip the pre-commit protection rules check.
|
// Create internal write params. Note: This will skip the pre-commit protection rules check.
|
||||||
writeParams, err := controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, repo)
|
writeParams, err := controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, fmt.Errorf("failed to create RPC write params: %w", err)
|
return types.CommitFilesResponse{}, nil, fmt.Errorf("failed to create RPC write params: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@ -144,9 +144,10 @@ func (c *Controller) CommitFiles(ctx context.Context,
|
|||||||
AuthorDate: &now,
|
AuthorDate: &now,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, err
|
return types.CommitFilesResponse{}, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.CommitFilesResponse{
|
return types.CommitFilesResponse{
|
||||||
CommitID: commit.CommitID,
|
CommitID: commit.CommitID,
|
||||||
}, nil
|
}, nil, nil
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,15 @@ func HandleMerge(pullreqCtrl *pullreq.Controller) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pr, err := pullreqCtrl.Merge(ctx, session, repoRef, pullreqNumber, in)
|
pr, violation, err := pullreqCtrl.Merge(ctx, session, repoRef, pullreqNumber, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
render.TranslatedUserError(w, err)
|
render.TranslatedUserError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if violation != nil {
|
||||||
|
render.Unprocessable(w, violation)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
render.JSON(w, http.StatusOK, pr)
|
render.JSON(w, http.StatusOK, pr)
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,15 @@ func HandleCommitFiles(repoCtrl *repo.Controller) http.HandlerFunc {
|
|||||||
render.BadRequestf(w, "Invalid request body: %s.", err)
|
render.BadRequestf(w, "Invalid request body: %s.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response, err := repoCtrl.CommitFiles(ctx, session, repoRef, in)
|
response, violations, err := repoCtrl.CommitFiles(ctx, session, repoRef, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
render.TranslatedUserError(w, err)
|
render.TranslatedUserError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if violations != nil {
|
||||||
|
render.Violations(w, violations)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
render.JSON(w, http.StatusOK, response)
|
render.JSON(w, http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
@ -456,6 +456,7 @@ func pullReqOperations(reflector *openapi3.Reflector) {
|
|||||||
_ = reflector.SetJSONResponse(&reviewSubmit, new(usererror.Error), http.StatusForbidden)
|
_ = reflector.SetJSONResponse(&reviewSubmit, new(usererror.Error), http.StatusForbidden)
|
||||||
_ = reflector.Spec.AddOperation(http.MethodPost,
|
_ = reflector.Spec.AddOperation(http.MethodPost,
|
||||||
"/repos/{repo_ref}/pullreq/{pullreq_number}/reviews", reviewSubmit)
|
"/repos/{repo_ref}/pullreq/{pullreq_number}/reviews", reviewSubmit)
|
||||||
|
|
||||||
mergePullReqOp := openapi3.Operation{}
|
mergePullReqOp := openapi3.Operation{}
|
||||||
mergePullReqOp.WithTags("pullreq")
|
mergePullReqOp.WithTags("pullreq")
|
||||||
mergePullReqOp.WithMapOfAnything(map[string]interface{}{"operationId": "mergePullReqOp"})
|
mergePullReqOp.WithMapOfAnything(map[string]interface{}{"operationId": "mergePullReqOp"})
|
||||||
@ -467,7 +468,7 @@ func pullReqOperations(reflector *openapi3.Reflector) {
|
|||||||
_ = reflector.SetJSONResponse(&mergePullReqOp, new(usererror.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&mergePullReqOp, new(usererror.Error), http.StatusNotFound)
|
||||||
_ = reflector.SetJSONResponse(&mergePullReqOp, new(usererror.Error), http.StatusMethodNotAllowed)
|
_ = reflector.SetJSONResponse(&mergePullReqOp, new(usererror.Error), http.StatusMethodNotAllowed)
|
||||||
_ = reflector.SetJSONResponse(&mergePullReqOp, new(usererror.Error), http.StatusConflict)
|
_ = reflector.SetJSONResponse(&mergePullReqOp, new(usererror.Error), http.StatusConflict)
|
||||||
_ = reflector.SetJSONResponse(&mergePullReqOp, new(usererror.Error), http.StatusUnprocessableEntity)
|
_ = reflector.SetJSONResponse(&mergePullReqOp, new(types.MergeViolations), http.StatusUnprocessableEntity)
|
||||||
_ = reflector.Spec.AddOperation(http.MethodPost,
|
_ = reflector.Spec.AddOperation(http.MethodPost,
|
||||||
"/repos/{repo_ref}/pullreq/{pullreq_number}/merge", mergePullReqOp)
|
"/repos/{repo_ref}/pullreq/{pullreq_number}/merge", mergePullReqOp)
|
||||||
|
|
||||||
|
@ -689,6 +689,7 @@ func repoOperations(reflector *openapi3.Reflector) {
|
|||||||
_ = reflector.SetJSONResponse(&opCommitFiles, new(usererror.Error), http.StatusUnauthorized)
|
_ = reflector.SetJSONResponse(&opCommitFiles, new(usererror.Error), http.StatusUnauthorized)
|
||||||
_ = reflector.SetJSONResponse(&opCommitFiles, new(usererror.Error), http.StatusForbidden)
|
_ = reflector.SetJSONResponse(&opCommitFiles, new(usererror.Error), http.StatusForbidden)
|
||||||
_ = reflector.SetJSONResponse(&opCommitFiles, new(usererror.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&opCommitFiles, new(usererror.Error), http.StatusNotFound)
|
||||||
|
_ = reflector.SetJSONResponse(&opCommitFiles, new(types.RulesViolations), http.StatusUnprocessableEntity)
|
||||||
_ = reflector.Spec.AddOperation(http.MethodPost, "/repos/{repo_ref}/commits", opCommitFiles)
|
_ = reflector.Spec.AddOperation(http.MethodPost, "/repos/{repo_ref}/commits", opCommitFiles)
|
||||||
|
|
||||||
opDiff := openapi3.Operation{}
|
opDiff := openapi3.Operation{}
|
||||||
|
@ -65,12 +65,7 @@ func BadRequest(w http.ResponseWriter) {
|
|||||||
UserError(w, usererror.ErrBadRequest)
|
UserError(w, usererror.ErrBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BadRequestError writes the json-encoded error with a bad request status code.
|
// BadRequestf writes the json-encoded message with a bad request status code.
|
||||||
func BadRequestError(w http.ResponseWriter, err *usererror.Error) {
|
|
||||||
UserError(w, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BadRequest writes the json-encoded message with a bad request status code.
|
|
||||||
func BadRequestf(w http.ResponseWriter, format string, args ...interface{}) {
|
func BadRequestf(w http.ResponseWriter, format string, args ...interface{}) {
|
||||||
ErrorMessagef(w, http.StatusBadRequest, format, args...)
|
ErrorMessagef(w, http.StatusBadRequest, format, args...)
|
||||||
}
|
}
|
||||||
@ -98,21 +93,9 @@ func DeleteSuccessful(w http.ResponseWriter) {
|
|||||||
// JSON writes the json-encoded value to the response
|
// JSON writes the json-encoded value to the response
|
||||||
// with the provides status.
|
// with the provides status.
|
||||||
func JSON(w http.ResponseWriter, code int, v interface{}) {
|
func JSON(w http.ResponseWriter, code int, v interface{}) {
|
||||||
// set common headers
|
setCommonHeaders(w)
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
||||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
||||||
|
|
||||||
// flush the headers - before body or status will be 200 OK
|
|
||||||
w.WriteHeader(code)
|
w.WriteHeader(code)
|
||||||
|
writeJSON(w, v)
|
||||||
// write body
|
|
||||||
enc := json.NewEncoder(w)
|
|
||||||
if indent { // is this necessary? it will affect performance
|
|
||||||
enc.SetIndent("", " ")
|
|
||||||
}
|
|
||||||
if err := enc.Encode(v); err != nil {
|
|
||||||
log.Err(err).Msgf("Failed to write json encoding to response body.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reader reads the content from the provided reader and writes it as is to the response body.
|
// Reader reads the content from the provided reader and writes it as is to the response body.
|
||||||
@ -157,8 +140,7 @@ func JSONArrayDynamic[T comparable](ctx context.Context, w http.ResponseWriter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
setCommonHeaders(w)
|
||||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
_, _ = w.Write([]byte{'['})
|
_, _ = w.Write([]byte{'['})
|
||||||
} else {
|
} else {
|
||||||
@ -176,3 +158,28 @@ func JSONArrayDynamic[T comparable](ctx context.Context, w http.ResponseWriter,
|
|||||||
|
|
||||||
_, _ = w.Write([]byte{']'})
|
_, _ = w.Write([]byte{']'})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Unprocessable(w http.ResponseWriter, v any) {
|
||||||
|
JSON(w, http.StatusUnprocessableEntity, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Violations(w http.ResponseWriter, violations []types.RuleViolations) {
|
||||||
|
Unprocessable(w, types.RulesViolations{
|
||||||
|
Violations: violations,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func setCommonHeaders(w http.ResponseWriter) {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeJSON(w http.ResponseWriter, v any) {
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
if indent {
|
||||||
|
enc.SetIndent("", " ")
|
||||||
|
}
|
||||||
|
if err := enc.Encode(v); err != nil {
|
||||||
|
log.Err(err).Msgf("Failed to write json encoding to response body.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,6 +16,5 @@ package types
|
|||||||
|
|
||||||
// CommitFilesResponse holds commit id.
|
// CommitFilesResponse holds commit id.
|
||||||
type CommitFilesResponse struct {
|
type CommitFilesResponse struct {
|
||||||
CommitID string `json:"commit_id"`
|
CommitID string `json:"commit_id"`
|
||||||
RuleViolations []RuleViolations `json:"rule_violations,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
@ -144,3 +144,8 @@ type MergeResponse struct {
|
|||||||
ConflictFiles []string `json:"conflict_files,omitempty"`
|
ConflictFiles []string `json:"conflict_files,omitempty"`
|
||||||
RuleViolations []RuleViolations `json:"rule_violations,omitempty"`
|
RuleViolations []RuleViolations `json:"rule_violations,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MergeViolations struct {
|
||||||
|
ConflictFiles []string `json:"conflict_files,omitempty"`
|
||||||
|
RuleViolations []RuleViolations `json:"rule_violations,omitempty"`
|
||||||
|
}
|
||||||
|
@ -102,3 +102,7 @@ type RuleInfoInternal struct {
|
|||||||
Pattern json.RawMessage
|
Pattern json.RawMessage
|
||||||
Definition json.RawMessage
|
Definition json.RawMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RulesViolations struct {
|
||||||
|
Violations []RuleViolations `json:"violations"`
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user