Compare commits
1 Commits
master
...
feat/submo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f04b18189a |
4
.gitmodules
vendored
4
.gitmodules
vendored
|
|
@ -70,7 +70,3 @@
|
||||||
path = examples/cpplint/simple
|
path = examples/cpplint/simple
|
||||||
url = ssh://git@focs.ji.sjtu.edu.cn:2222/JOJ/JOJ3-examples.git
|
url = ssh://git@focs.ji.sjtu.edu.cn:2222/JOJ/JOJ3-examples.git
|
||||||
branch = cpplint/simple
|
branch = cpplint/simple
|
||||||
[submodule "examples/healthcheck/whitelistedchars-success"]
|
|
||||||
path = examples/healthcheck/whitelistedchars-success
|
|
||||||
url = ssh://git@focs.ji.sjtu.edu.cn:2222/JOJ/JOJ3-examples.git
|
|
||||||
branch = healthcheck/whitelistedchars-success
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ $ git clone ssh://git@focs.ji.sjtu.edu.cn:2222/JOJ/JOJ3.git
|
||||||
|
|
||||||
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`.
|
||||||
|
|
||||||
- If you have problem on connecting to the Go website and Go packages, download Go from [studygolang](https://studygolang.com/dl) and run `go env -w GOPROXY=https://goproxy.cn,direct` to set the Go modules mirror proxy after installing Go.
|
- If you have problem on connecting to the Go website and Go packages, download Go from [studygolang](https://studygolang.com/dl) and run `go env -w GOPROXY=https://goproxy.io,direct` to set the Go modules mirror proxy after installing Go.
|
||||||
|
|
||||||
3. Enable cgroup v2 for your OS. For WSL2, check [here](https://stackoverflow.com/a/73376219/13724598). Also, enable linger for the user you used to run `go-judge` if you are using `systemd`, e.g. if the user is `go-judge`, run `loginctl enable-linger go-judge`. So that you do not need root permission to run `go-judge` (it can create a nesting cgroup in its user slice).
|
3. Enable cgroup v2 for your OS. For WSL2, check [here](https://stackoverflow.com/a/73376219/13724598). Also, enable linger for the user you used to run `go-judge` if you are using `systemd`, e.g. if the user is `go-judge`, run `loginctl enable-linger go-judge`. So that you do not need root permission to run `go-judge` (it can create a nesting cgroup in its user slice).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/koding/multiconfig"
|
"github.com/koding/multiconfig"
|
||||||
|
|
@ -184,17 +183,6 @@ func GetConfPath(confRoot, confName, fallbackConfName, msg, tag string) (
|
||||||
return confPath, confStat, conventionalCommit, err
|
return confPath, confStat, conventionalCommit, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check file ownership
|
|
||||||
if stat, ok := confStat.Sys().(*syscall.Stat_t); ok {
|
|
||||||
uid := int(stat.Uid)
|
|
||||||
currentUID := os.Getuid()
|
|
||||||
if uid != currentUID {
|
|
||||||
err = fmt.Errorf("insecure configuration file: owned by uid %d, expected %d", uid, currentUID)
|
|
||||||
slog.Error("insecure conf file", "path", confPath, "uid", uid, "currentUID", currentUID)
|
|
||||||
return confPath, confStat, conventionalCommit, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return confPath, confStat, conventionalCommit, err
|
return confPath, confStat, conventionalCommit, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,12 +190,32 @@ func MatchGroups(conf *Conf, conventionalCommit *ConventionalCommit) []string {
|
||||||
seen := make(map[string]bool)
|
seen := make(map[string]bool)
|
||||||
keywords := []string{}
|
keywords := []string{}
|
||||||
loweredCommitGroup := strings.ToLower(conventionalCommit.Group)
|
loweredCommitGroup := strings.ToLower(conventionalCommit.Group)
|
||||||
matchAllGroups := loweredCommitGroup == "all"
|
if loweredCommitGroup == "all" {
|
||||||
|
for i := range conf.PreStages {
|
||||||
|
conf.PreStages[i].Group = ""
|
||||||
|
conf.PreStages[i].Groups = nil
|
||||||
|
}
|
||||||
|
for i := range conf.Stages {
|
||||||
|
conf.Stages[i].Group = ""
|
||||||
|
conf.Stages[i].Groups = nil
|
||||||
|
}
|
||||||
|
for i := range conf.PostStages {
|
||||||
|
conf.PostStages[i].Group = ""
|
||||||
|
conf.PostStages[i].Groups = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
confStages := []ConfStage{}
|
confStages := []ConfStage{}
|
||||||
confStages = append(confStages, conf.PreStages...)
|
confStages = append(confStages, conf.PreStages...)
|
||||||
confStages = append(confStages, conf.Stages...)
|
confStages = append(confStages, conf.Stages...)
|
||||||
confStages = append(confStages, conf.PostStages...)
|
confStages = append(confStages, conf.PostStages...)
|
||||||
for _, stage := range confStages {
|
for _, stage := range confStages {
|
||||||
|
if stage.Group != "" {
|
||||||
|
keyword := strings.ToLower(stage.Group)
|
||||||
|
if _, exists := seen[keyword]; !exists {
|
||||||
|
seen[keyword] = true
|
||||||
|
keywords = append(keywords, keyword)
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(stage.Groups) > 0 {
|
if len(stage.Groups) > 0 {
|
||||||
for _, group := range stage.Groups {
|
for _, group := range stage.Groups {
|
||||||
keyword := strings.ToLower(group)
|
keyword := strings.ToLower(group)
|
||||||
|
|
@ -221,21 +229,10 @@ func MatchGroups(conf *Conf, conventionalCommit *ConventionalCommit) []string {
|
||||||
slog.Info("group keywords from stages", "keywords", keywords)
|
slog.Info("group keywords from stages", "keywords", keywords)
|
||||||
groups := []string{}
|
groups := []string{}
|
||||||
for _, keyword := range keywords {
|
for _, keyword := range keywords {
|
||||||
if matchAllGroups || strings.Contains(loweredCommitGroup, keyword) {
|
if strings.Contains(loweredCommitGroup, keyword) {
|
||||||
groups = append(groups, keyword)
|
groups = append(groups, keyword)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slog.Info("matched groups", "groups", groups)
|
slog.Info("matched groups", "groups", groups)
|
||||||
if matchAllGroups {
|
|
||||||
for i := range conf.PreStages {
|
|
||||||
conf.PreStages[i].Groups = nil
|
|
||||||
}
|
|
||||||
for i := range conf.Stages {
|
|
||||||
conf.Stages[i].Groups = nil
|
|
||||||
}
|
|
||||||
for i := range conf.PostStages {
|
|
||||||
conf.PostStages[i].Groups = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
type ConfStage struct {
|
type ConfStage struct {
|
||||||
Name string
|
Name string
|
||||||
|
Group string // TODO: remove Group in the future
|
||||||
Groups []string
|
Groups []string
|
||||||
Executor struct {
|
Executor struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
@ -30,6 +31,15 @@ type Conf struct {
|
||||||
PreStages []ConfStage
|
PreStages []ConfStage
|
||||||
Stages []ConfStage
|
Stages []ConfStage
|
||||||
PostStages []ConfStage
|
PostStages []ConfStage
|
||||||
|
// TODO: remove this nested struct
|
||||||
|
Stage struct {
|
||||||
|
SandboxExecServer string
|
||||||
|
SandboxToken string
|
||||||
|
OutputPath string
|
||||||
|
PreStages []ConfStage
|
||||||
|
Stages []ConfStage
|
||||||
|
PostStages []ConfStage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionalCmd struct {
|
type OptionalCmd struct {
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,31 @@ func loadConf(confPath string) (*joj3Conf.Conf, error) {
|
||||||
slog.Error("parse conf", "error", err)
|
slog.Error("parse conf", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// TODO: remove this compatible code for nested struct
|
||||||
|
if conf.Stage.SandboxExecServer != "" {
|
||||||
|
conf.SandboxExecServer = conf.Stage.SandboxExecServer
|
||||||
|
conf.Stage.SandboxExecServer = ""
|
||||||
|
}
|
||||||
|
if conf.Stage.SandboxToken != "" {
|
||||||
|
conf.SandboxToken = conf.Stage.SandboxToken
|
||||||
|
conf.Stage.SandboxToken = ""
|
||||||
|
}
|
||||||
|
if conf.Stage.OutputPath != "" {
|
||||||
|
conf.OutputPath = conf.Stage.OutputPath
|
||||||
|
conf.Stage.OutputPath = ""
|
||||||
|
}
|
||||||
|
if len(conf.Stage.PreStages) > 0 {
|
||||||
|
conf.PreStages = conf.Stage.PreStages
|
||||||
|
conf.Stage.PreStages = nil
|
||||||
|
}
|
||||||
|
if len(conf.Stage.Stages) > 0 {
|
||||||
|
conf.Stages = conf.Stage.Stages
|
||||||
|
conf.Stage.Stages = nil
|
||||||
|
}
|
||||||
|
if len(conf.Stage.PostStages) > 0 {
|
||||||
|
conf.PostStages = conf.Stage.PostStages
|
||||||
|
conf.Stage.PostStages = nil
|
||||||
|
}
|
||||||
slog.Debug("conf loaded", "conf", conf, "joj3 version", Version)
|
slog.Debug("conf loaded", "conf", conf, "joj3 version", Version)
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,21 @@ func generateStages(confStages []conf.ConfStage, groups []string) (
|
||||||
stages := []stage.Stage{}
|
stages := []stage.Stage{}
|
||||||
existNames := map[string]bool{}
|
existNames := map[string]bool{}
|
||||||
for i, s := range confStages {
|
for i, s := range confStages {
|
||||||
if len(groups) == 0 && (len(s.Groups) != 0) {
|
if len(groups) == 0 && (len(s.Groups) != 0 || s.Group != "") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ok := false
|
ok := false
|
||||||
if len(s.Groups) == 0 {
|
if s.Group == "" && len(s.Groups) == 0 {
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
|
if !ok && s.Group != "" {
|
||||||
|
for _, group := range groups {
|
||||||
|
if strings.EqualFold(group, s.Group) {
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if !ok && len(s.Groups) > 0 {
|
if !ok && len(s.Groups) > 0 {
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
for _, g := range s.Groups {
|
for _, g := range s.Groups {
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ var (
|
||||||
checkFileNameList string
|
checkFileNameList string
|
||||||
checkFileSumList string
|
checkFileSumList string
|
||||||
metaFile []string
|
metaFile []string
|
||||||
whitelistedChars string
|
|
||||||
allowedDomainList string
|
allowedDomainList string
|
||||||
actorCsvPath string
|
actorCsvPath string
|
||||||
showVersion *bool
|
showVersion *bool
|
||||||
|
|
@ -58,7 +57,6 @@ func init() {
|
||||||
flag.Float64Var(&repoSize, "repoSize", 2, "maximum size of the repo in MiB")
|
flag.Float64Var(&repoSize, "repoSize", 2, "maximum size of the repo in MiB")
|
||||||
flag.StringVar(&checkFileNameList, "checkFileNameList", "", "comma-separated list of files to check")
|
flag.StringVar(&checkFileNameList, "checkFileNameList", "", "comma-separated list of files to check")
|
||||||
flag.StringVar(&checkFileSumList, "checkFileSumList", "", "comma-separated list of expected checksums")
|
flag.StringVar(&checkFileSumList, "checkFileSumList", "", "comma-separated list of expected checksums")
|
||||||
flag.StringVar(&whitelistedChars, "whitelistedChars", "", "comma-separated list of non-ASCII characters allowed in files")
|
|
||||||
flag.StringVar(&allowedDomainList, "allowedDomainList", "sjtu.edu.cn", "comma-separated list of allowed domains for commit author email")
|
flag.StringVar(&allowedDomainList, "allowedDomainList", "sjtu.edu.cn", "comma-separated list of allowed domains for commit author email")
|
||||||
flag.StringVar(&actorCsvPath, "actorCsvPath", "/home/tt/.config/joj/students.csv", "path to actor csv file")
|
flag.StringVar(&actorCsvPath, "actorCsvPath", "/home/tt/.config/joj/students.csv", "path to actor csv file")
|
||||||
parseMultiValueFlag(&metaFile, "meta", "meta files to check")
|
parseMultiValueFlag(&metaFile, "meta", "meta files to check")
|
||||||
|
|
@ -76,14 +74,12 @@ func main() {
|
||||||
"repoSize", repoSize,
|
"repoSize", repoSize,
|
||||||
"checkFileNameList", checkFileNameList,
|
"checkFileNameList", checkFileNameList,
|
||||||
"checkFileSumList", checkFileSumList,
|
"checkFileSumList", checkFileSumList,
|
||||||
"whitelistedChars", whitelistedChars,
|
|
||||||
"meta", metaFile,
|
"meta", metaFile,
|
||||||
)
|
)
|
||||||
res := healthcheck.All(
|
res := healthcheck.All(
|
||||||
rootDir,
|
rootDir,
|
||||||
checkFileNameList,
|
checkFileNameList,
|
||||||
checkFileSumList,
|
checkFileSumList,
|
||||||
whitelistedChars,
|
|
||||||
allowedDomainList,
|
allowedDomainList,
|
||||||
actorCsvPath,
|
actorCsvPath,
|
||||||
metaFile,
|
metaFile,
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 08aaaf1c3ab5863cc53475d8cbca0d668d6a8a1d
|
|
||||||
18
go.mod
18
go.mod
|
|
@ -5,15 +5,15 @@ go 1.24.0
|
||||||
toolchain go1.24.1
|
toolchain go1.24.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/criyle/go-judge/pb v1.3.2
|
github.com/criyle/go-judge/pb v1.0.0
|
||||||
github.com/go-git/go-git/v5 v5.16.5
|
github.com/go-git/go-git/v5 v5.16.2
|
||||||
github.com/jinzhu/copier v0.4.0
|
github.com/jinzhu/copier v0.4.0
|
||||||
github.com/joint-online-judge/go-gitignore v0.0.0-20250212104351-ad79a46f8dcc
|
github.com/joint-online-judge/go-gitignore v0.0.0-20250212104351-ad79a46f8dcc
|
||||||
github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7
|
github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7
|
||||||
github.com/mcuadros/go-defaults v1.2.0
|
github.com/mcuadros/go-defaults v1.2.0
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
google.golang.org/grpc v1.79.3
|
google.golang.org/grpc v1.75.1
|
||||||
google.golang.org/protobuf v1.36.11
|
google.golang.org/protobuf v1.36.9
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
@ -37,11 +37,11 @@ require (
|
||||||
github.com/sergi/go-diff v1.4.0 // indirect
|
github.com/sergi/go-diff v1.4.0 // indirect
|
||||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
golang.org/x/crypto v0.46.0 // indirect
|
golang.org/x/crypto v0.43.0 // indirect
|
||||||
golang.org/x/net v0.48.0 // indirect
|
golang.org/x/net v0.45.0 // indirect
|
||||||
golang.org/x/sys v0.39.0 // indirect
|
golang.org/x/sys v0.37.0 // indirect
|
||||||
golang.org/x/text v0.32.0 // indirect
|
golang.org/x/text v0.30.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
66
go.sum
66
go.sum
|
|
@ -11,12 +11,10 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
github.com/criyle/go-judge/pb v1.3.2 h1:S0c0EqRF+xePOwcZxSb9mPV+bkXgfOX9f7SQMrcdeb4=
|
github.com/criyle/go-judge/pb v1.0.0 h1:8A4zHPPCGCDTuFY1GW5Hqpg+8ETIwzgXxiRpYKKb2zA=
|
||||||
github.com/criyle/go-judge/pb v1.3.2/go.mod h1:QfjmF1w4t5ODXikuUcy8Alqb901R6p0HDxJXGKZy0NE=
|
github.com/criyle/go-judge/pb v1.0.0/go.mod h1:hjgixgK9NH9ktwc29xbXVdZDOlKfEkRkEbZ4W5bOMmw=
|
||||||
github.com/cyphar/filepath-securejoin v0.5.0 h1:hIAhkRBMQ8nIeuVwcAoymp7MY4oherZdAxD+m0u9zaw=
|
github.com/cyphar/filepath-securejoin v0.5.0 h1:hIAhkRBMQ8nIeuVwcAoymp7MY4oherZdAxD+m0u9zaw=
|
||||||
github.com/cyphar/filepath-securejoin v0.5.0/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
github.com/cyphar/filepath-securejoin v0.5.0/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||||
|
|
@ -40,8 +38,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
|
||||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
|
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
||||||
github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
|
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
|
@ -100,49 +98,49 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 h1:i8QOKZfYg6AbGVZzUAY3LrNWCKF8O6zFisU9Wl9RER4=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
|
||||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
|
||||||
|
|
@ -8,34 +8,33 @@ import (
|
||||||
|
|
||||||
"github.com/criyle/go-judge/pb"
|
"github.com/criyle/go-judge/pb"
|
||||||
"github.com/joint-online-judge/JOJ3/internal/stage"
|
"github.com/joint-online-judge/JOJ3/internal/stage"
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// copied from https://github.com/criyle/go-judge/blob/master/cmd/go-judge-shell/grpc.go
|
// copied from https://github.com/criyle/go-judge/blob/master/cmd/go-judge-shell/grpc.go
|
||||||
func convertPBCmd(cmd []stage.Cmd) []*pb.Request_CmdType {
|
func convertPBCmd(cmd []stage.Cmd) []*pb.Request_CmdType {
|
||||||
ret := make([]*pb.Request_CmdType, 0, len(cmd))
|
ret := make([]*pb.Request_CmdType, 0, len(cmd))
|
||||||
for _, c := range cmd {
|
for _, c := range cmd {
|
||||||
req := &pb.Request_CmdType{}
|
ret = append(ret, &pb.Request_CmdType{
|
||||||
req.SetArgs(c.Args)
|
Args: c.Args,
|
||||||
req.SetEnv(c.Env)
|
Env: c.Env,
|
||||||
req.SetTty(c.TTY)
|
Tty: c.TTY,
|
||||||
req.SetFiles(convertPBFiles([]*stage.CmdFile{c.Stdin, c.Stdout, c.Stderr}))
|
Files: convertPBFiles([]*stage.CmdFile{c.Stdin, c.Stdout, c.Stderr}),
|
||||||
req.SetCpuTimeLimit(c.CPULimit)
|
CpuTimeLimit: c.CPULimit,
|
||||||
req.SetClockTimeLimit(c.ClockLimit)
|
ClockTimeLimit: c.ClockLimit,
|
||||||
req.SetMemoryLimit(c.MemoryLimit)
|
MemoryLimit: c.MemoryLimit,
|
||||||
req.SetStackLimit(c.StackLimit)
|
StackLimit: c.StackLimit,
|
||||||
req.SetProcLimit(c.ProcLimit)
|
ProcLimit: c.ProcLimit,
|
||||||
req.SetCpuRateLimit(c.CPURateLimit)
|
CpuRateLimit: c.CPURateLimit,
|
||||||
req.SetCpuSetLimit(c.CPUSetLimit)
|
CpuSetLimit: c.CPUSetLimit,
|
||||||
req.SetDataSegmentLimit(c.DataSegmentLimit)
|
DataSegmentLimit: c.DataSegmentLimit,
|
||||||
req.SetAddressSpaceLimit(c.AddressSpaceLimit)
|
AddressSpaceLimit: c.AddressSpaceLimit,
|
||||||
req.SetCopyIn(convertPBCopyIn(c.CopyIn, c.CopyInDir))
|
CopyIn: convertPBCopyIn(c.CopyIn, c.CopyInDir),
|
||||||
req.SetCopyOut(convertPBCopyOut(c.CopyOut))
|
CopyOut: convertPBCopyOut(c.CopyOut),
|
||||||
req.SetCopyOutCached(convertPBCopyOut(c.CopyOutCached))
|
CopyOutCached: convertPBCopyOut(c.CopyOutCached),
|
||||||
req.SetCopyOutMax(c.CopyOutMax)
|
CopyOutMax: c.CopyOutMax,
|
||||||
req.SetCopyOutDir(c.CopyOutDir)
|
CopyOutDir: c.CopyOutDir,
|
||||||
req.SetSymlinks(convertSymlink(c.CopyIn))
|
Symlinks: convertSymlink(c.CopyIn),
|
||||||
ret = append(ret, req)
|
})
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
@ -82,10 +81,10 @@ func convertPBCopyOut(copyOut []string) []*pb.Request_CmdCopyOutFile {
|
||||||
optional = true
|
optional = true
|
||||||
n = strings.TrimSuffix(n, "?")
|
n = strings.TrimSuffix(n, "?")
|
||||||
}
|
}
|
||||||
elem := &pb.Request_CmdCopyOutFile{}
|
rt = append(rt, &pb.Request_CmdCopyOutFile{
|
||||||
elem.SetName(n)
|
Name: n,
|
||||||
elem.SetOptional(optional)
|
Optional: optional,
|
||||||
rt = append(rt, elem)
|
})
|
||||||
}
|
}
|
||||||
return rt
|
return rt
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +113,6 @@ func convertPBFiles(files []*stage.CmdFile) []*pb.Request_File {
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertPBFile(i stage.CmdFile) *pb.Request_File {
|
func convertPBFile(i stage.CmdFile) *pb.Request_File {
|
||||||
req := &pb.Request_File{}
|
|
||||||
switch {
|
switch {
|
||||||
case i.Src != nil:
|
case i.Src != nil:
|
||||||
if !filepath.IsAbs(*i.Src) {
|
if !filepath.IsAbs(*i.Src) {
|
||||||
|
|
@ -130,34 +128,18 @@ func convertPBFile(i stage.CmdFile) *pb.Request_File {
|
||||||
s = []byte{}
|
s = []byte{}
|
||||||
slog.Error("convert pb file read file", "path", *i.Src, "error", err)
|
slog.Error("convert pb file read file", "path", *i.Src, "error", err)
|
||||||
}
|
}
|
||||||
m := &pb.Request_MemoryFile{}
|
return &pb.Request_File{File: &pb.Request_File_Memory{Memory: &pb.Request_MemoryFile{Content: s}}}
|
||||||
m.SetContent(s)
|
|
||||||
req.SetMemory(m)
|
|
||||||
return req
|
|
||||||
case i.Content != nil:
|
case i.Content != nil:
|
||||||
s := strToBytes(*i.Content)
|
s := strToBytes(*i.Content)
|
||||||
m := &pb.Request_MemoryFile{}
|
return &pb.Request_File{File: &pb.Request_File_Memory{Memory: &pb.Request_MemoryFile{Content: s}}}
|
||||||
m.SetContent(s)
|
|
||||||
req.SetMemory(m)
|
|
||||||
return req
|
|
||||||
case i.FileID != nil:
|
case i.FileID != nil:
|
||||||
c := &pb.Request_CachedFile{}
|
return &pb.Request_File{File: &pb.Request_File_Cached{Cached: &pb.Request_CachedFile{FileID: *i.FileID}}}
|
||||||
c.SetFileID(*i.FileID)
|
|
||||||
req.SetCached(c)
|
|
||||||
return req
|
|
||||||
case i.Name != nil && i.Max != nil:
|
case i.Name != nil && i.Max != nil:
|
||||||
p := &pb.Request_PipeCollector{}
|
return &pb.Request_File{File: &pb.Request_File_Pipe{Pipe: &pb.Request_PipeCollector{Name: *i.Name, Max: *i.Max, Pipe: i.Pipe}}}
|
||||||
p.SetName(*i.Name)
|
|
||||||
p.SetMax(*i.Max)
|
|
||||||
p.SetPipe(i.Pipe)
|
|
||||||
req.SetPipe(p)
|
|
||||||
return req
|
|
||||||
case i.StreamIn:
|
case i.StreamIn:
|
||||||
req.SetStreamIn(&emptypb.Empty{})
|
return &pb.Request_File{File: &pb.Request_File_StreamIn{}}
|
||||||
return req
|
|
||||||
case i.StreamOut:
|
case i.StreamOut:
|
||||||
req.SetStreamOut(&emptypb.Empty{})
|
return &pb.Request_File{File: &pb.Request_File_StreamOut{}}
|
||||||
return req
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -166,17 +148,17 @@ func convertPBResult(res []*pb.Response_Result) []stage.ExecutorResult {
|
||||||
ret := make([]stage.ExecutorResult, 0, len(res))
|
ret := make([]stage.ExecutorResult, 0, len(res))
|
||||||
for _, r := range res {
|
for _, r := range res {
|
||||||
ret = append(ret, stage.ExecutorResult{
|
ret = append(ret, stage.ExecutorResult{
|
||||||
Status: stage.Status(r.GetStatus()),
|
Status: stage.Status(r.Status),
|
||||||
ExitStatus: int(r.GetExitStatus()),
|
ExitStatus: int(r.ExitStatus),
|
||||||
Error: r.GetError(),
|
Error: r.Error,
|
||||||
Time: r.GetTime(),
|
Time: r.Time,
|
||||||
Memory: r.GetMemory(),
|
Memory: r.Memory,
|
||||||
RunTime: r.GetRunTime(),
|
RunTime: r.RunTime,
|
||||||
ProcPeak: r.GetProcPeak(),
|
ProcPeak: r.ProcPeak,
|
||||||
Files: convertFiles(r.GetFiles()),
|
Files: convertFiles(r.Files),
|
||||||
Buffs: r.GetFiles(),
|
Buffs: r.Files,
|
||||||
FileIDs: r.GetFileIDs(),
|
FileIDs: r.FileIDs,
|
||||||
FileError: convertPBFileError(r.GetFileError()),
|
FileError: convertPBFileError(r.FileError),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
@ -194,9 +176,9 @@ func convertPBFileError(fe []*pb.Response_FileError) []stage.FileError {
|
||||||
ret := make([]stage.FileError, 0, len(fe))
|
ret := make([]stage.FileError, 0, len(fe))
|
||||||
for _, v := range fe {
|
for _, v := range fe {
|
||||||
ret = append(ret, stage.FileError{
|
ret = append(ret, stage.FileError{
|
||||||
Name: v.GetName(),
|
Name: v.Name,
|
||||||
Type: stage.FileErrorType(v.GetType()),
|
Type: stage.FileErrorType(v.Type),
|
||||||
Message: v.GetMessage(),
|
Message: v.Message,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,16 @@ func (e *Sandbox) Run(cmds []stage.Cmd) ([]stage.ExecutorResult, error) {
|
||||||
for i, pbCmd := range pbCmds {
|
for i, pbCmd := range pbCmds {
|
||||||
slog.Debug("sandbox execute", "i", i, "pbCmd size", proto.Size(pbCmd))
|
slog.Debug("sandbox execute", "i", i, "pbCmd size", proto.Size(pbCmd))
|
||||||
}
|
}
|
||||||
pbReq := &pb.Request{}
|
pbReq := &pb.Request{Cmd: pbCmds}
|
||||||
pbReq.SetCmd(pbCmds)
|
|
||||||
slog.Debug("sandbox execute", "pbReq size", proto.Size(pbReq))
|
slog.Debug("sandbox execute", "pbReq size", proto.Size(pbReq))
|
||||||
pbRet, err := e.execClient.Exec(context.TODO(), pbReq)
|
pbRet, err := e.execClient.Exec(context.TODO(), pbReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if pbRet.GetError() != "" {
|
if pbRet.Error != "" {
|
||||||
return nil, fmt.Errorf("sandbox execute error: %s", pbRet.GetError())
|
return nil, fmt.Errorf("sandbox execute error: %s", pbRet.Error)
|
||||||
}
|
}
|
||||||
results := convertPBResult(pbRet.GetResults())
|
results := convertPBResult(pbRet.Results)
|
||||||
for _, result := range results {
|
for _, result := range results {
|
||||||
maps.Copy(e.cachedMap, result.FileIDs)
|
maps.Copy(e.cachedMap, result.FileIDs)
|
||||||
}
|
}
|
||||||
|
|
@ -55,9 +54,9 @@ func (e *Sandbox) Run(cmds []stage.Cmd) ([]stage.ExecutorResult, error) {
|
||||||
|
|
||||||
func (e *Sandbox) Cleanup() error {
|
func (e *Sandbox) Cleanup() error {
|
||||||
for k, fileID := range e.cachedMap {
|
for k, fileID := range e.cachedMap {
|
||||||
req := &pb.FileID{}
|
_, err := e.execClient.FileDelete(context.TODO(), &pb.FileID{
|
||||||
req.SetFileID(fileID)
|
FileID: fileID,
|
||||||
_, err := e.execClient.FileDelete(context.TODO(), req)
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("sandbox cleanup", "error", err)
|
slog.Error("sandbox cleanup", "error", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,37 +5,21 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/joint-online-judge/JOJ3/internal/stage"
|
"github.com/joint-online-judge/JOJ3/internal/stage"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*Log) parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult {
|
func (*Log) parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult {
|
||||||
content, ok := executorResult.Files[conf.Filename]
|
content := executorResult.Files[conf.Filename]
|
||||||
if !ok {
|
var data map[string]any
|
||||||
slog.Error("file not found for log parser", "filename", conf.Filename)
|
err := json.Unmarshal([]byte(content), &data)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(conf.Msg, "error", err)
|
||||||
return stage.ParserResult{
|
return stage.ParserResult{
|
||||||
Score: 0,
|
Score: 0,
|
||||||
Comment: fmt.Sprintf("log parser: file %s not found", conf.Filename),
|
Comment: fmt.Sprintf("Failed to parse content: %s", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contentBytes := []byte(content)
|
|
||||||
var data map[string]any
|
|
||||||
if err := json.Unmarshal(contentBytes, &data); err != nil {
|
|
||||||
// Not a valid json or failed to unmarshal, log as raw string line by line.
|
|
||||||
for line := range strings.SplitSeq(content, "\n") {
|
|
||||||
if strings.TrimSpace(line) != "" {
|
|
||||||
slog.Default().Log(
|
|
||||||
context.Background(),
|
|
||||||
slog.Level(conf.Level),
|
|
||||||
conf.Msg,
|
|
||||||
"line",
|
|
||||||
line,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Valid json, log as key-value pairs.
|
|
||||||
args := make([]any, 0, len(data)*2)
|
args := make([]any, 0, len(data)*2)
|
||||||
for key, value := range data {
|
for key, value := range data {
|
||||||
args = append(args, key, value)
|
args = append(args, key, value)
|
||||||
|
|
@ -46,7 +30,6 @@ func (*Log) parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserRe
|
||||||
conf.Msg,
|
conf.Msg,
|
||||||
args...,
|
args...,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
return stage.ParserResult{
|
return stage.ParserResult{
|
||||||
Score: 0,
|
Score: 0,
|
||||||
Comment: "",
|
Comment: "",
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ type Result struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func All(
|
func All(
|
||||||
rootDir, checkFileNameList, checkFileSumList, whitelistedChars,
|
rootDir, checkFileNameList, checkFileSumList, allowedDomainList, actorCsvPath string,
|
||||||
allowedDomainList, actorCsvPath string,
|
|
||||||
metaFile []string, repoSize float64,
|
metaFile []string, repoSize float64,
|
||||||
) (res Result) {
|
) (res Result) {
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -45,7 +44,7 @@ func All(
|
||||||
} else {
|
} else {
|
||||||
res.Msg += "### Meta File Check Passed\n"
|
res.Msg += "### Meta File Check Passed\n"
|
||||||
}
|
}
|
||||||
err = NonASCIIFiles(rootDir, whitelistedChars)
|
err = NonASCIIFiles(rootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Msg += fmt.Sprintf("### Non-ASCII Characters File Check Failed:\n%s\n", err.Error())
|
res.Msg += fmt.Sprintf("### Non-ASCII Characters File Check Failed:\n%s\n", err.Error())
|
||||||
res.Failed = true
|
res.Failed = true
|
||||||
|
|
|
||||||
|
|
@ -8,47 +8,11 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing/format/gitattributes"
|
"github.com/go-git/go-git/v5/plumbing/format/gitattributes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Read the list of comma-separated allowed characters from command line and convert it to a hashmap.
|
|
||||||
func parseWhitelistedChars(csv string) map[rune]struct{} {
|
|
||||||
whitelist := make(map[rune]struct{})
|
|
||||||
if strings.TrimSpace(csv) == "" {
|
|
||||||
return whitelist
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, raw := range strings.Split(csv, ",") {
|
|
||||||
elem := strings.TrimSpace(raw)
|
|
||||||
if elem == "" {
|
|
||||||
slog.Warn("ignoring invalid whitelisted-chars element", "element", raw, "reason", "empty element")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if utf8.RuneCountInString(elem) != 1 {
|
|
||||||
slog.Warn("ignoring invalid whitelisted-chars element", "element", elem, "reason", "element must be exactly one character")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ch, _ := utf8.DecodeRuneInString(elem)
|
|
||||||
if ch == utf8.RuneError {
|
|
||||||
slog.Warn("ignoring invalid whitelisted-chars element", "element", elem, "reason", "invalid utf-8 rune")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ch <= unicode.MaxASCII {
|
|
||||||
slog.Warn("ignoring invalid whitelisted-chars element", "element", elem, "reason", "ASCII characters are not allowed")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
whitelist[ch] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return whitelist
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSubmodulePathsFromGoGit uses the go-git library to open the repository
|
// getSubmodulePathsFromGoGit uses the go-git library to open the repository
|
||||||
// at the given root path and retrieve a list of all submodule paths.
|
// at the given root path and retrieve a list of all submodule paths.
|
||||||
// It returns a set of submodule paths for efficient lookup.
|
// It returns a set of submodule paths for efficient lookup.
|
||||||
|
|
@ -84,7 +48,7 @@ func getSubmodulePathsFromGoGit(root string) (map[string]struct{}, error) {
|
||||||
|
|
||||||
// getNonASCII retrieves a list of files in the specified root directory that contain non-ASCII characters.
|
// getNonASCII retrieves a list of files in the specified root directory that contain non-ASCII characters.
|
||||||
// It searches for non-ASCII characters in each file's content and returns a list of paths to files containing non-ASCII characters.
|
// It searches for non-ASCII characters in each file's content and returns a list of paths to files containing non-ASCII characters.
|
||||||
func getNonASCII(root string, whitelist map[rune]struct{}) ([]string, error) {
|
func getNonASCII(root string) ([]string, error) {
|
||||||
var nonASCII []string
|
var nonASCII []string
|
||||||
gitattrExist := true
|
gitattrExist := true
|
||||||
var matcher gitattributes.Matcher
|
var matcher gitattributes.Matcher
|
||||||
|
|
@ -149,9 +113,6 @@ func getNonASCII(root string, whitelist map[rune]struct{}) ([]string, error) {
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
cont := true
|
cont := true
|
||||||
for _, c := range scanner.Text() {
|
for _, c := range scanner.Text() {
|
||||||
if _, ok := whitelist[c]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if c > unicode.MaxASCII {
|
if c > unicode.MaxASCII {
|
||||||
nonASCII = append(nonASCII, "\t"+path)
|
nonASCII = append(nonASCII, "\t"+path)
|
||||||
cont = false
|
cont = false
|
||||||
|
|
@ -171,10 +132,8 @@ func getNonASCII(root string, whitelist map[rune]struct{}) ([]string, error) {
|
||||||
|
|
||||||
// NonASCIIFiles checks for non-ASCII characters in files within the specified root directory.
|
// NonASCIIFiles checks for non-ASCII characters in files within the specified root directory.
|
||||||
// It prints a message with the paths to files containing non-ASCII characters, if any.
|
// It prints a message with the paths to files containing non-ASCII characters, if any.
|
||||||
// Additionally it accept a list of whitelisted characters that are allowed, repo-wide.
|
func NonASCIIFiles(root string) error {
|
||||||
func NonASCIIFiles(root, whitelistedChars string) error {
|
nonASCII, err := getNonASCII(root)
|
||||||
whitelist := parseWhitelistedChars(whitelistedChars)
|
|
||||||
nonASCII, err := getNonASCII(root, whitelist)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("getting non-ascii", "err", err)
|
slog.Error("getting non-ascii", "err", err)
|
||||||
return fmt.Errorf("error getting non-ascii: %w", err)
|
return fmt.Errorf("error getting non-ascii: %w", err)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user