package main import ( "flag" "fmt" "os" "github.com/Mond1c/judge/dsl" "github.com/Mond1c/judge/reporter" "github.com/Mond1c/judge/runner" ) const usage = `judge — CI/CD testing system for student solutions Usage: judge [flags] judge aggregate Flags: --json output as JSON instead of text --wrapper exec wrapper (e.g. "valgrind --error-exitcode=99") --binary name of executable produced by build (overrides .jdg) --help show help Example: judge lab1.jdg ./student-solution judge lab1.jdg ./student-solution --json judge aggregate reports/ ` func main() { if len(os.Args) >= 2 && os.Args[1] == "aggregate" { runAggregate() return } fs := flag.NewFlagSet("judge", flag.ContinueOnError) fs.SetOutput(os.Stderr) fs.Usage = func() { fmt.Fprint(os.Stderr, usage) } jsonOutput := fs.Bool("json", false, "output as JSON") wrapper := fs.String("wrapper", "", "exec wrapper command") binary := fs.String("binary", "", "binary name override") if err := fs.Parse(os.Args[1:]); err != nil { os.Exit(2) } if fs.NArg() < 2 { fmt.Fprintf(os.Stderr, "error: need and \n\n%s", usage) os.Exit(1) } testFile := fs.Arg(0) solutionDir := fs.Arg(1) src, err := os.ReadFile(testFile) if err != nil { fatalf("cannot read %q: %v", testFile, err) } f, warns, err := dsl.Parse(string(src)) if err != nil { fatalf("parse error in %q:\n %v", testFile, err) } for _, w := range warns { fmt.Fprintf(os.Stderr, "warning: %s\n", w) } if _, err := os.Stat(solutionDir); err != nil { fatalf("solution dir %q not found: %v", solutionDir, err) } r := runner.New(f, runner.Config{ WorkDir: solutionDir, BinaryName: *binary, Wrapper: *wrapper, }) result := r.Run() if *jsonOutput { if err := reporter.JSON(os.Stdout, result); err != nil { fatalf("json output error: %v", err) } } else { reporter.Text(os.Stdout, result) } if result.TotalScore < 0.9999 { os.Exit(1) } } func runAggregate() { if len(os.Args) < 3 { fatalf("usage: judge aggregate ") } dir := os.Args[2] if err := reporter.Aggregate(os.Stdout, dir); err != nil { fatalf("%v", err) } } func fatalf(msg string, args ...any) { fmt.Fprintf(os.Stderr, "error: "+msg+"\n", args...) os.Exit(1) }