init:
This commit is contained in:
119
runner/expander.go
Normal file
119
runner/expander.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/Mond1c/judge/dsl"
|
||||
)
|
||||
|
||||
func expandPattern(pattern *dsl.Pattern, groupTimeout interface{ IsZero() bool }) ([]*dsl.Test, error) {
|
||||
if pattern.IsDirMode() {
|
||||
return expandDirPattern(pattern)
|
||||
}
|
||||
return expandGlobPattern(pattern)
|
||||
}
|
||||
|
||||
func expandGlobPattern(pattern *dsl.Pattern) ([]*dsl.Test, error) {
|
||||
inputFiles, err := filepath.Glob(pattern.InputGlob)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid input glob %q: %w", pattern.InputGlob, err)
|
||||
}
|
||||
if len(inputFiles) == 0 {
|
||||
return nil, fmt.Errorf("no files matched input glob %q", pattern.InputGlob)
|
||||
}
|
||||
|
||||
inputPrefix, inputSuffix := splitGlob(pattern.InputGlob)
|
||||
outputPrefix, outputSuffix := splitGlob(pattern.OutputGlob)
|
||||
|
||||
var tests []*dsl.Test
|
||||
for _, inputPath := range inputFiles {
|
||||
wildcard := extractWildcard(inputPath, inputPrefix, inputSuffix)
|
||||
outputPath := outputPrefix + wildcard + outputSuffix
|
||||
|
||||
inputContent, err := os.ReadFile(inputPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read input %q: %w", inputPath, err)
|
||||
}
|
||||
outputContent, err := os.ReadFile(outputPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read output %q: %w", outputPath, err)
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("pattern:%s", wildcard)
|
||||
stdin := string(inputContent)
|
||||
expected := string(outputContent)
|
||||
|
||||
tests = append(tests, &dsl.Test{
|
||||
Name: name,
|
||||
Stdin: &stdin,
|
||||
Env: map[string]string{},
|
||||
InFiles: map[string]string{},
|
||||
OutFiles: map[string]string{},
|
||||
Stdout: dsl.ExactMatcher{Value: expected},
|
||||
Stderr: dsl.NoMatcher{},
|
||||
})
|
||||
}
|
||||
return tests, nil
|
||||
}
|
||||
|
||||
func expandDirPattern(pattern *dsl.Pattern) ([]*dsl.Test, error) {
|
||||
dirs, err := filepath.Glob(pattern.DirsGlob)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid dirs glob %q: %w", pattern.DirsGlob, err)
|
||||
}
|
||||
if len(dirs) == 0 {
|
||||
return nil, fmt.Errorf("no directories matched %q", pattern.DirsGlob)
|
||||
}
|
||||
|
||||
var tests []*dsl.Test
|
||||
for _, dir := range dirs {
|
||||
info, err := os.Stat(dir)
|
||||
if err != nil || !info.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
inputPath := filepath.Join(dir, pattern.InputFile)
|
||||
outputPath := filepath.Join(dir, pattern.OutputFile)
|
||||
|
||||
inputContent, err := os.ReadFile(inputPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read %q: %w", inputPath, err)
|
||||
}
|
||||
outputContent, err := os.ReadFile(outputPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read %q: %w", outputPath, err)
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("pattern:%s", filepath.Base(dir))
|
||||
stdin := string(inputContent)
|
||||
expected := string(outputContent)
|
||||
|
||||
tests = append(tests, &dsl.Test{
|
||||
Name: name,
|
||||
Stdin: &stdin,
|
||||
Env: map[string]string{},
|
||||
InFiles: map[string]string{},
|
||||
OutFiles: map[string]string{},
|
||||
Stdout: dsl.ExactMatcher{Value: expected},
|
||||
Stderr: dsl.NoMatcher{},
|
||||
})
|
||||
}
|
||||
return tests, nil
|
||||
}
|
||||
|
||||
func splitGlob(pattern string) (prefix, suffix string) {
|
||||
idx := strings.Index(pattern, "*")
|
||||
if idx < 0 {
|
||||
return pattern, ""
|
||||
}
|
||||
return pattern[:idx], pattern[idx+1:]
|
||||
}
|
||||
|
||||
func extractWildcard(path, prefix, suffix string) string {
|
||||
s := strings.TrimPrefix(path, prefix)
|
||||
s = strings.TrimSuffix(s, suffix)
|
||||
return s
|
||||
}
|
||||
Reference in New Issue
Block a user