Skip to content

Commit a704dbb

Browse files
committed
output now can be set to multi writer
1 parent bf41d1d commit a704dbb

File tree

20 files changed

+232
-163
lines changed

20 files changed

+232
-163
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@
176176

177177
END OF TERMS AND CONDITIONS
178178

179-
Copyright [yyyy] [name of copyright owner]
179+
Copyright 2017-2022 GuardRails Pte. Ltd.
180180

181181
Licensed under the Apache License, Version 2.0 (the "License");
182182
you may not use this file except in compliance with the License.

cmd/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"fmt"
55
"os"
66

7-
prettyFmt "github.com/guardrailsio/guardrails-cli/internal/formatter/pretty"
7+
prettyFmt "github.com/guardrailsio/guardrails-cli/internal/format/pretty"
88
)
99

1010
func fail(err error) {

cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ Commands:
3535
[-o,--output=<path>][-q,--quiet]
3636
help
3737
38-
scan scans a repository for vulnerabilities and output results
38+
scan: scans a repository for vulnerabilities and output results
3939
-t, --token a valid Guardrails CLI token you can obtain from dashboard > settings
4040
-p, --path the path to the repository to scan, defaults to $PWD
4141
-f, --format the output format for scan results, defaults to pretty
4242
-o, --output if provided, will save the output to the specified file path
4343
-q, --quiet if provided, will only output scan results in --format and nothing else
4444
45-
help displays this help menu
45+
help: displays this help menu
4646
4747
Environment variables:
4848
GUARDRAILS_CLI_TOKEN if set, will be used as token when --token is not provided

cmd/scan.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
guardrailsclient "github.com/guardrailsio/guardrails-cli/internal/client/guardrails"
88
scan "github.com/guardrailsio/guardrails-cli/internal/command/scan"
99
"github.com/guardrailsio/guardrails-cli/internal/config"
10+
outputwriter "github.com/guardrailsio/guardrails-cli/internal/output"
1011
"github.com/guardrailsio/guardrails-cli/internal/repository"
1112
spinner "github.com/guardrailsio/guardrails-cli/internal/tools/spinner"
1213
"github.com/spf13/cobra"
@@ -58,11 +59,15 @@ var scanCmd = &cobra.Command{
5859
// setup guardrails api client
5960
grclient := guardrailsclient.New(cfg.HttpClient, args.Token)
6061

62+
// setup output writer
63+
outputWriter := outputwriter.New(args.Output)
64+
outputWriter.SetWriter()
65+
6166
// setup spinner animation
6267
spinner := spinner.New()
6368

6469
// inject all scan command dependencies and execute the command
65-
cmd := scan.New(args, spinner, cfg, repo, arc, grclient)
70+
cmd := scan.New(args, spinner, cfg, repo, arc, outputWriter, grclient)
6671
if err := cmd.Execute(ctx); err != nil {
6772
fail(err)
6873
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/guardrailsio/guardrails-cli
33
go 1.18
44

55
require (
6+
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
67
github.com/briandowns/spinner v1.19.0
78
github.com/cenkalti/backoff v2.2.1+incompatible
89
github.com/enescakir/emoji v1.0.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/
4343
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
4444
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
4545
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
46+
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
47+
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
4648
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
4749
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
4850
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=

internal/command/scan/format.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package scan
2+
3+
import (
4+
guardrailsclient "github.com/guardrailsio/guardrails-cli/internal/client/guardrails"
5+
formatter "github.com/guardrailsio/guardrails-cli/internal/command/scan/format"
6+
)
7+
8+
// GetScanDataFormatter parses guardrailsclient.GetScanDataResp to chosen format.
9+
func (h *Handler) GetScanDataFormatter(resp *guardrailsclient.GetScanDataResp) error {
10+
w := h.OutputWriter.Writer
11+
12+
switch h.Args.Format {
13+
case "json":
14+
return formatter.GetScanDataJSONFormat(w, resp)
15+
case "csv":
16+
return formatter.GetScanDataCSVFormat(w, resp)
17+
case "sarif":
18+
return formatter.GetScanDataSARIFFormat(w, resp, h.Args.Quiet)
19+
default:
20+
return formatter.GetScanDataPrettyFormat(w, resp)
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,46 @@
1-
package csv
1+
package scanformat
22

33
import (
44
"bytes"
55
"encoding/csv"
66
"fmt"
7+
"io"
78
"strconv"
89

910
guardrailsclient "github.com/guardrailsio/guardrails-cli/internal/client/guardrails"
1011
)
1112

12-
func ScanResult(result *guardrailsclient.GetScanDataResp) error {
13+
// GetScanDataCSVFormat parses guardrailsclient.GetScanDataResp to csv format.
14+
func GetScanDataCSVFormat(w io.Writer, resp *guardrailsclient.GetScanDataResp) error {
1315
var b []byte
1416
buf := bytes.NewBuffer(b)
15-
w := csv.NewWriter(buf)
17+
csvWriter := csv.NewWriter(buf)
1618

1719
header := []string{"rule_id", "rule_title", "total", "finding_id", "path", "line_number", "docs"}
18-
if err := w.Write(header); err != nil {
20+
if err := csvWriter.Write(header); err != nil {
1921
return err
2022
}
2123

22-
for _, r := range result.Results.Rules {
24+
for _, r := range resp.Results.Rules {
2325
for _, v := range r.Vulnerabilities {
2426
ruleID := strconv.FormatInt(r.Rule.RuleID, 10)
2527
total := strconv.Itoa(r.Count.Total)
2628
lineNumber := strconv.FormatInt(v.LineNumber, 10)
2729
docs := fmt.Sprintf("https://docs.guardrails.io/docs/vulnerabilities/%s/%s", v.Language, r.Rule.Docs)
2830

2931
record := []string{ruleID, r.Rule.Title, total, v.FindingID, v.Path, lineNumber, docs}
30-
if err := w.Write(record); err != nil {
32+
if err := csvWriter.Write(record); err != nil {
3133
return err
3234
}
3335
}
3436
}
3537

36-
w.Flush()
37-
if err := w.Error(); err != nil {
38+
csvWriter.Flush()
39+
if err := csvWriter.Error(); err != nil {
3840
return err
3941
}
4042

41-
fmt.Printf("%s", buf.String())
43+
fmt.Fprintf(w, "%s", buf.String())
4244

4345
return nil
4446
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package scanformat
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io"
7+
8+
guardrailsclient "github.com/guardrailsio/guardrails-cli/internal/client/guardrails"
9+
)
10+
11+
// GetScanDataJSONFormat parses guardrailsclient.GetScanDataResp to json format.
12+
func GetScanDataJSONFormat(w io.Writer, resp *guardrailsclient.GetScanDataResp) error {
13+
manifestJson, err := json.MarshalIndent(resp, "", " ")
14+
if err != nil {
15+
return err
16+
}
17+
18+
fmt.Fprintf(w, "%s\n", string(manifestJson))
19+
20+
return nil
21+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package scanformat
2+
3+
import (
4+
"fmt"
5+
"io"
6+
7+
guardrailsclient "github.com/guardrailsio/guardrails-cli/internal/client/guardrails"
8+
prettyFmt "github.com/guardrailsio/guardrails-cli/internal/format/pretty"
9+
"github.com/jedib0t/go-pretty/text"
10+
)
11+
12+
// GetScanDataJSONFormat parses guardrailsclient.GetScanDataResp to pretty format.
13+
func GetScanDataPrettyFormat(w io.Writer, resp *guardrailsclient.GetScanDataResp) error {
14+
if resp.OK {
15+
fmt.Fprintf(w, "%s\n", prettyFmt.Success("No issues detected, well done!"))
16+
} else {
17+
fmt.Fprintf(w, "%s\n", prettyFmt.Warning(fmt.Sprintf("We detected %d security issue", resp.Results.Count.Total)))
18+
19+
for _, r := range resp.Results.Rules {
20+
fmt.Fprintf(w, "%s (%d)\n", r.Rule.Title, r.Count.Total)
21+
22+
for _, v := range r.Vulnerabilities {
23+
fmt.Fprintln(w, text.FgCyan.Sprintf("%s (line %d)", v.Path, v.LineNumber))
24+
}
25+
26+
fmt.Fprintln(w, "Not sure how to fix this ?")
27+
for _, l := range r.Languages {
28+
fmt.Fprintln(w, text.FgBlue.Sprintf("https://docs.guardrails.io/docs/vulnerabilities/%s/%s\n", l, r.Rule.Docs))
29+
}
30+
}
31+
}
32+
33+
return nil
34+
}

0 commit comments

Comments
 (0)