diff --git a/cmd/repo-health-checker/main.go b/cmd/repo-health-checker/main.go index e170c13..82833f6 100644 --- a/cmd/repo-health-checker/main.go +++ b/cmd/repo-health-checker/main.go @@ -46,6 +46,7 @@ var ( checkFileSumList string metaFile []string allowedDomainList string + actorCsvPath string showVersion *bool Version string ) @@ -57,6 +58,7 @@ func init() { flag.StringVar(&checkFileNameList, "checkFileNameList", "", "comma-separated list of files to check") flag.StringVar(&checkFileSumList, "checkFileSumList", "", "comma-separated list of expected checksums") flag.StringVar(&allowedDomainList, "allowedDomainList", "sjtu.edu.cn", "comma-separated list of allowed domains for commit author email") + flag.StringVar(&actorCsvPath, "actorCsvPath", "/home/tt/.config/joj/students.csv", "path to actor csv file") parseMultiValueFlag(&metaFile, "meta", "meta files to check") } @@ -79,6 +81,7 @@ func main() { checkFileNameList, checkFileSumList, allowedDomainList, + actorCsvPath, metaFile, repoSize, ) diff --git a/pkg/healthcheck/all.go b/pkg/healthcheck/all.go index 85fa35d..ef886a8 100644 --- a/pkg/healthcheck/all.go +++ b/pkg/healthcheck/all.go @@ -12,7 +12,7 @@ type Result struct { } func All( - rootDir, checkFileNameList, checkFileSumList, allowedDomainList string, + rootDir, checkFileNameList, checkFileSumList, allowedDomainList, actorCsvPath string, metaFile []string, repoSize float64, ) (res Result) { var err error @@ -65,7 +65,7 @@ func All( } else { res.Msg += "### Repo File Check Passed\n" } - err = AuthorEmailCheck(rootDir, strings.Split(allowedDomainList, ",")) + err = AuthorEmailCheck(rootDir, strings.Split(allowedDomainList, ","), actorCsvPath) if err != nil { res.Msg += fmt.Sprintf("### Author Email Check Failed:\n%s\n", err.Error()) res.Failed = true diff --git a/pkg/healthcheck/commit.go b/pkg/healthcheck/commit.go index bdbdd6e..e0c36f4 100644 --- a/pkg/healthcheck/commit.go +++ b/pkg/healthcheck/commit.go @@ -1,8 +1,11 @@ package healthcheck import ( + "encoding/csv" "fmt" + "io" "log/slog" + "os" "strings" "unicode" @@ -75,7 +78,7 @@ func NonASCIIMsg(root string) error { return nil } -func AuthorEmailCheck(root string, allowedDomains []string) error { +func AuthorEmailCheck(root string, allowedDomains []string, actorCsvPath string) error { repo, err := git.PlainOpen(root) if err != nil { slog.Error("opening git repo", "err", err) @@ -94,13 +97,60 @@ func AuthorEmailCheck(root string, allowedDomains []string) error { return fmt.Errorf("error getting latest commit: %v", err) } - email := commit.Author.Email - for _, domain := range allowedDomains { - if strings.HasSuffix(email, "@"+domain) { - return nil + email := strings.ToLower(commit.Author.Email) + + checkDomains := true + if _, err := os.Stat(actorCsvPath); err != nil { + slog.Error("checking actor CSV file stat", "err", err, "path", actorCsvPath) + } else { + f, err := os.Open(actorCsvPath) + if err != nil { + slog.Error("opening actor CSV file", "err", err, "path", actorCsvPath) + } else { + defer f.Close() + reader := csv.NewReader(f) + for { + row, err := reader.Read() + if err == io.EOF { + checkDomains = false + break + } + if err != nil { + slog.Error("reading actor CSV file", "err", err, "path", actorCsvPath) + break + } + if len(row) >= 3 { + actor := row[2] + for _, domain := range allowedDomains { + if email == actor+"@"+domain { + return nil + } + } + } + } } } - return fmt.Errorf("Author email %s is not in the allowed domains: `%s`\n\n"+ + var msgPrefix string + if checkDomains { + for _, domain := range allowedDomains { + if strings.HasSuffix(email, "@"+domain) { + return nil + } + } + msgPrefix = fmt.Sprintf( + "Author email %s is not in the allowed domains: `%s`", + email, + strings.Join(allowedDomains, "`, `"), + ) + } else { + msgPrefix = fmt.Sprintf( + "Author email %s is not stored in `%s`", + email, + actorCsvPath, + ) + } + + return fmt.Errorf("%s\n\n"+ "To fix it, please run the following commands:\n"+ "```bash\n"+ "git config user.email \"\"\n"+ @@ -108,7 +158,6 @@ func AuthorEmailCheck(root string, allowedDomains []string) error { "git push --force\n"+ "```\n"+ "Replace `` with your actual email address\n", - email, - strings.Join(allowedDomains, "`, `"), + msgPrefix, ) }