You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by wa...@apache.org on 2022/06/10 03:43:05 UTC

[incubator-devlake] 04/06: feat: add order type semver

This is an automated email from the ASF dual-hosted git repository.

warren pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git

commit 2b15cefc6b94212cf8ea3337eb1b467a2a1b0286
Author: Nddtfjiang <jz...@qq.com>
AuthorDate: Wed Jun 8 13:52:04 2022 +0000

    feat: add order type semver
    
    Add tagOrder rule semver
    Add tagOrder rule reverse semver
    CaculateTagPattern now only run once in PrepareTaskData.
    
    Nddtfjiang <zh...@merico.dev>
---
 plugins/refdiff/README.md                          |  4 +-
 plugins/refdiff/refdiff.go                         | 10 +++
 .../refdiff/tasks/ref_commit_diff_calculator.go    | 14 +---
 plugins/refdiff/tasks/ref_issue_diff_calculator.go | 14 +---
 plugins/refdiff/tasks/refdiff_task_data.go         | 77 ++++++++++++++++++----
 5 files changed, 84 insertions(+), 35 deletions(-)

diff --git a/plugins/refdiff/README.md b/plugins/refdiff/README.md
index 3c065aea..1db6a4d2 100644
--- a/plugins/refdiff/README.md
+++ b/plugins/refdiff/README.md
@@ -85,7 +85,7 @@ and if you want to perform certain subtasks.
 ]
 ```
 Or you can use tagsPattern to match the tags you want
-And you can use tagOrder (support `alphabetically` and `reverse alphabetically`) to set the order rule with tagLimit to limit the count of matching.
+And you can use tagOrder (support `alphabetically`,`reverse alphabetically`,`semver`,`reverse semver`) to set the order rule with tagLimit to limit the count of matching.
 This is support to calculateCommitsDiff and calculateIssuesDiff
 ```json
 [
@@ -100,7 +100,7 @@ This is support to calculateCommitsDiff and calculateIssuesDiff
         "repoId": "github:GithubRepo:384111310",
         "tagsPattern":".*\\.11\\..*",
         "tagLimit":3,
-        "tagOrder":"reverse alphabetically",
+        "tagOrder":"reverse semver",
       }
     }
   ]
