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:
|
||||
from_secret: gitea-token
|
||||
commands:
|
||||
- make prepare-test
|
||||
- make test
|
||||
- name: store
|
||||
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 *.out
|
||||
|
||||
prepare-test:
|
||||
git submodule update --init --remote
|
||||
|
||||
test:
|
||||
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).
|
||||
|
||||
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).
|
||||
```bash
|
||||
|
@ -20,40 +20,47 @@ $ # make sure you are in go-judge directory
|
|||
$ ./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
|
||||
$ # 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
|
||||
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/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/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/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/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
|
||||
=== RUN TestMain
|
||||
=== 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
|
||||
main_test.go:101: stageResults: [{Name:compile Results:[{Score:0 Comment:Unexpected executor status: Nonzero Exit Status.}]}]
|
||||
=== 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
|
||||
main_test.go:101: stageResults: [{Name:dummy Results:[{Score:0 Comment:Unexpected executor status: Nonzero Exit Status.
|
||||
Stderr: dummy negative score: -1}]}]
|
||||
--- PASS: TestMain (0.39s)
|
||||
--- PASS: TestMain/compile/success (0.36s)
|
||||
=== RUN TestMain/cpplint/sillycode
|
||||
--- PASS: TestMain (0.42s)
|
||||
--- PASS: TestMain/compile/success (0.28s)
|
||||
--- 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/cpplint/sillycode (0.11s)
|
||||
PASS
|
||||
coverage: 68.5% of statements
|
||||
ok focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/joj3 0.403s coverage: 68.5% of statements
|
||||
coverage: 72.4% of statements
|
||||
ok focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/joj3 0.425s coverage: 72.4% of statements
|
||||
```
|
||||
|
||||
### For developers
|
||||
|
@ -66,7 +73,7 @@ $ pre-commit install
|
|||
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
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ func commitMsgToConf() (conf Conf, err error) {
|
|||
return
|
||||
}
|
||||
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
|
||||
conf = parseConfFile("conf.toml")
|
||||
return
|
||||
|
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"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/stage"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
|
@ -75,14 +73,9 @@ func outputResult(conf Conf, results []stage.StageResult) error {
|
|||
func main() {
|
||||
conf, err := commitMsgToConf()
|
||||
if err != nil {
|
||||
// FIXME: just for local testing purpose
|
||||
if errors.Is(err, git.ErrRepositoryNotExists) {
|
||||
conf = parseConfFile("conf.toml")
|
||||
} else {
|
||||
slog.Error("no conf found", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
setupSlog(conf)
|
||||
stages := generateStages(conf)
|
||||
defer stage.Cleanup()
|
||||
|
|
|
@ -10,72 +10,70 @@ import (
|
|||
"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()
|
||||
if len(actual) != len(want) {
|
||||
t.Fatalf("len(actual) = %d, want %d", len(actual), len(want))
|
||||
if len(actual) != len(expected) {
|
||||
t.Fatalf("len(actual) = %d, expected %d", len(actual), len(expected))
|
||||
}
|
||||
for i := range actual {
|
||||
if actual[i].Name != want[i].Name {
|
||||
t.Errorf("actual[%d].Name = %s, want = %s", i, actual[i].Name,
|
||||
want[i].Name)
|
||||
if actual[i].Name != expected[i].Name {
|
||||
t.Errorf("actual[%d].Name = %s, expected = %s", i, actual[i].Name,
|
||||
expected[i].Name)
|
||||
}
|
||||
if len(actual[i].Results) != len(want[i].Results) {
|
||||
t.Fatalf("len(actual[%d].Results) = %d, want = %d", i,
|
||||
len(actual[i].Results), len(want[i].Results))
|
||||
if len(actual[i].Results) != len(expected[i].Results) {
|
||||
t.Fatalf("len(actual[%d].Results) = %d, expected = %d", i,
|
||||
len(actual[i].Results), len(expected[i].Results))
|
||||
}
|
||||
for j := range actual[i].Results {
|
||||
if actual[i].Results[j].Score != want[i].Results[j].Score {
|
||||
t.Errorf("actual[%d].Results[%d].Score = %d, want = %d", i, j,
|
||||
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, expected = %d", i, j,
|
||||
actual[i].Results[j].Score, expected[i].Results[j].Score)
|
||||
}
|
||||
r := regexp.MustCompile(want[i].Results[j].Comment)
|
||||
if regex {
|
||||
r := regexp.MustCompile(expected[i].Results[j].Comment)
|
||||
if !r.MatchString(actual[i].Results[j].Comment) {
|
||||
t.Errorf("actual[%d].Results[%d].Comment = %s, want RegExp = %s",
|
||||
t.Errorf("actual[%d].Results[%d].Comment = %s, expected RegExp = %s",
|
||||
i, j, actual[i].Results[j].Comment,
|
||||
want[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) {
|
||||
tests := []struct {
|
||||
name string
|
||||
want []stage.StageResult
|
||||
}{
|
||||
{"compile/success", []stage.StageResult{
|
||||
{Name: "compile", Results: []stage.ParserResult{
|
||||
{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"},
|
||||
}},
|
||||
}},
|
||||
tests := []string{
|
||||
"compile/success",
|
||||
"compile/error",
|
||||
"dummy/success",
|
||||
"dummy/error",
|
||||
"cpplint/sillycode",
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt, func(t *testing.T) {
|
||||
origDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = os.Chdir(fmt.Sprintf("../../examples/%s", tt.name))
|
||||
err = os.Chdir(fmt.Sprintf("../../examples/%s", tt))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -86,20 +84,18 @@ func TestMain(t *testing.T) {
|
|||
}
|
||||
}()
|
||||
os.Args = []string{"./joj3"}
|
||||
main()
|
||||
outputFile := "joj3_result.json"
|
||||
data, err := os.ReadFile(outputFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(outputFile)
|
||||
var stageResults []stage.StageResult
|
||||
err = json.Unmarshal(data, &stageResults)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
main()
|
||||
stageResults := readStageResults(t, outputFile)
|
||||
regex := true
|
||||
expectedFile := "expected_regex.json"
|
||||
if _, err := os.Stat(expectedFile); os.IsNotExist(err) {
|
||||
regex = false
|
||||
expectedFile = "expected.json"
|
||||
}
|
||||
t.Logf("stageResults: %+v", stageResults)
|
||||
compareStageResults(t, stageResults, tt.want)
|
||||
expectedStageResults := readStageResults(t, expectedFile)
|
||||
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
|
||||
|
||||
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/dummy"
|
||||
_ "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