1
0
mirror of https://github.com/go-gitea/gitea.git synced 2024-10-26 07:55:34 +03:00
This commit is contained in:
Lunny Xiao 2024-10-25 21:12:20 +00:00 committed by GitHub
commit 03da9bf16b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 29 deletions

View File

@ -11,12 +11,14 @@ import (
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
)
// ErrMilestoneNotExist represents a "MilestoneNotExist" kind of error.
@ -82,9 +84,18 @@ func (m *Milestone) BeforeUpdate() {
// AfterLoad is invoked from XORM after setting the value of a field of
// this object.
func (m *Milestone) AfterLoad() {
func (m *Milestone) AfterLoad(session *xorm.Session) {
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
if m.DeadlineUnix.Year() == 9999 {
if m.DeadlineUnix == 0 {
return
}
// for legacy reasons, all years after 9000 are considered as no deadline
if m.DeadlineUnix.Year() > 9000 {
m.DeadlineUnix = 0
m.IsOverdue = false
if _, err := session.ID(m.ID).NoAutoTime().Cols("deadline_unix", "is_overdue").Update(m); err != nil {
log.Error("AfterLoad update legacy deadline failed: %v", err)
}
return
}

View File

@ -7,7 +7,6 @@ package repo
import (
"net/http"
"strconv"
"time"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
@ -155,16 +154,16 @@ func CreateMilestone(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.CreateMilestoneOption)
if form.Deadline == nil {
defaultDeadline, _ := time.ParseInLocation("2006-01-02", "9999-12-31", time.Local)
form.Deadline = &defaultDeadline
var deadlineUnix int64
if form.Deadline != nil {
deadlineUnix = form.Deadline.Unix()
}
milestone := &issues_model.Milestone{
RepoID: ctx.Repo.Repository.ID,
Name: form.Title,
Content: form.Description,
DeadlineUnix: timeutil.TimeStamp(form.Deadline.Unix()),
DeadlineUnix: timeutil.TimeStamp(deadlineUnix),
}
if form.State == "closed" {

View File

@ -134,22 +134,24 @@ func NewMilestonePost(ctx *context.Context) {
return
}
if len(form.Deadline) == 0 {
form.Deadline = "9999-12-31"
}
deadline, err := time.ParseInLocation("2006-01-02", form.Deadline, time.Local)
if err != nil {
ctx.Data["Err_Deadline"] = true
ctx.RenderWithErr(ctx.Tr("repo.milestones.invalid_due_date_format"), tplMilestoneNew, &form)
return
var deadlineUnix int64
if len(form.Deadline) > 0 {
deadline, err := time.ParseInLocation("2006-01-02", form.Deadline, time.Local)
if err != nil {
ctx.Data["Err_Deadline"] = true
ctx.RenderWithErr(ctx.Tr("repo.milestones.invalid_due_date_format"), tplMilestoneNew, &form)
return
}
deadline = time.Date(deadline.Year(), deadline.Month(), deadline.Day(), 23, 59, 59, 0, deadline.Location())
deadlineUnix = deadline.Unix()
}
deadline = time.Date(deadline.Year(), deadline.Month(), deadline.Day(), 23, 59, 59, 0, deadline.Location())
if err = issues_model.NewMilestone(ctx, &issues_model.Milestone{
if err := issues_model.NewMilestone(ctx, &issues_model.Milestone{
RepoID: ctx.Repo.Repository.ID,
Name: form.Title,
Content: form.Content,
DeadlineUnix: timeutil.TimeStamp(deadline.Unix()),
DeadlineUnix: timeutil.TimeStamp(deadlineUnix),
}); err != nil {
ctx.ServerError("NewMilestone", err)
return
@ -194,17 +196,19 @@ func EditMilestonePost(ctx *context.Context) {
return
}
if len(form.Deadline) == 0 {
form.Deadline = "9999-12-31"
}
deadline, err := time.ParseInLocation("2006-01-02", form.Deadline, time.Local)
if err != nil {
ctx.Data["Err_Deadline"] = true
ctx.RenderWithErr(ctx.Tr("repo.milestones.invalid_due_date_format"), tplMilestoneNew, &form)
return
var deadlineUnix int64
if len(form.Deadline) > 0 {
deadline, err := time.ParseInLocation("2006-01-02", form.Deadline, time.Local)
if err != nil {
ctx.Data["Err_Deadline"] = true
ctx.RenderWithErr(ctx.Tr("repo.milestones.invalid_due_date_format"), tplMilestoneNew, &form)
return
}
deadline = time.Date(deadline.Year(), deadline.Month(), deadline.Day(), 23, 59, 59, 0, deadline.Location())
deadlineUnix = deadline.Unix()
}
deadline = time.Date(deadline.Year(), deadline.Month(), deadline.Day(), 23, 59, 59, 0, deadline.Location())
m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrMilestoneNotExist(err) {
@ -216,7 +220,7 @@ func EditMilestonePost(ctx *context.Context) {
}
m.Name = form.Title
m.Content = form.Content
m.DeadlineUnix = timeutil.TimeStamp(deadline.Unix())
m.DeadlineUnix = timeutil.TimeStamp(deadlineUnix)
if err = issues_model.UpdateMilestone(ctx, m, m.IsClosed); err != nil {
ctx.ServerError("UpdateMilestone", err)
return

View File

@ -260,7 +260,10 @@ func ToAPIMilestone(m *issues_model.Milestone) *api.Milestone {
if m.IsClosed {
apiMilestone.Closed = m.ClosedDateUnix.AsTimePtr()
}
if m.DeadlineUnix.Year() < 9999 {
// for legacy reasons, all years after 9000 are considered as no deadline
if m.DeadlineUnix.Year() > 9000 || m.DeadlineUnix == 0 {
apiMilestone.Deadline = nil
} else {
apiMilestone.Deadline = m.DeadlineUnix.AsTimePtr()
}
return apiMilestone

View File

@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"testing"
"time"
auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
@ -59,6 +60,7 @@ func TestAPIIssuesMilestone(t *testing.T) {
DecodeJSON(t, resp, &apiMilestone)
assert.Equal(t, "wow", apiMilestone.Title)
assert.Equal(t, structs.StateClosed, apiMilestone.State)
assert.Equal(t, (*time.Time)(nil), apiMilestone.Deadline)
var apiMilestones []structs.Milestone
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s", owner.Name, repo.Name, "all")).
@ -66,6 +68,7 @@ func TestAPIIssuesMilestone(t *testing.T) {
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiMilestones)
assert.Len(t, apiMilestones, 4)
assert.Equal(t, (*time.Time)(nil), apiMilestones[0].Deadline)
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%s", owner.Name, repo.Name, apiMilestones[2].Title)).
AddTokenAuth(token)