1. New build system
All checks were successful
build-dsl-smoke / Build judge (push) Successful in 12s
build-dsl-smoke / debug / clang / linux (push) Successful in 6s
build-dsl-smoke / debug / gcc / linux (push) Successful in 8s
build-dsl-smoke / release / clang / linux (push) Successful in 8s
build-dsl-smoke / release / gcc / linux (push) Successful in 6s
build-dsl-smoke / sanitized / clang / linux (push) Successful in 8s
build-dsl-smoke / sanitized / gcc / linux (push) Successful in 7s
build-dsl-smoke / debug / clang / windows (push) Successful in 13s
build-dsl-smoke / debug-valgrind / gcc / linux (push) Successful in 14s
build-dsl-smoke / release / clang / windows (push) Successful in 16s
build-dsl-smoke / debug / msvc / windows (push) Successful in 18s
build-dsl-smoke / release / msvc / windows (push) Successful in 17s
build-dsl-smoke / SUMMARY (push) Successful in 4s
Release / Build & publish (push) Successful in 48s
All checks were successful
build-dsl-smoke / Build judge (push) Successful in 12s
build-dsl-smoke / debug / clang / linux (push) Successful in 6s
build-dsl-smoke / debug / gcc / linux (push) Successful in 8s
build-dsl-smoke / release / clang / linux (push) Successful in 8s
build-dsl-smoke / release / gcc / linux (push) Successful in 6s
build-dsl-smoke / sanitized / clang / linux (push) Successful in 8s
build-dsl-smoke / sanitized / gcc / linux (push) Successful in 7s
build-dsl-smoke / debug / clang / windows (push) Successful in 13s
build-dsl-smoke / debug-valgrind / gcc / linux (push) Successful in 14s
build-dsl-smoke / release / clang / windows (push) Successful in 16s
build-dsl-smoke / debug / msvc / windows (push) Successful in 18s
build-dsl-smoke / release / msvc / windows (push) Successful in 17s
build-dsl-smoke / SUMMARY (push) Successful in 4s
Release / Build & publish (push) Successful in 48s
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -16,47 +16,85 @@ func expandPattern(pattern *dsl.Pattern) ([]*dsl.Test, error) {
|
||||
return expandGlobPattern(pattern)
|
||||
}
|
||||
|
||||
type patternCase struct {
|
||||
name string
|
||||
inputPath string
|
||||
outputPath string
|
||||
dir string
|
||||
}
|
||||
|
||||
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)
|
||||
inputIsGlob := strings.Contains(pattern.InputGlob, "*")
|
||||
outputIsGlob := strings.Contains(pattern.OutputGlob, "*")
|
||||
|
||||
if pattern.InputGlob == "" && pattern.OutputGlob == "" {
|
||||
return nil, fmt.Errorf("pattern needs at least one of input/output/dirs")
|
||||
}
|
||||
if len(inputFiles) == 0 {
|
||||
return nil, fmt.Errorf("no files matched input glob %q", pattern.InputGlob)
|
||||
if !inputIsGlob && !outputIsGlob {
|
||||
return nil, fmt.Errorf("pattern needs at least one glob field (input or output must contain *)")
|
||||
}
|
||||
|
||||
inputPrefix, inputSuffix := splitGlob(pattern.InputGlob)
|
||||
outputPrefix, outputSuffix := splitGlob(pattern.OutputGlob)
|
||||
var cases []patternCase
|
||||
|
||||
var tests []*dsl.Test
|
||||
for _, inputPath := range inputFiles {
|
||||
wildcard := extractWildcard(inputPath, inputPrefix, inputSuffix)
|
||||
outputPath := outputPrefix + wildcard + outputSuffix
|
||||
|
||||
inputContent, err := os.ReadFile(inputPath)
|
||||
switch {
|
||||
case inputIsGlob && outputIsGlob:
|
||||
inputFiles, err := filepath.Glob(pattern.InputGlob)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read input %q: %w", inputPath, err)
|
||||
return nil, fmt.Errorf("invalid input glob %q: %w", pattern.InputGlob, err)
|
||||
}
|
||||
outputContent, err := os.ReadFile(outputPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read output %q: %w", outputPath, 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)
|
||||
for _, inputPath := range inputFiles {
|
||||
wildcard := extractWildcard(inputPath, inputPrefix, inputSuffix)
|
||||
outputPath := outputPrefix + wildcard + outputSuffix
|
||||
cases = append(cases, patternCase{
|
||||
name: wildcard,
|
||||
inputPath: inputPath,
|
||||
outputPath: outputPath,
|
||||
})
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("pattern:%s", wildcard)
|
||||
stdin := string(inputContent)
|
||||
expected := string(outputContent)
|
||||
case inputIsGlob && !outputIsGlob:
|
||||
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)
|
||||
for _, inputPath := range inputFiles {
|
||||
wildcard := extractWildcard(inputPath, inputPrefix, inputSuffix)
|
||||
cases = append(cases, patternCase{
|
||||
name: wildcard,
|
||||
inputPath: inputPath,
|
||||
outputPath: pattern.OutputGlob,
|
||||
})
|
||||
}
|
||||
|
||||
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{},
|
||||
})
|
||||
case !inputIsGlob && outputIsGlob:
|
||||
outputFiles, err := filepath.Glob(pattern.OutputGlob)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid output glob %q: %w", pattern.OutputGlob, err)
|
||||
}
|
||||
if len(outputFiles) == 0 {
|
||||
return nil, fmt.Errorf("no files matched output glob %q", pattern.OutputGlob)
|
||||
}
|
||||
outputPrefix, outputSuffix := splitGlob(pattern.OutputGlob)
|
||||
for _, outputPath := range outputFiles {
|
||||
wildcard := extractWildcard(outputPath, outputPrefix, outputSuffix)
|
||||
cases = append(cases, patternCase{
|
||||
name: wildcard,
|
||||
inputPath: pattern.InputGlob,
|
||||
outputPath: outputPath,
|
||||
})
|
||||
}
|
||||
}
|
||||
return tests, nil
|
||||
|
||||
return buildTests(cases, pattern.Args)
|
||||
}
|
||||
|
||||
func expandDirPattern(pattern *dsl.Pattern) ([]*dsl.Test, error) {
|
||||
@@ -68,42 +106,96 @@ func expandDirPattern(pattern *dsl.Pattern) ([]*dsl.Test, error) {
|
||||
return nil, fmt.Errorf("no directories matched %q", pattern.DirsGlob)
|
||||
}
|
||||
|
||||
var tests []*dsl.Test
|
||||
var cases []patternCase
|
||||
for _, dir := range dirs {
|
||||
info, err := os.Stat(dir)
|
||||
if err != nil || !info.IsDir() {
|
||||
continue
|
||||
}
|
||||
cases = append(cases, patternCase{
|
||||
name: filepath.Base(dir),
|
||||
inputPath: filepath.Join(dir, pattern.InputFile),
|
||||
outputPath: filepath.Join(dir, pattern.OutputFile),
|
||||
dir: dir,
|
||||
})
|
||||
}
|
||||
return buildTests(cases, pattern.Args)
|
||||
}
|
||||
|
||||
inputPath := filepath.Join(dir, pattern.InputFile)
|
||||
outputPath := filepath.Join(dir, pattern.OutputFile)
|
||||
func buildTests(cases []patternCase, argTemplate []string) ([]*dsl.Test, error) {
|
||||
useInputAsFile := argsContain(argTemplate, "{input_path}")
|
||||
useOutputAsFile := argsContain(argTemplate, "{output_path}")
|
||||
|
||||
inputContent, err := os.ReadFile(inputPath)
|
||||
var tests []*dsl.Test
|
||||
for _, c := range cases {
|
||||
inputContent, err := os.ReadFile(c.inputPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read %q: %w", inputPath, err)
|
||||
return nil, fmt.Errorf("read input %q: %w", c.inputPath, err)
|
||||
}
|
||||
outputContent, err := os.ReadFile(outputPath)
|
||||
outputContent, err := os.ReadFile(c.outputPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read %q: %w", outputPath, err)
|
||||
return nil, fmt.Errorf("read output %q: %w", c.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,
|
||||
t := &dsl.Test{
|
||||
Name: fmt.Sprintf("pattern:%s", c.name),
|
||||
Env: map[string]string{},
|
||||
InFiles: map[string]string{},
|
||||
OutFiles: map[string]string{},
|
||||
Stdout: dsl.ExactMatcher{Value: expected},
|
||||
Stderr: dsl.NoMatcher{},
|
||||
})
|
||||
}
|
||||
|
||||
inputName := filepath.Base(c.inputPath)
|
||||
outputName := filepath.Base(c.outputPath)
|
||||
|
||||
if useInputAsFile {
|
||||
t.InFiles[inputName] = string(inputContent)
|
||||
} else {
|
||||
s := string(inputContent)
|
||||
t.Stdin = &s
|
||||
}
|
||||
|
||||
if useOutputAsFile {
|
||||
t.OutFiles[outputName] = string(outputContent)
|
||||
t.Stdout = dsl.NoMatcher{}
|
||||
} else {
|
||||
t.Stdout = dsl.ExactMatcher{Value: string(outputContent)}
|
||||
}
|
||||
|
||||
if len(argTemplate) > 0 {
|
||||
t.Args = substituteArgs(argTemplate, map[string]string{
|
||||
"{input_path}": inputName,
|
||||
"{output_path}": outputName,
|
||||
"{name}": c.name,
|
||||
"{dir}": c.dir,
|
||||
})
|
||||
}
|
||||
|
||||
tests = append(tests, t)
|
||||
}
|
||||
return tests, nil
|
||||
}
|
||||
|
||||
func argsContain(args []string, placeholder string) bool {
|
||||
for _, a := range args {
|
||||
if strings.Contains(a, placeholder) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func substituteArgs(template []string, vars map[string]string) []string {
|
||||
out := make([]string, len(template))
|
||||
for i, a := range template {
|
||||
for k, v := range vars {
|
||||
a = strings.ReplaceAll(a, k, v)
|
||||
}
|
||||
out[i] = a
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func splitGlob(pattern string) (prefix, suffix string) {
|
||||
before, after, found := strings.Cut(pattern, "*")
|
||||
if !found {
|
||||
|
||||
Reference in New Issue
Block a user