fix: match stage groups exactly

This commit is contained in:
张泊明518370910136 2026-08-02 00:38:20 -07:00
parent 100b04b876
commit 0a5947f45e
GPG Key ID: D47306D7062CDA9D
3 changed files with 22 additions and 3 deletions

View File

@ -100,6 +100,7 @@ Here are the steps `joj3` will run.
3. Generate stages.
- We have an empty list of stages at the beginning.
- We check all the stages from the configuration file. Stages with empty `group` field will always be added. Stages with non-empty `group` field requires that value (case insensitive) appears in the commit group. e.g. with commit msg `feat(h5/e3): joj msan [joj]`, stages with the following `group` field will run: `""`, `"joj"`. Currently, it does not support multiple groups within one commit. If the group specified in the commit message is `[all]`, then all groups will run.
- Groups are matched as case-insensitive, comma/space/semicolon/pipe-separated tokens. For example, `[joj, lint]` selects the `joj` and `lint` groups without substring matching.
- Every stage needs to have an unique `name`, which means if two stages have the same name, only the first one will be added.
4. Run stages.
- By default, all the stages will run sequentially.

View File

@ -201,8 +201,13 @@ func GetConfPath(confRoot, confName, fallbackConfName, msg, tag string) (
func MatchGroups(conf *Conf, conventionalCommit *ConventionalCommit) []string {
seen := make(map[string]bool)
keywords := []string{}
loweredCommitGroup := strings.ToLower(conventionalCommit.Group)
matchAllGroups := loweredCommitGroup == "all"
requestedGroups := make(map[string]bool)
for _, group := range strings.FieldsFunc(conventionalCommit.Group, func(r rune) bool {
return r == ',' || r == ';' || r == '|' || r == ' ' || r == '\t'
}) {
requestedGroups[strings.ToLower(group)] = true
}
matchAllGroups := requestedGroups["all"]
confStages := []ConfStage{}
confStages = append(confStages, conf.PreStages...)
confStages = append(confStages, conf.Stages...)
@ -221,7 +226,7 @@ func MatchGroups(conf *Conf, conventionalCommit *ConventionalCommit) []string {
slog.Info("group keywords from stages", "keywords", keywords)
groups := []string{}
for _, keyword := range keywords {
if matchAllGroups || strings.Contains(loweredCommitGroup, keyword) {
if matchAllGroups || requestedGroups[keyword] {
groups = append(groups, keyword)
}
}

View File

@ -130,3 +130,16 @@ func TestParseConventionalCommit(t *testing.T) {
})
}
}
func TestMatchGroupsUsesExactTokens(t *testing.T) {
conf := &Conf{Stages: []ConfStage{
{Name: "short", Groups: []string{"c"}},
{Name: "cpp", Groups: []string{"cpp"}},
{Name: "lint", Groups: []string{"lint"}},
}}
got := MatchGroups(conf, &ConventionalCommit{Group: "cpp, lint"})
want := []string{"cpp", "lint"}
if !reflect.DeepEqual(got, want) {
t.Fatalf("MatchGroups() = %v, want %v", got, want)
}
}