1. New build system
All checks were successful
build-dsl-smoke / Build judge (push) Successful in 12s
build-dsl-smoke / debug / clang / linux (push) Successful in 6s
build-dsl-smoke / debug / gcc / linux (push) Successful in 8s
build-dsl-smoke / release / clang / linux (push) Successful in 8s
build-dsl-smoke / release / gcc / linux (push) Successful in 6s
build-dsl-smoke / sanitized / clang / linux (push) Successful in 8s
build-dsl-smoke / sanitized / gcc / linux (push) Successful in 7s
build-dsl-smoke / debug / clang / windows (push) Successful in 13s
build-dsl-smoke / debug-valgrind / gcc / linux (push) Successful in 14s
build-dsl-smoke / release / clang / windows (push) Successful in 16s
build-dsl-smoke / debug / msvc / windows (push) Successful in 18s
build-dsl-smoke / release / msvc / windows (push) Successful in 17s
build-dsl-smoke / SUMMARY (push) Successful in 4s
Release / Build & publish (push) Successful in 48s
All checks were successful
build-dsl-smoke / Build judge (push) Successful in 12s
build-dsl-smoke / debug / clang / linux (push) Successful in 6s
build-dsl-smoke / debug / gcc / linux (push) Successful in 8s
build-dsl-smoke / release / clang / linux (push) Successful in 8s
build-dsl-smoke / release / gcc / linux (push) Successful in 6s
build-dsl-smoke / sanitized / clang / linux (push) Successful in 8s
build-dsl-smoke / sanitized / gcc / linux (push) Successful in 7s
build-dsl-smoke / debug / clang / windows (push) Successful in 13s
build-dsl-smoke / debug-valgrind / gcc / linux (push) Successful in 14s
build-dsl-smoke / release / clang / windows (push) Successful in 16s
build-dsl-smoke / debug / msvc / windows (push) Successful in 18s
build-dsl-smoke / release / msvc / windows (push) Successful in 17s
build-dsl-smoke / SUMMARY (push) Successful in 4s
Release / Build & publish (push) Successful in 48s
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
138
cmd/cli/main.go
138
cmd/cli/main.go
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -20,11 +21,16 @@ 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)
|
||||
--build <name> run only the named structured build (use with matrix CI)
|
||||
--list-builds print the names of structured builds in the suite as JSON
|
||||
--list-matrix print the full (build, toolchain, platform) matrix as JSON
|
||||
--help show help
|
||||
|
||||
Example:
|
||||
judge lab1.jdg ./student-solution
|
||||
judge lab1.jdg ./student-solution --json
|
||||
judge lab1.jdg ./student-solution --build=sanitized
|
||||
judge --list-builds lab1.jdg
|
||||
judge aggregate reports/
|
||||
`
|
||||
|
||||
@@ -41,9 +47,20 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
if hasFlag(args, "--list-builds") {
|
||||
runListBuilds(args)
|
||||
return
|
||||
}
|
||||
|
||||
if hasFlag(args, "--list-matrix") {
|
||||
runListMatrix(args)
|
||||
return
|
||||
}
|
||||
|
||||
jsonOutput := hasFlag(args, "--json")
|
||||
wrapper := flagValue(args, "--wrapper")
|
||||
binary := flagValue(args, "--binary")
|
||||
targetBuild := flagValue(args, "--build")
|
||||
positional := positionalArgs(args)
|
||||
|
||||
if len(positional) < 2 {
|
||||
@@ -54,27 +71,17 @@ func main() {
|
||||
testFile := positional[0]
|
||||
solutionDir := positional[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)
|
||||
}
|
||||
f := parseSuite(testFile)
|
||||
|
||||
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,
|
||||
WorkDir: solutionDir,
|
||||
BinaryName: binary,
|
||||
Wrapper: wrapper,
|
||||
TargetBuild: targetBuild,
|
||||
})
|
||||
result := r.Run()
|
||||
|
||||
@@ -91,6 +98,91 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func parseSuite(path string) *dsl.File {
|
||||
f, warns, err := dsl.ParseFile(path)
|
||||
if err != nil {
|
||||
fatalf("parse error in %q:\n %v", path, err)
|
||||
}
|
||||
for _, w := range warns {
|
||||
fmt.Fprintf(os.Stderr, "warning: %s\n", w)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func runListBuilds(args []string) {
|
||||
positional := positionalArgs(args)
|
||||
if len(positional) < 1 {
|
||||
fatalf("--list-builds requires the path to a .jdg file")
|
||||
}
|
||||
f := parseSuite(positional[0])
|
||||
|
||||
var names []string
|
||||
if len(f.Builds) == 0 {
|
||||
names = []string{"default"}
|
||||
} else {
|
||||
for _, b := range f.Builds {
|
||||
names = append(names, b.Name)
|
||||
}
|
||||
}
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
if err := enc.Encode(names); err != nil {
|
||||
fatalf("encode list-builds: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type matrixEntry struct {
|
||||
Build string `json:"build"`
|
||||
Toolchain string `json:"toolchain"`
|
||||
Platform string `json:"platform"`
|
||||
Wrapper string `json:"wrapper,omitempty"`
|
||||
}
|
||||
|
||||
func runListMatrix(args []string) {
|
||||
positional := positionalArgs(args)
|
||||
if len(positional) < 1 {
|
||||
fatalf("--list-matrix requires the path to a .jdg file")
|
||||
}
|
||||
f := parseSuite(positional[0])
|
||||
|
||||
var entries []matrixEntry
|
||||
|
||||
if len(f.Builds) == 0 {
|
||||
if len(f.Toolchains) == 0 {
|
||||
entries = append(entries, matrixEntry{Build: "default", Toolchain: "default", Platform: "linux"})
|
||||
} else {
|
||||
for _, tc := range f.Toolchains {
|
||||
for _, platform := range tc.Platforms {
|
||||
entries = append(entries, matrixEntry{Build: "default", Toolchain: tc.Name, Platform: platform})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if len(f.Toolchains) == 0 {
|
||||
fatalf("suite has structured builds but no `toolchains { ... }` block; add one to use --list-matrix")
|
||||
} else {
|
||||
for _, b := range f.Builds {
|
||||
for _, tc := range f.Toolchains {
|
||||
for _, platform := range tc.Platforms {
|
||||
eff := b.Resolve(f.BuildDefaults, platform)
|
||||
if !eff.AppliesTo(platform, tc.Name) {
|
||||
continue
|
||||
}
|
||||
entries = append(entries, matrixEntry{
|
||||
Build: b.Name,
|
||||
Toolchain: tc.Name,
|
||||
Platform: platform,
|
||||
Wrapper: eff.Wrapper,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
if err := enc.Encode(entries); err != nil {
|
||||
fatalf("encode list-matrix: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func runAggregate(args []string) {
|
||||
if len(args) < 1 {
|
||||
fatalf("usage: judge aggregate <reports-dir>")
|
||||
@@ -128,8 +220,18 @@ func flagValue(args []string, name string) string {
|
||||
}
|
||||
|
||||
func positionalArgs(args []string) []string {
|
||||
known := map[string]bool{"--json": true, "--help": true, "-h": true}
|
||||
withValue := map[string]bool{"--wrapper": true, "--binary": true}
|
||||
known := map[string]bool{
|
||||
"--json": true,
|
||||
"--help": true,
|
||||
"-h": true,
|
||||
"--list-builds": true,
|
||||
"--list-matrix": true,
|
||||
}
|
||||
withValue := map[string]bool{
|
||||
"--wrapper": true,
|
||||
"--binary": true,
|
||||
"--build": true,
|
||||
}
|
||||
|
||||
var out []string
|
||||
skip := false
|
||||
@@ -145,7 +247,7 @@ func positionalArgs(args []string) []string {
|
||||
skip = true
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(a, "--wrapper=") || strings.HasPrefix(a, "--binary=") {
|
||||
if strings.HasPrefix(a, "--wrapper=") || strings.HasPrefix(a, "--binary=") || strings.HasPrefix(a, "--build=") {
|
||||
continue
|
||||
}
|
||||
out = append(out, a)
|
||||
|
||||
Reference in New Issue
Block a user