-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce the "report" command to combine multiple evaluations into a…
… single file Closes #205
- Loading branch information
1 parent
5a7fb63
commit 090eeb2
Showing
6 changed files
with
616 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"sort" | ||
|
||
pkgerrors "github.com/pkg/errors" | ||
"golang.org/x/exp/maps" | ||
|
||
"github.com/symflower/eval-dev-quality/evaluate/report" | ||
"github.com/symflower/eval-dev-quality/log" | ||
) | ||
|
||
// Report holds the "report" command. | ||
type Report struct { | ||
// EvaluationPaths holds the list of file paths where the results of previous evaluations are stored. | ||
EvaluationPaths []string `long:"evaluation-path" description:"File path for an evaluation CSV file where the results of a previous evaluation are stored."` | ||
// ResultPath holds the directory path where the overall results should be written to. | ||
ResultPath string `long:"result-path" description:"Directory path were the combined results are written to."` | ||
|
||
// logger holds the logger of the command. | ||
logger *log.Logger | ||
} | ||
|
||
var _ SetLogger = (*Evaluate)(nil) | ||
|
||
// SetLogger sets the logger of the command. | ||
func (command *Report) SetLogger(logger *log.Logger) { | ||
command.logger = logger | ||
} | ||
|
||
// Execute executes the command. | ||
func (command *Report) Execute(args []string) (err error) { | ||
// Create the result path directory and check if there is already an evaluation CSV file in there. | ||
var evaluationCSVFile *os.File | ||
if err = os.MkdirAll(filepath.Dir(command.ResultPath), 0755); err != nil { | ||
command.logger.Panicf("ERROR: %s", err) | ||
} | ||
if _, err := os.Stat(filepath.Join(command.ResultPath, "evaluation.csv")); err != nil { | ||
if os.IsNotExist(err) { | ||
evaluationCSVFile, err = os.Create(filepath.Join(command.ResultPath, "evaluation.csv")) | ||
if err != nil { | ||
command.logger.Panicf("ERROR: %s", err) | ||
} | ||
defer evaluationCSVFile.Close() | ||
} else { | ||
command.logger.Panicf("ERROR: %s", err) | ||
} | ||
} else { | ||
command.logger.Panicf("ERROR: an evaluation CSV file already exists in %s", command.ResultPath) | ||
} | ||
|
||
var allRecords []string | ||
for _, evaluationPath := range command.EvaluationPaths { | ||
// Collect all evaluation CSV file paths. | ||
evaluationFilePaths, err := pathsFromGlobPattern(evaluationPath) | ||
if err != nil { | ||
command.logger.Panicf("ERROR: %s", err) | ||
} | ||
// Collect all records from the evaluation CSV files. | ||
records, err := report.RecordsFromEvaluationCSVFiles(evaluationFilePaths) | ||
if err != nil { | ||
command.logger.Panicf("ERROR: %s", err) | ||
} | ||
allRecords = append(allRecords, records...) | ||
} | ||
|
||
if len(allRecords) == 0 { | ||
command.logger.Printf("no evaluation records found in %+v", command.EvaluationPaths) | ||
|
||
return nil | ||
} | ||
sort.Strings(allRecords) | ||
|
||
// Write all records into a single evaluation CSV file. | ||
evaluationFile, err := report.NewEvaluationFile(evaluationCSVFile) | ||
if err != nil { | ||
command.logger.Panicf("ERROR: %s", err) | ||
} | ||
if err := evaluationFile.WriteEvaluationRawRecords(allRecords); err != nil { | ||
command.logger.Panicf("ERROR: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// pathsFromGlobPattern returns all evaluation CSV file paths. | ||
func pathsFromGlobPattern(evaluationGlobPattern string) (evaluationFilePaths []string, err error) { | ||
if filepath.Base(evaluationGlobPattern) != "evaluation.csv" { | ||
return nil, pkgerrors.WithStack(pkgerrors.Errorf(`the path needs to end with "evaluation.csv" file, but found %q`, evaluationGlobPattern)) | ||
} | ||
|
||
evaluationGlobFilePaths, err := filepath.Glob(evaluationGlobPattern) | ||
if err != nil { | ||
return nil, pkgerrors.WithStack(err) | ||
} else if len(evaluationGlobFilePaths) == 0 { | ||
return nil, pkgerrors.Errorf("no files matched the pattern %q", evaluationGlobPattern) | ||
} | ||
|
||
evaluationCSVFilePaths := map[string]bool{} | ||
for _, evaluationCSVFilePath := range evaluationGlobFilePaths { | ||
evaluationCSVFilePaths[evaluationCSVFilePath] = true | ||
} | ||
|
||
return maps.Keys(evaluationCSVFilePaths), nil | ||
} |
Oops, something went wrong.