From d211e576ba8323b803223f7cc1574952501e0072 Mon Sep 17 00:00:00 2001
From: zzjc1234 <2359047351@qq.com>
Date: Tue, 8 Oct 2024 10:26:57 +0800
Subject: [PATCH] feat: get release tag from msg scope

---
 cmd/repo-health-checker/main.go |  6 ++--
 pkg/healthcheck/tag.go          | 57 ++++++++++++++++++++++-----------
 2 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/cmd/repo-health-checker/main.go b/cmd/repo-health-checker/main.go
index 1cc28aa..8a6eb81 100644
--- a/cmd/repo-health-checker/main.go
+++ b/cmd/repo-health-checker/main.go
@@ -41,13 +41,11 @@ var Version string
 func main() {
 	var gitWhitelist, metaFile []string
 	showVersion := flag.Bool("version", false, "print current version")
+	checkRelease := flag.Bool("checkRelease", false, "trigger release check")
 	rootDir := flag.String("root", "", "")
 	repo := flag.String("repo", "", "")
 	localList := flag.String("localList", "", "")
 	droneBranch := flag.String("droneBranch", "", "")
-	releaseCategories := flag.String("releaseCategories", "", "")
-	releaseNumber := flag.Int("releaseNumber", 0, "")
-	mileStoneNumber := flag.Int("mileStoneNumber", 0, "")
 	checkFileNameList := flag.String("checkFileNameList", "", "Comma-separated list of files to check.")
 	checkFileSumList := flag.String("checkFileSumList", "", "Comma-separated list of expected checksums.")
 	parseMultiValueFlag(&gitWhitelist, "whitelist", "")
@@ -79,7 +77,7 @@ func main() {
 	if err != nil {
 		fmt.Printf("### Non-ASCII Characters Commit Message Check Failed:\n%s\n", err.Error())
 	}
-	err = healthcheck.CheckTags(*rootDir, *releaseCategories, *releaseNumber, *mileStoneNumber)
+	err = healthcheck.CheckTags(*rootDir, *checkRelease)
 	if err != nil {
 		fmt.Printf("### Release Tag Check Failed:\n%s\n", err.Error())
 	}
diff --git a/pkg/healthcheck/tag.go b/pkg/healthcheck/tag.go
index ee94f46..a682d29 100644
--- a/pkg/healthcheck/tag.go
+++ b/pkg/healthcheck/tag.go
@@ -2,12 +2,42 @@ package healthcheck
 
 import (
 	"fmt"
+	"regexp"
 	"strings"
 
 	"github.com/go-git/go-git/v5"
 	"github.com/go-git/go-git/v5/plumbing"
+	"github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
 )
 
+func parseConventionalCommit(commit string) (*conf.ConventionalCommit, error) {
+	re := regexp.MustCompile(`(?s)^(\w+)(\(([^)]+)\))?!?: (.+?)(\n\n(.+?))?(\n\n(.+))?$`)
+	matches := re.FindStringSubmatch(strings.TrimSpace(commit))
+	if matches == nil {
+		return nil, fmt.Errorf("invalid conventional commit format")
+	}
+	cc := &conf.ConventionalCommit{
+		Type:        matches[1],
+		Scope:       matches[3],
+		Description: strings.TrimSpace(matches[4]),
+		Body:        strings.TrimSpace(matches[6]),
+		Footer:      strings.TrimSpace(matches[8]),
+	}
+	return cc, nil
+}
+
+func getTagFromMsg() (tag string, err error) {
+	msg, err := conf.GetCommitMsg()
+	if err != nil {
+		return "", err
+	}
+	conventionalCommit, err := parseConventionalCommit(msg)
+	if err != nil {
+		return "", err
+	}
+	return conventionalCommit.Scope, err
+}
+
 func getTagsFromRepo(repoPath string) ([]string, error) {
 	repo, err := git.PlainOpen(repoPath)
 	if err != nil {
@@ -31,29 +61,18 @@ func getTagsFromRepo(repoPath string) ([]string, error) {
 	return tags, nil
 }
 
-func CheckTags(repoPath string, category string, n int, m int) error {
-	// INFO: if category not specified, skipping this check by default
-	if category == "" {
+func CheckTags(repoPath string, skip bool) error {
+	if skip {
 		return nil
 	}
 	tags, err := getTagsFromRepo(repoPath)
 	if err != nil {
-		return fmt.Errorf("error getting tags: %v", err)
+		return fmt.Errorf("error getting tags from repo: %v", err)
 	}
-	var prefix string
-	switch category {
-	case "exam":
-		prefix = "e"
-	case "project":
-		prefix = "p"
-	case "homework":
-		prefix = "h"
-	default:
-		prefix = "a"
-	}
-	target := prefix + fmt.Sprintf("%d", n)
-	if category == "project" {
-		target += fmt.Sprintf("m%d", m)
+
+	target, err := getTagFromMsg()
+	if err != nil {
+		return fmt.Errorf("error getting tag from msg scope: %v", err)
 	}
 	found := false
 	for _, tag := range tags {
@@ -63,7 +82,7 @@ func CheckTags(repoPath string, category string, n int, m int) error {
 		}
 	}
 	if !found {
-		return fmt.Errorf("Wrong release tag '%s' or missing release tags. Please use one of '%s'.", strings.Join(tags, "', '"), target)
+		return fmt.Errorf("Wrong release tag '%s' or missing release tags. Please use one of '%s'.", target, strings.Join(tags, "', '"))
 	}
 	return nil
 }