From 05876c290dada9d7d1fe8040844ae9767b391d8e Mon Sep 17 00:00:00 2001 From: BoYanZh Date: Fri, 7 Jun 2024 20:36:19 -0400 Subject: [PATCH 01/37] feat: file check squash all previous commits --- .gitmodules | 28 ++++++ README.md | 4 + cmd/healthcheck/main.go | 78 ++++++++++++++++ cmd/joj3/main_test.go | 12 +++ examples/healthcheck/asciifile | 1 + examples/healthcheck/asciimsg | 1 + examples/healthcheck/forbiddenfile | 1 + examples/healthcheck/meta | 1 + examples/healthcheck/release | 1 + examples/healthcheck/reposize | 1 + examples/healthcheck/repoverify | 1 + internal/parsers/all.go | 1 + internal/parsers/healthcheck/meta.go | 9 ++ internal/parsers/healthcheck/parser.go | 49 ++++++++++ internal/parsers/keyword/parser.go | 6 +- internal/parsers/resultstatus/parser.go | 6 +- internal/stage/model.go | 5 +- internal/stage/run.go | 9 +- pkg/healthcheck/commit.go | 83 +++++++++++++++++ pkg/healthcheck/forbidden.go | 94 +++++++++++++++++++ pkg/healthcheck/main.go | 1 - pkg/healthcheck/meta.go | 86 ++++++++++++++++++ pkg/healthcheck/nonascii.go | 90 +++++++++++++++++++ pkg/healthcheck/release.go | 88 ++++++++++++++++++ pkg/healthcheck/reposize.go | 56 ++++++++++++ pkg/healthcheck/utils.go | 39 ++++++++ pkg/healthcheck/verify.go | 114 ++++++++++++++++++++++++ 27 files changed, 850 insertions(+), 15 deletions(-) create mode 100644 cmd/healthcheck/main.go create mode 160000 examples/healthcheck/asciifile create mode 160000 examples/healthcheck/asciimsg create mode 160000 examples/healthcheck/forbiddenfile create mode 160000 examples/healthcheck/meta create mode 160000 examples/healthcheck/release create mode 160000 examples/healthcheck/reposize create mode 160000 examples/healthcheck/repoverify create mode 100644 internal/parsers/healthcheck/meta.go create mode 100644 internal/parsers/healthcheck/parser.go create mode 100644 pkg/healthcheck/commit.go create mode 100644 pkg/healthcheck/forbidden.go delete mode 100644 pkg/healthcheck/main.go create mode 100644 pkg/healthcheck/meta.go create mode 100644 pkg/healthcheck/nonascii.go create mode 100644 pkg/healthcheck/release.go create mode 100644 pkg/healthcheck/reposize.go create mode 100644 pkg/healthcheck/utils.go create mode 100644 pkg/healthcheck/verify.go diff --git a/.gitmodules b/.gitmodules index 9261291..517e6cd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -38,6 +38,34 @@ path = examples/keyword/clangtidy/sillycode url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git branch = keyword/clangtidy/sillycode +[submodule "examples/healthcheck/asciifile"] + path = examples/healthcheck/asciifile + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = healthcheck/asciifile +[submodule "examples/healthcheck/asciimsg"] + path = examples/healthcheck/asciimsg + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = healthcheck/asciimsg +[submodule "examples/healthcheck/forbiddenfile"] + path = examples/healthcheck/forbiddenfile + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = healthcheck/forbiddenfile +[submodule "examples/healthcheck/meta"] + path = examples/healthcheck/meta + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = healthcheck/meta +[submodule "examples/healthcheck/release"] + path = examples/healthcheck/release + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = healthcheck/release +[submodule "examples/healthcheck/reposize"] + path = examples/healthcheck/reposize + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = healthcheck/reposize +[submodule "examples/healthcheck/repoverify"] + path = examples/healthcheck/repoverify + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = healthcheck/repoverify [submodule "examples/cppcheck/sillycode"] path = examples/cppcheck/sillycode url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git diff --git a/README.md b/README.md index 7416adf..7f5c3d3 100644 --- a/README.md +++ b/README.md @@ -84,3 +84,7 @@ Check the `Result` at . - `Score int`: score of the stage. - `Comment string`: comment on the stage. + +### HealthCheck + +The repohealth check will return a json list to for check result. The structure of json file is in `pkg/healthcheck/util.go` diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go new file mode 100644 index 0000000..a575046 --- /dev/null +++ b/cmd/healthcheck/main.go @@ -0,0 +1,78 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "os" + + "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/healthcheck" +) + +// parseMultiValueFlag parses a multi-value command-line flag and appends its values to the provided slice. +// It registers a flag with the specified name and description, associating it with a multiStringValue receiver. +func parseMultiValueFlag(values *[]string, flagName, description string) { + flag.Var((*multiStringValue)(values), flagName, description) +} + +type multiStringValue []string + +// Set appends a new value to the multiStringValue slice. +// It satisfies the flag.Value interface, allowing multiStringValue to be used as a flag value. +func (m *multiStringValue) Set(value string) error { + *m = append(*m, value) + return nil +} + +func (m *multiStringValue) String() string { + return fmt.Sprintf("%v", *m) +} + +// Generally, err is used for runtime errors, and checkRes is used for the result of the checks. +func main() { + var info []healthcheck.CheckStage + var gitWhitelist, metaFile, releaseTags []string + var tmp healthcheck.CheckStage + + rootDir := flag.String("root", "", "") + repo := flag.String("repo", "", "") + droneBranch := flag.String("droneBranch", "", "") + releaseCategories := flag.String("releaseCategories", "", "") + releaseNumber := flag.Int("releaseNumber", 0, "") + // FIXME: for drone usage + adminDir := flag.String("admin", "", "") // adminDir is for config files + parseMultiValueFlag(&gitWhitelist, "whitelist", "") + parseMultiValueFlag(&metaFile, "meta", "") + parseMultiValueFlag(&releaseTags, "releaseTags", "") + flag.Parse() + + tmp = healthcheck.RepoSize() + info = append(info, tmp) + + tmp = healthcheck.ForbiddenCheck(*rootDir, gitWhitelist, *repo, *droneBranch) + info = append(info, tmp) + + tmp = healthcheck.MetaCheck(*rootDir, metaFile) + info = append(info, tmp) + + tmp = healthcheck.NonAsciiFiles(*rootDir) + info = append(info, tmp) + + tmp = healthcheck.NonAsciiMsg(*rootDir) + info = append(info, tmp) + + // TODO: find a way to test the release tag + tmp = healthcheck.CheckReleases(*rootDir, *releaseCategories, *releaseNumber) + info = append(info, tmp) + + // FIXME: for drone usage + tmp = healthcheck.Verify(*rootDir, *adminDir) + info = append(info, tmp) + + jsonData, err := json.Marshal(info) + if err != nil { + fmt.Fprint(os.Stderr, err) + os.Exit(1) + } + fmt.Printf("%s", jsonData) +} diff --git a/cmd/joj3/main_test.go b/cmd/joj3/main_test.go index 0f35e6b..6daad37 100644 --- a/cmd/joj3/main_test.go +++ b/cmd/joj3/main_test.go @@ -14,6 +14,18 @@ import ( func compareStageResults(t *testing.T, actual, expected []stage.StageResult, regex bool) { t.Helper() + + // For Test + fmt.Println("Actual:") + for _, result := range actual { + fmt.Println(result) + } + + fmt.Println("Expected:") + for _, result := range expected { + fmt.Println(result) + } + if len(actual) != len(expected) { t.Fatalf("len(actual) = %d, expected %d", len(actual), len(expected)) } diff --git a/examples/healthcheck/asciifile b/examples/healthcheck/asciifile new file mode 160000 index 0000000..46804af --- /dev/null +++ b/examples/healthcheck/asciifile @@ -0,0 +1 @@ +Subproject commit 46804afd2ebe8787a9d43711b191e424134ce25b diff --git a/examples/healthcheck/asciimsg b/examples/healthcheck/asciimsg new file mode 160000 index 0000000..e9ed6a4 --- /dev/null +++ b/examples/healthcheck/asciimsg @@ -0,0 +1 @@ +Subproject commit e9ed6a464a507730ef956bb8ea6dbe84fffea7ad diff --git a/examples/healthcheck/forbiddenfile b/examples/healthcheck/forbiddenfile new file mode 160000 index 0000000..245d036 --- /dev/null +++ b/examples/healthcheck/forbiddenfile @@ -0,0 +1 @@ +Subproject commit 245d036af0cbfe3745ef303d239a2d7225067d0b diff --git a/examples/healthcheck/meta b/examples/healthcheck/meta new file mode 160000 index 0000000..4f5e444 --- /dev/null +++ b/examples/healthcheck/meta @@ -0,0 +1 @@ +Subproject commit 4f5e444940d2c383a0b069405e2ef42b01878bc5 diff --git a/examples/healthcheck/release b/examples/healthcheck/release new file mode 160000 index 0000000..a4cedea --- /dev/null +++ b/examples/healthcheck/release @@ -0,0 +1 @@ +Subproject commit a4cedea002a198c2dae373f7ee6f6dc67753fae6 diff --git a/examples/healthcheck/reposize b/examples/healthcheck/reposize new file mode 160000 index 0000000..d78308b --- /dev/null +++ b/examples/healthcheck/reposize @@ -0,0 +1 @@ +Subproject commit d78308bcaaaeda9ead86069652288ae911503e33 diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify new file mode 160000 index 0000000..a7a3bd0 --- /dev/null +++ b/examples/healthcheck/repoverify @@ -0,0 +1 @@ +Subproject commit a7a3bd0894c2e727e3ab3f9ddda3d438fbb86b30 diff --git a/internal/parsers/all.go b/internal/parsers/all.go index f1404a7..8e4e29a 100644 --- a/internal/parsers/all.go +++ b/internal/parsers/all.go @@ -5,6 +5,7 @@ import ( _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cppcheck" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cpplint" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff" + _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/healthcheck" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/keyword" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/sample" diff --git a/internal/parsers/healthcheck/meta.go b/internal/parsers/healthcheck/meta.go new file mode 100644 index 0000000..d6c89ae --- /dev/null +++ b/internal/parsers/healthcheck/meta.go @@ -0,0 +1,9 @@ +package healthcheck + +import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" + +var name = "healthcheck" + +func init() { + stage.RegisterParser(name, &Healthcheck{}) +} diff --git a/internal/parsers/healthcheck/parser.go b/internal/parsers/healthcheck/parser.go new file mode 100644 index 0000000..046ff18 --- /dev/null +++ b/internal/parsers/healthcheck/parser.go @@ -0,0 +1,49 @@ +package healthcheck + +import ( + // "encoding/json" + "fmt" + + "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" + // "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/healthcheck" + "github.com/criyle/go-judge/envexec" +) + +type Conf struct { + Score int + Comment string +} + +type Healthcheck struct{} + +func Parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult { + stdout := executorResult.Files["stdout"] + stderr := executorResult.Files["stderr"] + if executorResult.Status != stage.Status(envexec.StatusAccepted) { + return stage.ParserResult{ + Score: 0, + Comment: fmt.Sprintf( + "Unexpected executor status: %s.\nStderr: %s", + executorResult.Status, stderr, + ), + } + } + return stage.ParserResult{ + Score: 0, + Comment: stdout, + } +} + +func (*Healthcheck) Run(results []stage.ExecutorResult, confAny any) ( + []stage.ParserResult, bool, error, +) { + conf, err := stage.DecodeConf[Conf](confAny) + if err != nil { + return nil, true, err + } + var res []stage.ParserResult + for _, result := range results { + res = append(res, Parse(result, *conf)) + } + return res, false, nil +} diff --git a/internal/parsers/keyword/parser.go b/internal/parsers/keyword/parser.go index 9671a78..d376977 100644 --- a/internal/parsers/keyword/parser.go +++ b/internal/parsers/keyword/parser.go @@ -57,13 +57,13 @@ func (*Keyword) Run(results []stage.ExecutorResult, confAny any) ( return nil, true, err } var res []stage.ParserResult - forceQuit := false + end := false for _, result := range results { tmp, matched := Parse(result, *conf) if matched && conf.EndOnMatch { - forceQuit = true + end = true } res = append(res, tmp) } - return res, forceQuit, nil + return res, end, nil } diff --git a/internal/parsers/resultstatus/parser.go b/internal/parsers/resultstatus/parser.go index 3b1aad3..b023a76 100644 --- a/internal/parsers/resultstatus/parser.go +++ b/internal/parsers/resultstatus/parser.go @@ -19,12 +19,12 @@ func (*ResultStatus) Run(results []stage.ExecutorResult, confAny any) ( if err != nil { return nil, true, err } - forceQuit := false + end := false var res []stage.ParserResult for _, result := range results { comment := "" if result.Status != stage.Status(envexec.StatusAccepted) { - forceQuit = true + end = true comment = fmt.Sprintf( "Unexpected executor status: %s.", result.Status, ) @@ -34,5 +34,5 @@ func (*ResultStatus) Run(results []stage.ExecutorResult, confAny any) ( Comment: comment, }) } - return res, forceQuit, nil + return res, end, nil } diff --git a/internal/stage/model.go b/internal/stage/model.go index cb33462..1b052d8 100644 --- a/internal/stage/model.go +++ b/internal/stage/model.go @@ -164,7 +164,6 @@ type ParserResult struct { } type StageResult struct { - Name string `json:"name"` - Results []ParserResult `json:"results"` - ForceQuit bool `json:"force_quit"` + Name string `json:"name"` + Results []ParserResult `json:"results"` } diff --git a/internal/stage/run.go b/internal/stage/run.go index 670f666..6c74758 100644 --- a/internal/stage/run.go +++ b/internal/stage/run.go @@ -26,18 +26,17 @@ func Run(stages []Stage) []StageResult { slog.Error("parser not found", "name", stage.ParserName) break } - parserResults, forceQuit, err := parser.Run(executorResults, stage.ParserConf) + parserResults, end, err := parser.Run(executorResults, stage.ParserConf) if err != nil { slog.Error("parser run error", "name", stage.ExecutorName, "error", err) break } slog.Debug("parser run done", "results", parserResults) stageResults = append(stageResults, StageResult{ - Name: stage.Name, - Results: parserResults, - ForceQuit: forceQuit, + Name: stage.Name, + Results: parserResults, }) - if forceQuit { + if end { break } } diff --git a/pkg/healthcheck/commit.go b/pkg/healthcheck/commit.go new file mode 100644 index 0000000..7c94fb2 --- /dev/null +++ b/pkg/healthcheck/commit.go @@ -0,0 +1,83 @@ +package healthcheck + +import ( + "fmt" + "strings" + "unicode" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" +) + +// nonAsciiMsg checks for non-ASCII characters in the commit message. +// If the message starts with "Merge pull request", it skips the non-ASCII characters check. +// Otherwise, it iterates over each character in the message and checks if it is a non-ASCII character. +// If a non-ASCII character is found, it returns an error indicating not to use non-ASCII characters in commit messages. +// Otherwise, it returns nil indicating that the commit message is valid. +func NonAsciiMsg(root string) (jsonOut CheckStage) { + jsonOut = CheckStage{ + Name: "NonAsciiMsg", + StdOut: "Checking for non-ASCII characters in commit message: ", + ExitCode: 0, + StdErr: "", + } + + // cmd := exec.Command("git", "log", "--encoding=UTF-8", "--format=%B") + repo, err := git.PlainOpen(root) + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = fmt.Errorf("Error openning git repo%w", err) + return jsonOut + } + + ref, err := repo.Head() + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = fmt.Errorf("Error getting reference%w", err) + return jsonOut + } + commits, err := repo.Log(&git.LogOptions{From: ref.Hash()}) + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = fmt.Errorf("Error getting commits%w", err) + return jsonOut + } + + var msgs []string + err = commits.ForEach(func(c *object.Commit) error { + msgs = append(msgs, c.Message) + return nil + }) + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = fmt.Errorf("Error converting log to string%w", err) + return jsonOut + } + + var nonAsciiMsgs []string + for _, msg := range msgs { + if msg == "" { + continue + } + if strings.HasPrefix(msg, "Merge pull request") { + continue + } + for _, c := range msg { + if c > unicode.MaxASCII { + nonAsciiMsgs = append(nonAsciiMsgs, msg) + } + } + } + if len(nonAsciiMsgs) > 0 { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 105 + jsonOut.StdErr = "Non-ASCII characters in commit messages:\n" + strings.Join(nonAsciiMsgs, "\n") + return jsonOut + } + jsonOut.StdOut += "OK" + return jsonOut +} diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go new file mode 100644 index 0000000..af98747 --- /dev/null +++ b/pkg/healthcheck/forbidden.go @@ -0,0 +1,94 @@ +package healthcheck + +import ( + "fmt" + "os" + "path/filepath" + "regexp" +) + +// getForbiddens retrieves a list of forbidden files in the specified root directory. +// It searches for files that do not match the specified regex patterns in the given file list. +func getForbiddens(root string, fileList []string) ([]string, error) { + var matches []string + + var regexList []*regexp.Regexp + regexList, err := getRegex(fileList) + if err != nil { + fmt.Println("Error compiling regex:", err) + return nil, err + } + + err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if info.IsDir() { + if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" { + return filepath.SkipDir + } else { + return nil + } + } + + match := false + for _, regex := range regexList { + if regex.MatchString(info.Name()) { + match = true + break + } + } + + if !match { + matches = append(matches, path) + } + return nil + }) + + return matches, err +} + +// forbiddenCheck checks for forbidden files in the specified root directory. +// It prints the list of forbidden files found, along with instructions on how to fix them. +func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch string) (jsonOut CheckStage) { + jsonOut = CheckStage{ + Name: "forbiddenFile", + StdOut: "Checking forbidden files: ", + ExitCode: 0, + StdErr: "", + } + + // INFO: test case + // regexList := []string{`\.$`, `\.git`, `\.drone.yml`, `Makefile`, `CMakeLists.txt`,`.*\.go`,`.*\.toml`, `.*\.c`, `.*\.cc`, `.*\.cpp`, `.*\.h`, `.*\.md`} + // rootDir = "/Users/zhouzhaojiacheng/Desktop/STUDENT_ORG/TechJI/Dev/joj/JOJ3" + + forbids, err := getForbiddens(rootDir, regexList) + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = err + return jsonOut + } + + var message string + + if len(forbids) > 0 { + message += fmt.Sprint(103, "the following forbidden files were found: ") + for _, file := range forbids { + message += fmt.Sprint(file, ", ") + } + message += "\n\nTo fix it, first make a backup of your repository and then run the following commands:\nfor i in " + for _, file := range forbids { + message += fmt.Sprint(file, " ") + } + message += fmt.Sprint("; do git filter-repo --force --invert-paths --path \\\"\\$i\\\"; done\ngit remote add origin ", repo, "\ngit push --set-upstream origin ", droneBranch, " --force") + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 103 + jsonOut.StdErr = message + return jsonOut + } else { + jsonOut.StdOut += "OK" + return jsonOut + } +} diff --git a/pkg/healthcheck/main.go b/pkg/healthcheck/main.go deleted file mode 100644 index 9b4e3b7..0000000 --- a/pkg/healthcheck/main.go +++ /dev/null @@ -1 +0,0 @@ -package healthcheck diff --git a/pkg/healthcheck/meta.go b/pkg/healthcheck/meta.go new file mode 100644 index 0000000..e4bcfce --- /dev/null +++ b/pkg/healthcheck/meta.go @@ -0,0 +1,86 @@ +package healthcheck + +import ( + "fmt" + "os" +) + +// getMetas retrieves a list of metadata files that are expected to exist in the specified root directory. +// It checks for the existence of each file in the fileList and provides instructions if any file is missing. +func getMetas(rootDir string, fileList []string) ([]string, string, error) { + addExt(fileList, "\\.*") + regexList, err := getRegex(fileList) + var unmatchedList []string + + if err != nil { + return nil, "", err + } + + files, err := os.ReadDir(rootDir) + if err != nil { + return nil, "", fmt.Errorf("Error reading directory:%w", err) + } + + matched := false + umatchedRes := "" + + // TODO: it seems that there is no good find subsitution now + // modify current code if exist a better solution + for i, regex := range regexList { + for _, file := range files { + if file.IsDir() { + continue + } + + if regex.MatchString(file.Name()) { + matched = true + break + } + } + if !matched { + unmatchedList = append(unmatchedList, fileList[i]) + str := fmt.Sprint("\tno ", fileList[i], " file found") + switch fileList[i] { + case "readme\\.*": + str += ", please refer to https://www.makeareadme.com/ for more information" + case "changelog\\.*": + str += ", please refer to https://keepachangelog.com/en/1.1.0/ for more information" + default: + str += "" + } + str += "\n" + + umatchedRes += str + } + } + + return unmatchedList, umatchedRes, nil +} + +// metaCheck performs a check for metadata files in the specified root directory. +// It prints a message if any required metadata files are missing. +func MetaCheck(rootDir string, fileList []string) (jsonOut CheckStage) { + unmatchedList, umatchedRes, err := getMetas(rootDir, fileList) + jsonOut = CheckStage{ + Name: "metaFile", + StdOut: "Checking the existence of meta file: ", + ExitCode: 0, + StdErr: "", + } + + if err != nil { + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = err + return jsonOut + } + + if len(unmatchedList) == 0 { + jsonOut.StdOut += "OK" + return jsonOut + } else { + jsonOut.ExitCode = 104 + jsonOut.StdOut += "Failed" + jsonOut.StdErr = fmt.Sprintf("%d important project files missing\n"+umatchedRes, len(unmatchedList)) + return jsonOut + } +} diff --git a/pkg/healthcheck/nonascii.go b/pkg/healthcheck/nonascii.go new file mode 100644 index 0000000..eb4d6b7 --- /dev/null +++ b/pkg/healthcheck/nonascii.go @@ -0,0 +1,90 @@ +package healthcheck + +import ( + "bufio" + "fmt" + "os" + "path/filepath" + "strings" + "unicode" +) + +// getNonAscii retrieves a list of files in the specified root directory that contain non-ASCII characters. +// It searches for non-ASCII characters in each file's content and returns a list of paths to files containing non-ASCII characters. +func getNonAscii(root string) ([]string, error) { + var nonAscii []string + + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if info.IsDir() { + if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" { + return filepath.SkipDir + } else { + return nil + } + } + + if info.Name() == "healthcheck" { + return nil + } + + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + cont := true + for _, c := range scanner.Text() { + if c > unicode.MaxASCII { + nonAscii = append(nonAscii, "\t"+path) + cont = false + break + } + } + if !cont { + break + } + } + + return nil + }) + + return nonAscii, err +} + +// nonAsciiFiles checks for non-ASCII characters in files within the specified root directory. +// It prints a message with the paths to files containing non-ASCII characters, if any. +func NonAsciiFiles(root string) (jsonOut CheckStage) { + jsonOut = CheckStage{ + Name: "NonAsciiFiles", + StdOut: "Checking for non-ascii files: ", + ExitCode: 0, + StdErr: "", + } + nonAscii, err := getNonAscii(root) + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = err + return jsonOut + } + + var nonAsciiRes string + if len(nonAscii) > 0 { + nonAsciiRes = fmt.Sprintf("Non-ASCII characters found in the following files:\n" + strings.Join(nonAscii, "\n")) + jsonOut.ExitCode = 105 + jsonOut.StdOut += "Failed" + } else { + jsonOut.StdOut += "OK" + } + + jsonOut.StdErr = nonAsciiRes + + return jsonOut +} diff --git a/pkg/healthcheck/release.go b/pkg/healthcheck/release.go new file mode 100644 index 0000000..43e35e8 --- /dev/null +++ b/pkg/healthcheck/release.go @@ -0,0 +1,88 @@ +package healthcheck + +import ( + "fmt" + "log" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" +) + +func catTags(all []string) (out string) { + out = "" + for _, str := range all { + out += str + " " + } + return out +} + +func getTagsFromRepo(repoPath string) ([]string, error) { + repo, err := git.PlainOpen(repoPath) + if err != nil { + return nil, fmt.Errorf("Cannot open repo: %v", err) + } + + refs, err := repo.Tags() + if err != nil { + return nil, fmt.Errorf("Cannot get tags: %v", err) + } + + var tags []string + err = refs.ForEach(func(ref *plumbing.Reference) error { + tags = append(tags, ref.Name().Short()) + return nil + }) + if err != nil { + return nil, fmt.Errorf("Error while iterating tags: %v", err) + } + + return tags, nil +} + +func CheckReleases(repoPath string, category string, n int) (jsonOut CheckStage) { + jsonOut = CheckStage{ + Name: "ReleaseCheck", + StdOut: "Checking release tag: ", + ExitCode: 0, + StdErr: "", + } + + tags, err := getTagsFromRepo(repoPath) + if err != nil { + log.Fatalf("Error in getting tags: %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) + found := false + for _, tag := range tags { + if tag == target { + found = true + break + } + } + if !found { + tagList := catTags(tags) + jsonOut.ExitCode = 107 + jsonOut.StdOut = "Failed" + jsonOut.StdErr = fmt.Sprintf("wrong release tag '%s', please use one of %s aborting", target, tagList) + return jsonOut + } + + jsonOut.StdOut += "OK" + jsonOut.ExitCode = 0 + jsonOut.StdErr = "Fine" + return jsonOut +} diff --git a/pkg/healthcheck/reposize.go b/pkg/healthcheck/reposize.go new file mode 100644 index 0000000..3c362b2 --- /dev/null +++ b/pkg/healthcheck/reposize.go @@ -0,0 +1,56 @@ +package healthcheck + +import ( + "fmt" + "os/exec" + "strconv" + "strings" +) + +// RepoSize checks the size of the repository to determine if it is oversized. +// It executes the 'git count-objects -v' command to obtain the size information, +func RepoSize() (jsonOut CheckStage) { + jsonOut = CheckStage{ + Name: "RepoSize", + StdOut: "Checking repository size: ", + ExitCode: 0, + StdErr: "", + } + + // TODO: reimplement here when go-git is available + // https://github.com/go-git/go-git/blob/master/COMPATIBILITY.md + cmd := exec.Command("git", "count-objects", "-v") + output, err := cmd.CombinedOutput() + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = fmt.Errorf("Error running git command:%w", err) + return jsonOut + } + + lines := strings.Split(string(output), "\n") + var sum int + for _, line := range lines { + if strings.Contains(line, "size") { + fields := strings.Fields(line) + sizeStr := fields[1] + size, err := strconv.Atoi(sizeStr) + if err != nil { + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 1 + jsonOut.ErrorLog = fmt.Errorf("Error running git command:%w", err) + return jsonOut + } + sum += size + } + } + + if sum <= 2048 { + jsonOut.StdOut += "OK" + return jsonOut + } + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 100 + jsonOut.StdErr = "repository larger than 2MB, please clean up or contact the teaching team." + return jsonOut +} diff --git a/pkg/healthcheck/utils.go b/pkg/healthcheck/utils.go new file mode 100644 index 0000000..21bb256 --- /dev/null +++ b/pkg/healthcheck/utils.go @@ -0,0 +1,39 @@ +package healthcheck + +import ( + "fmt" + "regexp" +) + +// For ExitCode, see https://focs.ji.sjtu.edu.cn/git/TAs/resources/src/branch/drone/dronelib.checks +// 1 for unrecoverable error and 0 for succeses +type CheckStage struct { + Name string `json:"name of check"` + StdOut string `json:"stdout"` + ExitCode int `json:"exit code"` + StdErr string `json:"stderr"` + ErrorLog error `json:"errorLog"` +} + +// addExt appends the specified extension to each file name in the given fileList. +// It modifies the original fileList in place. +func addExt(fileList []string, ext string) { + for i, file := range fileList { + fileList[i] = file + ext + } +} + +// getRegex compiles each regex pattern in the fileList into a []*regexp.Regexp slice. +// It returns a slice containing compiled regular expressions. +func getRegex(fileList []string) ([]*regexp.Regexp, error) { + var regexList []*regexp.Regexp + for _, pattern := range fileList { + regex, err := regexp.Compile("(?i)" + pattern) + if err != nil { + return nil, fmt.Errorf("Error compiling regex:%w", err) + } + regexList = append(regexList, regex) + } + + return regexList, nil +} diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go new file mode 100644 index 0000000..b201b53 --- /dev/null +++ b/pkg/healthcheck/verify.go @@ -0,0 +1,114 @@ +package healthcheck + +import ( + "bufio" + "fmt" + "os" + "path/filepath" +) + +// fileExists checks if a file exists at the specified path. +func fileExists(filePath string) bool { + _, err := os.Stat(filePath) + return !os.IsNotExist(err) +} + +// filesMatch checks if two files are identical. +func filesMatch(file1, file2 string) (bool, error) { + f1, err := os.Open(file1) + if err != nil { + return false, err + } + defer f1.Close() + + f2, err := os.Open(file2) + if err != nil { + return false, err + } + defer f2.Close() + + scanner1 := bufio.NewScanner(f1) + scanner2 := bufio.NewScanner(f2) + + for scanner1.Scan() && scanner2.Scan() { + line1 := scanner1.Text() + line2 := scanner2.Text() + + if line1 != line2 { + return false, nil + } + } + + if scanner1.Scan() || scanner2.Scan() { + // One file has more lines than the other + return false, nil + } + + return true, nil +} + +// compareDirectories compares the contents of two directories. +func compareDirectories(dir1, dir2 string, jsonOut *CheckStage) error { + allMatch := true + var message string + err := filepath.Walk(dir1, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !info.IsDir() { + relPath, _ := filepath.Rel(dir1, path) + file2 := filepath.Join(dir2, relPath) + + if !fileExists(file2) { + // fmt.Printf("File %s in %s is missing in %s\n, please immediately revert your changes!\n", relPath, dir1, dir2) + message += "File missing" + allMatch = false + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 101 + jsonOut.StdErr = message + return nil + } + + // fmt.Printf("Checking integrity of %s:\n", path) + match, err := filesMatch(path, file2) + if err != nil { + return err + } + + if !match { + // fmt.Printf("File %s in %s is not identical to %s\nPlease revert your changes or contact the teaching team if you have a valid reason for adjusting them.\n", relPath, dir1, dir2) + message += "File is not identical" + allMatch = false + jsonOut.StdOut += "Failed" + jsonOut.ExitCode = 101 + jsonOut.StdErr = message + } + } + return nil + }) + + if allMatch { + jsonOut.StdOut += "OK!" + } else { + jsonOut.StdOut += "Failed!" + } + + return err +} + +// Verify checks if the contents of two directories are identical. +func Verify(rootDir, compareDir string) CheckStage { + jsonOut := CheckStage{ + Name: "verifyFile", + StdOut: "Checking files to be verified: ", + ExitCode: 0, + StdErr: "", + } + err := compareDirectories(rootDir, compareDir, &jsonOut) + // fmt.Println("Comparison finished ") + if err != nil { + fmt.Println("Error:", err) + } + return jsonOut +} -- 2.30.2 From a505b7050606b4d0ced2d84964b9eca2b0d13f1f Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Fri, 7 Jun 2024 13:57:29 +0800 Subject: [PATCH 02/37] feat: output force quit (#29) Reviewed-on: https://focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pulls/29 Co-authored-by: Boming Zhang Co-committed-by: Boming Zhang --- internal/parsers/keyword/parser.go | 6 +++--- internal/parsers/resultstatus/parser.go | 6 +++--- internal/stage/model.go | 5 +++-- internal/stage/run.go | 9 +++++---- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/internal/parsers/keyword/parser.go b/internal/parsers/keyword/parser.go index d376977..9671a78 100644 --- a/internal/parsers/keyword/parser.go +++ b/internal/parsers/keyword/parser.go @@ -57,13 +57,13 @@ func (*Keyword) Run(results []stage.ExecutorResult, confAny any) ( return nil, true, err } var res []stage.ParserResult - end := false + forceQuit := false for _, result := range results { tmp, matched := Parse(result, *conf) if matched && conf.EndOnMatch { - end = true + forceQuit = true } res = append(res, tmp) } - return res, end, nil + return res, forceQuit, nil } diff --git a/internal/parsers/resultstatus/parser.go b/internal/parsers/resultstatus/parser.go index b023a76..3b1aad3 100644 --- a/internal/parsers/resultstatus/parser.go +++ b/internal/parsers/resultstatus/parser.go @@ -19,12 +19,12 @@ func (*ResultStatus) Run(results []stage.ExecutorResult, confAny any) ( if err != nil { return nil, true, err } - end := false + forceQuit := false var res []stage.ParserResult for _, result := range results { comment := "" if result.Status != stage.Status(envexec.StatusAccepted) { - end = true + forceQuit = true comment = fmt.Sprintf( "Unexpected executor status: %s.", result.Status, ) @@ -34,5 +34,5 @@ func (*ResultStatus) Run(results []stage.ExecutorResult, confAny any) ( Comment: comment, }) } - return res, end, nil + return res, forceQuit, nil } diff --git a/internal/stage/model.go b/internal/stage/model.go index 1b052d8..cb33462 100644 --- a/internal/stage/model.go +++ b/internal/stage/model.go @@ -164,6 +164,7 @@ type ParserResult struct { } type StageResult struct { - Name string `json:"name"` - Results []ParserResult `json:"results"` + Name string `json:"name"` + Results []ParserResult `json:"results"` + ForceQuit bool `json:"force_quit"` } diff --git a/internal/stage/run.go b/internal/stage/run.go index 6c74758..670f666 100644 --- a/internal/stage/run.go +++ b/internal/stage/run.go @@ -26,17 +26,18 @@ func Run(stages []Stage) []StageResult { slog.Error("parser not found", "name", stage.ParserName) break } - parserResults, end, err := parser.Run(executorResults, stage.ParserConf) + parserResults, forceQuit, err := parser.Run(executorResults, stage.ParserConf) if err != nil { slog.Error("parser run error", "name", stage.ExecutorName, "error", err) break } slog.Debug("parser run done", "results", parserResults) stageResults = append(stageResults, StageResult{ - Name: stage.Name, - Results: parserResults, + Name: stage.Name, + Results: parserResults, + ForceQuit: forceQuit, }) - if end { + if forceQuit { break } } -- 2.30.2 From 9625fb210c2e023ebfe7a3daf9a8b5fbf1adbc07 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 9 Jun 2024 18:53:49 -0400 Subject: [PATCH 03/37] chore: remove test Println --- cmd/joj3/main_test.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/cmd/joj3/main_test.go b/cmd/joj3/main_test.go index 6daad37..0f35e6b 100644 --- a/cmd/joj3/main_test.go +++ b/cmd/joj3/main_test.go @@ -14,18 +14,6 @@ import ( func compareStageResults(t *testing.T, actual, expected []stage.StageResult, regex bool) { t.Helper() - - // For Test - fmt.Println("Actual:") - for _, result := range actual { - fmt.Println(result) - } - - fmt.Println("Expected:") - for _, result := range expected { - fmt.Println(result) - } - if len(actual) != len(expected) { t.Fatalf("len(actual) = %d, expected %d", len(actual), len(expected)) } -- 2.30.2 From ca590175d96fe4a8d0aa98ddd4354741234240b5 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 9 Jun 2024 19:10:42 -0400 Subject: [PATCH 04/37] feat: remove ErrorLog field --- cmd/healthcheck/main.go | 10 +++++++++- internal/parsers/healthcheck/parser.go | 2 -- pkg/healthcheck/commit.go | 10 +++++----- pkg/healthcheck/forbidden.go | 3 ++- pkg/healthcheck/meta.go | 3 ++- pkg/healthcheck/nonascii.go | 3 ++- pkg/healthcheck/reposize.go | 6 +++--- pkg/healthcheck/utils.go | 3 +-- 8 files changed, 24 insertions(+), 16 deletions(-) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index a575046..2542a62 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -4,6 +4,7 @@ import ( "encoding/json" "flag" "fmt" + "log/slog" "os" "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/healthcheck" @@ -28,6 +29,13 @@ func (m *multiStringValue) String() string { return fmt.Sprintf("%v", *m) } +func setupSlog() { + opts := &slog.HandlerOptions{} + handler := slog.NewTextHandler(os.Stderr, opts) + logger := slog.New(handler) + slog.SetDefault(logger) +} + // Generally, err is used for runtime errors, and checkRes is used for the result of the checks. func main() { var info []healthcheck.CheckStage @@ -45,7 +53,7 @@ func main() { parseMultiValueFlag(&metaFile, "meta", "") parseMultiValueFlag(&releaseTags, "releaseTags", "") flag.Parse() - + setupSlog() tmp = healthcheck.RepoSize() info = append(info, tmp) diff --git a/internal/parsers/healthcheck/parser.go b/internal/parsers/healthcheck/parser.go index 046ff18..5655c3d 100644 --- a/internal/parsers/healthcheck/parser.go +++ b/internal/parsers/healthcheck/parser.go @@ -1,11 +1,9 @@ package healthcheck import ( - // "encoding/json" "fmt" "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" - // "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/healthcheck" "github.com/criyle/go-judge/envexec" ) diff --git a/pkg/healthcheck/commit.go b/pkg/healthcheck/commit.go index 7c94fb2..1532cc1 100644 --- a/pkg/healthcheck/commit.go +++ b/pkg/healthcheck/commit.go @@ -1,7 +1,7 @@ package healthcheck import ( - "fmt" + "log/slog" "strings" "unicode" @@ -27,7 +27,7 @@ func NonAsciiMsg(root string) (jsonOut CheckStage) { if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = fmt.Errorf("Error openning git repo%w", err) + slog.Error("openning git repo", "err", err) return jsonOut } @@ -35,14 +35,14 @@ func NonAsciiMsg(root string) (jsonOut CheckStage) { if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = fmt.Errorf("Error getting reference%w", err) + slog.Error("getting reference", "err", err) return jsonOut } commits, err := repo.Log(&git.LogOptions{From: ref.Hash()}) if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = fmt.Errorf("Error getting commits%w", err) + slog.Error("getting commits", "err", err) return jsonOut } @@ -54,7 +54,7 @@ func NonAsciiMsg(root string) (jsonOut CheckStage) { if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = fmt.Errorf("Error converting log to string%w", err) + slog.Error("converting log to string", "err", err) return jsonOut } diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index af98747..9333094 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -2,6 +2,7 @@ package healthcheck import ( "fmt" + "log/slog" "os" "path/filepath" "regexp" @@ -67,7 +68,7 @@ func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = err + slog.Error("get forbiddens", "error", err) return jsonOut } diff --git a/pkg/healthcheck/meta.go b/pkg/healthcheck/meta.go index e4bcfce..3cad159 100644 --- a/pkg/healthcheck/meta.go +++ b/pkg/healthcheck/meta.go @@ -2,6 +2,7 @@ package healthcheck import ( "fmt" + "log/slog" "os" ) @@ -70,7 +71,7 @@ func MetaCheck(rootDir string, fileList []string) (jsonOut CheckStage) { if err != nil { jsonOut.ExitCode = 1 - jsonOut.ErrorLog = err + slog.Error("get metas", "err", err) return jsonOut } diff --git a/pkg/healthcheck/nonascii.go b/pkg/healthcheck/nonascii.go index eb4d6b7..f2fe523 100644 --- a/pkg/healthcheck/nonascii.go +++ b/pkg/healthcheck/nonascii.go @@ -3,6 +3,7 @@ package healthcheck import ( "bufio" "fmt" + "log/slog" "os" "path/filepath" "strings" @@ -71,7 +72,7 @@ func NonAsciiFiles(root string) (jsonOut CheckStage) { if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = err + slog.Error("get non-ascii", "err", err) return jsonOut } diff --git a/pkg/healthcheck/reposize.go b/pkg/healthcheck/reposize.go index 3c362b2..7103be4 100644 --- a/pkg/healthcheck/reposize.go +++ b/pkg/healthcheck/reposize.go @@ -1,7 +1,7 @@ package healthcheck import ( - "fmt" + "log/slog" "os/exec" "strconv" "strings" @@ -24,7 +24,7 @@ func RepoSize() (jsonOut CheckStage) { if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = fmt.Errorf("Error running git command:%w", err) + slog.Error("running git command:", "err", err) return jsonOut } @@ -38,7 +38,7 @@ func RepoSize() (jsonOut CheckStage) { if err != nil { jsonOut.StdOut += "Failed" jsonOut.ExitCode = 1 - jsonOut.ErrorLog = fmt.Errorf("Error running git command:%w", err) + slog.Error("running git command:", "err", err) return jsonOut } sum += size diff --git a/pkg/healthcheck/utils.go b/pkg/healthcheck/utils.go index 21bb256..449953c 100644 --- a/pkg/healthcheck/utils.go +++ b/pkg/healthcheck/utils.go @@ -8,11 +8,10 @@ import ( // For ExitCode, see https://focs.ji.sjtu.edu.cn/git/TAs/resources/src/branch/drone/dronelib.checks // 1 for unrecoverable error and 0 for succeses type CheckStage struct { - Name string `json:"name of check"` + Name string `json:"name"` StdOut string `json:"stdout"` ExitCode int `json:"exit code"` StdErr string `json:"stderr"` - ErrorLog error `json:"errorLog"` } // addExt appends the specified extension to each file name in the given fileList. -- 2.30.2 From 2d5fe25d1a5f92f97a9de44a9329ea347668f43d Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sat, 15 Jun 2024 04:06:32 -0400 Subject: [PATCH 05/37] fix: output format --- cmd/healthcheck/main.go | 60 +++++++++++++------------- internal/parsers/healthcheck/parser.go | 26 +++++------ pkg/healthcheck/commit.go | 36 ++++------------ pkg/healthcheck/forbidden.go | 29 +++---------- pkg/healthcheck/meta.go | 28 +++--------- pkg/healthcheck/nonascii.go | 27 +++--------- pkg/healthcheck/release.go | 32 +++----------- pkg/healthcheck/reposize.go | 30 +++---------- pkg/healthcheck/utils.go | 9 ---- pkg/healthcheck/verify.go | 59 ++++--------------------- 10 files changed, 88 insertions(+), 248 deletions(-) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index 2542a62..d10b311 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -1,7 +1,6 @@ package main import ( - "encoding/json" "flag" "fmt" "log/slog" @@ -38,10 +37,7 @@ func setupSlog() { // Generally, err is used for runtime errors, and checkRes is used for the result of the checks. func main() { - var info []healthcheck.CheckStage var gitWhitelist, metaFile, releaseTags []string - var tmp healthcheck.CheckStage - rootDir := flag.String("root", "", "") repo := flag.String("repo", "", "") droneBranch := flag.String("droneBranch", "", "") @@ -54,33 +50,35 @@ func main() { parseMultiValueFlag(&releaseTags, "releaseTags", "") flag.Parse() setupSlog() - tmp = healthcheck.RepoSize() - info = append(info, tmp) - - tmp = healthcheck.ForbiddenCheck(*rootDir, gitWhitelist, *repo, *droneBranch) - info = append(info, tmp) - - tmp = healthcheck.MetaCheck(*rootDir, metaFile) - info = append(info, tmp) - - tmp = healthcheck.NonAsciiFiles(*rootDir) - info = append(info, tmp) - - tmp = healthcheck.NonAsciiMsg(*rootDir) - info = append(info, tmp) - - // TODO: find a way to test the release tag - tmp = healthcheck.CheckReleases(*rootDir, *releaseCategories, *releaseNumber) - info = append(info, tmp) - - // FIXME: for drone usage - tmp = healthcheck.Verify(*rootDir, *adminDir) - info = append(info, tmp) - - jsonData, err := json.Marshal(info) + var err error + err = healthcheck.RepoSize() if err != nil { - fmt.Fprint(os.Stderr, err) - os.Exit(1) + fmt.Printf("## Repo Size Check Failed:\n%s\n", err.Error()) + } + err = healthcheck.ForbiddenCheck(*rootDir, gitWhitelist, *repo, *droneBranch) + if err != nil { + fmt.Printf("## Forbidden File Check Failed:\n%s\n", err.Error()) + } + err = healthcheck.MetaCheck(*rootDir, metaFile) + if err != nil { + fmt.Printf("## Forbidden File Check Failed:\n%s\n", err.Error()) + } + err = healthcheck.NonAsciiFiles(*rootDir) + if err != nil { + fmt.Printf("## Non-ASCII Characters File Check Failed:\n%s\n", err.Error()) + } + err = healthcheck.NonAsciiMsg(*rootDir) + if err != nil { + fmt.Printf("## Non-ASCII Characters Commit Message Check Failed:\n%s\n", err.Error()) + } + // TODO: find a way to test the release tag + err = healthcheck.CheckReleases(*rootDir, *releaseCategories, *releaseNumber) + if err != nil { + fmt.Printf("## Release Tag Check Failed:\n%s\n", err.Error()) + } + // FIXME: for drone usage + err = healthcheck.VerifyDirectory(*rootDir, *adminDir) + if err != nil { + fmt.Printf("## Directory File Check Failed:\n%s\n", err.Error()) } - fmt.Printf("%s", jsonData) } diff --git a/internal/parsers/healthcheck/parser.go b/internal/parsers/healthcheck/parser.go index 5655c3d..cae365c 100644 --- a/internal/parsers/healthcheck/parser.go +++ b/internal/parsers/healthcheck/parser.go @@ -7,41 +7,35 @@ import ( "github.com/criyle/go-judge/envexec" ) -type Conf struct { - Score int - Comment string -} - type Healthcheck struct{} -func Parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult { +func Parse(executorResult stage.ExecutorResult) (stage.ParserResult, bool) { stdout := executorResult.Files["stdout"] stderr := executorResult.Files["stderr"] if executorResult.Status != stage.Status(envexec.StatusAccepted) { return stage.ParserResult{ Score: 0, Comment: fmt.Sprintf( - "Unexpected executor status: %s.\nStderr: %s", - executorResult.Status, stderr, + "Unexpected executor status: %s.\nStdout: %s\nStderr: %s", + executorResult.Status, stdout, stderr, ), - } + }, true } return stage.ParserResult{ Score: 0, Comment: stdout, - } + }, stdout != "" } func (*Healthcheck) Run(results []stage.ExecutorResult, confAny any) ( []stage.ParserResult, bool, error, ) { - conf, err := stage.DecodeConf[Conf](confAny) - if err != nil { - return nil, true, err - } var res []stage.ParserResult + forceQuit := false for _, result := range results { - res = append(res, Parse(result, *conf)) + parserResult, forceQuitResult := Parse(result) + res = append(res, parserResult) + forceQuit = forceQuit || forceQuitResult } - return res, false, nil + return res, forceQuit, nil } diff --git a/pkg/healthcheck/commit.go b/pkg/healthcheck/commit.go index 1532cc1..2db46d9 100644 --- a/pkg/healthcheck/commit.go +++ b/pkg/healthcheck/commit.go @@ -1,6 +1,7 @@ package healthcheck import ( + "fmt" "log/slog" "strings" "unicode" @@ -14,36 +15,23 @@ import ( // Otherwise, it iterates over each character in the message and checks if it is a non-ASCII character. // If a non-ASCII character is found, it returns an error indicating not to use non-ASCII characters in commit messages. // Otherwise, it returns nil indicating that the commit message is valid. -func NonAsciiMsg(root string) (jsonOut CheckStage) { - jsonOut = CheckStage{ - Name: "NonAsciiMsg", - StdOut: "Checking for non-ASCII characters in commit message: ", - ExitCode: 0, - StdErr: "", - } - +func NonAsciiMsg(root string) error { // cmd := exec.Command("git", "log", "--encoding=UTF-8", "--format=%B") repo, err := git.PlainOpen(root) if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 slog.Error("openning git repo", "err", err) - return jsonOut + return fmt.Errorf("error openning git repo: %v", err) } ref, err := repo.Head() if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 slog.Error("getting reference", "err", err) - return jsonOut + return fmt.Errorf("error getting reference: %v", err) } commits, err := repo.Log(&git.LogOptions{From: ref.Hash()}) if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 slog.Error("getting commits", "err", err) - return jsonOut + return fmt.Errorf("error getting commits: %v", err) } var msgs []string @@ -52,10 +40,8 @@ func NonAsciiMsg(root string) (jsonOut CheckStage) { return nil }) if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 - slog.Error("converting log to string", "err", err) - return jsonOut + slog.Error("iterating commits", "err", err) + return fmt.Errorf("error iterating commits: %v", err) } var nonAsciiMsgs []string @@ -73,11 +59,7 @@ func NonAsciiMsg(root string) (jsonOut CheckStage) { } } if len(nonAsciiMsgs) > 0 { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 105 - jsonOut.StdErr = "Non-ASCII characters in commit messages:\n" + strings.Join(nonAsciiMsgs, "\n") - return jsonOut + return fmt.Errorf("Non-ASCII characters in commit messages:\n" + strings.Join(nonAsciiMsgs, "\n")) } - jsonOut.StdOut += "OK" - return jsonOut + return nil } diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index 9333094..042767f 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -16,7 +16,6 @@ func getForbiddens(root string, fileList []string) ([]string, error) { var regexList []*regexp.Regexp regexList, err := getRegex(fileList) if err != nil { - fmt.Println("Error compiling regex:", err) return nil, err } @@ -52,24 +51,11 @@ func getForbiddens(root string, fileList []string) ([]string, error) { // forbiddenCheck checks for forbidden files in the specified root directory. // It prints the list of forbidden files found, along with instructions on how to fix them. -func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch string) (jsonOut CheckStage) { - jsonOut = CheckStage{ - Name: "forbiddenFile", - StdOut: "Checking forbidden files: ", - ExitCode: 0, - StdErr: "", - } - - // INFO: test case - // regexList := []string{`\.$`, `\.git`, `\.drone.yml`, `Makefile`, `CMakeLists.txt`,`.*\.go`,`.*\.toml`, `.*\.c`, `.*\.cc`, `.*\.cpp`, `.*\.h`, `.*\.md`} - // rootDir = "/Users/zhouzhaojiacheng/Desktop/STUDENT_ORG/TechJI/Dev/joj/JOJ3" - +func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch string) error { forbids, err := getForbiddens(rootDir, regexList) if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 - slog.Error("get forbiddens", "error", err) - return jsonOut + slog.Error("getting forbiddens", "error", err) + return fmt.Errorf("error getting forbiddens: %w", err) } var message string @@ -84,12 +70,7 @@ func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch message += fmt.Sprint(file, " ") } message += fmt.Sprint("; do git filter-repo --force --invert-paths --path \\\"\\$i\\\"; done\ngit remote add origin ", repo, "\ngit push --set-upstream origin ", droneBranch, " --force") - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 103 - jsonOut.StdErr = message - return jsonOut - } else { - jsonOut.StdOut += "OK" - return jsonOut + return fmt.Errorf(message) } + return nil } diff --git a/pkg/healthcheck/meta.go b/pkg/healthcheck/meta.go index 3cad159..2e78d50 100644 --- a/pkg/healthcheck/meta.go +++ b/pkg/healthcheck/meta.go @@ -19,7 +19,7 @@ func getMetas(rootDir string, fileList []string) ([]string, string, error) { files, err := os.ReadDir(rootDir) if err != nil { - return nil, "", fmt.Errorf("Error reading directory:%w", err) + return nil, "", fmt.Errorf("error reading directory: %w", err) } matched := false @@ -60,28 +60,14 @@ func getMetas(rootDir string, fileList []string) ([]string, string, error) { // metaCheck performs a check for metadata files in the specified root directory. // It prints a message if any required metadata files are missing. -func MetaCheck(rootDir string, fileList []string) (jsonOut CheckStage) { +func MetaCheck(rootDir string, fileList []string) error { unmatchedList, umatchedRes, err := getMetas(rootDir, fileList) - jsonOut = CheckStage{ - Name: "metaFile", - StdOut: "Checking the existence of meta file: ", - ExitCode: 0, - StdErr: "", - } - if err != nil { - jsonOut.ExitCode = 1 - slog.Error("get metas", "err", err) - return jsonOut + slog.Error("getting metas", "err", err) + return fmt.Errorf("error getting metas: %w", err) } - - if len(unmatchedList) == 0 { - jsonOut.StdOut += "OK" - return jsonOut - } else { - jsonOut.ExitCode = 104 - jsonOut.StdOut += "Failed" - jsonOut.StdErr = fmt.Sprintf("%d important project files missing\n"+umatchedRes, len(unmatchedList)) - return jsonOut + if len(unmatchedList) != 0 { + return fmt.Errorf("%d important project files missing\n"+umatchedRes, len(unmatchedList)) } + return nil } diff --git a/pkg/healthcheck/nonascii.go b/pkg/healthcheck/nonascii.go index f2fe523..1d910f9 100644 --- a/pkg/healthcheck/nonascii.go +++ b/pkg/healthcheck/nonascii.go @@ -61,31 +61,14 @@ func getNonAscii(root string) ([]string, error) { // nonAsciiFiles checks for non-ASCII characters in files within the specified root directory. // It prints a message with the paths to files containing non-ASCII characters, if any. -func NonAsciiFiles(root string) (jsonOut CheckStage) { - jsonOut = CheckStage{ - Name: "NonAsciiFiles", - StdOut: "Checking for non-ascii files: ", - ExitCode: 0, - StdErr: "", - } +func NonAsciiFiles(root string) error { nonAscii, err := getNonAscii(root) if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 - slog.Error("get non-ascii", "err", err) - return jsonOut + slog.Error("getting non-ascii", "err", err) + return fmt.Errorf("error getting non-ascii: %w", err) } - - var nonAsciiRes string if len(nonAscii) > 0 { - nonAsciiRes = fmt.Sprintf("Non-ASCII characters found in the following files:\n" + strings.Join(nonAscii, "\n")) - jsonOut.ExitCode = 105 - jsonOut.StdOut += "Failed" - } else { - jsonOut.StdOut += "OK" + return fmt.Errorf("Non-ASCII characters found in the following files:\n" + strings.Join(nonAscii, "\n")) } - - jsonOut.StdErr = nonAsciiRes - - return jsonOut + return nil } diff --git a/pkg/healthcheck/release.go b/pkg/healthcheck/release.go index 43e35e8..81beade 100644 --- a/pkg/healthcheck/release.go +++ b/pkg/healthcheck/release.go @@ -2,7 +2,6 @@ package healthcheck import ( "fmt" - "log" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" @@ -19,12 +18,12 @@ func catTags(all []string) (out string) { func getTagsFromRepo(repoPath string) ([]string, error) { repo, err := git.PlainOpen(repoPath) if err != nil { - return nil, fmt.Errorf("Cannot open repo: %v", err) + return nil, fmt.Errorf("error opening repo: %v", err) } refs, err := repo.Tags() if err != nil { - return nil, fmt.Errorf("Cannot get tags: %v", err) + return nil, fmt.Errorf("error getting tags: %v", err) } var tags []string @@ -33,27 +32,18 @@ func getTagsFromRepo(repoPath string) ([]string, error) { return nil }) if err != nil { - return nil, fmt.Errorf("Error while iterating tags: %v", err) + return nil, fmt.Errorf("error iterating tags: %v", err) } return tags, nil } -func CheckReleases(repoPath string, category string, n int) (jsonOut CheckStage) { - jsonOut = CheckStage{ - Name: "ReleaseCheck", - StdOut: "Checking release tag: ", - ExitCode: 0, - StdErr: "", - } - +func CheckReleases(repoPath string, category string, n int) error { tags, err := getTagsFromRepo(repoPath) if err != nil { - log.Fatalf("Error in getting tags: %v", err) + return fmt.Errorf("error getting tags: %v", err) } - var prefix string - switch category { case "exam": prefix = "e" @@ -64,7 +54,6 @@ func CheckReleases(repoPath string, category string, n int) (jsonOut CheckStage) default: prefix = "a" } - target := prefix + fmt.Sprintf("%d", n) found := false for _, tag := range tags { @@ -75,14 +64,7 @@ func CheckReleases(repoPath string, category string, n int) (jsonOut CheckStage) } if !found { tagList := catTags(tags) - jsonOut.ExitCode = 107 - jsonOut.StdOut = "Failed" - jsonOut.StdErr = fmt.Sprintf("wrong release tag '%s', please use one of %s aborting", target, tagList) - return jsonOut + return fmt.Errorf("Wrong release tag '%s'. Please use one of %s.", target, tagList) } - - jsonOut.StdOut += "OK" - jsonOut.ExitCode = 0 - jsonOut.StdErr = "Fine" - return jsonOut + return nil } diff --git a/pkg/healthcheck/reposize.go b/pkg/healthcheck/reposize.go index 7103be4..dd17d06 100644 --- a/pkg/healthcheck/reposize.go +++ b/pkg/healthcheck/reposize.go @@ -1,6 +1,7 @@ package healthcheck import ( + "fmt" "log/slog" "os/exec" "strconv" @@ -9,25 +10,15 @@ import ( // RepoSize checks the size of the repository to determine if it is oversized. // It executes the 'git count-objects -v' command to obtain the size information, -func RepoSize() (jsonOut CheckStage) { - jsonOut = CheckStage{ - Name: "RepoSize", - StdOut: "Checking repository size: ", - ExitCode: 0, - StdErr: "", - } - +func RepoSize() error { // TODO: reimplement here when go-git is available // https://github.com/go-git/go-git/blob/master/COMPATIBILITY.md cmd := exec.Command("git", "count-objects", "-v") output, err := cmd.CombinedOutput() if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 slog.Error("running git command:", "err", err) - return jsonOut + return fmt.Errorf("error running git command: %w", err) } - lines := strings.Split(string(output), "\n") var sum int for _, line := range lines { @@ -36,21 +27,14 @@ func RepoSize() (jsonOut CheckStage) { sizeStr := fields[1] size, err := strconv.Atoi(sizeStr) if err != nil { - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 1 slog.Error("running git command:", "err", err) - return jsonOut + return fmt.Errorf("error running git command: %w", err) } sum += size } } - - if sum <= 2048 { - jsonOut.StdOut += "OK" - return jsonOut + if sum > 2048 { + return fmt.Errorf("Repository larger than 2MB. Please clean up or contact the teaching team.") } - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 100 - jsonOut.StdErr = "repository larger than 2MB, please clean up or contact the teaching team." - return jsonOut + return nil } diff --git a/pkg/healthcheck/utils.go b/pkg/healthcheck/utils.go index 449953c..8939f22 100644 --- a/pkg/healthcheck/utils.go +++ b/pkg/healthcheck/utils.go @@ -5,15 +5,6 @@ import ( "regexp" ) -// For ExitCode, see https://focs.ji.sjtu.edu.cn/git/TAs/resources/src/branch/drone/dronelib.checks -// 1 for unrecoverable error and 0 for succeses -type CheckStage struct { - Name string `json:"name"` - StdOut string `json:"stdout"` - ExitCode int `json:"exit code"` - StdErr string `json:"stderr"` -} - // addExt appends the specified extension to each file name in the given fileList. // It modifies the original fileList in place. func addExt(fileList []string, ext string) { diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index b201b53..d1595ce 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -47,68 +47,27 @@ func filesMatch(file1, file2 string) (bool, error) { return true, nil } -// compareDirectories compares the contents of two directories. -func compareDirectories(dir1, dir2 string, jsonOut *CheckStage) error { - allMatch := true - var message string - err := filepath.Walk(dir1, func(path string, info os.FileInfo, err error) error { +// VerifyDirectory checks if the contents of two directories are identical. +func VerifyDirectory(rootDir, compareDir string) error { + err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error { if err != nil { - return err + return fmt.Errorf("error walking directory: %w", err) } - if !info.IsDir() { - relPath, _ := filepath.Rel(dir1, path) - file2 := filepath.Join(dir2, relPath) - + relPath, _ := filepath.Rel(rootDir, path) + file2 := filepath.Join(compareDir, relPath) if !fileExists(file2) { - // fmt.Printf("File %s in %s is missing in %s\n, please immediately revert your changes!\n", relPath, dir1, dir2) - message += "File missing" - allMatch = false - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 101 - jsonOut.StdErr = message - return nil + return fmt.Errorf("File %s in %s is missing in %s. Please immediately revert your changes!\n", relPath, rootDir, compareDir) } - - // fmt.Printf("Checking integrity of %s:\n", path) match, err := filesMatch(path, file2) if err != nil { - return err + return fmt.Errorf("error matching files: %w", err) } - if !match { - // fmt.Printf("File %s in %s is not identical to %s\nPlease revert your changes or contact the teaching team if you have a valid reason for adjusting them.\n", relPath, dir1, dir2) - message += "File is not identical" - allMatch = false - jsonOut.StdOut += "Failed" - jsonOut.ExitCode = 101 - jsonOut.StdErr = message + return fmt.Errorf("File %s in %s is not identical to %s. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.\n", relPath, rootDir, compareDir) } } return nil }) - - if allMatch { - jsonOut.StdOut += "OK!" - } else { - jsonOut.StdOut += "Failed!" - } - return err } - -// Verify checks if the contents of two directories are identical. -func Verify(rootDir, compareDir string) CheckStage { - jsonOut := CheckStage{ - Name: "verifyFile", - StdOut: "Checking files to be verified: ", - ExitCode: 0, - StdErr: "", - } - err := compareDirectories(rootDir, compareDir, &jsonOut) - // fmt.Println("Comparison finished ") - if err != nil { - fmt.Println("Error:", err) - } - return jsonOut -} -- 2.30.2 From dc6e5648323c5200ae4d433866a2369e518f2964 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 16 Jun 2024 15:19:47 -0400 Subject: [PATCH 06/37] fix: output content --- cmd/healthcheck/main.go | 8 +++++--- pkg/healthcheck/forbidden.go | 16 +++++++--------- pkg/healthcheck/release.go | 12 ++---------- pkg/healthcheck/verify.go | 6 ++++-- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index d10b311..03497dd 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -77,8 +77,10 @@ func main() { fmt.Printf("## Release Tag Check Failed:\n%s\n", err.Error()) } // FIXME: for drone usage - err = healthcheck.VerifyDirectory(*rootDir, *adminDir) - if err != nil { - fmt.Printf("## Directory File Check Failed:\n%s\n", err.Error()) + if adminDir != nil && *adminDir != "" { + err = healthcheck.VerifyDirectory(*rootDir, *adminDir) + if err != nil { + fmt.Printf("## Directory File Check Failed:\n%s\n", err.Error()) + } } } diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index 042767f..16549f8 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "regexp" + "strings" ) // getForbiddens retrieves a list of forbidden files in the specified root directory. @@ -61,15 +62,12 @@ func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch var message string if len(forbids) > 0 { - message += fmt.Sprint(103, "the following forbidden files were found: ") - for _, file := range forbids { - message += fmt.Sprint(file, ", ") - } - message += "\n\nTo fix it, first make a backup of your repository and then run the following commands:\nfor i in " - for _, file := range forbids { - message += fmt.Sprint(file, " ") - } - message += fmt.Sprint("; do git filter-repo --force --invert-paths --path \\\"\\$i\\\"; done\ngit remote add origin ", repo, "\ngit push --set-upstream origin ", droneBranch, " --force") + message = "The following forbidden files were found: " + + strings.Join(forbids, ", ") + + "\n\nTo fix it, first make a backup of your repository and then run the following commands:\nfor i in " + + strings.Join(forbids, " ") + + fmt.Sprint("; do git filter-repo --force --invert-paths --path \\\"\\$i\\\"; done\ngit remote add origin ", + repo, "\ngit push --set-upstream origin ", droneBranch, " --force") return fmt.Errorf(message) } return nil diff --git a/pkg/healthcheck/release.go b/pkg/healthcheck/release.go index 81beade..7bc1e85 100644 --- a/pkg/healthcheck/release.go +++ b/pkg/healthcheck/release.go @@ -2,19 +2,12 @@ package healthcheck import ( "fmt" + "strings" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" ) -func catTags(all []string) (out string) { - out = "" - for _, str := range all { - out += str + " " - } - return out -} - func getTagsFromRepo(repoPath string) ([]string, error) { repo, err := git.PlainOpen(repoPath) if err != nil { @@ -63,8 +56,7 @@ func CheckReleases(repoPath string, category string, n int) error { } } if !found { - tagList := catTags(tags) - return fmt.Errorf("Wrong release tag '%s'. Please use one of %s.", target, tagList) + return fmt.Errorf("Wrong release tag '%s'. Please use one of '%s'.", target, strings.Join(tags, "', '")) } return nil } diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index d1595ce..1549f0a 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -57,14 +57,16 @@ func VerifyDirectory(rootDir, compareDir string) error { relPath, _ := filepath.Rel(rootDir, path) file2 := filepath.Join(compareDir, relPath) if !fileExists(file2) { - return fmt.Errorf("File %s in %s is missing in %s. Please immediately revert your changes!\n", relPath, rootDir, compareDir) + return fmt.Errorf("File %s is missing. Please immediately revert your changes!\n", + filepath.Join(rootDir, relPath)) } match, err := filesMatch(path, file2) if err != nil { return fmt.Errorf("error matching files: %w", err) } if !match { - return fmt.Errorf("File %s in %s is not identical to %s. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.\n", relPath, rootDir, compareDir) + return fmt.Errorf("File %s is altered. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.\n", + filepath.Join(rootDir, relPath)) } } return nil -- 2.30.2 From 1b284dd04e5c57e60e21ec655de9326be70aad3f Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Tue, 18 Jun 2024 12:54:17 +0800 Subject: [PATCH 07/37] chore: update submodule --- examples/healthcheck/asciifile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/healthcheck/asciifile b/examples/healthcheck/asciifile index 46804af..ff1d788 160000 --- a/examples/healthcheck/asciifile +++ b/examples/healthcheck/asciifile @@ -1 +1 @@ -Subproject commit 46804afd2ebe8787a9d43711b191e424134ce25b +Subproject commit ff1d788beeae458682296c77ea759ad6b0313c01 -- 2.30.2 From 04127c5b129bfa42ba63f480e7cd2937bb3b3b4f Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Tue, 18 Jun 2024 16:40:41 +0800 Subject: [PATCH 08/37] fix: forbid --- examples/healthcheck/asciifile | 2 +- pkg/healthcheck/forbidden.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/healthcheck/asciifile b/examples/healthcheck/asciifile index ff1d788..a0a9a6a 160000 --- a/examples/healthcheck/asciifile +++ b/examples/healthcheck/asciifile @@ -1 +1 @@ -Subproject commit ff1d788beeae458682296c77ea759ad6b0313c01 +Subproject commit a0a9a6a629d48179fb2647027e5fadad242b2601 diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index 16549f8..7cd6d71 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -66,7 +66,7 @@ func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch strings.Join(forbids, ", ") + "\n\nTo fix it, first make a backup of your repository and then run the following commands:\nfor i in " + strings.Join(forbids, " ") + - fmt.Sprint("; do git filter-repo --force --invert-paths --path \\\"\\$i\\\"; done\ngit remote add origin ", + fmt.Sprint("; do git filter-repo --force --invert-paths --path \"$i\"; done\ngit remote add origin ", repo, "\ngit push --set-upstream origin ", droneBranch, " --force") return fmt.Errorf(message) } -- 2.30.2 From 6dfe99bee1db3eb99ff97a744b0a19a4f7671904 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Tue, 18 Jun 2024 17:31:51 +0800 Subject: [PATCH 09/37] chore: update submodules --- examples/healthcheck/asciifile | 2 +- examples/healthcheck/asciimsg | 2 +- examples/healthcheck/forbiddenfile | 2 +- examples/healthcheck/release | 2 +- examples/healthcheck/reposize | 2 +- examples/healthcheck/repoverify | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/healthcheck/asciifile b/examples/healthcheck/asciifile index a0a9a6a..0462736 160000 --- a/examples/healthcheck/asciifile +++ b/examples/healthcheck/asciifile @@ -1 +1 @@ -Subproject commit a0a9a6a629d48179fb2647027e5fadad242b2601 +Subproject commit 04627367d521b696daa37c45b3d4439166374728 diff --git a/examples/healthcheck/asciimsg b/examples/healthcheck/asciimsg index e9ed6a4..52c9787 160000 --- a/examples/healthcheck/asciimsg +++ b/examples/healthcheck/asciimsg @@ -1 +1 @@ -Subproject commit e9ed6a464a507730ef956bb8ea6dbe84fffea7ad +Subproject commit 52c9787a8a735e99f42c493fd28931b424bfc2eb diff --git a/examples/healthcheck/forbiddenfile b/examples/healthcheck/forbiddenfile index 245d036..f1c9d84 160000 --- a/examples/healthcheck/forbiddenfile +++ b/examples/healthcheck/forbiddenfile @@ -1 +1 @@ -Subproject commit 245d036af0cbfe3745ef303d239a2d7225067d0b +Subproject commit f1c9d8474482b75e6ce7f36c296e6f8bc9c0b799 diff --git a/examples/healthcheck/release b/examples/healthcheck/release index a4cedea..721fa45 160000 --- a/examples/healthcheck/release +++ b/examples/healthcheck/release @@ -1 +1 @@ -Subproject commit a4cedea002a198c2dae373f7ee6f6dc67753fae6 +Subproject commit 721fa459fa9408b9628e143120a378a7a500584e diff --git a/examples/healthcheck/reposize b/examples/healthcheck/reposize index d78308b..25c5453 160000 --- a/examples/healthcheck/reposize +++ b/examples/healthcheck/reposize @@ -1 +1 @@ -Subproject commit d78308bcaaaeda9ead86069652288ae911503e33 +Subproject commit 25c5453a575b154345ea235d79410014ee35e618 diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify index a7a3bd0..66a3d6f 160000 --- a/examples/healthcheck/repoverify +++ b/examples/healthcheck/repoverify @@ -1 +1 @@ -Subproject commit a7a3bd0894c2e727e3ab3f9ddda3d438fbb86b30 +Subproject commit 66a3d6f739b22330569e259f4c7799a85cb2a345 -- 2.30.2 From 395ff2bb28a9ed4c75de25dcf0cddb5da73deac5 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Wed, 19 Jun 2024 03:38:33 -0400 Subject: [PATCH 10/37] chore: update submodule --- examples/healthcheck/forbiddenfile | 2 +- examples/healthcheck/meta | 2 +- examples/healthcheck/release | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/healthcheck/forbiddenfile b/examples/healthcheck/forbiddenfile index f1c9d84..656999a 160000 --- a/examples/healthcheck/forbiddenfile +++ b/examples/healthcheck/forbiddenfile @@ -1 +1 @@ -Subproject commit f1c9d8474482b75e6ce7f36c296e6f8bc9c0b799 +Subproject commit 656999a9093968a8208f1964beba504eea6b304a diff --git a/examples/healthcheck/meta b/examples/healthcheck/meta index 4f5e444..3a9e737 160000 --- a/examples/healthcheck/meta +++ b/examples/healthcheck/meta @@ -1 +1 @@ -Subproject commit 4f5e444940d2c383a0b069405e2ef42b01878bc5 +Subproject commit 3a9e737b3963a03eb00c5c3c021d613764972c94 diff --git a/examples/healthcheck/release b/examples/healthcheck/release index 721fa45..ee28550 160000 --- a/examples/healthcheck/release +++ b/examples/healthcheck/release @@ -1 +1 @@ -Subproject commit 721fa459fa9408b9628e143120a378a7a500584e +Subproject commit ee285502ff5bab1653566c3bd893dda9e2aaf067 -- 2.30.2 From 8383c21b2864688eae0e8ec8cbcc7c6dcb1e033f Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Wed, 19 Jun 2024 16:47:14 +0800 Subject: [PATCH 11/37] fix: release tag --- pkg/healthcheck/release.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/healthcheck/release.go b/pkg/healthcheck/release.go index 7bc1e85..924d782 100644 --- a/pkg/healthcheck/release.go +++ b/pkg/healthcheck/release.go @@ -56,7 +56,7 @@ func CheckReleases(repoPath string, category string, n int) error { } } if !found { - return fmt.Errorf("Wrong release tag '%s'. Please use one of '%s'.", target, strings.Join(tags, "', '")) + return fmt.Errorf("Wrong release tag '%s' or missing release tags. Please use one of '%s'.", target, strings.Join(tags, "', '")) } return nil } -- 2.30.2 From c42c7e402ef92ab413260eed779fb386b3b583b2 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Thu, 20 Jun 2024 04:34:18 -0400 Subject: [PATCH 12/37] chore: update submodule --- examples/healthcheck/asciifile | 2 +- examples/healthcheck/asciimsg | 2 +- examples/healthcheck/forbiddenfile | 2 +- examples/healthcheck/meta | 2 +- examples/healthcheck/release | 2 +- examples/healthcheck/reposize | 2 +- examples/healthcheck/repoverify | 2 +- scripts/run_foreach_test_repos.sh | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/healthcheck/asciifile b/examples/healthcheck/asciifile index 0462736..54fe3e3 160000 --- a/examples/healthcheck/asciifile +++ b/examples/healthcheck/asciifile @@ -1 +1 @@ -Subproject commit 04627367d521b696daa37c45b3d4439166374728 +Subproject commit 54fe3e3a386a656664372fd95b527fe1f957dcc8 diff --git a/examples/healthcheck/asciimsg b/examples/healthcheck/asciimsg index 52c9787..36bb5fb 160000 --- a/examples/healthcheck/asciimsg +++ b/examples/healthcheck/asciimsg @@ -1 +1 @@ -Subproject commit 52c9787a8a735e99f42c493fd28931b424bfc2eb +Subproject commit 36bb5fb15f100078bd3af1027017825932f8c24b diff --git a/examples/healthcheck/forbiddenfile b/examples/healthcheck/forbiddenfile index 656999a..62c43fe 160000 --- a/examples/healthcheck/forbiddenfile +++ b/examples/healthcheck/forbiddenfile @@ -1 +1 @@ -Subproject commit 656999a9093968a8208f1964beba504eea6b304a +Subproject commit 62c43fe51666417c7cbb227d6daaeee7189b6944 diff --git a/examples/healthcheck/meta b/examples/healthcheck/meta index 3a9e737..5c2cd9e 160000 --- a/examples/healthcheck/meta +++ b/examples/healthcheck/meta @@ -1 +1 @@ -Subproject commit 3a9e737b3963a03eb00c5c3c021d613764972c94 +Subproject commit 5c2cd9e6b31c6f223ac5d3ee5b07f11fbd378427 diff --git a/examples/healthcheck/release b/examples/healthcheck/release index ee28550..fc9828b 160000 --- a/examples/healthcheck/release +++ b/examples/healthcheck/release @@ -1 +1 @@ -Subproject commit ee285502ff5bab1653566c3bd893dda9e2aaf067 +Subproject commit fc9828bde135e53a7ef3e6367c708d9a000afc74 diff --git a/examples/healthcheck/reposize b/examples/healthcheck/reposize index 25c5453..2073d68 160000 --- a/examples/healthcheck/reposize +++ b/examples/healthcheck/reposize @@ -1 +1 @@ -Subproject commit 25c5453a575b154345ea235d79410014ee35e618 +Subproject commit 2073d687142470aed2dcabb5bb0e016301a4140d diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify index 66a3d6f..36c8659 160000 --- a/examples/healthcheck/repoverify +++ b/examples/healthcheck/repoverify @@ -1 +1 @@ -Subproject commit 66a3d6f739b22330569e259f4c7799a85cb2a345 +Subproject commit 36c86597630525689ff7ee087685a67f0f294408 diff --git a/scripts/run_foreach_test_repos.sh b/scripts/run_foreach_test_repos.sh index 3c9ce55..862524a 100755 --- a/scripts/run_foreach_test_repos.sh +++ b/scripts/run_foreach_test_repos.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -ex +# set -ex tmp_dir=${1:-./tmp} JOJ3=$(git rev-parse --show-toplevel)/build/joj3 command=${2:-$JOJ3} -- 2.30.2 From 1c72d004371dfab9c12d3b9420267b44ae1be8ff Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Thu, 20 Jun 2024 05:04:44 -0400 Subject: [PATCH 13/37] chore: update submodule --- examples/healthcheck/repoverify | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify index 36c8659..f9bed91 160000 --- a/examples/healthcheck/repoverify +++ b/examples/healthcheck/repoverify @@ -1 +1 @@ -Subproject commit 36c86597630525689ff7ee087685a67f0f294408 +Subproject commit f9bed916b7b8af0175210837a67b24fab614508e -- 2.30.2 From 8ba39d521a87c468bed7719bbe15590e0a827ac6 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Thu, 20 Jun 2024 20:24:39 +0800 Subject: [PATCH 14/37] feat: skip gitlocallist --- cmd/healthcheck/main.go | 3 ++- pkg/healthcheck/forbidden.go | 38 +++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index 03497dd..3557115 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -40,6 +40,7 @@ func main() { var gitWhitelist, metaFile, releaseTags []string 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, "") @@ -55,7 +56,7 @@ func main() { if err != nil { fmt.Printf("## Repo Size Check Failed:\n%s\n", err.Error()) } - err = healthcheck.ForbiddenCheck(*rootDir, gitWhitelist, *repo, *droneBranch) + err = healthcheck.ForbiddenCheck(*rootDir, gitWhitelist, localList, *repo, *droneBranch) if err != nil { fmt.Printf("## Forbidden File Check Failed:\n%s\n", err.Error()) } diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index 7cd6d71..0cbb21b 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -1,6 +1,7 @@ package healthcheck import ( + "bufio" "fmt" "log/slog" "os" @@ -9,9 +10,18 @@ import ( "strings" ) +func inString(str1 string, strList []string) bool { + for _, str := range strList { + if str1 == str { + return true + } + } + return false +} + // getForbiddens retrieves a list of forbidden files in the specified root directory. // It searches for files that do not match the specified regex patterns in the given file list. -func getForbiddens(root string, fileList []string) ([]string, error) { +func getForbiddens(root string, fileList []string, localList string) ([]string, error) { var matches []string var regexList []*regexp.Regexp @@ -20,6 +30,24 @@ func getForbiddens(root string, fileList []string) ([]string, error) { return nil, err } + var dirs []string + + if localList != "" { + file, err := os.Open(localList) + if err != nil { + return nil, fmt.Errorf("Failed to open file %s: %v\n", localList, err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + dirs = append(dirs, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("Error reading file %s: %v\n", localList, err) + } + } + err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err @@ -28,6 +56,10 @@ func getForbiddens(root string, fileList []string) ([]string, error) { if info.IsDir() { if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" { return filepath.SkipDir + } else if localList != "" { + if inString(info.Name(), dirs) { + return filepath.SkipDir + } } else { return nil } @@ -52,8 +84,8 @@ func getForbiddens(root string, fileList []string) ([]string, error) { // forbiddenCheck checks for forbidden files in the specified root directory. // It prints the list of forbidden files found, along with instructions on how to fix them. -func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch string) error { - forbids, err := getForbiddens(rootDir, regexList) +func ForbiddenCheck(rootDir string, regexList []string, localList string, repo string, droneBranch string) error { + forbids, err := getForbiddens(rootDir, regexList, localList) if err != nil { slog.Error("getting forbiddens", "error", err) return fmt.Errorf("error getting forbiddens: %w", err) -- 2.30.2 From 5d44956f4f59e05111fc855770800f308ff676e0 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Thu, 20 Jun 2024 20:26:29 +0800 Subject: [PATCH 15/37] feat: skip gitlocallist --- cmd/healthcheck/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index 3557115..3ff8733 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -56,7 +56,7 @@ func main() { if err != nil { fmt.Printf("## Repo Size Check Failed:\n%s\n", err.Error()) } - err = healthcheck.ForbiddenCheck(*rootDir, gitWhitelist, localList, *repo, *droneBranch) + err = healthcheck.ForbiddenCheck(*rootDir, gitWhitelist, *localList, *repo, *droneBranch) if err != nil { fmt.Printf("## Forbidden File Check Failed:\n%s\n", err.Error()) } -- 2.30.2 From 38ae48e30a13a75e26a88dce8def590b6568ba0d Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Thu, 20 Jun 2024 16:30:52 -0400 Subject: [PATCH 16/37] fix: typo --- scripts/run_foreach_test_repos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_foreach_test_repos.sh b/scripts/run_foreach_test_repos.sh index 862524a..3c9ce55 100755 --- a/scripts/run_foreach_test_repos.sh +++ b/scripts/run_foreach_test_repos.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# set -ex +set -ex tmp_dir=${1:-./tmp} JOJ3=$(git rev-parse --show-toplevel)/build/joj3 command=${2:-$JOJ3} -- 2.30.2 From 2838f4171f70a1f6ab01ebdc4a06cc7f5a90f5c4 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sat, 29 Jun 2024 15:43:03 -0400 Subject: [PATCH 17/37] chore: rename check --- cmd/healthcheck/main.go | 2 +- pkg/healthcheck/forbidden.go | 7 ++++--- pkg/healthcheck/{release.go => tag.go} | 5 ++--- 3 files changed, 7 insertions(+), 7 deletions(-) rename pkg/healthcheck/{release.go => tag.go} (83%) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index 3ff8733..7fe98bc 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -73,7 +73,7 @@ func main() { fmt.Printf("## Non-ASCII Characters Commit Message Check Failed:\n%s\n", err.Error()) } // TODO: find a way to test the release tag - err = healthcheck.CheckReleases(*rootDir, *releaseCategories, *releaseNumber) + err = healthcheck.CheckTags(*rootDir, *releaseCategories, *releaseNumber) if err != nil { fmt.Printf("## Release Tag Check Failed:\n%s\n", err.Error()) } diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index 0cbb21b..f700b74 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -54,13 +54,14 @@ func getForbiddens(root string, fileList []string, localList string) ([]string, } if info.IsDir() { - if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" { + switch { + case info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci": return filepath.SkipDir - } else if localList != "" { + case localList != "": if inString(info.Name(), dirs) { return filepath.SkipDir } - } else { + default: return nil } } diff --git a/pkg/healthcheck/release.go b/pkg/healthcheck/tag.go similarity index 83% rename from pkg/healthcheck/release.go rename to pkg/healthcheck/tag.go index 924d782..46e2b89 100644 --- a/pkg/healthcheck/release.go +++ b/pkg/healthcheck/tag.go @@ -2,7 +2,6 @@ package healthcheck import ( "fmt" - "strings" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" @@ -31,7 +30,7 @@ func getTagsFromRepo(repoPath string) ([]string, error) { return tags, nil } -func CheckReleases(repoPath string, category string, n int) error { +func CheckTags(repoPath string, category string, n int) error { tags, err := getTagsFromRepo(repoPath) if err != nil { return fmt.Errorf("error getting tags: %v", err) @@ -56,7 +55,7 @@ func CheckReleases(repoPath string, category string, n int) error { } } if !found { - return fmt.Errorf("Wrong release tag '%s' or missing release tags. Please use one of '%s'.", target, strings.Join(tags, "', '")) + return fmt.Errorf("Expected tag '%s' not found.", target) } return nil } -- 2.30.2 From 9e4a2c4e295fc7608a2a62b4ef56d57d9728922b Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Tue, 20 Aug 2024 14:23:48 +0800 Subject: [PATCH 18/37] fix: tag check output --- examples/healthcheck/asciifile | 2 +- examples/healthcheck/reposize | 2 +- pkg/healthcheck/tag.go | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/healthcheck/asciifile b/examples/healthcheck/asciifile index 54fe3e3..a236c7e 160000 --- a/examples/healthcheck/asciifile +++ b/examples/healthcheck/asciifile @@ -1 +1 @@ -Subproject commit 54fe3e3a386a656664372fd95b527fe1f957dcc8 +Subproject commit a236c7ea934de5e59525fa27e4211f4a48dbbf93 diff --git a/examples/healthcheck/reposize b/examples/healthcheck/reposize index 2073d68..a49a6aa 160000 --- a/examples/healthcheck/reposize +++ b/examples/healthcheck/reposize @@ -1 +1 @@ -Subproject commit 2073d687142470aed2dcabb5bb0e016301a4140d +Subproject commit a49a6aa29d3dcb0509e8de540db0781aca596f26 diff --git a/pkg/healthcheck/tag.go b/pkg/healthcheck/tag.go index 46e2b89..d0f7f76 100644 --- a/pkg/healthcheck/tag.go +++ b/pkg/healthcheck/tag.go @@ -2,6 +2,7 @@ package healthcheck import ( "fmt" + "strings" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" @@ -55,7 +56,7 @@ func CheckTags(repoPath string, category string, n int) error { } } if !found { - return fmt.Errorf("Expected tag '%s' not found.", target) + return fmt.Errorf("Wrong release tag '%s' or missing release tags. Please use one of '%s'.", target, strings.Join(tags, "', '")) } return nil } -- 2.30.2 From 3500abb29256566c150b0125be0c8d8914372508 Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Sun, 25 Aug 2024 23:18:24 +0800 Subject: [PATCH 19/37] fix: checksum --- pkg/healthcheck/verify.go | 125 +++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 55 deletions(-) diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index 1549f0a..e5d81a5 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -1,75 +1,90 @@ package healthcheck import ( - "bufio" + "crypto/sha256" + "encoding/hex" "fmt" + "io" "os" "path/filepath" + "strings" ) -// fileExists checks if a file exists at the specified path. -func fileExists(filePath string) bool { - _, err := os.Stat(filePath) - return !os.IsNotExist(err) -} - -// filesMatch checks if two files are identical. -func filesMatch(file1, file2 string) (bool, error) { - f1, err := os.Open(file1) +// getChecksum calculates the SHA-256 checksum of a file +func getChecksum(filePath string) (string, error) { + // Open the file + file, err := os.Open(filePath) if err != nil { - return false, err + return "", err } - defer f1.Close() + defer file.Close() - f2, err := os.Open(file2) + // Calculate SHA-256 + hash := sha256.New() + if _, err := io.Copy(hash, file); err != nil { + return "", err + } + + return hex.EncodeToString(hash.Sum(nil)), nil +} + +// checkFileChecksum checks if a single file's checksum matches the expected value +func checkFileChecksum(rootDir, fileName, expectedChecksum string) (bool, string) { + filePath := filepath.Join(rootDir, strings.TrimSpace(fileName)) + actualChecksum, err := getChecksum(filePath) if err != nil { - return false, err - } - defer f2.Close() - - scanner1 := bufio.NewScanner(f1) - scanner2 := bufio.NewScanner(f2) - - for scanner1.Scan() && scanner2.Scan() { - line1 := scanner1.Text() - line2 := scanner2.Text() - - if line1 != line2 { - return false, nil - } + return false, fmt.Sprintf("Error reading file %s: %v", filePath, err) } - if scanner1.Scan() || scanner2.Scan() { - // One file has more lines than the other - return false, nil + if actualChecksum == expectedChecksum { + return true, fmt.Sprintf("Checksum for %s passed!", filePath) + } else { + return false, fmt.Sprintf("Checksum for %s failed. Expected %s, but got %s. Please revert the changes!", filePath, expectedChecksum, actualChecksum) } - - return true, nil } -// VerifyDirectory checks if the contents of two directories are identical. -func VerifyDirectory(rootDir, compareDir string) error { - err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return fmt.Errorf("error walking directory: %w", err) +func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList string ) error { + // Parse command-line arguments + // checkFileNameList := flag.String("checkFileNameList", "", "Comma-separated list of files to check.") + // checkFileSumList := flag.String("checkFileSumList", "", "Comma-separated list of expected checksums.") + // rootDir := flag.String("rootDir", ".", "Root directory containing the files.") + // flag.Parse() + + // Process input file names and checksums + fileNames := strings.Split(checkFileNameList, ",") + checkSums := strings.Split(checkFileSumList, ",") + + // Check if the number of files matches the number of checksums + if len(fileNames) == 0 { + return fmt.Errorf("No checksum happened") + } + + if len(fileNames) != len(checkSums) { + return fmt.Errorf("Error: The number of files and checksums do not match.") + os.Exit(1) + } + + allPassed := true + var errorMessages []string + + // Check each file's checksum + for i, fileName := range fileNames { + expectedChecksum := strings.TrimSpace(checkSums[i]) + passed, message := checkFileChecksum(rootDir, fileName, expectedChecksum) + return fmt.Errorf(message) + if !passed { + allPassed = false + errorMessages = append(errorMessages, message) } - if !info.IsDir() { - relPath, _ := filepath.Rel(rootDir, path) - file2 := filepath.Join(compareDir, relPath) - if !fileExists(file2) { - return fmt.Errorf("File %s is missing. Please immediately revert your changes!\n", - filepath.Join(rootDir, relPath)) - } - match, err := filesMatch(path, file2) - if err != nil { - return fmt.Errorf("error matching files: %w", err) - } - if !match { - return fmt.Errorf("File %s is altered. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.\n", - filepath.Join(rootDir, relPath)) - } + } + + if allPassed { + return fmt.Errorf("Congratulations! All checksums passed!") + } else { + return fmt.Errorf("Some checksums failed. Please review the errors below:") + for _, msg := range errorMessages { + return fmt.Errorf(msg) } - return nil - }) - return err + } + return nil } -- 2.30.2 From 9cdc381e06950426c74a0709ed4f8cbcb935cadd Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Sun, 25 Aug 2024 23:19:04 +0800 Subject: [PATCH 20/37] fix: checksum function --- cmd/healthcheck/main.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index 7fe98bc..9901f70 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -44,8 +44,8 @@ func main() { droneBranch := flag.String("droneBranch", "", "") releaseCategories := flag.String("releaseCategories", "", "") releaseNumber := flag.Int("releaseNumber", 0, "") - // FIXME: for drone usage - adminDir := flag.String("admin", "", "") // adminDir is for config files + checkFileNameList := flag.String("checkFileNameList", "", "Comma-separated list of files to check.") + checkFileSumList := flag.String("checkFileSumList", "", "Comma-separated list of expected checksums.") parseMultiValueFlag(&gitWhitelist, "whitelist", "") parseMultiValueFlag(&metaFile, "meta", "") parseMultiValueFlag(&releaseTags, "releaseTags", "") @@ -72,16 +72,14 @@ func main() { if err != nil { fmt.Printf("## Non-ASCII Characters Commit Message Check Failed:\n%s\n", err.Error()) } - // TODO: find a way to test the release tag err = healthcheck.CheckTags(*rootDir, *releaseCategories, *releaseNumber) if err != nil { fmt.Printf("## Release Tag Check Failed:\n%s\n", err.Error()) } // FIXME: for drone usage - if adminDir != nil && *adminDir != "" { - err = healthcheck.VerifyDirectory(*rootDir, *adminDir) - if err != nil { - fmt.Printf("## Directory File Check Failed:\n%s\n", err.Error()) - } + err = healthcheck.VerifyFiles(*rootDir, *checkFileNameList, *checkFileSumList) + if err != nil { + fmt.Printf("## Repo File Check Failed:\n%s\n", err.Error()) } + } -- 2.30.2 From db2be886ab0d9b75e51076e8649c4dd89414d85d Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Sun, 25 Aug 2024 23:29:55 +0800 Subject: [PATCH 21/37] fix: output --- examples/healthcheck/repoverify | 2 +- pkg/healthcheck/verify.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify index f9bed91..1c23924 160000 --- a/examples/healthcheck/repoverify +++ b/examples/healthcheck/repoverify @@ -1 +1 @@ -Subproject commit f9bed916b7b8af0175210837a67b24fab614508e +Subproject commit 1c2392436643d53782eccd4e37958811e7ecd480 diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index e5d81a5..2b04363 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -85,6 +85,7 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin for _, msg := range errorMessages { return fmt.Errorf(msg) } + return fmt.Errorf("Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.") } return nil } -- 2.30.2 From 0a71c9832dc0098ed379d7fdfdc012148c49b475 Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Sun, 25 Aug 2024 23:59:58 +0800 Subject: [PATCH 22/37] fix: verify --- examples/healthcheck/repoverify | 2 +- pkg/healthcheck/verify.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify index 1c23924..cf03a19 160000 --- a/examples/healthcheck/repoverify +++ b/examples/healthcheck/repoverify @@ -1 +1 @@ -Subproject commit 1c2392436643d53782eccd4e37958811e7ecd480 +Subproject commit cf03a190af343cc65a55bacc51cd8603cc2be2e4 diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index 2b04363..ac9dbe6 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -49,7 +49,6 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin // checkFileSumList := flag.String("checkFileSumList", "", "Comma-separated list of expected checksums.") // rootDir := flag.String("rootDir", ".", "Root directory containing the files.") // flag.Parse() - // Process input file names and checksums fileNames := strings.Split(checkFileNameList, ",") checkSums := strings.Split(checkFileSumList, ",") -- 2.30.2 From 63c8b418ec205d22e16dad4c6c87efc17d4aceca Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Mon, 26 Aug 2024 00:04:13 +0800 Subject: [PATCH 23/37] fix: verify --- examples/healthcheck/repoverify | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify index cf03a19..b1b27f5 160000 --- a/examples/healthcheck/repoverify +++ b/examples/healthcheck/repoverify @@ -1 +1 @@ -Subproject commit cf03a190af343cc65a55bacc51cd8603cc2be2e4 +Subproject commit b1b27f5d847684307740005f16fa133e67a2e6cc -- 2.30.2 From 36b75ad578f019a840c40cbbb4ef2338044dac2e Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Mon, 26 Aug 2024 19:43:24 +0800 Subject: [PATCH 24/37] fix: verify --- pkg/healthcheck/verify.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index ac9dbe6..3ca75d9 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -37,7 +37,7 @@ func checkFileChecksum(rootDir, fileName, expectedChecksum string) (bool, string } if actualChecksum == expectedChecksum { - return true, fmt.Sprintf("Checksum for %s passed!", filePath) + return true, ""//fmt.Sprintf("Checksum for %s passed!", filePath) } else { return false, fmt.Sprintf("Checksum for %s failed. Expected %s, but got %s. Please revert the changes!", filePath, expectedChecksum, actualChecksum) } @@ -55,7 +55,7 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin // Check if the number of files matches the number of checksums if len(fileNames) == 0 { - return fmt.Errorf("No checksum happened") + return nil//fmt.Errorf("No checksum happened") } if len(fileNames) != len(checkSums) { @@ -70,15 +70,17 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin for i, fileName := range fileNames { expectedChecksum := strings.TrimSpace(checkSums[i]) passed, message := checkFileChecksum(rootDir, fileName, expectedChecksum) - return fmt.Errorf(message) + if message != "" { + return fmt.Errorf(message) + } if !passed { allPassed = false errorMessages = append(errorMessages, message) } } - + fmt.Printf("test") if allPassed { - return fmt.Errorf("Congratulations! All checksums passed!") + return nil//fmt.Errorf("Congratulations! All checksums passed!") } else { return fmt.Errorf("Some checksums failed. Please review the errors below:") for _, msg := range errorMessages { -- 2.30.2 From 296fdcbd121de4583c9bae5871a26c1dd5e43e61 Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Mon, 26 Aug 2024 20:06:18 +0800 Subject: [PATCH 25/37] fix: repo verify --- examples/healthcheck/repoverify | 2 +- pkg/healthcheck/verify.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/healthcheck/repoverify b/examples/healthcheck/repoverify index b1b27f5..2f455dc 160000 --- a/examples/healthcheck/repoverify +++ b/examples/healthcheck/repoverify @@ -1 +1 @@ -Subproject commit b1b27f5d847684307740005f16fa133e67a2e6cc +Subproject commit 2f455dca9d28e39926e68b9b13eef39b0a9f67fc diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index 3ca75d9..31dd6c6 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -39,7 +39,7 @@ func checkFileChecksum(rootDir, fileName, expectedChecksum string) (bool, string if actualChecksum == expectedChecksum { return true, ""//fmt.Sprintf("Checksum for %s passed!", filePath) } else { - return false, fmt.Sprintf("Checksum for %s failed. Expected %s, but got %s. Please revert the changes!", filePath, expectedChecksum, actualChecksum) + return false, fmt.Sprintf("Checksum for %s failed. Expected %s, but got %s. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.", filePath, expectedChecksum, actualChecksum) } } -- 2.30.2 From 48ab754ddf2275bb7d356f3b3dfa9ff97396f166 Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Mon, 26 Aug 2024 20:12:20 +0800 Subject: [PATCH 26/37] fix: verify --- pkg/healthcheck/verify.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index 31dd6c6..d8076bf 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -50,13 +50,15 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin // rootDir := flag.String("rootDir", ".", "Root directory containing the files.") // flag.Parse() // Process input file names and checksums + if len(checkFileNameList) == 0 { + return nil//fmt.Errorf("No checksum happened") + os.Exit(1) + } fileNames := strings.Split(checkFileNameList, ",") checkSums := strings.Split(checkFileSumList, ",") // Check if the number of files matches the number of checksums - if len(fileNames) == 0 { - return nil//fmt.Errorf("No checksum happened") - } + if len(fileNames) != len(checkSums) { return fmt.Errorf("Error: The number of files and checksums do not match.") -- 2.30.2 From 07ff31a6966357484ed5f974df43cf3e294fb78b Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Thu, 29 Aug 2024 17:10:34 +0800 Subject: [PATCH 27/37] fix: more debug info in git commit check --- pkg/healthcheck/commit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/healthcheck/commit.go b/pkg/healthcheck/commit.go index 2db46d9..855bb16 100644 --- a/pkg/healthcheck/commit.go +++ b/pkg/healthcheck/commit.go @@ -31,7 +31,7 @@ func NonAsciiMsg(root string) error { commits, err := repo.Log(&git.LogOptions{From: ref.Hash()}) if err != nil { slog.Error("getting commits", "err", err) - return fmt.Errorf("error getting commits: %v", err) + return fmt.Errorf("error getting commits from reference %s: %v", ref.Hash(), err) } var msgs []string -- 2.30.2 From 9937bb8b1a324dbe75a0e211caa5408ab1e37101 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Fri, 30 Aug 2024 12:50:55 +0800 Subject: [PATCH 28/37] fix: skip dir --- pkg/healthcheck/forbidden.go | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index f700b74..2f40d4e 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -54,29 +54,23 @@ func getForbiddens(root string, fileList []string, localList string) ([]string, } if info.IsDir() { - switch { - case info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci": + if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" || (localList != "" && inString(info.Name(), dirs)) { return filepath.SkipDir - case localList != "": - if inString(info.Name(), dirs) { - return filepath.SkipDir + } + } else { + match := false + for _, regex := range regexList { + if regex.MatchString(info.Name()) { + match = true + break } - default: - return nil + } + + if !match { + matches = append(matches, path) } } - match := false - for _, regex := range regexList { - if regex.MatchString(info.Name()) { - match = true - break - } - } - - if !match { - matches = append(matches, path) - } return nil }) -- 2.30.2 From c0bd1c1fcfad57fb077ebb5d1f44abf4a281ec71 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Fri, 30 Aug 2024 14:00:48 +0800 Subject: [PATCH 29/37] fix: nonascii in localList --- cmd/healthcheck/main.go | 3 +-- pkg/healthcheck/nonascii.go | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/cmd/healthcheck/main.go b/cmd/healthcheck/main.go index 9901f70..1a6b3cf 100644 --- a/cmd/healthcheck/main.go +++ b/cmd/healthcheck/main.go @@ -64,7 +64,7 @@ func main() { if err != nil { fmt.Printf("## Forbidden File Check Failed:\n%s\n", err.Error()) } - err = healthcheck.NonAsciiFiles(*rootDir) + err = healthcheck.NonAsciiFiles(*rootDir, *localList) if err != nil { fmt.Printf("## Non-ASCII Characters File Check Failed:\n%s\n", err.Error()) } @@ -81,5 +81,4 @@ func main() { if err != nil { fmt.Printf("## Repo File Check Failed:\n%s\n", err.Error()) } - } diff --git a/pkg/healthcheck/nonascii.go b/pkg/healthcheck/nonascii.go index 1d910f9..ca152fb 100644 --- a/pkg/healthcheck/nonascii.go +++ b/pkg/healthcheck/nonascii.go @@ -12,16 +12,34 @@ import ( // getNonAscii retrieves a list of files in the specified root directory that contain non-ASCII characters. // It searches for non-ASCII characters in each file's content and returns a list of paths to files containing non-ASCII characters. -func getNonAscii(root string) ([]string, error) { +func getNonAscii(root string, localList string) ([]string, error) { var nonAscii []string + var dirs []string + + if localList != "" { + file, err := os.Open(localList) + if err != nil { + return nil, fmt.Errorf("Failed to open file %s: %v\n", localList, err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + dirs = append(dirs, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("Error reading file %s: %v\n", localList, err) + } + } + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { - if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" { + if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" || (localList != "" && inString(info.Name(), dirs)) { return filepath.SkipDir } else { return nil @@ -61,8 +79,8 @@ func getNonAscii(root string) ([]string, error) { // nonAsciiFiles checks for non-ASCII characters in files within the specified root directory. // It prints a message with the paths to files containing non-ASCII characters, if any. -func NonAsciiFiles(root string) error { - nonAscii, err := getNonAscii(root) +func NonAsciiFiles(root string, localList string) error { + nonAscii, err := getNonAscii(root, localList) if err != nil { slog.Error("getting non-ascii", "err", err) return fmt.Errorf("error getting non-ascii: %w", err) -- 2.30.2 From 43b8f374db2f720f168bad590a48d772ae72a227 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Fri, 30 Aug 2024 14:06:01 +0800 Subject: [PATCH 30/37] chore: reorgnalize function --- pkg/healthcheck/forbidden.go | 9 --------- pkg/healthcheck/utils.go | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index 2f40d4e..a07cbad 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -10,15 +10,6 @@ import ( "strings" ) -func inString(str1 string, strList []string) bool { - for _, str := range strList { - if str1 == str { - return true - } - } - return false -} - // getForbiddens retrieves a list of forbidden files in the specified root directory. // It searches for files that do not match the specified regex patterns in the given file list. func getForbiddens(root string, fileList []string, localList string) ([]string, error) { diff --git a/pkg/healthcheck/utils.go b/pkg/healthcheck/utils.go index 8939f22..005379a 100644 --- a/pkg/healthcheck/utils.go +++ b/pkg/healthcheck/utils.go @@ -5,6 +5,15 @@ import ( "regexp" ) +func inString(str1 string, strList []string) bool { + for _, str := range strList { + if str1 == str { + return true + } + } + return false +} + // addExt appends the specified extension to each file name in the given fileList. // It modifies the original fileList in place. func addExt(fileList []string, ext string) { -- 2.30.2 From 8d2c4932e8feacc431ac987c04a7aa40d3051f41 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Fri, 30 Aug 2024 15:22:18 +0800 Subject: [PATCH 31/37] fix: block check if healthcheck fails --- internal/stage/run.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/stage/run.go b/internal/stage/run.go index 670f666..da0828c 100644 --- a/internal/stage/run.go +++ b/internal/stage/run.go @@ -38,6 +38,9 @@ func Run(stages []Stage) []StageResult { ForceQuit: forceQuit, }) if forceQuit { + if stage.Name == "healthcheck" { + return stageResults + } break } } -- 2.30.2 From 2e2445521f9bd519c2c2016956ce03373cfcda3c Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Fri, 30 Aug 2024 15:24:25 +0800 Subject: [PATCH 32/37] Revert "fix: block check if healthcheck fails" This reverts commit 657fba98b6735a2cf78ade00f16392b241763d93. --- internal/stage/run.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/stage/run.go b/internal/stage/run.go index da0828c..670f666 100644 --- a/internal/stage/run.go +++ b/internal/stage/run.go @@ -38,9 +38,6 @@ func Run(stages []Stage) []StageResult { ForceQuit: forceQuit, }) if forceQuit { - if stage.Name == "healthcheck" { - return stageResults - } break } } -- 2.30.2 From ac583504e57ce2edca74c6d33008b0d1fe161d4a Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Sat, 31 Aug 2024 11:43:55 +0800 Subject: [PATCH 33/37] fix: rm debug code --- pkg/healthcheck/verify.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index d8076bf..3372712 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -37,13 +37,13 @@ func checkFileChecksum(rootDir, fileName, expectedChecksum string) (bool, string } if actualChecksum == expectedChecksum { - return true, ""//fmt.Sprintf("Checksum for %s passed!", filePath) + return true, "" // fmt.Sprintf("Checksum for %s passed!", filePath) } else { return false, fmt.Sprintf("Checksum for %s failed. Expected %s, but got %s. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.", filePath, expectedChecksum, actualChecksum) } } -func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList string ) error { +func VerifyFiles(rootDir string, checkFileNameList string, checkFileSumList string) error { // Parse command-line arguments // checkFileNameList := flag.String("checkFileNameList", "", "Comma-separated list of files to check.") // checkFileSumList := flag.String("checkFileSumList", "", "Comma-separated list of expected checksums.") @@ -51,7 +51,7 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin // flag.Parse() // Process input file names and checksums if len(checkFileNameList) == 0 { - return nil//fmt.Errorf("No checksum happened") + return nil // fmt.Errorf("No checksum happened") os.Exit(1) } fileNames := strings.Split(checkFileNameList, ",") @@ -59,7 +59,6 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin // Check if the number of files matches the number of checksums - if len(fileNames) != len(checkSums) { return fmt.Errorf("Error: The number of files and checksums do not match.") os.Exit(1) @@ -80,9 +79,8 @@ func VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList strin errorMessages = append(errorMessages, message) } } - fmt.Printf("test") if allPassed { - return nil//fmt.Errorf("Congratulations! All checksums passed!") + return nil // fmt.Errorf("Congratulations! All checksums passed!") } else { return fmt.Errorf("Some checksums failed. Please review the errors below:") for _, msg := range errorMessages { -- 2.30.2 From 0a299964e84448f7b095d131ef83c5b7e36ad549 Mon Sep 17 00:00:00 2001 From: zzjc1234 <2359047351@qq.com> Date: Tue, 10 Sep 2024 16:37:51 +0800 Subject: [PATCH 34/37] doc: readme --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f5c3d3..98a94e8 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,14 @@ 3. Enable cgroup v2 for your OS. Check [here](https://stackoverflow.com/a/73376219/13724598). So that you do not need root permission to run `go-judge`. 4. Clone [go-judge](https://github.com/criyle/go-judge). + ```bash $ git clone https://github.com/criyle/go-judge && cd go-judge $ go build -o ./tmp/go-judge ./cmd/go-judge ``` 5. Run `go-judge`. + ```bash $ # make sure you are in go-judge directory $ ./tmp/go-judge -http-addr 0.0.0.0:5050 -grpc-addr 0.0.0.0:5051 -monitor-addr 0.0.0.0:5052 -enable-grpc -enable-debug -enable-metrics @@ -51,6 +53,7 @@ ok focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/joj3 2.290s coverage: 74.0% 1. Install [`pre-commit`](https://pre-commit.com/), [`golangci-lint`](https://golangci-lint.run), [`goimports`](https://golang.org/x/tools/cmd/goimports), [`gofumpt`](https://github.com/mvdan/gofumpt). 2. Install the pre-commit hooks. It will run some checks before you commit. + ```bash $ pre-commit install pre-commit installed at .git/hooks/pre-commit @@ -87,4 +90,8 @@ Check the `Result` at . ### HealthCheck -The repohealth check will return a json list to for check result. The structure of json file is in `pkg/healthcheck/util.go` +The repohealth check will return a json list to for check result. The structure follows the score-comment pattern. + +HealthCheck currently includes, `reposize`, `forbidden file`, `Metafile existence`, `non-ascii character` in file and message, `release tag`, and `ci files invariance` check. + +The workflow is `joj3` pass cli args to healthcheck binary. See `./cmd/healthcheck/main.go` to view all flags. -- 2.30.2 From a551072e327d6e9126ce1db6dbbcb26f32514d25 Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Tue, 10 Sep 2024 19:08:09 +0800 Subject: [PATCH 35/37] fix: verify --- pkg/healthcheck/verify.go | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index 3372712..e983170 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -37,33 +37,20 @@ func checkFileChecksum(rootDir, fileName, expectedChecksum string) (bool, string } if actualChecksum == expectedChecksum { - return true, "" // fmt.Sprintf("Checksum for %s passed!", filePath) + return true, "" } else { return false, fmt.Sprintf("Checksum for %s failed. Expected %s, but got %s. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.", filePath, expectedChecksum, actualChecksum) } } func VerifyFiles(rootDir string, checkFileNameList string, checkFileSumList string) error { - // Parse command-line arguments - // checkFileNameList := flag.String("checkFileNameList", "", "Comma-separated list of files to check.") - // checkFileSumList := flag.String("checkFileSumList", "", "Comma-separated list of expected checksums.") - // rootDir := flag.String("rootDir", ".", "Root directory containing the files.") - // flag.Parse() - // Process input file names and checksums if len(checkFileNameList) == 0 { - return nil // fmt.Errorf("No checksum happened") + return nil os.Exit(1) } fileNames := strings.Split(checkFileNameList, ",") checkSums := strings.Split(checkFileSumList, ",") - // Check if the number of files matches the number of checksums - - if len(fileNames) != len(checkSums) { - return fmt.Errorf("Error: The number of files and checksums do not match.") - os.Exit(1) - } - allPassed := true var errorMessages []string @@ -80,7 +67,7 @@ func VerifyFiles(rootDir string, checkFileNameList string, checkFileSumList stri } } if allPassed { - return nil // fmt.Errorf("Congratulations! All checksums passed!") + return nil } else { return fmt.Errorf("Some checksums failed. Please review the errors below:") for _, msg := range errorMessages { -- 2.30.2 From 102b0ef2a5f04915145c5d199800c0c51bf1665e Mon Sep 17 00:00:00 2001 From: Hydraallen Date: Tue, 10 Sep 2024 23:49:28 +0800 Subject: [PATCH 36/37] fix: verfiy --- pkg/healthcheck/verify.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index e983170..debc531 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -70,10 +70,6 @@ func VerifyFiles(rootDir string, checkFileNameList string, checkFileSumList stri return nil } else { return fmt.Errorf("Some checksums failed. Please review the errors below:") - for _, msg := range errorMessages { - return fmt.Errorf(msg) - } - return fmt.Errorf("Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.") } return nil } -- 2.30.2 From 07dd356e055ce99d69ef2458fc258af176046e5b Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Wed, 11 Sep 2024 08:07:07 -0400 Subject: [PATCH 37/37] fix: verify files --- pkg/healthcheck/commit.go | 2 +- pkg/healthcheck/forbidden.go | 16 +++++++--------- pkg/healthcheck/nonascii.go | 3 ++- pkg/healthcheck/verify.go | 32 ++++++++------------------------ 4 files changed, 18 insertions(+), 35 deletions(-) diff --git a/pkg/healthcheck/commit.go b/pkg/healthcheck/commit.go index 855bb16..ada9e5a 100644 --- a/pkg/healthcheck/commit.go +++ b/pkg/healthcheck/commit.go @@ -59,7 +59,7 @@ func NonAsciiMsg(root string) error { } } if len(nonAsciiMsgs) > 0 { - return fmt.Errorf("Non-ASCII characters in commit messages:\n" + strings.Join(nonAsciiMsgs, "\n")) + return fmt.Errorf("Non-ASCII characters in commit messages:\n%s", strings.Join(nonAsciiMsgs, "\n")) } return nil } diff --git a/pkg/healthcheck/forbidden.go b/pkg/healthcheck/forbidden.go index a07cbad..1a46c70 100644 --- a/pkg/healthcheck/forbidden.go +++ b/pkg/healthcheck/forbidden.go @@ -77,16 +77,14 @@ func ForbiddenCheck(rootDir string, regexList []string, localList string, repo s return fmt.Errorf("error getting forbiddens: %w", err) } - var message string - if len(forbids) > 0 { - message = "The following forbidden files were found: " + - strings.Join(forbids, ", ") + - "\n\nTo fix it, first make a backup of your repository and then run the following commands:\nfor i in " + - strings.Join(forbids, " ") + - fmt.Sprint("; do git filter-repo --force --invert-paths --path \"$i\"; done\ngit remote add origin ", - repo, "\ngit push --set-upstream origin ", droneBranch, " --force") - return fmt.Errorf(message) + return fmt.Errorf("The following forbidden files were found: %s\n\nTo fix it, first make a backup of your repository and then run the following commands:\nfor i in %s%s", + strings.Join(forbids, ", "), + strings.Join(forbids, " "), + fmt.Sprint( + "; do git filter-repo --force --invert-paths --path \"$i\"; done\ngit remote add origin ", + repo, "\ngit push --set-upstream origin ", + droneBranch, " --force")) } return nil } diff --git a/pkg/healthcheck/nonascii.go b/pkg/healthcheck/nonascii.go index ca152fb..0204c3c 100644 --- a/pkg/healthcheck/nonascii.go +++ b/pkg/healthcheck/nonascii.go @@ -86,7 +86,8 @@ func NonAsciiFiles(root string, localList string) error { return fmt.Errorf("error getting non-ascii: %w", err) } if len(nonAscii) > 0 { - return fmt.Errorf("Non-ASCII characters found in the following files:\n" + strings.Join(nonAscii, "\n")) + return fmt.Errorf("Non-ASCII characters found in the following files:\n%s", + strings.Join(nonAscii, "\n")) } return nil } diff --git a/pkg/healthcheck/verify.go b/pkg/healthcheck/verify.go index debc531..659777f 100644 --- a/pkg/healthcheck/verify.go +++ b/pkg/healthcheck/verify.go @@ -29,47 +29,31 @@ func getChecksum(filePath string) (string, error) { } // checkFileChecksum checks if a single file's checksum matches the expected value -func checkFileChecksum(rootDir, fileName, expectedChecksum string) (bool, string) { +func checkFileChecksum(rootDir, fileName, expectedChecksum string) error { filePath := filepath.Join(rootDir, strings.TrimSpace(fileName)) actualChecksum, err := getChecksum(filePath) if err != nil { - return false, fmt.Sprintf("Error reading file %s: %v", filePath, err) + return fmt.Errorf("Error reading file %s: %v", filePath, err) } - - if actualChecksum == expectedChecksum { - return true, "" - } else { - return false, fmt.Sprintf("Checksum for %s failed. Expected %s, but got %s. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.", filePath, expectedChecksum, actualChecksum) + if actualChecksum != expectedChecksum { + return fmt.Errorf("Checksum for %s failed. Expected %s, but got %s. Please revert your changes or contact the teaching team if you have a valid reason for adjusting them.", filePath, expectedChecksum, actualChecksum) } + return nil } func VerifyFiles(rootDir string, checkFileNameList string, checkFileSumList string) error { if len(checkFileNameList) == 0 { return nil - os.Exit(1) } fileNames := strings.Split(checkFileNameList, ",") checkSums := strings.Split(checkFileSumList, ",") - - allPassed := true - var errorMessages []string - // Check each file's checksum for i, fileName := range fileNames { expectedChecksum := strings.TrimSpace(checkSums[i]) - passed, message := checkFileChecksum(rootDir, fileName, expectedChecksum) - if message != "" { - return fmt.Errorf(message) + err := checkFileChecksum(rootDir, fileName, expectedChecksum) + if err != nil { + return err } - if !passed { - allPassed = false - errorMessages = append(errorMessages, message) - } - } - if allPassed { - return nil - } else { - return fmt.Errorf("Some checksums failed. Please review the errors below:") } return nil } -- 2.30.2