Skip to content

Commit 1462774

Browse files
Add support for pattern matching on allowed/ignored repo lists
This allows to use pattern matching on allowed/ignored repo lists instead of simple string comparison only. By default, string comparison is used. If pattern begins with "~", it's compiled as a regexp (excluding "~" character). The regexp pattern has added start of string anchor automatically, i.e. pattern "~apache.*" is compiled as "^apache.*". If pattern ends with "*", it's used as a wildcard and matches any repo starting with pattern excluding "*" character, i.e. pattern "apache-*" is equivalent to regexp "^apache-.*$".
1 parent 90d22b7 commit 1462774

File tree

1 file changed

+57
-10
lines changed

1 file changed

+57
-10
lines changed

newt/project/project.go

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"os"
2525
"path"
2626
"path/filepath"
27+
"regexp"
2728
"strings"
2829

2930
log "github.com/sirupsen/logrus"
@@ -72,11 +73,11 @@ type Project struct {
7273

7374
// Contains names of repositories that will be upgraded.
7475
// If it's empty all repos are allowed.
75-
reposAllowed []string
76+
reposAllowedRe []*regexp.Regexp
7677

7778
// Contains names of repositories that will be excluded from upgrade.
7879
// Can override repositories from reposAllowed.
79-
reposIgnored []string
80+
reposIgnoredRe []*regexp.Regexp
8081

8182
// The local repository at the top-level of the project. This repo is
8283
// excluded from most repo operations.
@@ -181,10 +182,21 @@ func NewProject(dir string, download bool) (*Project, error) {
181182
return proj, nil
182183
}
183184

185+
func (proj *Project) patternsMatch(patterns *[]*regexp.Regexp, repoName string) bool {
186+
for _, re := range *patterns {
187+
if re.MatchString(repoName) {
188+
return true
189+
}
190+
}
191+
192+
return false
193+
}
194+
184195
func (proj *Project) isRepoAllowed(repoName string) bool {
185-
if (len(proj.reposAllowed) == 0) || (util.SliceContains(proj.reposAllowed, repoName)) {
186-
return !util.SliceContains(proj.reposIgnored, repoName)
196+
if (len(proj.reposAllowedRe) == 0) || proj.patternsMatch(&proj.reposAllowedRe, repoName) {
197+
return !proj.patternsMatch(&proj.reposIgnoredRe, repoName)
187198
}
199+
188200
return false
189201
}
190202

@@ -641,6 +653,36 @@ func (proj *Project) addRepo(r *repo.Repo, download bool) error {
641653
return nil
642654
}
643655

656+
func (proj *Project) createRegexpPatterns(patterns []string) ([]*regexp.Regexp, error) {
657+
var ret []*regexp.Regexp
658+
var errLines []string
659+
660+
for _, pattern := range patterns {
661+
var s string
662+
663+
if strings.HasPrefix(pattern, "~") {
664+
s = "^" + pattern[1:]
665+
} else if strings.HasSuffix(pattern, "*") {
666+
s = "^" + pattern[:len(pattern)-1] + ".*$"
667+
} else {
668+
s = "^" + pattern + "$"
669+
}
670+
671+
re, err := regexp.Compile(s)
672+
if err != nil {
673+
errLines = append(errLines, fmt.Sprintf("Invalid pattern: %s", pattern))
674+
} else {
675+
ret = append(ret, re)
676+
}
677+
}
678+
679+
if len(errLines) > 0 {
680+
return ret, util.NewNewtError(strings.Join(errLines, "\n"))
681+
} else {
682+
return ret, nil
683+
}
684+
}
685+
644686
func (proj *Project) loadConfig(download bool) error {
645687
yc, err := config.ReadFile(proj.BasePath + "/" + PROJECT_FILE_NAME)
646688
if err != nil {
@@ -654,14 +696,19 @@ func (proj *Project) loadConfig(download bool) error {
654696
proj.name, err = yc.GetValString("project.name", nil)
655697
util.OneTimeWarningError(err)
656698

657-
proj.reposAllowed = make([]string, 0)
658-
proj.reposAllowed, err = yc.GetValStringSlice("project.repositories.allowed", nil)
699+
var reposAllowed []string
700+
var reposIgnored []string
701+
702+
reposAllowed, err = yc.GetValStringSlice("project.repositories.allowed", nil)
703+
util.OneTimeWarningError(err)
704+
proj.reposAllowedRe, err = proj.createRegexpPatterns(reposAllowed)
659705
util.OneTimeWarningError(err)
660706

661-
proj.reposIgnored = make([]string, 0)
662-
proj.reposIgnored, err = yc.GetValStringSlice("project.repositories.ignored", nil)
707+
reposIgnored, err = yc.GetValStringSlice("project.repositories.ignored", nil)
708+
util.OneTimeWarningError(err)
709+
reposIgnored = append(reposIgnored, newtutil.NewtIgnore...)
710+
proj.reposIgnoredRe, err = proj.createRegexpPatterns(reposIgnored)
663711
util.OneTimeWarningError(err)
664-
proj.reposIgnored = append(proj.reposIgnored, newtutil.NewtIgnore...)
665712

666713
if !proj.isRepoAllowed("apache-mynewt-core") {
667714
return util.NewNewtError("apache-mynewt-core repository must be allowed. " +
@@ -684,7 +731,7 @@ func (proj *Project) loadConfig(download bool) error {
684731
// and try to load it.
685732
for k, _ := range yc.AllSettings() {
686733
repoName := strings.TrimPrefix(k, "repository.")
687-
if repoName != k && !util.SliceContains(proj.reposIgnored, repoName) {
734+
if repoName != k {
688735
fields, err := yc.GetValStringMapString(k, nil)
689736
util.OneTimeWarningError(err)
690737

0 commit comments

Comments
 (0)