feat: cpplint parser (#22)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Co-authored-by: Boming Zhang <bomingzh@sjtu.edu.cn> Reviewed-on: FOCS-dev/JOJ3#22
This commit is contained in:
parent
0bf349c032
commit
51539c1e7c
|
@ -25,6 +25,7 @@ steps:
|
||||||
CONF_GITEATOKEN:
|
CONF_GITEATOKEN:
|
||||||
from_secret: gitea-token
|
from_secret: gitea-token
|
||||||
commands:
|
commands:
|
||||||
|
- make prepare-test
|
||||||
- make test
|
- make test
|
||||||
- name: store
|
- name: store
|
||||||
commands:
|
commands:
|
||||||
|
|
20
.gitmodules
vendored
Normal file
20
.gitmodules
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[submodule "examples/cpplint/sillycode"]
|
||||||
|
path = examples/cpplint/sillycode
|
||||||
|
url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git
|
||||||
|
branch = cpplint/sillycode
|
||||||
|
[submodule "examples/compile/success"]
|
||||||
|
path = examples/compile/success
|
||||||
|
url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git
|
||||||
|
branch = compile/success
|
||||||
|
[submodule "examples/compile/error"]
|
||||||
|
path = examples/compile/error
|
||||||
|
url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git
|
||||||
|
branch = compile/error
|
||||||
|
[submodule "examples/dummy/success"]
|
||||||
|
path = examples/dummy/success
|
||||||
|
url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git
|
||||||
|
branch = dummy/success
|
||||||
|
[submodule "examples/dummy/error"]
|
||||||
|
path = examples/dummy/error
|
||||||
|
url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git
|
||||||
|
branch = dummy/error
|
3
Makefile
3
Makefile
|
@ -11,5 +11,8 @@ clean:
|
||||||
rm -rf $(BUILD_DIR)/*
|
rm -rf $(BUILD_DIR)/*
|
||||||
rm -rf *.out
|
rm -rf *.out
|
||||||
|
|
||||||
|
prepare-test:
|
||||||
|
git submodule update --init --remote
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -coverprofile cover.out -v ./...
|
go test -coverprofile cover.out -v ./...
|
||||||
|
|
41
README.md
41
README.md
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
1. Make sure you are in a Unix-like OS (Linux, MacOS). For Windows, use [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install).
|
1. Make sure you are in a Unix-like OS (Linux, MacOS). For Windows, use [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install).
|
||||||
|
|
||||||
2. Install [Go](https://go.dev/doc/install). Also make sure `make` and `git` are installed and all 3 programs are presented in `$PATH`.
|
2. Install [Go](https://go.dev/doc/install). Also, make sure `make` and `git` are installed and all 3 programs are presented in `$PATH`.
|
||||||
|
|
||||||
3. Enable cgroups v2 for your OS. Check [here](https://stackoverflow.com/a/73376219/13724598). So that you do not need root permission to run `go-judge`.
|
3. Enable cgroup v2 for your OS. Check [here](https://stackoverflow.com/a/73376219/13724598). So that you do not need root permission to run `go-judge`.
|
||||||
|
|
||||||
4. Clone [go-judge](https://github.com/criyle/go-judge).
|
4. Clone [go-judge](https://github.com/criyle/go-judge).
|
||||||
```bash
|
```bash
|
||||||
|
@ -20,40 +20,47 @@ $ # make sure you are in go-judge directory
|
||||||
$ ./tmp/go-judge -enable-grpc -enable-debug -enable-metrics
|
$ ./tmp/go-judge -enable-grpc -enable-debug -enable-metrics
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Check the functions of `joj3` with the `make test`, which should pass all the test cases. The cases used here are in `/examples`.
|
6. Pull submodules. It might be slow, so only run it when necessary.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ # make sure you are in JOJ3 directory
|
$ # make sure you are in JOJ3 directory
|
||||||
|
$ make prepare-test
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Check the functions of `joj3` with the `make test`, which should pass all the test cases. The cases used here are in `/examples`.
|
||||||
|
|
||||||
|
Note: you may fail the test if the checking tools are not installed. e.g. For the test case `cpplint/sillycode`, you need to install `cpplint` in `/usr/bin` or `/usr/local/bin`.
|
||||||
|
|
||||||
|
```bash
|
||||||
$ make test
|
$ make test
|
||||||
go test -coverprofile cover.out -v ./...
|
go test -coverprofile cover.out -v ./...
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/dummy coverage: 0.0% of statements
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/dummy coverage: 0.0% of statements
|
||||||
? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors [no test files]
|
? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors [no test files]
|
||||||
? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers [no test files]
|
? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers [no test files]
|
||||||
? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/healthcheck [no test files]
|
? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/healthcheck [no test files]
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/sandbox coverage: 0.0% of statements
|
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/dummy coverage: 0.0% of statements
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/dummy coverage: 0.0% of statements
|
||||||
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cpplint coverage: 0.0% of statements
|
||||||
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/sandbox coverage: 0.0% of statements
|
||||||
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy coverage: 0.0% of statements
|
||||||
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage coverage: 0.0% of statements
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff coverage: 0.0% of statements
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff coverage: 0.0% of statements
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/dummy coverage: 0.0% of statements
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/dummy coverage: 0.0% of statements
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage coverage: 0.0% of statements
|
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy coverage: 0.0% of statements
|
|
||||||
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus coverage: 0.0% of statements
|
focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus coverage: 0.0% of statements
|
||||||
=== RUN TestMain
|
=== RUN TestMain
|
||||||
=== RUN TestMain/compile/success
|
=== RUN TestMain/compile/success
|
||||||
main_test.go:101: stageResults: [{Name:compile Results:[{Score:0 Comment:}]} {Name:run Results:[{Score:100 Comment:executor status: run time: 1867950 ns, memory: 10813440 bytes} {Score:100 Comment:executor status: run time: 1948947 ns, memory: 10813440 bytes}]}]
|
|
||||||
=== RUN TestMain/compile/error
|
=== RUN TestMain/compile/error
|
||||||
main_test.go:101: stageResults: [{Name:compile Results:[{Score:0 Comment:Unexpected executor status: Nonzero Exit Status.}]}]
|
|
||||||
=== RUN TestMain/dummy/success
|
=== RUN TestMain/dummy/success
|
||||||
main_test.go:101: stageResults: [{Name:dummy Results:[{Score:110 Comment:dummy comment + comment from toml conf}]}]
|
|
||||||
=== RUN TestMain/dummy/error
|
=== RUN TestMain/dummy/error
|
||||||
main_test.go:101: stageResults: [{Name:dummy Results:[{Score:0 Comment:Unexpected executor status: Nonzero Exit Status.
|
=== RUN TestMain/cpplint/sillycode
|
||||||
Stderr: dummy negative score: -1}]}]
|
--- PASS: TestMain (0.42s)
|
||||||
--- PASS: TestMain (0.39s)
|
--- PASS: TestMain/compile/success (0.28s)
|
||||||
--- PASS: TestMain/compile/success (0.36s)
|
|
||||||
--- PASS: TestMain/compile/error (0.01s)
|
--- PASS: TestMain/compile/error (0.01s)
|
||||||
--- PASS: TestMain/dummy/success (0.02s)
|
--- PASS: TestMain/dummy/success (0.01s)
|
||||||
--- PASS: TestMain/dummy/error (0.01s)
|
--- PASS: TestMain/dummy/error (0.01s)
|
||||||
|
--- PASS: TestMain/cpplint/sillycode (0.11s)
|
||||||
PASS
|
PASS
|
||||||
coverage: 68.5% of statements
|
coverage: 72.4% of statements
|
||||||
ok focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/joj3 0.403s coverage: 68.5% of statements
|
ok focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/joj3 0.425s coverage: 72.4% of statements
|
||||||
```
|
```
|
||||||
|
|
||||||
### For developers
|
### For developers
|
||||||
|
@ -66,7 +73,7 @@ $ pre-commit install
|
||||||
pre-commit installed at .git/hooks/pre-commit
|
pre-commit installed at .git/hooks/pre-commit
|
||||||
```
|
```
|
||||||
|
|
||||||
3. You only need to run step 5 and 6 in quick start during development.
|
3. You only need to run steps 5 and 7 in the quick start during development. If the test cases need to be updated, step 6 is also needed.
|
||||||
|
|
||||||
## Models
|
## Models
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ func commitMsgToConf() (conf Conf, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg := commit.Message
|
msg := commit.Message
|
||||||
slog.Info("commit msg to conf", "msg", msg)
|
slog.Debug("commit msg to conf", "msg", msg)
|
||||||
// TODO: parse msg to conf name
|
// TODO: parse msg to conf name
|
||||||
conf = parseConfFile("conf.toml")
|
conf = parseConfFile("conf.toml")
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -10,7 +9,6 @@ import (
|
||||||
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers"
|
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers"
|
||||||
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5"
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -75,13 +73,8 @@ func outputResult(conf Conf, results []stage.StageResult) error {
|
||||||
func main() {
|
func main() {
|
||||||
conf, err := commitMsgToConf()
|
conf, err := commitMsgToConf()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME: just for local testing purpose
|
slog.Error("no conf found", "error", err)
|
||||||
if errors.Is(err, git.ErrRepositoryNotExists) {
|
os.Exit(1)
|
||||||
conf = parseConfFile("conf.toml")
|
|
||||||
} else {
|
|
||||||
slog.Error("no conf found", "error", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setupSlog(conf)
|
setupSlog(conf)
|
||||||
stages := generateStages(conf)
|
stages := generateStages(conf)
|
||||||
|
|
|
@ -10,72 +10,70 @@ import (
|
||||||
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||||
)
|
)
|
||||||
|
|
||||||
func compareStageResults(t *testing.T, actual, want []stage.StageResult) {
|
func compareStageResults(t *testing.T, actual, expected []stage.StageResult, regex bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if len(actual) != len(want) {
|
if len(actual) != len(expected) {
|
||||||
t.Fatalf("len(actual) = %d, want %d", len(actual), len(want))
|
t.Fatalf("len(actual) = %d, expected %d", len(actual), len(expected))
|
||||||
}
|
}
|
||||||
for i := range actual {
|
for i := range actual {
|
||||||
if actual[i].Name != want[i].Name {
|
if actual[i].Name != expected[i].Name {
|
||||||
t.Errorf("actual[%d].Name = %s, want = %s", i, actual[i].Name,
|
t.Errorf("actual[%d].Name = %s, expected = %s", i, actual[i].Name,
|
||||||
want[i].Name)
|
expected[i].Name)
|
||||||
}
|
}
|
||||||
if len(actual[i].Results) != len(want[i].Results) {
|
if len(actual[i].Results) != len(expected[i].Results) {
|
||||||
t.Fatalf("len(actual[%d].Results) = %d, want = %d", i,
|
t.Fatalf("len(actual[%d].Results) = %d, expected = %d", i,
|
||||||
len(actual[i].Results), len(want[i].Results))
|
len(actual[i].Results), len(expected[i].Results))
|
||||||
}
|
}
|
||||||
for j := range actual[i].Results {
|
for j := range actual[i].Results {
|
||||||
if actual[i].Results[j].Score != want[i].Results[j].Score {
|
if actual[i].Results[j].Score != expected[i].Results[j].Score {
|
||||||
t.Errorf("actual[%d].Results[%d].Score = %d, want = %d", i, j,
|
t.Errorf("actual[%d].Results[%d].Score = %d, expected = %d", i, j,
|
||||||
actual[i].Results[j].Score, want[i].Results[j].Score)
|
actual[i].Results[j].Score, expected[i].Results[j].Score)
|
||||||
}
|
}
|
||||||
r := regexp.MustCompile(want[i].Results[j].Comment)
|
if regex {
|
||||||
if !r.MatchString(actual[i].Results[j].Comment) {
|
r := regexp.MustCompile(expected[i].Results[j].Comment)
|
||||||
t.Errorf("actual[%d].Results[%d].Comment = %s, want RegExp = %s",
|
if !r.MatchString(actual[i].Results[j].Comment) {
|
||||||
i, j, actual[i].Results[j].Comment,
|
t.Errorf("actual[%d].Results[%d].Comment = %s, expected RegExp = %s",
|
||||||
want[i].Results[j].Comment)
|
i, j, actual[i].Results[j].Comment,
|
||||||
|
expected[i].Results[j].Comment)
|
||||||
|
}
|
||||||
|
} else if actual[i].Results[j].Comment != expected[i].Results[j].Comment {
|
||||||
|
t.Errorf("actual[%d].Results[%d].Comment = %s, expected = %s", i, j,
|
||||||
|
actual[i].Results[j].Comment, expected[i].Results[j].Comment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readStageResults(t *testing.T, path string) []stage.StageResult {
|
||||||
|
t.Helper()
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
var results []stage.StageResult
|
||||||
|
err = json.NewDecoder(file).Decode(&results)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
func TestMain(t *testing.T) {
|
func TestMain(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []string{
|
||||||
name string
|
"compile/success",
|
||||||
want []stage.StageResult
|
"compile/error",
|
||||||
}{
|
"dummy/success",
|
||||||
{"compile/success", []stage.StageResult{
|
"dummy/error",
|
||||||
{Name: "compile", Results: []stage.ParserResult{
|
"cpplint/sillycode",
|
||||||
{Score: 0, Comment: ""},
|
|
||||||
}},
|
|
||||||
{Name: "run", Results: []stage.ParserResult{
|
|
||||||
{Score: 100, Comment: "executor status: run time: \\d+ ns, memory: \\d+ bytes"},
|
|
||||||
{Score: 100, Comment: "executor status: run time: \\d+ ns, memory: \\d+ bytes"},
|
|
||||||
}},
|
|
||||||
}},
|
|
||||||
{"compile/error", []stage.StageResult{
|
|
||||||
{Name: "compile", Results: []stage.ParserResult{
|
|
||||||
{Score: 0, Comment: "Unexpected executor status: Nonzero Exit Status\\."},
|
|
||||||
}},
|
|
||||||
}},
|
|
||||||
{"dummy/success", []stage.StageResult{
|
|
||||||
{Name: "dummy", Results: []stage.ParserResult{
|
|
||||||
{Score: 110, Comment: "dummy comment \\+ comment from toml conf"},
|
|
||||||
}},
|
|
||||||
}},
|
|
||||||
{"dummy/error", []stage.StageResult{
|
|
||||||
{Name: "dummy", Results: []stage.ParserResult{
|
|
||||||
{Score: 0, Comment: "Unexpected executor status: Nonzero Exit Status\\.\\s*Stderr: dummy negative score: -1"},
|
|
||||||
}},
|
|
||||||
}},
|
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt, func(t *testing.T) {
|
||||||
origDir, err := os.Getwd()
|
origDir, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = os.Chdir(fmt.Sprintf("../../examples/%s", tt.name))
|
err = os.Chdir(fmt.Sprintf("../../examples/%s", tt))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -86,20 +84,18 @@ func TestMain(t *testing.T) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
os.Args = []string{"./joj3"}
|
os.Args = []string{"./joj3"}
|
||||||
main()
|
|
||||||
outputFile := "joj3_result.json"
|
outputFile := "joj3_result.json"
|
||||||
data, err := os.ReadFile(outputFile)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.Remove(outputFile)
|
defer os.Remove(outputFile)
|
||||||
var stageResults []stage.StageResult
|
main()
|
||||||
err = json.Unmarshal(data, &stageResults)
|
stageResults := readStageResults(t, outputFile)
|
||||||
if err != nil {
|
regex := true
|
||||||
t.Fatal(err)
|
expectedFile := "expected_regex.json"
|
||||||
|
if _, err := os.Stat(expectedFile); os.IsNotExist(err) {
|
||||||
|
regex = false
|
||||||
|
expectedFile = "expected.json"
|
||||||
}
|
}
|
||||||
t.Logf("stageResults: %+v", stageResults)
|
expectedStageResults := readStageResults(t, expectedFile)
|
||||||
compareStageResults(t, stageResults, tt.want)
|
compareStageResults(t, stageResults, expectedStageResults, regex)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
examples/compile/error
Submodule
1
examples/compile/error
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit dc7be30db1fbfd83ecb78f214cff3f42732a1365
|
|
@ -1,61 +0,0 @@
|
||||||
skipGitea = true
|
|
||||||
logLevel = 0
|
|
||||||
[[stages]]
|
|
||||||
name = "compile"
|
|
||||||
[stages.executor]
|
|
||||||
name = "sandbox"
|
|
||||||
[stages.executor.with.default]
|
|
||||||
args = ["g++", "b.cc", "-o", "a"]
|
|
||||||
env = ["PATH=/usr/bin:/bin"]
|
|
||||||
cpuLimit = 10_000_000_000
|
|
||||||
memoryLimit = 104_857_600
|
|
||||||
procLimit = 50
|
|
||||||
copyInCwd = true
|
|
||||||
copyOut = ["stdout", "stderr"]
|
|
||||||
copyOutCached = ["a"]
|
|
||||||
[stages.executor.with.default.stdin]
|
|
||||||
content = ""
|
|
||||||
[stages.executor.with.default.stdout]
|
|
||||||
name = "stdout"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.stderr]
|
|
||||||
name = "stderr"
|
|
||||||
max = 4_096
|
|
||||||
[stages.parser]
|
|
||||||
name = "result-status"
|
|
||||||
[stages.parser.with]
|
|
||||||
score = 100
|
|
||||||
comment = "compile done"
|
|
||||||
[[stages]]
|
|
||||||
name = "run"
|
|
||||||
[stages.executor]
|
|
||||||
name = "sandbox"
|
|
||||||
[stages.executor.with.default]
|
|
||||||
args = ["./a"]
|
|
||||||
env = ["PATH=/usr/bin:/bin"]
|
|
||||||
cpuLimit = 1_000_000_000
|
|
||||||
memoryLimit = 104_857_600
|
|
||||||
procLimit = 50
|
|
||||||
copyOut = ["stdout", "stderr"]
|
|
||||||
[stages.executor.with.default.stdout]
|
|
||||||
name = "stdout"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.stderr]
|
|
||||||
name = "stderr"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.copyInCached]
|
|
||||||
a = "a"
|
|
||||||
[[stages.executor.with.cases]]
|
|
||||||
[stages.executor.with.cases.stdin]
|
|
||||||
src = "./cases/1.in"
|
|
||||||
[[stages.executor.with.cases]]
|
|
||||||
[stages.executor.with.cases.stdin]
|
|
||||||
src = "./cases/2.in"
|
|
||||||
[stages.parser]
|
|
||||||
name = "diff"
|
|
||||||
[[stages.parser.with.cases]]
|
|
||||||
score = 100
|
|
||||||
stdoutPath = "./cases/1.out"
|
|
||||||
[[stages.parser.with.cases]]
|
|
||||||
score = 100
|
|
||||||
stdoutPath = "./cases/2.out"
|
|
1
examples/compile/success
Submodule
1
examples/compile/success
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 21f6df70d483f34a99b50335e0a1fbe50d3a82dd
|
|
@ -1,6 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
int main() {
|
|
||||||
int a, b;
|
|
||||||
std::cin >> a >> b;
|
|
||||||
std::cout << a + b << '\n';
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
1 1
|
|
|
@ -1 +0,0 @@
|
||||||
2
|
|
|
@ -1 +0,0 @@
|
||||||
1024 2048
|
|
|
@ -1 +0,0 @@
|
||||||
3072
|
|
|
@ -1,60 +0,0 @@
|
||||||
skipGitea = true
|
|
||||||
[[stages]]
|
|
||||||
name = "compile"
|
|
||||||
[stages.executor]
|
|
||||||
name = "sandbox"
|
|
||||||
[stages.executor.with.default]
|
|
||||||
args = ["g++", "a.cc", "-o", "a"]
|
|
||||||
env = ["PATH=/usr/bin:/bin"]
|
|
||||||
cpuLimit = 10_000_000_000
|
|
||||||
memoryLimit = 104_857_600
|
|
||||||
procLimit = 50
|
|
||||||
copyInCwd = true
|
|
||||||
copyOut = ["stdout", "stderr"]
|
|
||||||
copyOutCached = ["a"]
|
|
||||||
[stages.executor.with.default.stdin]
|
|
||||||
content = ""
|
|
||||||
[stages.executor.with.default.stdout]
|
|
||||||
name = "stdout"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.stderr]
|
|
||||||
name = "stderr"
|
|
||||||
max = 4_096
|
|
||||||
[stages.parser]
|
|
||||||
name = "result-status"
|
|
||||||
[stages.parser.with]
|
|
||||||
score = 100
|
|
||||||
comment = "compile done"
|
|
||||||
[[stages]]
|
|
||||||
name = "run"
|
|
||||||
[stages.executor]
|
|
||||||
name = "sandbox"
|
|
||||||
[stages.executor.with.default]
|
|
||||||
args = ["./a"]
|
|
||||||
env = ["PATH=/usr/bin:/bin"]
|
|
||||||
cpuLimit = 1_000_000_000
|
|
||||||
memoryLimit = 104_857_600
|
|
||||||
procLimit = 50
|
|
||||||
copyOut = ["stdout", "stderr"]
|
|
||||||
[stages.executor.with.default.stdout]
|
|
||||||
name = "stdout"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.stderr]
|
|
||||||
name = "stderr"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.copyInCached]
|
|
||||||
a = "a"
|
|
||||||
[[stages.executor.with.cases]]
|
|
||||||
[stages.executor.with.cases.stdin]
|
|
||||||
src = "./cases/1.in"
|
|
||||||
[[stages.executor.with.cases]]
|
|
||||||
[stages.executor.with.cases.stdin]
|
|
||||||
src = "./cases/2.in"
|
|
||||||
[stages.parser]
|
|
||||||
name = "diff"
|
|
||||||
[[stages.parser.with.cases]]
|
|
||||||
score = 100
|
|
||||||
stdoutPath = "./cases/1.out"
|
|
||||||
[[stages.parser.with.cases]]
|
|
||||||
score = 100
|
|
||||||
stdoutPath = "./cases/2.out"
|
|
1
examples/cpplint/sillycode
Submodule
1
examples/cpplint/sillycode
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit e6504575379ef49c1495dc635f7aba36f57dddc8
|
1
examples/dummy/error
Submodule
1
examples/dummy/error
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 3ebebbc913534fb4c4598d3ed313d1bb3ff29020
|
|
@ -1,28 +0,0 @@
|
||||||
skipGitea = true
|
|
||||||
[[stages]]
|
|
||||||
name = "dummy"
|
|
||||||
[stages.executor]
|
|
||||||
name = "sandbox"
|
|
||||||
[stages.executor.with.default]
|
|
||||||
args = ["./dummy", "--score", "-1"]
|
|
||||||
env = ["PATH=/usr/bin:/bin"]
|
|
||||||
cpuLimit = 10_000_000_000
|
|
||||||
memoryLimit = 104_857_600
|
|
||||||
procLimit = 50
|
|
||||||
copyInCwd = true
|
|
||||||
[stages.executor.with.default.copyIn.dummy]
|
|
||||||
src = "./../../../build/dummy"
|
|
||||||
copyOut = ["stdout", "stderr"]
|
|
||||||
[stages.executor.with.default.stdin]
|
|
||||||
content = ""
|
|
||||||
[stages.executor.with.default.stdout]
|
|
||||||
name = "stdout"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.stderr]
|
|
||||||
name = "stderr"
|
|
||||||
max = 4_096
|
|
||||||
[stages.parser]
|
|
||||||
name = "dummy"
|
|
||||||
[stages.parser.with]
|
|
||||||
score = 10
|
|
||||||
comment = " + comment from toml conf"
|
|
1
examples/dummy/success
Submodule
1
examples/dummy/success
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 4bca6f0e4b5e263532b8410afecca615e90524e9
|
|
@ -1,28 +0,0 @@
|
||||||
skipGitea = true
|
|
||||||
[[stages]]
|
|
||||||
name = "dummy"
|
|
||||||
[stages.executor]
|
|
||||||
name = "sandbox"
|
|
||||||
[stages.executor.with.default]
|
|
||||||
args = ["./dummy", "--score", "100"]
|
|
||||||
env = ["PATH=/usr/bin:/bin"]
|
|
||||||
cpuLimit = 10_000_000_000
|
|
||||||
memoryLimit = 104_857_600
|
|
||||||
procLimit = 50
|
|
||||||
copyInCwd = true
|
|
||||||
[stages.executor.with.default.copyIn.dummy]
|
|
||||||
src = "./../../../build/dummy"
|
|
||||||
copyOut = ["stdout", "stderr"]
|
|
||||||
[stages.executor.with.default.stdin]
|
|
||||||
content = ""
|
|
||||||
[stages.executor.with.default.stdout]
|
|
||||||
name = "stdout"
|
|
||||||
max = 4_096
|
|
||||||
[stages.executor.with.default.stderr]
|
|
||||||
name = "stderr"
|
|
||||||
max = 4_096
|
|
||||||
[stages.parser]
|
|
||||||
name = "dummy"
|
|
||||||
[stages.parser.with]
|
|
||||||
score = 10
|
|
||||||
comment = " + comment from toml conf"
|
|
|
@ -1,6 +1,7 @@
|
||||||
package parsers
|
package parsers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cpplint"
|
||||||
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff"
|
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff"
|
||||||
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy"
|
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy"
|
||||||
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus"
|
_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus"
|
||||||
|
|
9
internal/parsers/cpplint/meta.go
Normal file
9
internal/parsers/cpplint/meta.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package cpplint
|
||||||
|
|
||||||
|
import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||||
|
|
||||||
|
var name = "cpplint"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
stage.RegisterParser(name, &Cpplint{})
|
||||||
|
}
|
53
internal/parsers/cpplint/parser.go
Normal file
53
internal/parsers/cpplint/parser.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package cpplint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Conf struct {
|
||||||
|
Score int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Cpplint struct{}
|
||||||
|
|
||||||
|
func Parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult {
|
||||||
|
stderr := executorResult.Files["stderr"]
|
||||||
|
pattern := `(.+):(\d+): (.+) \[(.+)\] \[(\d)]\n`
|
||||||
|
re := regexp.MustCompile(pattern)
|
||||||
|
matches := re.FindAllStringSubmatch(stderr, -1)
|
||||||
|
score := 0
|
||||||
|
comment := ""
|
||||||
|
for _, match := range matches {
|
||||||
|
fileName := match[1]
|
||||||
|
lineNum, _ := strconv.Atoi(match[2])
|
||||||
|
message := match[3]
|
||||||
|
category := match[4]
|
||||||
|
confidence, _ := strconv.Atoi(match[5])
|
||||||
|
score -= confidence
|
||||||
|
// TODO: add more detailed comment, just re-assemble for now
|
||||||
|
comment += fmt.Sprintf("%s:%d: %s [%s] [%d]\n",
|
||||||
|
fileName, lineNum, message, category, confidence)
|
||||||
|
}
|
||||||
|
return stage.ParserResult{
|
||||||
|
Score: score,
|
||||||
|
Comment: comment,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Cpplint) Run(results []stage.ExecutorResult, confAny any) (
|
||||||
|
[]stage.ParserResult, bool, error,
|
||||||
|
) {
|
||||||
|
conf, err := stage.DecodeConf[Conf](confAny)
|
||||||
|
if err != nil {
|
||||||
|
return nil, true, err
|
||||||
|
}
|
||||||
|
var res []stage.ParserResult
|
||||||
|
for _, result := range results {
|
||||||
|
res = append(res, Parse(result, *conf))
|
||||||
|
}
|
||||||
|
return res, false, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user