diff --git a/plugins/refdiff/refdiff.go b/plugins/refdiff/refdiff.go
index c9c3b9d0..8fb502e1 100644
--- a/plugins/refdiff/refdiff.go
+++ b/plugins/refdiff/refdiff.go
@@ -64,6 +64,16 @@ func (plugin RefDiff) PrepareTaskData(taskCtx core.TaskContext, options map[stri
 		return nil, err
 	}
 
+	db := taskCtx.GetDb()
+	tagsPattern := op.TagsPattern
+	tagsLimit := op.TagsLimit
+	tagsOrder := op.TagsOrder
+
+	op.TagsRefs, err = tasks.CaculateTagPattern(db, tagsPattern, tagsLimit, tagsOrder)
+	if err != nil {
+		return nil, err
+	}
+
 	return &tasks.RefdiffTaskData{
 		Options: &op,
 	}, nil
diff --git a/plugins/refdiff/tasks/ref_commit_diff_calculator.go b/plugins/refdiff/tasks/ref_commit_diff_calculator.go
index 606d1462..7e2b3504 100644
--- a/plugins/refdiff/tasks/ref_commit_diff_calculator.go
+++ b/plugins/refdiff/tasks/ref_commit_diff_calculator.go
@@ -32,19 +32,11 @@ func CalculateCommitsPairs(taskCtx core.SubTaskContext) (RefCommitPairs, error)
 	data := taskCtx.GetData().(*RefdiffTaskData)
 	repoId := data.Options.RepoId
 	pairs := data.Options.Pairs
-	tagsLimit := data.Options.TagsLimit
+	rs := data.Options.TagsRefs
 	db := taskCtx.GetDb()
 
-	rs, err := CaculateTagPattern(taskCtx)
-	if err != nil {
-		return RefCommitPairs{}, err
-	}
-	if tagsLimit > rs.Len() {
-		tagsLimit = rs.Len()
-	}
-
-	commitPairs := make(RefCommitPairs, 0, tagsLimit+len(pairs))
-	for i := 1; i < tagsLimit; i++ {
+	commitPairs := make(RefCommitPairs, 0, len(rs)+len(pairs))
+	for i := 1; i < len(rs); i++ {
 		commitPairs = append(commitPairs, [4]string{rs[i-1].CommitSha, rs[i].CommitSha, rs[i-1].Name, rs[i].Name})
 	}
 
diff --git a/plugins/refdiff/tasks/ref_issue_diff_calculator.go b/plugins/refdiff/tasks/ref_issue_diff_calculator.go
index aed0f4e8..3f6809f5 100644
--- a/plugins/refdiff/tasks/ref_issue_diff_calculator.go
+++ b/plugins/refdiff/tasks/ref_issue_diff_calculator.go
@@ -31,18 +31,10 @@ func CaculatePairList(taskCtx core.SubTaskContext) (RefPairLists, error) {
 	data := taskCtx.GetData().(*RefdiffTaskData)
 	repoId := data.Options.RepoId
 	pairs := data.Options.Pairs
-	tagsLimit := data.Options.TagsLimit
+	rs := data.Options.TagsRefs
 
-	rs, err := CaculateTagPattern(taskCtx)
-	if err != nil {
-		return RefPairLists{}, err
-	}
-	if tagsLimit > rs.Len() {
-		tagsLimit = rs.Len()
-	}
-
-	pairList := make(RefPairLists, 0, tagsLimit+len(pairs))
-	for i := 1; i < tagsLimit; i++ {
+	pairList := make(RefPairLists, 0, len(rs)+len(pairs))
+	for i := 1; i < len(rs); i++ {
 		pairList = append(pairList, RefPairList{fmt.Sprintf("%s:%s", repoId, rs[i-1].Id), fmt.Sprintf("%s:%s", repoId, rs[i].Id)})
 	}
 
diff --git a/plugins/refdiff/tasks/refdiff_task_data.go b/plugins/refdiff/tasks/refdiff_task_data.go
index ad36b2c1..37781308 100644
--- a/plugins/refdiff/tasks/refdiff_task_data.go
+++ b/plugins/refdiff/tasks/refdiff_task_data.go
@@ -21,10 +21,11 @@ import (
 	"fmt"
 	"regexp"
 	"sort"
+	"strings"
 	"time"
 
 	"github.com/apache/incubator-devlake/models/domainlayer/code"
-	"github.com/apache/incubator-devlake/plugins/core"
+	"gorm.io/gorm"
 )
 
 type RefdiffOptions struct {
@@ -32,9 +33,10 @@ type RefdiffOptions struct {
 	Tasks  []string `json:"tasks,omitempty"`
 	Pairs  []RefPair
 
-	TagsPattern string // The Pattern to match from all tags
-	TagsLimit   int    // How many tags be matched should be used.
-	TagsOrder   string // The Rule to Order the tag list
+	TagsPattern string     // The Pattern to match from all tags
+	TagsLimit   int        // How many tags be matched should be used.
+	TagsOrder   string     // The Rule to Order the tag list
+	TagsRefs    []code.Ref // Caculate out by TagsPattern TagsLimit TagsOrder from db
 }
 
 type RefdiffTaskData struct {
@@ -54,6 +56,8 @@ type RefPairLists []RefPairList
 type Refs []code.Ref
 type RefsAlphabetically Refs
 type RefsReverseAlphabetically Refs
+type RefsSemver Refs
+type RefsReverseSemver Refs
 
 func (rs Refs) Len() int {
 	return len(rs)
@@ -83,16 +87,58 @@ func (rs RefsReverseAlphabetically) Swap(i, j int) {
 	rs[i], rs[j] = rs[j], rs[i]
 }
 
+func (rs RefsSemver) Len() int {
+	return len(rs)
+}
+
+func (rs RefsSemver) Less(i, j int) bool {
+	parti := strings.Split(rs[i].Name, ".")
+	partj := strings.Split(rs[j].Name, ".")
+
+	for k := 0; k < len(partj); k++ {
+		if k >= len(parti) {
+			return true
+		}
+
+		if len(parti[k]) < len(partj[k]) {
+			return true
+		}
+		if len(parti[k]) > len(partj[k]) {
+			return false
+		}
+
+		if parti[k] < partj[k] {
+			return true
+		}
+		if parti[k] > partj[k] {
+			return false
+		}
+	}
+	return false
+}
+
+func (rs RefsSemver) Swap(i, j int) {
+	rs[i], rs[j] = rs[j], rs[i]
+}
+
+func (rs RefsReverseSemver) Len() int {
+	return len(rs)
+}
+
+func (rs RefsReverseSemver) Less(i, j int) bool {
+	return RefsSemver(rs).Less(j, i)
+}
+
+func (rs RefsReverseSemver) Swap(i, j int) {
+	rs[i], rs[j] = rs[j], rs[i]
+}
+
 // Calculate the TagPattern order by tagsOrder and return the Refs
-func CaculateTagPattern(taskCtx core.SubTaskContext) (Refs, error) {
+func CaculateTagPattern(db *gorm.DB, tagsPattern string, tagsLimit int, tagsOrder string) (Refs, error) {
 	rs := Refs{}
-	data := taskCtx.GetData().(*RefdiffTaskData)
-	tagsPattern := data.Options.TagsPattern
-	tagsOrder := data.Options.TagsOrder
-	db := taskCtx.GetDb()
 
 	// caculate Pattern part
-	if data.Options.TagsPattern == "" || data.Options.TagsLimit <= 1 {
+	if tagsPattern == "" || tagsLimit <= 1 {
 		return rs, nil
 	}
 	rows, err := db.Model(&code.Ref{}).Order("created_date desc").Rows()
@@ -111,7 +157,7 @@ func CaculateTagPattern(taskCtx core.SubTaskContext) (Refs, error) {
 			return rs, err
 		}
 
-		if ok := r.Match([]byte(ref.Id)); ok {
+		if ok := r.Match([]byte(ref.Name)); ok {
 			rs = append(rs, ref)
 		}
 	}
@@ -120,8 +166,17 @@ func CaculateTagPattern(taskCtx core.SubTaskContext) (Refs, error) {
 		sort.Sort(RefsAlphabetically(rs))
 	case "reverse alphabetically":
 		sort.Sort(RefsReverseAlphabetically(rs))
+	case "semver":
+		sort.Sort(RefsSemver(rs))
+	case "reverse semver":
+		sort.Sort(RefsReverseSemver(rs))
 	default:
 		break
 	}
+
+	if tagsLimit < rs.Len() {
+		rs = rs[:tagsLimit]
+	}
+
 	return rs, nil
 }