feat: repo health check (#16) #17

Merged
张泊明518370910136 merged 37 commits from file_check into master 2024-09-11 20:09:27 +08:00
Showing only changes of commit 3500abb292 - Show all commits

View File

@ -1,75 +1,90 @@
package healthcheck package healthcheck
import ( import (
"bufio" "crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"io"
"os" "os"
"path/filepath" "path/filepath"
"strings"
) )
// fileExists checks if a file exists at the specified path. // getChecksum calculates the SHA-256 checksum of a file
func fileExists(filePath string) bool { func getChecksum(filePath string) (string, error) {
_, err := os.Stat(filePath) // Open the file
return !os.IsNotExist(err) file, err := os.Open(filePath)
}
// filesMatch checks if two files are identical.
func filesMatch(file1, file2 string) (bool, error) {
f1, err := os.Open(file1)
if err != nil { 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 { if err != nil {
return false, err return false, fmt.Sprintf("Error reading file %s: %v", filePath, 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() { if actualChecksum == expectedChecksum {
// One file has more lines than the other return true, fmt.Sprintf("Checksum for %s passed!", filePath)
bomingzh marked this conversation as resolved Outdated

remove the comment

remove the comment
return false, nil } 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 VerifyFiles(rootDir string,checkFileNameList string, checkFileSumList string ) error {
func VerifyDirectory(rootDir, compareDir string) error { // Parse command-line arguments
bomingzh marked this conversation as resolved Outdated

ditto

ditto
err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error { // checkFileNameList := flag.String("checkFileNameList", "", "Comma-separated list of files to check.")
if err != nil { // checkFileSumList := flag.String("checkFileSumList", "", "Comma-separated list of expected checksums.")
return fmt.Errorf("error walking directory: %w", err) // 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, ",")
bomingzh marked this conversation as resolved Outdated

remove it

remove it
// 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)

remove it

remove it

I mean remove the os.Exit(1), and also the one on line 55.

I mean remove the `os.Exit(1)`, and also the one on line 55.
}
allPassed := true
var errorMessages []string

why not just return error on not all passed?

why not just return error on not all passed?
// 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 allPassed {
if !fileExists(file2) { return fmt.Errorf("Congratulations! All checksums passed!")
return fmt.Errorf("File %s is missing. Please immediately revert your changes!\n", } else {

ditto

ditto
filepath.Join(rootDir, relPath)) return fmt.Errorf("Some checksums failed. Please review the errors below:")
} for _, msg := range errorMessages {

Why so many returns?

Why so many returns?
match, err := filesMatch(path, file2) return fmt.Errorf(msg)
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))
}
} }
return nil }
}) return nil
return err
} }