-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
dashboard.go
116 lines (99 loc) · 3.65 KB
/
dashboard.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2020-2022 Dave Shanley / Quobix
// SPDX-License-Identifier: MIT
package cmd
import (
"errors"
"github.com/daveshanley/vacuum/cui"
"github.com/daveshanley/vacuum/model"
"github.com/daveshanley/vacuum/motor"
vacuum_report "github.com/daveshanley/vacuum/vacuum-report"
"github.com/pb33f/libopenapi/datamodel"
"github.com/pb33f/libopenapi/index"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"net/url"
"time"
)
func GetDashboardCommand() *cobra.Command {
return &cobra.Command{
Use: "dashboard",
Short: "Show vacuum dashboard for linting report",
Long: "Interactive console dashboard to explore linting report in detail",
Example: "vacuum dashboard my-awesome-spec.yaml",
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
return []string{"yaml", "yml", "json"}, cobra.ShellCompDirectiveFilterFileExt
},
RunE: func(cmd *cobra.Command, args []string) error {
// check for file args
if len(args) == 0 {
errText := "please supply an OpenAPI specification to generate a report"
pterm.Error.Println(errText)
pterm.Println()
return errors.New(errText)
}
baseFlag, _ := cmd.Flags().GetString("base")
skipCheckFlag, _ := cmd.Flags().GetBool("skip-check")
timeoutFlag, _ := cmd.Flags().GetInt("timeout")
hardModeFlag, _ := cmd.Flags().GetBool("hard-mode")
silent, _ := cmd.Flags().GetBool("silent")
var err error
vacuumReport, specBytes, _ := vacuum_report.BuildVacuumReportFromFile(args[0])
if len(specBytes) <= 0 {
pterm.Error.Printf("Failed to read specification: %v\n\n", args[0])
return err
}
var resultSet *model.RuleResultSet
var ruleset *motor.RuleSetExecutionResult
var specIndex *index.SpecIndex
var specInfo *datamodel.SpecInfo
// if we have a pre-compiled report, jump straight to the end and collect $500
if vacuumReport == nil {
functionsFlag, _ := cmd.Flags().GetString("functions")
customFunctions, _ := LoadCustomFunctions(functionsFlag, silent)
rulesetFlag, _ := cmd.Flags().GetString("ruleset")
resultSet, ruleset, err = BuildResultsWithDocCheckSkip(false, hardModeFlag, rulesetFlag, specBytes, customFunctions,
baseFlag, skipCheckFlag, time.Duration(timeoutFlag)*time.Second)
if err != nil {
pterm.Error.Printf("Failed to render dashboard: %v\n\n", err)
return err
}
specIndex = ruleset.Index
specInfo = ruleset.SpecInfo
specInfo.Generated = time.Now()
} else {
resultSet = model.NewRuleResultSetPointer(vacuumReport.ResultSet.Results)
// TODO: refactor dashboard to hold state and rendering as separate entities.
// dashboard will be slower because it needs an index
var rootNode yaml.Node
err = yaml.Unmarshal(*vacuumReport.SpecInfo.SpecBytes, &rootNode)
if err != nil {
pterm.Error.Printf("Unable to read spec bytes from report file '%s': %s\n", args[0], err.Error())
pterm.Println()
return err
}
config := index.CreateClosedAPIIndexConfig()
if baseFlag != "" {
u, e := url.Parse(baseFlag)
if e == nil && u.Scheme != "" && u.Host != "" {
config.BaseURL = u
config.BasePath = ""
} else {
config.BasePath = baseFlag
}
config.AllowFileLookup = true
config.AllowRemoteLookup = true
}
specIndex = index.NewSpecIndexWithConfig(&rootNode, config)
specInfo = vacuumReport.SpecInfo
specInfo.Generated = vacuumReport.Generated
}
dash := cui.CreateDashboard(resultSet, specIndex, specInfo)
dash.Version = Version
return dash.Render()
},
}
}