Files
judge/cmd/cli/main.go
Mikhail Kornilovich cb70adbf09
Some checks failed
judge / Build judge (push) Successful in 8s
judge / Linux / gcc / Debug (push) Successful in 7s
judge / Linux / clang / Release (push) Successful in 9s
judge / Linux / gcc / Release (push) Successful in 10s
judge / Linux / clang / Sanitized (push) Successful in 8s
judge / Linux / gcc / Sanitized (push) Successful in 9s
judge / Linux / gcc / Debug (valgrind) (push) Successful in 15s
judge / Windows / clang / Debug (push) Successful in 37s
judge / Windows / clang / Release (push) Successful in 40s
judge / Windows / msvc / Debug (push) Successful in 45s
judge / Windows / msvc / Release (push) Successful in 43s
judge / SUMMARY (push) Failing after 2s
fixes
2026-04-05 22:26:07 +03:00

92 lines
2.0 KiB
Go

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 <tests.jdg> <solution-dir> [flags]
Flags:
--json output as JSON instead of text
--wrapper <cmd> exec wrapper (e.g. "valgrind --error-exitcode=99")
--binary <name> name of executable produced by build (overrides .jdg)
--help show help
Example:
judge lab1.jdg ./student-solution
judge lab1.jdg ./student-solution --json
judge lab1.jdg ./student-solution --wrapper "valgrind --error-exitcode=99"
`
func main() {
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 <tests.jdg> and <solution-dir>\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 fatalf(msg string, args ...any) {
fmt.Fprintf(os.Stderr, "error: "+msg+"\n", args...)
os.Exit(1)
}