Merge branch 'master' into commit-parser
Some checks failed
checks / build (push) Failing after 0s
checks / build (pull_request) Failing after 0s

This commit is contained in:
zzjc1234 2024-09-23 12:36:34 +08:00
commit 9d3a980272
9 changed files with 97 additions and 64 deletions

View File

@ -22,7 +22,7 @@ $ # make sure you are in go-judge directory
$ ./tmp/go-judge -http-addr 0.0.0.0:5050 -grpc-addr 0.0.0.0:5051 -monitor-addr 0.0.0.0:5052 -enable-grpc -enable-debug -enable-metrics
```
6. Pull submodules. It might be slow, so only run it when necessary.
6. Pull submodules. It might be slow, so only run it when the test branches are out of date.
```bash
$ # make sure you are in JOJ3 directory
@ -75,7 +75,7 @@ Check `Cmd` at <https://github.com/criyle/go-judge#rest-api-interface>.
Some difference:
- `CopyInCwd bool`: set to `true` to add everything in the current working directory to `CopyIn`.
- `CopyInDir string`: set to non-empty string to add everything in that directory to `CopyIn`.
- `CopyInCached map[string]string`: key: file name in the sandbox, value: file name used in `CopyOutCached`.
- `LocalFile`: now supports the relative path
@ -88,6 +88,12 @@ Check the `Result` at <https://github.com/criyle/go-judge#rest-api-interface>.
- `Score int`: score of the stage.
- `Comment string`: comment on the stage.
## Binaries (under `/cmd` and `/pkg`)
### Sample
Just a sample on how to write an executable that can be called by the executor.
### HealthCheck
The repohealth check will return a json list to for check result. The structure follows the score-comment pattern.
@ -95,3 +101,53 @@ The repohealth check will return a json list to for check result. The structure
HealthCheck currently includes, `reposize`, `forbidden file`, `Metafile existence`, `non-ascii character` in file and message, `release tag`, and `ci files invariance` check.
The workflow is `joj3` pass cli args to healthcheck binary. See `./cmd/healthcheck/main.go` to view all flags.
## Executors (under `/internal/executors`)
### Dummy
Do not execute any command. Just return empty `ExecutorResult` slice.
### Sandbox
Run the commands in `go-judge` and output the `ExecutorResult` slice.
## Parsers (under `/internal/parsers`)
### Clang Tidy
Parser for `clang-tidy`, check `/examples/clangtidy` on how to call `clang-tidy` with proper parameters.
### Cppcheck
Parser for `cppcheck`, check `/examples/cppcheck` on how to call `cppcheck` with proper parameters.
### Cpplint
Parser for `cpplint`, check `/examples/cpplint` on how to call `cpplint` with proper parameters.
### Diff
Compare the specified output of `ExecutorResult` with the content of the answer file. If they are the same, then score will be given. Just like a normal online judge system.
### Dummy
Does not parse the output of `ExecutorResult`. It just output what is set inside the configuration file as score and comment. Currently it is used to output metadata for `joint-teapot`.
In `joint-teapot`, it will take the content before `-` of the comment of the first stage with name `metadata` as the exercise name and record in the scoreboard. (e.g. If the comment is `p2-s2-0xdeadbeef`, then the exercise name is `p2`.)
### Healthcheck
Parser for the `healthcheck` binary mentioned before.
### Keyword
Match the given keyword from the specified output of `ExecutorResult`. For each match, a deduction of score is given. Can be useful if we do not have a specific parser for a code quality tool. Check `/examples/keyword`.
### Result Status
Only check if all the status of the executor is `StatusAccepted`. Can be used to check whether the command run in the executor exit normally.
### Sample
Parser for the `sample` binary mentioned before. Only used as a sample.

View File

@ -85,22 +85,6 @@ func parseConfFile(path string, jobtype JobType) (conf Conf, err error) {
slog.Error("parse stages conf", "error", err)
return
}
if err = d.Validate(&conf); err != nil {
slog.Error("validate stages conf", "error", err)
return
}
filteredStages := []Stage{}
for _, stage := range conf.Stages {
if filterStage(stage, jobtype) {
filteredStages = append(filteredStages, stage)
}
}
conf.Stages = filteredStages
return
}

View File

