Add merge reports option in report command#10
Conversation
dimityrmirchev
left a comment
There was a problem hiding this comment.
Thanks! I left some comments. Also it would be nice if we can have a simple test for the MergeReport function
| if len(args) != 1 { | ||
| return errors.New("report requires a single filepath argument") | ||
| if len(args) == 0 { | ||
| return errors.New("report requires a minimum of one filepath arguments") |
There was a problem hiding this comment.
| return errors.New("report requires a minimum of one filepath arguments") | |
| return errors.New("report command requires a minimum of one filepath argument") |
| } | ||
|
|
||
| if len(args) > 1 && len(opts.distinctBy) == 0 { | ||
| return errors.New("report requires a single filepath argument when flag distinct-by is not set ") |
There was a problem hiding this comment.
| return errors.New("report requires a single filepath argument when flag distinct-by is not set ") | |
| return errors.New("report command requires a single filepath argument when the distinct-by flag is not set ") |
| #### Report | ||
|
|
||
| Generate an html report | ||
| Diki report generates a human readable html report from the .json output of a `diki run` execution. Merged reports can be generated using the `distinct-by` flag, the value of this flag is a list of key:value pairs where the keys are the IDs of the providers we want to include in the merged report and the values are the unique metadata fields to be used for IDs of the different reports. |
There was a problem hiding this comment.
| Diki report generates a human readable html report from the .json output of a `diki run` execution. Merged reports can be generated using the `distinct-by` flag, the value of this flag is a list of key:value pairs where the keys are the IDs of the providers we want to include in the merged report and the values are the unique metadata fields to be used for IDs of the different reports. | |
| Diki can generate a human readable report from the output files of a `diki run` execution. Merged reports can be produced by setting the `distinct-by` flag. The value of this flag is a list of `key=value` pairs where the keys are the IDs of the providers we want to include in the merged report and the values are the unique metadata fields to be used as distinction values between different provider runs. |
| for _, arg := range args { | ||
| fileData, err := os.ReadFile(filepath.Clean(arg)) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to read file %s:%w", arg, err) |
There was a problem hiding this comment.
| return fmt.Errorf("failed to read file %s:%w", arg, err) | |
| return fmt.Errorf("failed to read file %s: %w", arg, err) |
| case *MergedReport: | ||
| return r.templates[tmplMergedReportName].Execute(w, rep) | ||
| default: | ||
| return fmt.Errorf("unsupported report type: %T", rep) |
There was a problem hiding this comment.
| return fmt.Errorf("unsupported report type: %T", rep) | |
| return fmt.Errorf("unsupported report type: %T", report) |
| } | ||
|
|
||
| if _, ok := mergedProvider.Metadata[uniqueAttr]; ok { | ||
| return &MergedReport{}, fmt.Errorf("distinct attribute %s is not unique", mergedProvider.DistinctBy) |
There was a problem hiding this comment.
| return &MergedReport{}, fmt.Errorf("distinct attribute %s is not unique", mergedProvider.DistinctBy) | |
| return nil, fmt.Errorf("distinct attribute %s is not unique", mergedProvider.DistinctBy) |
| } | ||
|
|
||
| mergedProvider.Metadata[uniqueAttr] = report.Providers[idx].Metadata | ||
| mergedProvider.Metadata[uniqueAttr]["time"] = report.Time.Format("01-02-2006") |
There was a problem hiding this comment.
Should we also add the time of the report?
There was a problem hiding this comment.
That would be a good addition for a more detailed report. I have added HH-MM-SS now as well.
| func numOfMergedRulesWithStatus(ruleset *MergedRuleset, status rule.Status) int { | ||
| num := 0 | ||
| for _, rule := range ruleset.Rules { | ||
| for _, check := range rule.Checks { |
There was a problem hiding this comment.
Maybe we can use slices.ContainsFunc here?
| } | ||
|
|
||
| func metadataTextForMergedProvider(mp MergedProvider) map[string]string { | ||
| metadataTexts := map[string]string{} |
There was a problem hiding this comment.
| metadataTexts := map[string]string{} | |
| metadataTexts := make(map[string]string, len(mp.Metadata)) |
| func metadataTextForMergedProvider(mp MergedProvider) map[string]string { | ||
| metadataTexts := map[string]string{} | ||
| for id, metadata := range mp.Metadata { | ||
| metadataText := "(" |
There was a problem hiding this comment.
I think this is a good place to use strings.Builder
| for key := range distinctByAttrs { | ||
| distinctByAttrsProviders = append(distinctByAttrsProviders, key) | ||
| } | ||
| sort.Strings(distinctByAttrsProviders) |
| handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}) | ||
| logger := slog.New(handler) | ||
| testLogger = logger |
What this PR does / why we need it:
This PR add a new functionality to the
diki reportcommand which allows the merge of multiplejsonreports into a singlehtmlreport. To use this feature thedistinct-byflag should be set with unique attributes which would be used for each provider to distinct the different reports.TODO: write documentation
Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
Release note: