diff options
author | Lauris BH <lauris@nix.lv> | 2020-09-04 18:37:37 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-04 11:37:37 -0400 |
commit | e710a3498129a53343e08279012ea9c45988349f (patch) | |
tree | ad353035dbb8a1b3bbebe29f043c92bc150f29ba /modules/repofiles | |
parent | 4c557eff5d4002299dd8a9dfca7917084c2307f6 (diff) | |
download | gitea-e710a3498129a53343e08279012ea9c45988349f.tar.gz gitea-e710a3498129a53343e08279012ea9c45988349f.zip |
Add spent time to referenced issue in commit message (#12220)
Diffstat (limited to 'modules/repofiles')
-rw-r--r-- | modules/repofiles/action.go | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/modules/repofiles/action.go b/modules/repofiles/action.go index 464249d19b..05e9fc958d 100644 --- a/modules/repofiles/action.go +++ b/modules/repofiles/action.go @@ -8,7 +8,10 @@ import ( "encoding/json" "fmt" "html" + "regexp" + "strconv" "strings" + "time" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" @@ -19,6 +22,16 @@ import ( "code.gitea.io/gitea/modules/setting" ) +const ( + secondsByMinute = float64(time.Minute / time.Second) // seconds in a minute + secondsByHour = 60 * secondsByMinute // seconds in an hour + secondsByDay = 8 * secondsByHour // seconds in a day + secondsByWeek = 5 * secondsByDay // seconds in a week + secondsByMonth = 4 * secondsByWeek // seconds in a month +) + +var reDuration = regexp.MustCompile(`(?i)^(?:(\d+([\.,]\d+)?)(?:mo))?(?:(\d+([\.,]\d+)?)(?:w))?(?:(\d+([\.,]\d+)?)(?:d))?(?:(\d+([\.,]\d+)?)(?:h))?(?:(\d+([\.,]\d+)?)(?:m))?$`) + // getIssueFromRef returns the issue referenced by a ref. Returns a nil *Issue // if the provided ref references a non-existent issue. func getIssueFromRef(repo *models.Repository, index int64) (*models.Issue, error) { @@ -32,6 +45,60 @@ func getIssueFromRef(repo *models.Repository, index int64) (*models.Issue, error return issue, nil } +// timeLogToAmount parses time log string and returns amount in seconds +func timeLogToAmount(str string) int64 { + matches := reDuration.FindAllStringSubmatch(str, -1) + if len(matches) == 0 { + return 0 + } + + match := matches[0] + + var a int64 + + // months + if len(match[1]) > 0 { + mo, _ := strconv.ParseFloat(strings.Replace(match[1], ",", ".", 1), 64) + a += int64(mo * secondsByMonth) + } + + // weeks + if len(match[3]) > 0 { + w, _ := strconv.ParseFloat(strings.Replace(match[3], ",", ".", 1), 64) + a += int64(w * secondsByWeek) + } + + // days + if len(match[5]) > 0 { + d, _ := strconv.ParseFloat(strings.Replace(match[5], ",", ".", 1), 64) + a += int64(d * secondsByDay) + } + + // hours + if len(match[7]) > 0 { + h, _ := strconv.ParseFloat(strings.Replace(match[7], ",", ".", 1), 64) + a += int64(h * secondsByHour) + } + + // minutes + if len(match[9]) > 0 { + d, _ := strconv.ParseFloat(strings.Replace(match[9], ",", ".", 1), 64) + a += int64(d * secondsByMinute) + } + + return a +} + +func issueAddTime(issue *models.Issue, doer *models.User, time time.Time, timeLog string) error { + amount := timeLogToAmount(timeLog) + if amount == 0 { + return nil + } + + _, err := models.AddTime(doer, issue, amount, time) + return err +} + func changeIssueStatus(repo *models.Repository, issue *models.Issue, doer *models.User, closed bool) error { stopTimerIfAvailable := func(doer *models.User, issue *models.Issue) error { @@ -139,6 +206,11 @@ func UpdateIssuesCommit(doer *models.User, repo *models.Repository, commits []*r } } close := (ref.Action == references.XRefActionCloses) + if close && len(ref.TimeLog) > 0 { + if err := issueAddTime(refIssue, doer, c.Timestamp, ref.TimeLog); err != nil { + return err + } + } if close != refIssue.IsClosed { if err := changeIssueStatus(refRepo, refIssue, doer, close); err != nil { return err |