@ -28,7 +28,7 @@ func convertPBCmd(cmd []stage.Cmd) []*pb.Request_CmdType {
CpuSetLimit: c.CPUSetLimit,
DataSegmentLimit: c.DataSegmentLimit,
AddressSpaceLimit: c.AddressSpaceLimit,
CopyIn: convertPBCopyIn(c.CopyIn, c.CopyInCwd),
CopyIn: convertPBCopyIn(c.CopyIn, c.CopyInDir),
CopyOut: convertPBCopyOut(c.CopyOut),
CopyOutCached: convertPBCopyOut(c.CopyOutCached),
CopyOutMax: c.CopyOutMax,
@ -39,9 +39,11 @@ func convertPBCmd(cmd []stage.Cmd) []*pb.Request_CmdType {
return ret
}
func convertPBCopyIn(copyIn map[string]stage.CmdFile, copyInCwd bool) map[string]*pb.Request_File {
if copyInCwd {
_ = filepath.Walk(".",
func convertPBCopyIn(
copyIn map[string]stage.CmdFile, copyInDir string,
) map[string]*pb.Request_File {
if copyInDir != "" {
_ = filepath.Walk(copyInDir,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil

View File

@ -29,7 +29,7 @@ func severityFromString(severityString string) (Severity, error) {
case "information":
return INFORMATION, nil
default:
return UNKNOWN, fmt.Errorf("unkown severity type \"%s\" for cppcheck", severityString)
return UNKNOWN, fmt.Errorf("unknown severity type \"%s\" for cppcheck", severityString)
}
}

View File

@ -46,7 +46,7 @@ type Cmd struct {
CopyIn map[string]CmdFile `json:"copyIn"`
CopyInCached map[string]string `json:"copyInCached"`
CopyInCwd bool `json:"copyInCwd"`
CopyInDir string `json:"copyInDir"`
CopyOut []string `json:"copyOut"`
CopyOutCached []string `json:"copyOutCached"`

View File

@ -7,7 +7,6 @@ import (
"unicode"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
)
// nonAsciiMsg checks for non-ASCII characters in the commit message.
@ -28,23 +27,19 @@ func NonAsciiMsg(root string) error {
slog.Error("getting reference", "err", err)
return fmt.Errorf("error getting reference: %v", err)
}
commits, err := repo.Log(&git.LogOptions{From: ref.Hash()})
commit, err := repo.CommitObject(ref.Hash())
if err != nil {
slog.Error("getting commits", "err", err)
return fmt.Errorf("error getting commits from reference %s: %v", ref.Hash(), err)
slog.Error("getting latest commit", "err", err)
return fmt.Errorf("error getting latest commit: %v", err)
}
var msgs []string
err = commits.ForEach(func(c *object.Commit) error {
msgs = append(msgs, c.Message)
msg := commit.Message
if msg == "" {
return nil
})
if err != nil {
slog.Error("iterating commits", "err", err)
return fmt.Errorf("error iterating commits: %v", err)
}
var nonAsciiMsgs []string
var isCommitLegal bool = true
// List of prefixes to ignore in the commit message
ignoredPrefixes := []string{
"Co-authored-by:",
@ -53,35 +48,31 @@ func NonAsciiMsg(root string) error {
"Reviewed-on:",
}
for _, msg := range msgs {
if msg == "" {
// Split message by lines and ignore specific lines with prefixes
lines := strings.Split(msg, "\n")
for _, line := range lines {
trimmedLine := strings.TrimSpace(line)
ignore := false
for _, prefix := range ignoredPrefixes {
if strings.HasPrefix(trimmedLine, prefix) {
ignore = true
break
}
}
if ignore {
continue
}
// Split message by lines and ignore specific lines with prefixes
lines := strings.Split(msg, "\n")
for _, line := range lines {
trimmedLine := strings.TrimSpace(line)
ignore := false
for _, prefix := range ignoredPrefixes {
if strings.HasPrefix(trimmedLine, prefix) {
ignore = true
break
}
}
if ignore {
continue
}
// Check for non-ASCII characters in the rest of the lines
for _, c := range line {
if c > unicode.MaxASCII {
nonAsciiMsgs = append(nonAsciiMsgs, msg)
break
}
// Check for non-ASCII characters in the rest of the lines
for _, c := range line {
if c > unicode.MaxASCII {
isCommitLegal = false
break
}
}
}
if len(nonAsciiMsgs) > 0 {
return fmt.Errorf("Non-ASCII characters in commit messages:\n%s", strings.Join(nonAsciiMsgs, "\n"))
if !isCommitLegal {
return fmt.Errorf("Non-ASCII characters in commit messages:\n%s", msg)
}
return nil
}

View File

@ -25,7 +25,7 @@ func getMetas(rootDir string, fileList []string) ([]string, string, error) {
matched := false
umatchedRes := ""
// TODO: it seems that there is no good find subsitution now
// TODO: it seems that there is no good find substitution now
// modify current code if exist a better solution
for i, regex := range regexList {
for _, file := range files {

View File

@ -18,14 +18,14 @@ for submodule in $submodules; do
else
cd $repo_dir
git fetch --all
cd -
cd - > /dev/null
fi
fi
repo_names[$repo_name]=1
cd $repo_dir
git checkout -q $branch
git reset -q --hard origin/$branch
cd -
cd - > /dev/null
submodule_dir="$submodules_dir/$repo_name/$submodule"
mkdir -p $submodule_dir
cp -rT $repo_dir $submodule_dir

View File

@ -17,5 +17,5 @@ for submodule in $submodules; do
mv -f "joj3_result.json" "expected.json"
fi
fi
cd -
cd - > /dev/null
done