mirror of
https://github.com/ossf/scorecard.git
synced 2024-09-17 11:57:12 +03:00
✨ Improve JSON format (#934)
* support for verison * fix * fix * linter * typo * fix
This commit is contained in:
parent
b5e4c7797b
commit
8f5e742e20
@ -173,9 +173,7 @@ or ./scorecard --{npm,pypi,rubgems}=<package_name> [--checks=check1,...] [--show
|
||||
log.Fatalf("cannot read yaml file: %v", err)
|
||||
}
|
||||
// TODO: support config files and update checker.MaxResultScore.
|
||||
// TODO: set version dynamically.
|
||||
scorecardVersion := "1.2.3"
|
||||
err = repoResult.AsSARIF(scorecardVersion, showDetails, *logLevel, os.Stdout, checkDocs, checker.MaxResultScore)
|
||||
err = repoResult.AsSARIF(showDetails, *logLevel, os.Stdout, checkDocs, checker.MaxResultScore)
|
||||
case formatCSV:
|
||||
err = repoResult.AsCSV(showDetails, *logLevel, os.Stdout)
|
||||
case formatJSON:
|
||||
|
@ -16,25 +16,10 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// Base version information.
|
||||
//
|
||||
// This is the fallback data used when version information from git is not
|
||||
// provided via go ldflags in the Makefile. See version.mk.
|
||||
var (
|
||||
// Output of "git describe". The prerequisite is that the branch should be
|
||||
// tagged using the correct versioning strategy.
|
||||
gitVersion = "unknown"
|
||||
// SHA1 from git, output of $(git rev-parse HEAD).
|
||||
gitCommit = "unknown"
|
||||
// State of git tree, either "clean" or "dirty".
|
||||
gitTreeState = "unknown"
|
||||
// Build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ').
|
||||
buildDate = "unknown"
|
||||
"github.com/ossf/scorecard/v2/pkg"
|
||||
)
|
||||
|
||||
//nolint:gochecknoinits
|
||||
@ -48,12 +33,12 @@ var versionCmd = &cobra.Command{
|
||||
Long: ``,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// not using logger, since it prints timing info, etc
|
||||
fmt.Printf("GitVersion:\t%s\n", gitVersion)
|
||||
fmt.Printf("GitCommit:\t%s\n", gitCommit)
|
||||
fmt.Printf("GitTreeState:\t%s\n", gitTreeState)
|
||||
fmt.Printf("BuildDate:\t%s\n", buildDate)
|
||||
fmt.Printf("GoVersion:\t%s\n", runtime.Version())
|
||||
fmt.Printf("Compiler:\t%s\n", runtime.Compiler)
|
||||
fmt.Printf("Platform:\t%s/%s\n", runtime.GOOS, runtime.GOARCH)
|
||||
fmt.Printf("GitVersion:\t%s\n", pkg.GetVersion())
|
||||
fmt.Printf("GitCommit:\t%s\n", pkg.GetCommit())
|
||||
fmt.Printf("GitTreeState:\t%s\n", pkg.GetTreeState())
|
||||
fmt.Printf("BuildDate:\t%s\n", pkg.GetBuildDate())
|
||||
fmt.Printf("GoVersion:\t%s\n", pkg.GetGoVersion())
|
||||
fmt.Printf("Compiler:\t%s\n", pkg.GetCompiler())
|
||||
fmt.Printf("Platform:\t%s/%s\n", pkg.GetOS(), pkg.GetArch())
|
||||
},
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func AsJSON(r *pkg.ScorecardResult, showDetails bool, logLevel zapcore.Level, wr
|
||||
encoder := json.NewEncoder(writer)
|
||||
|
||||
out := jsonScorecardCronResult{
|
||||
Repo: r.Repo,
|
||||
Repo: r.Repo.Name,
|
||||
Date: r.Date.Format("2006-01-02"),
|
||||
Metadata: r.Metadata,
|
||||
}
|
||||
@ -101,9 +101,9 @@ func AsJSON2(r *pkg.ScorecardResult, showDetails bool, logLevel zapcore.Level, w
|
||||
encoder := json.NewEncoder(writer)
|
||||
|
||||
out := jsonScorecardCronResultV2{
|
||||
Repo: r.Repo,
|
||||
Repo: r.Repo.Name,
|
||||
Date: r.Date.Format("2006-01-02"),
|
||||
Commit: r.CommitSHA,
|
||||
Commit: r.Repo.CommitSHA,
|
||||
Metadata: r.Metadata,
|
||||
}
|
||||
|
||||
|
40
pkg/json.go
40
pkg/json.go
@ -41,18 +41,28 @@ type jsonScorecardResult struct {
|
||||
|
||||
//nolint
|
||||
type jsonCheckResultV2 struct {
|
||||
Details []string
|
||||
Score int
|
||||
Reason string
|
||||
Name string
|
||||
Details []string `json:"details"`
|
||||
Score int `json:"score"`
|
||||
Reason string `json:"reason"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type jsonRepoV2 struct {
|
||||
Name string `json:"name"`
|
||||
Commit string `json:"commit"`
|
||||
}
|
||||
|
||||
type jsonScorecardV2 struct {
|
||||
Version string `json:"version"`
|
||||
Commit string `json:"commit"`
|
||||
}
|
||||
|
||||
type jsonScorecardResultV2 struct {
|
||||
Repo string
|
||||
Date string
|
||||
Commit string
|
||||
Checks []jsonCheckResultV2
|
||||
Metadata []string
|
||||
Date string `json:"date"`
|
||||
Repo jsonRepoV2 `json:"repo"`
|
||||
Scorecard jsonScorecardV2 `json:"scorecard"`
|
||||
Checks []jsonCheckResultV2 `json:"checks"`
|
||||
Metadata []string `json:"metadata"`
|
||||
}
|
||||
|
||||
// AsJSON exports results as JSON for new detail format.
|
||||
@ -60,7 +70,7 @@ func (r *ScorecardResult) AsJSON(showDetails bool, logLevel zapcore.Level, write
|
||||
encoder := json.NewEncoder(writer)
|
||||
|
||||
out := jsonScorecardResult{
|
||||
Repo: r.Repo,
|
||||
Repo: r.Repo.Name,
|
||||
Date: r.Date.Format("2006-01-02"),
|
||||
Metadata: r.Metadata,
|
||||
}
|
||||
@ -96,9 +106,15 @@ func (r *ScorecardResult) AsJSON2(showDetails bool, logLevel zapcore.Level, writ
|
||||
encoder := json.NewEncoder(writer)
|
||||
|
||||
out := jsonScorecardResultV2{
|
||||
Repo: r.Repo,
|
||||
Repo: jsonRepoV2{
|
||||
Name: r.Repo.Name,
|
||||
Commit: r.Repo.CommitSHA,
|
||||
},
|
||||
Scorecard: jsonScorecardV2{
|
||||
Version: r.Scorecard.Version,
|
||||
Commit: r.Scorecard.CommitSHA,
|
||||
},
|
||||
Date: r.Date.Format("2006-01-02"),
|
||||
Commit: r.CommitSHA,
|
||||
Metadata: r.Metadata,
|
||||
}
|
||||
|
||||
|
@ -1,60 +1,81 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"$id": "https://github.com/ossf/scorecard/pkg/schema.v2.json",
|
||||
"title": "Scorecard",
|
||||
"description": "A tool to assess the security posture of open-source projects",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Checks": {
|
||||
"checks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Details": {
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"Name": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"Reason": {
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"Score": {
|
||||
"score": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Details",
|
||||
"Score",
|
||||
"Reason",
|
||||
"Name"
|
||||
"details",
|
||||
"score",
|
||||
"reason",
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"Commit": {
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"Date": {
|
||||
"type": "string"
|
||||
},
|
||||
"Metadata": {
|
||||
"metadata": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"Repo": {
|
||||
"type": "string"
|
||||
"repo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"commit": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"commit"
|
||||
]
|
||||
},
|
||||
"scorecard": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"commit": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"commit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Repo",
|
||||
"Date",
|
||||
"Commit",
|
||||
"Checks",
|
||||
"Metadata"
|
||||
"date",
|
||||
"repo",
|
||||
"scorecard",
|
||||
"checks",
|
||||
"metadata"
|
||||
]
|
||||
}
|
||||
|
@ -34,7 +34,10 @@ import (
|
||||
func TestJSONOutput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
commit := "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
repoCommit := "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
scorecardCommit := "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
scorecardVersion := "1.2.3"
|
||||
repoName := "repo not used"
|
||||
date, e := time.Parse("2006-01-02", "2021-08-25")
|
||||
if e != nil {
|
||||
panic(fmt.Errorf("time.Parse: %w", e))
|
||||
@ -53,9 +56,15 @@ func TestJSONOutput(t *testing.T) {
|
||||
expected: "./testdata/check1.json",
|
||||
logLevel: zapcore.DebugLevel,
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -86,9 +95,15 @@ func TestJSONOutput(t *testing.T) {
|
||||
expected: "./testdata/check2.json",
|
||||
logLevel: zapcore.DebugLevel,
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -118,9 +133,15 @@ func TestJSONOutput(t *testing.T) {
|
||||
expected: "./testdata/check3.json",
|
||||
logLevel: zapcore.InfoLevel,
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -212,9 +233,15 @@ func TestJSONOutput(t *testing.T) {
|
||||
expected: "./testdata/check4.json",
|
||||
logLevel: zapcore.DebugLevel,
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -306,9 +333,15 @@ func TestJSONOutput(t *testing.T) {
|
||||
expected: "./testdata/check5.json",
|
||||
logLevel: zapcore.WarnLevel,
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -339,9 +372,15 @@ func TestJSONOutput(t *testing.T) {
|
||||
expected: "./testdata/check6.json",
|
||||
logLevel: zapcore.WarnLevel,
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -390,16 +429,16 @@ func TestJSONOutput(t *testing.T) {
|
||||
var expected bytes.Buffer
|
||||
n, err := expected.Write(content)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot write buffer: %v", err)
|
||||
t.Fatalf("%s: cannot write buffer: %v", tt.name, err)
|
||||
}
|
||||
if n != len(content) {
|
||||
t.Fatalf("write %d bytes but expected %d", n, len(content))
|
||||
t.Fatalf("%s: write %d bytes but expected %d", tt.name, n, len(content))
|
||||
}
|
||||
|
||||
var result bytes.Buffer
|
||||
err = tt.result.AsJSON2(tt.showDetails, tt.logLevel, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("AsJSON2: %v", err)
|
||||
t.Fatalf("%s: AsJSON2: %v", tt.name, err)
|
||||
}
|
||||
|
||||
// TODO: add indentation to AsJSON2() and remove
|
||||
@ -408,27 +447,27 @@ func TestJSONOutput(t *testing.T) {
|
||||
// Unmarshall expected output.
|
||||
var js jsonScorecardResultV2
|
||||
if err := json.Unmarshal(expected.Bytes(), &js); err != nil {
|
||||
t.Fatalf("json.Unmarshal %s: %s", tt.name, err)
|
||||
t.Fatalf("%s: json.Unmarshal: %s", tt.name, err)
|
||||
}
|
||||
|
||||
// Marshall.
|
||||
var es bytes.Buffer
|
||||
encoder := json.NewEncoder(&es)
|
||||
if err := encoder.Encode(js); err != nil {
|
||||
t.Fatalf("Encode %s: %s", tt.name, err)
|
||||
t.Fatalf("%s: Encode: %s", tt.name, err)
|
||||
}
|
||||
|
||||
// Compare outputs.
|
||||
r := bytes.Compare(result.Bytes(), es.Bytes())
|
||||
if r != 0 {
|
||||
t.Fatalf("invalid result for %s: %d", tt.name, r)
|
||||
t.Fatalf("%s: invalid result %d", tt.name, r)
|
||||
}
|
||||
|
||||
// Validate schema.
|
||||
docLoader := gojsonschema.NewReferenceLoader(fmt.Sprintf("file://%s", path.Join(cwd, tt.expected)))
|
||||
rr, err := schema.Validate(docLoader)
|
||||
if err != nil {
|
||||
t.Fatalf("Validate error for %s: %s", tt.name, err.Error())
|
||||
t.Fatalf("%s: Validate error: %s", tt.name, err.Error())
|
||||
}
|
||||
|
||||
if !rr.Valid() {
|
||||
@ -436,7 +475,7 @@ func TestJSONOutput(t *testing.T) {
|
||||
for _, desc := range rr.Errors() {
|
||||
s += fmt.Sprintf("- %s\n", desc)
|
||||
}
|
||||
t.Fatalf("invalid format %s: %s", tt.name, s)
|
||||
t.Fatalf("%s: invalid format: %s", tt.name, s)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -389,7 +389,7 @@ func createSARIFResult(pos int, checkID, reason string, minScore, score int,
|
||||
}
|
||||
|
||||
// AsSARIF outputs ScorecardResult in SARIF 2.1.0 format.
|
||||
func (r *ScorecardResult) AsSARIF(version string, showDetails bool, logLevel zapcore.Level,
|
||||
func (r *ScorecardResult) AsSARIF(showDetails bool, logLevel zapcore.Level,
|
||||
writer io.Writer, checkDocs docs.Doc, minScore int) error {
|
||||
//nolint
|
||||
// https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/sarif-v2.1.0-cs01.html.
|
||||
@ -397,7 +397,7 @@ func (r *ScorecardResult) AsSARIF(version string, showDetails bool, logLevel zap
|
||||
// see https://docs.github.com/en/code-security/secure-coding/integrating-with-code-scanning/sarif-support-for-code-scanning#supported-sarif-output-file-properties,
|
||||
// https://github.com/microsoft/sarif-tutorials.
|
||||
sarif := createSARIFHeader("https://github.com/ossf/scorecard",
|
||||
"supply-chain", "scorecard", version, r.CommitSHA, r.Date)
|
||||
"supply-chain", "scorecard", r.Scorecard.Version, r.Scorecard.CommitSHA, r.Date)
|
||||
results := []result{}
|
||||
rules := []rule{}
|
||||
|
||||
|
@ -39,7 +39,10 @@ func TestSARIFOutput(t *testing.T) {
|
||||
Tags string `yaml:"tags"`
|
||||
}
|
||||
|
||||
commit := "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
repoCommit := "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
scorecardCommit := "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
scorecardVersion := "1.2.3"
|
||||
repoName := "repo not used"
|
||||
date, e := time.Parse(time.RFC822Z, "17 Aug 21 18:57 +0000")
|
||||
if e != nil {
|
||||
panic(fmt.Errorf("time.Parse: %w", e))
|
||||
@ -72,9 +75,15 @@ func TestSARIFOutput(t *testing.T) {
|
||||
},
|
||||
},
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -115,9 +124,15 @@ func TestSARIFOutput(t *testing.T) {
|
||||
},
|
||||
},
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -171,9 +186,15 @@ func TestSARIFOutput(t *testing.T) {
|
||||
},
|
||||
},
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -281,9 +302,15 @@ func TestSARIFOutput(t *testing.T) {
|
||||
},
|
||||
},
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -377,9 +404,15 @@ func TestSARIFOutput(t *testing.T) {
|
||||
},
|
||||
},
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -420,9 +453,15 @@ func TestSARIFOutput(t *testing.T) {
|
||||
},
|
||||
},
|
||||
result: ScorecardResult{
|
||||
Repo: "repo not used",
|
||||
Date: date,
|
||||
CommitSHA: commit,
|
||||
Repo: RepoInfo{
|
||||
Name: repoName,
|
||||
CommitSHA: repoCommit,
|
||||
},
|
||||
Scorecard: ScorecardInfo{
|
||||
Version: scorecardVersion,
|
||||
CommitSHA: scorecardCommit,
|
||||
},
|
||||
Date: date,
|
||||
Checks: []checker.CheckResult{
|
||||
{
|
||||
Details2: []checker.CheckDetail{
|
||||
@ -452,27 +491,27 @@ func TestSARIFOutput(t *testing.T) {
|
||||
var err error
|
||||
content, err = ioutil.ReadFile(tt.expected)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot read file: %v", err)
|
||||
t.Fatalf("%s: cannot read file: %v", tt.name, err)
|
||||
}
|
||||
|
||||
var expected bytes.Buffer
|
||||
n, err := expected.Write(content)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot write buffer: %v", err)
|
||||
t.Fatalf("%s: cannot write buffer: %v", tt.name, err)
|
||||
}
|
||||
if n != len(content) {
|
||||
t.Fatalf("write %d bytes but expected %d", n, len(content))
|
||||
t.Fatalf("%s: write %d bytes but expected %d", tt.name, n, len(content))
|
||||
}
|
||||
|
||||
var result bytes.Buffer
|
||||
err = tt.result.AsSARIF("1.2.3", tt.showDetails, tt.logLevel, &result, tt.checkDocs, tt.minScore)
|
||||
err = tt.result.AsSARIF(tt.showDetails, tt.logLevel, &result, tt.checkDocs, tt.minScore)
|
||||
if err != nil {
|
||||
t.Fatalf("AsSARIF: %v", err)
|
||||
t.Fatalf("%s: AsSARIF: %v", tt.name, err)
|
||||
}
|
||||
|
||||
r := bytes.Compare(expected.Bytes(), result.Bytes())
|
||||
if r != 0 {
|
||||
t.Fatalf("invalid result for %s: %d", tt.name, r)
|
||||
t.Fatalf("%s: invalid result: %d", tt.name, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -106,9 +106,11 @@ func RunScorecards(ctx context.Context,
|
||||
}
|
||||
|
||||
ret := ScorecardResult{
|
||||
Repo: repo.URL(),
|
||||
Date: time.Now(),
|
||||
CommitSHA: commitSHA,
|
||||
Repo: RepoInfo{
|
||||
Name: repo.URL(),
|
||||
CommitSHA: commitSHA,
|
||||
},
|
||||
Date: time.Now(),
|
||||
}
|
||||
resultsCh := make(chan checker.CheckResult)
|
||||
go runEnabledChecks(ctx, repo, checksToRun, repoClient,
|
||||
|
@ -30,11 +30,23 @@ import (
|
||||
sce "github.com/ossf/scorecard/v2/errors"
|
||||
)
|
||||
|
||||
// ScorecardInfo contains information about the scorecard code that was run.
|
||||
type ScorecardInfo struct {
|
||||
Version string
|
||||
CommitSHA string
|
||||
}
|
||||
|
||||
// RepoInfo contains information about the repo that was analyzed.
|
||||
type RepoInfo struct {
|
||||
Name string
|
||||
CommitSHA string
|
||||
}
|
||||
|
||||
// ScorecardResult struct is returned on a successful Scorecard run.
|
||||
type ScorecardResult struct {
|
||||
Repo string
|
||||
Repo RepoInfo
|
||||
Date time.Time
|
||||
CommitSHA string
|
||||
Scorecard ScorecardInfo
|
||||
Checks []checker.CheckResult
|
||||
Metadata []string
|
||||
}
|
||||
@ -42,7 +54,7 @@ type ScorecardResult struct {
|
||||
// AsCSV outputs ScorecardResult in CSV format.
|
||||
func (r *ScorecardResult) AsCSV(showDetails bool, logLevel zapcore.Level, writer io.Writer) error {
|
||||
w := csv.NewWriter(writer)
|
||||
record := []string{r.Repo}
|
||||
record := []string{r.Repo.Name}
|
||||
columns := []string{"Repository"}
|
||||
// UPGRADEv2: remove nolint after ugrade.
|
||||
//nolint
|
||||
|
73
pkg/scorecard_version.go
Normal file
73
pkg/scorecard_version.go
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2021 Security Scorecard Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package pkg
|
||||
|
||||
import "runtime"
|
||||
|
||||
// Base version information.
|
||||
//
|
||||
// This is the fallback data used when version information from git is not
|
||||
// provided via go ldflags in the Makefile. See version.mk.
|
||||
var (
|
||||
// Output of "git describe". The prerequisite is that the branch should be
|
||||
// tagged using the correct versioning strategy.
|
||||
gitVersion = "unknown"
|
||||
// SHA1 from git, output of $(git rev-parse HEAD).
|
||||
gitCommit = "unknown"
|
||||
// State of git tree, either "clean" or "dirty".
|
||||
gitTreeState = "unknown"
|
||||
// Build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ').
|
||||
buildDate = "unknown"
|
||||
)
|
||||
|
||||
// GetVersion returns the scorecard version.
|
||||
func GetVersion() string {
|
||||
return gitVersion
|
||||
}
|
||||
|
||||
// GetCommit returns the GitHub's commit hash that scorecard was built from.
|
||||
func GetCommit() string {
|
||||
return gitCommit
|
||||
}
|
||||
|
||||
// GetTreeState returns the git tree state.
|
||||
func GetTreeState() string {
|
||||
return gitTreeState
|
||||
}
|
||||
|
||||
// GetBuildDate returns the date scorecard was build.
|
||||
func GetBuildDate() string {
|
||||
return buildDate
|
||||
}
|
||||
|
||||
// GetGoVersion returns the Go version used to build scorecard.
|
||||
func GetGoVersion() string {
|
||||
return runtime.Version()
|
||||
}
|
||||
|
||||
// GetOS returns the OS the build can run on.
|
||||
func GetOS() string {
|
||||
return runtime.GOOS
|
||||
}
|
||||
|
||||
// GetArch returns the architecture (e.g., x86) the build can run on.
|
||||
func GetArch() string {
|
||||
return runtime.GOARCH
|
||||
}
|
||||
|
||||
// GetCompiler returns the compiler that was used to build scorecard.
|
||||
func GetCompiler() string {
|
||||
return runtime.Compiler
|
||||
}
|
24
pkg/testdata/check1.json
vendored
24
pkg/testdata/check1.json
vendored
@ -1,16 +1,22 @@
|
||||
{
|
||||
"Repo": "repo not used",
|
||||
"Date": "2021-08-25",
|
||||
"Commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32",
|
||||
"Checks": [
|
||||
"date": "2021-08-25",
|
||||
"repo": {
|
||||
"name": "repo not used",
|
||||
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
},
|
||||
"scorecard": {
|
||||
"version": "1.2.3",
|
||||
"commit": "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: src/file1.cpp:5"
|
||||
],
|
||||
"Score": 5,
|
||||
"Reason": "half score reason",
|
||||
"Name": "Check-Name"
|
||||
"score": 5,
|
||||
"reason": "half score reason",
|
||||
"name": "Check-Name"
|
||||
}
|
||||
],
|
||||
"Metadata": []
|
||||
"metadata": []
|
||||
}
|
||||
|
2
pkg/testdata/check1.sarif
vendored
2
pkg/testdata/check1.sarif
vendored
@ -4,7 +4,7 @@
|
||||
"runs": [
|
||||
{
|
||||
"automationDetails": {
|
||||
"id": "supply-chain/scorecard/68bc59901773ab4c051dfcea0cc4201a1567ab32-17 Aug 21 18:57 +0000"
|
||||
"id": "supply-chain/scorecard/ccbc59901773ab4c051dfcea0cc4201a1567abdd-17 Aug 21 18:57 +0000"
|
||||
},
|
||||
"tool": {
|
||||
"driver": {
|
||||
|
26
pkg/testdata/check2.json
vendored
26
pkg/testdata/check2.json
vendored
@ -1,16 +1,22 @@
|
||||
{
|
||||
"Repo": "repo not used",
|
||||
"Date": "2021-08-25",
|
||||
"Commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32",
|
||||
"Checks": [
|
||||
"date": "2021-08-25",
|
||||
"repo": {
|
||||
"name": "repo not used",
|
||||
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
},
|
||||
"scorecard": {
|
||||
"version": "1.2.3",
|
||||
"commit": "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: bin/binary.elf"
|
||||
],
|
||||
"Score": 0,
|
||||
"Reason": "min score reason",
|
||||
"Name": "Check-Name"
|
||||
"score": 0,
|
||||
"reason": "min score reason",
|
||||
"name": "Check-Name"
|
||||
}
|
||||
],
|
||||
"Metadata": []
|
||||
}
|
||||
"metadata": []
|
||||
}
|
2
pkg/testdata/check2.sarif
vendored
2
pkg/testdata/check2.sarif
vendored
@ -4,7 +4,7 @@
|
||||
"runs": [
|
||||
{
|
||||
"automationDetails": {
|
||||
"id": "supply-chain/scorecard/68bc59901773ab4c051dfcea0cc4201a1567ab32-17 Aug 21 18:57 +0000"
|
||||
"id": "supply-chain/scorecard/ccbc59901773ab4c051dfcea0cc4201a1567abdd-17 Aug 21 18:57 +0000"
|
||||
},
|
||||
"tool": {
|
||||
"driver": {
|
||||
|
40
pkg/testdata/check3.json
vendored
40
pkg/testdata/check3.json
vendored
@ -1,33 +1,39 @@
|
||||
{
|
||||
"Repo": "repo not used",
|
||||
"Date": "2021-08-25",
|
||||
"Commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32",
|
||||
"Checks": [
|
||||
"date": "2021-08-25",
|
||||
"repo": {
|
||||
"name": "repo not used",
|
||||
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
},
|
||||
"scorecard": {
|
||||
"version": "1.2.3",
|
||||
"commit": "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: bin/binary.elf"
|
||||
],
|
||||
"Score": 0,
|
||||
"Reason": "min result reason",
|
||||
"Name": "Check-Name"
|
||||
"score": 0,
|
||||
"reason": "min result reason",
|
||||
"name": "Check-Name"
|
||||
},
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: src/doc.txt:3"
|
||||
],
|
||||
"Score": 0,
|
||||
"Reason": "min result reason",
|
||||
"Name": "Check-Name2"
|
||||
"score": 0,
|
||||
"reason": "min result reason",
|
||||
"name": "Check-Name2"
|
||||
},
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Info: info message: some/path.js:3",
|
||||
"Warn: warn message: some/path.py:3"
|
||||
],
|
||||
"Score": -1,
|
||||
"Reason": "inconclusive reason",
|
||||
"Name": "Check-Name3"
|
||||
"score": -1,
|
||||
"reason": "inconclusive reason",
|
||||
"name": "Check-Name3"
|
||||
}
|
||||
],
|
||||
"Metadata": []
|
||||
"metadata": []
|
||||
}
|
||||
|
2
pkg/testdata/check3.sarif
vendored
2
pkg/testdata/check3.sarif
vendored
@ -4,7 +4,7 @@
|
||||
"runs": [
|
||||
{
|
||||
"automationDetails": {
|
||||
"id": "supply-chain/scorecard/68bc59901773ab4c051dfcea0cc4201a1567ab32-17 Aug 21 18:57 +0000"
|
||||
"id": "supply-chain/scorecard/ccbc59901773ab4c051dfcea0cc4201a1567abdd-17 Aug 21 18:57 +0000"
|
||||
},
|
||||
"tool": {
|
||||
"driver": {
|
||||
|
42
pkg/testdata/check4.json
vendored
42
pkg/testdata/check4.json
vendored
@ -1,34 +1,40 @@
|
||||
{
|
||||
"Repo": "repo not used",
|
||||
"Date": "2021-08-25",
|
||||
"Commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32",
|
||||
"Checks": [
|
||||
"date": "2021-08-25",
|
||||
"repo": {
|
||||
"name": "repo not used",
|
||||
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
},
|
||||
"scorecard": {
|
||||
"version": "1.2.3",
|
||||
"commit": "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: bin/binary.elf"
|
||||
],
|
||||
"Score": 0,
|
||||
"Reason": "min result reason",
|
||||
"Name": "Check-Name"
|
||||
"score": 0,
|
||||
"reason": "min result reason",
|
||||
"name": "Check-Name"
|
||||
},
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: src/doc.txt:3"
|
||||
],
|
||||
"Score": 0,
|
||||
"Reason": "min result reason",
|
||||
"Name": "Check-Name2"
|
||||
"score": 0,
|
||||
"reason": "min result reason",
|
||||
"name": "Check-Name2"
|
||||
},
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Info: info message: some/path.js:3",
|
||||
"Warn: warn message: some/path.py:3",
|
||||
"Debug: debug message: some/path.go:3"
|
||||
],
|
||||
"Score": -1,
|
||||
"Reason": "inconclusive reason",
|
||||
"Name": "Check-Name3"
|
||||
"score": -1,
|
||||
"reason": "inconclusive reason",
|
||||
"name": "Check-Name3"
|
||||
}
|
||||
],
|
||||
"Metadata": []
|
||||
}
|
||||
"metadata": []
|
||||
}
|
2
pkg/testdata/check4.sarif
vendored
2
pkg/testdata/check4.sarif
vendored
@ -4,7 +4,7 @@
|
||||
"runs": [
|
||||
{
|
||||
"automationDetails": {
|
||||
"id": "supply-chain/scorecard/68bc59901773ab4c051dfcea0cc4201a1567ab32-17 Aug 21 18:57 +0000"
|
||||
"id": "supply-chain/scorecard/ccbc59901773ab4c051dfcea0cc4201a1567abdd-17 Aug 21 18:57 +0000"
|
||||
},
|
||||
"tool": {
|
||||
"driver": {
|
||||
|
24
pkg/testdata/check5.json
vendored
24
pkg/testdata/check5.json
vendored
@ -1,16 +1,22 @@
|
||||
{
|
||||
"Repo": "repo not used",
|
||||
"Date": "2021-08-25",
|
||||
"Commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32",
|
||||
"Checks": [
|
||||
"date": "2021-08-25",
|
||||
"repo": {
|
||||
"name": "repo not used",
|
||||
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
},
|
||||
"scorecard": {
|
||||
"version": "1.2.3",
|
||||
"commit": "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: src/file1.cpp:5"
|
||||
],
|
||||
"Score": 6,
|
||||
"Reason": "six score reason",
|
||||
"Name": "Check-Name"
|
||||
"score": 6,
|
||||
"reason": "six score reason",
|
||||
"name": "Check-Name"
|
||||
}
|
||||
],
|
||||
"Metadata": []
|
||||
"metadata": []
|
||||
}
|
||||
|
2
pkg/testdata/check5.sarif
vendored
2
pkg/testdata/check5.sarif
vendored
@ -4,7 +4,7 @@
|
||||
"runs": [
|
||||
{
|
||||
"automationDetails": {
|
||||
"id": "supply-chain/scorecard/68bc59901773ab4c051dfcea0cc4201a1567ab32-17 Aug 21 18:57 +0000"
|
||||
"id": "supply-chain/scorecard/ccbc59901773ab4c051dfcea0cc4201a1567abdd-17 Aug 21 18:57 +0000"
|
||||
},
|
||||
"tool": {
|
||||
"driver": {
|
||||
|
24
pkg/testdata/check6.json
vendored
24
pkg/testdata/check6.json
vendored
@ -1,16 +1,22 @@
|
||||
{
|
||||
"Repo": "repo not used",
|
||||
"Date": "2021-08-25",
|
||||
"Commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32",
|
||||
"Checks": [
|
||||
"date": "2021-08-25",
|
||||
"repo": {
|
||||
"name": "repo not used",
|
||||
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
|
||||
},
|
||||
"scorecard": {
|
||||
"version": "1.2.3",
|
||||
"commit": "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"Details": [
|
||||
"details": [
|
||||
"Warn: warn message: https://domain.com/something"
|
||||
],
|
||||
"Score": 6,
|
||||
"Reason": "six score reason",
|
||||
"Name": "Check-Name"
|
||||
"score": 6,
|
||||
"reason": "six score reason",
|
||||
"name": "Check-Name"
|
||||
}
|
||||
],
|
||||
"Metadata": []
|
||||
"metadata": []
|
||||
}
|
||||
|
2
pkg/testdata/check6.sarif
vendored
2
pkg/testdata/check6.sarif
vendored
@ -4,7 +4,7 @@
|
||||
"runs": [
|
||||
{
|
||||
"automationDetails": {
|
||||
"id": "supply-chain/scorecard/68bc59901773ab4c051dfcea0cc4201a1567ab32-17 Aug 21 18:57 +0000"
|
||||
"id": "supply-chain/scorecard/ccbc59901773ab4c051dfcea0cc4201a1567abdd-17 Aug 21 18:57 +0000"
|
||||
},
|
||||
"tool": {
|
||||
"driver": {
|
||||
|
@ -21,5 +21,5 @@ GIT_VERSION=$(git describe --tags --always --dirty)
|
||||
GIT_HASH=$(git rev-parse HEAD)
|
||||
BUILD_DATE=$(date +'%Y-%m-%dT%H:%M:%SZ')
|
||||
GIT_TREESTATE=$(if git diff --quiet; then echo "clean"; else echo "dirty"; fi)
|
||||
PKG=$(go list -m | head -n1)/cmd
|
||||
PKG=$(go list -m | head -n1)/pkg
|
||||
echo "-X $PKG.gitVersion=$GIT_VERSION -X $PKG.gitCommit=$GIT_HASH -X $PKG.gitTreeState=$GIT_TREESTATE -X $PKG.buildDate=$BUILD_DATE"
|
||||
|
Loading…
Reference in New Issue
Block a user