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 }