mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	Use CloseIssue and ReopenIssue instead of ChangeStatus (#32467)
				
					
				
			The behaviors of closing issues and reopening issues are very different. So splitting it into two different functions makes it easier to maintain. - [x] Split ChangeIssueStatus into CloseIssue and ReopenIssue both at the service layer and model layer - [x] Rename `isClosed` to `CloseOrReopen` to make it more readable. - [x] Add transactions for ReopenIssue and CloseIssue --------- Co-authored-by: Zettat123 <zettat123@gmail.com>
This commit is contained in:
		@@ -733,7 +733,7 @@ func CreateIssue(ctx *context.APIContext) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if form.Closed {
 | 
			
		||||
		if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", true); err != nil {
 | 
			
		||||
		if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil {
 | 
			
		||||
			if issues_model.IsErrDependenciesLeft(err) {
 | 
			
		||||
				ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
 | 
			
		||||
				return
 | 
			
		||||
@@ -912,27 +912,11 @@ func EditIssue(ctx *context.APIContext) {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var isClosed bool
 | 
			
		||||
		switch state := api.StateType(*form.State); state {
 | 
			
		||||
		case api.StateOpen:
 | 
			
		||||
			isClosed = false
 | 
			
		||||
		case api.StateClosed:
 | 
			
		||||
			isClosed = true
 | 
			
		||||
		default:
 | 
			
		||||
			ctx.Error(http.StatusPreconditionFailed, "UnknownIssueStateError", fmt.Sprintf("unknown state: %s", state))
 | 
			
		||||
		state := api.StateType(*form.State)
 | 
			
		||||
		closeOrReopenIssue(ctx, issue, state)
 | 
			
		||||
		if ctx.Written() {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if issue.IsClosed != isClosed {
 | 
			
		||||
			if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", isClosed); err != nil {
 | 
			
		||||
				if issues_model.IsErrDependenciesLeft(err) {
 | 
			
		||||
					ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Refetch from database to assign some automatic values
 | 
			
		||||
@@ -1055,3 +1039,26 @@ func UpdateIssueDeadline(ctx *context.APIContext) {
 | 
			
		||||
 | 
			
		||||
	ctx.JSON(http.StatusCreated, api.IssueDeadline{Deadline: deadlineUnix.AsTimePtr()})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func closeOrReopenIssue(ctx *context.APIContext, issue *issues_model.Issue, state api.StateType) {
 | 
			
		||||
	if state != api.StateOpen && state != api.StateClosed {
 | 
			
		||||
		ctx.Error(http.StatusPreconditionFailed, "UnknownIssueStateError", fmt.Sprintf("unknown state: %s", state))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if state == api.StateClosed && !issue.IsClosed {
 | 
			
		||||
		if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil {
 | 
			
		||||
			if issues_model.IsErrDependenciesLeft(err) {
 | 
			
		||||
				ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue or pull request because it still has open dependencies")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Error(http.StatusInternalServerError, "CloseIssue", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	} else if state == api.StateOpen && issue.IsClosed {
 | 
			
		||||
		if err := issue_service.ReopenIssue(ctx, issue, ctx.Doer, ""); err != nil {
 | 
			
		||||
			ctx.Error(http.StatusInternalServerError, "ReopenIssue", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -728,27 +728,11 @@ func EditPullRequest(ctx *context.APIContext) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var isClosed bool
 | 
			
		||||
		switch state := api.StateType(*form.State); state {
 | 
			
		||||
		case api.StateOpen:
 | 
			
		||||
			isClosed = false
 | 
			
		||||
		case api.StateClosed:
 | 
			
		||||
			isClosed = true
 | 
			
		||||
		default:
 | 
			
		||||
			ctx.Error(http.StatusPreconditionFailed, "UnknownPRStateError", fmt.Sprintf("unknown state: %s", state))
 | 
			
		||||
		state := api.StateType(*form.State)
 | 
			
		||||
		closeOrReopenIssue(ctx, issue, state)
 | 
			
		||||
		if ctx.Written() {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if issue.IsClosed != isClosed {
 | 
			
		||||
			if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", isClosed); err != nil {
 | 
			
		||||
				if issues_model.IsErrDependenciesLeft(err) {
 | 
			
		||||
					ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies")
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// change pull target branch
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user