Files
actions-sync/src/reponames.go
Bryan Hundven 67d84229a3 Filter comments in the list file as well as empty lines.
It's handy to have comments in the list file so that you describe to
other teams that may have different destination repos where to put
actions to sync.

closes #106

Signed-off-by: Bryan Hundven <bryanhundven@gmail.com>
2024-04-04 12:40:48 -07:00

132 lines
3.1 KiB
Go

package src
import (
"fmt"
"os"
"path"
"regexp"
"strings"
"github.com/pkg/errors"
)
var (
NwoRegExp = regexp.MustCompile(`^[^/\s]+/[^/\s]+$`)
ErrEmptyRepoList = errors.New("repo list cannot be empty")
ErrEmptyCacheDir = errors.New("cache directory contains no actions to sync")
)
func getRepoNamesFromRepoFlags(flags *CommonFlags) ([]string, error) {
if flags.RepoNameList != "" {
return getRepoNamesFromCSVString(flags.RepoNameList)
}
if flags.RepoNameListFile != "" {
return getRepoNamesFromFile(flags.RepoNameListFile)
}
if flags.RepoName != "" {
return []string{flags.RepoName}, nil
}
return nil, nil
}
func getRepoNamesFromCacheDir(flags *CommonFlags) ([]string, error) {
repoNames := make([]string, 0)
orgDirs, err := os.ReadDir(flags.CacheDir)
if err != nil {
return nil, errors.Wrapf(err, "error opening cache directory `%s`", flags.CacheDir)
}
for _, orgDir := range orgDirs {
orgDirPath := path.Join(flags.CacheDir, orgDir.Name())
if !orgDir.IsDir() {
return nil, errors.Errorf("unexpected file in root of cache directory `%s`", orgDirPath)
}
repoDirs, err := os.ReadDir(orgDirPath)
if err != nil {
return nil, errors.Wrapf(err, "error opening repository cache directory `%s`", orgDirPath)
}
for _, repoDir := range repoDirs {
nwo := fmt.Sprintf("%s/%s", orgDir.Name(), repoDir.Name())
repoNames = append(repoNames, nwo)
}
}
if len(repoNames) == 0 {
return nil, ErrEmptyCacheDir
}
return repoNames, nil
}
func getRepoNamesFromCSVString(csv string) ([]string, error) {
repos := filterEntries(strings.Split(csv, ","))
if len(repos) == 0 {
return nil, ErrEmptyRepoList
}
return repos, nil
}
func getRepoNamesFromFile(file string) ([]string, error) {
data, err := os.ReadFile(file)
if err != nil {
return nil, err
}
repos := filterEntries(strings.Split(string(data), "\n"))
if len(repos) == 0 {
return nil, ErrEmptyRepoList
}
return repos, nil
}
func filterEntries(names []string) []string {
filtered := []string{}
for _, name := range names {
if !strings.HasPrefix(name, "#") && len(name) > 0 {
filtered = append(filtered, name)
}
}
return filtered
}
func extractSourceDest(repoName string) (string, string, error) {
repoNameParts := strings.Split(repoName, ":")
if len(repoNameParts) > 2 {
return "", "", fmt.Errorf("`%s` is not a valid repo name. Use a single colon to separate source and destination arguments. Example: `upstream_owner/upstream_repo:destination_owner/destination_repo`", repoName)
}
originNwo, err := validateNwo(repoNameParts[0])
if err != nil {
return "", "", err
}
destNwo := originNwo
if len(repoNameParts) > 1 {
destNwo, err = validateNwo(repoNameParts[1])
if err != nil {
return "", "", err
}
}
return originNwo, destNwo, nil
}
func validateNwo(nwo string) (string, error) {
s := strings.TrimSpace(nwo)
if NwoRegExp.MatchString(s) {
return s, nil
}
return "", fmt.Errorf("`%s` is not a valid repo name", s)
}
func splitNwo(nwo string) (string, string, error) {
nwoParts := strings.Split(nwo, "/")
if len(nwoParts) != 2 {
return "", "", fmt.Errorf("`%s` is not a valid repo name", nwo)
}
return nwoParts[0], nwoParts[1], nil
}