Cleanup documentation code (#981)

* draft 1

* unit tests

* fix

* fixes

* fix

* mod

* comments

* fixes

* rename

* fix

* linter
This commit is contained in:
laurentsimon 2021-09-09 15:09:39 -07:00 committed by GitHub
parent 1da121da29
commit 870db56814
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 548 additions and 240 deletions

View File

@ -97,11 +97,11 @@ clients/branch.pb.go: clients/branch.proto | $(PROTOC)
generate-docs: ## Generates docs
generate-docs: docs/checks.md
docs/checks.md: docs/checks/checks.yaml docs/checks/*.go docs/checks/generate/*.go
docs/checks.md: docs/checks/internal/checks.yaml docs/checks/internal/*.go docs/checks/internal/generate/*.go
# Validating checks.yaml
go run ./docs/checks/validate/main.go
go run ./docs/checks/internal/validate/main.go
# Generating checks.md
cd ./docs/checks/generate && go run main.go
go run ./docs/checks/internal/generate/main.go docs/checks/checks.md
build-scorecard: ## Runs go build on repo
# Run go build and generate scorecard executable

View File

@ -168,7 +168,11 @@ or ./scorecard --{npm,pypi,rubgems}=<package_name> [--checks=check1,...] [--show
err = repoResult.AsCSV(showDetails, *logLevel, os.Stdout)
case formatJSON:
// UPGRADEv2: rename.
err = repoResult.AsJSON2(showDetails, *logLevel, os.Stdout)
checkDocs, e := docs.Read()
if e != nil {
log.Fatalf("cannot read yaml file: %v", err)
}
err = repoResult.AsJSON2(showDetails, *logLevel, checkDocs, os.Stdout)
default:
err = sce.Create(sce.ErrScorecardInternal,
fmt.Sprintf("invalid format flag: %v. Expected [default, csv, json]", format))

34
docs/checks/doc.go Normal file
View File

@ -0,0 +1,34 @@
// 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 checks contains documentation about checks.
package checks
// Doc defines the documentation interface.
type Doc interface {
GetCheck(name string) (CheckDoc, error)
GetChecks() []CheckDoc
CheckExists(name string) bool
}
// CheckDoc defines the documentation interface for a check.
type CheckDoc interface {
GetName() string
GetRisk() string
GetShort() string
GetDescription() string
GetRemediation() []string
GetTags() []string
GetDocumentationURL(commitish string) string
}

127
docs/checks/impl.go Normal file
View File

@ -0,0 +1,127 @@
// 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 checks contains documentation about checks.
package checks
import (
"errors"
"fmt"
"strings"
"github.com/ossf/scorecard/v2/docs/checks/internal"
sce "github.com/ossf/scorecard/v2/errors"
)
var errCheckNotExist = errors.New("check does not exist")
const docURL = "https://github.com/ossf/scorecard/blob/%s/docs/checks.md"
// DocImpl implements `Doc` interface and
// contains checks' documentation.
type DocImpl struct {
internaldoc internal.Doc
}
// Read loads the checks' documentation.
func Read() (Doc, error) {
m, e := internal.ReadDoc()
if e != nil {
d := DocImpl{}
return &d, fmt.Errorf("internal.ReadDoc: %w", e)
}
d := DocImpl{internaldoc: m}
return &d, nil
}
// GetCheck returns the information for check `name`.
func (d *DocImpl) GetCheck(name string) (CheckDoc, error) {
ic, exists := d.internaldoc.InternalChecks[name]
if !exists {
//nolint: wrapcheck
return nil, sce.CreateInternal(errCheckNotExist, "")
}
// Set the name and URL.
ic.Name = name
ic.URL = fmt.Sprintf("%s#%s", docURL, strings.ToLower(name))
return &CheckDocImpl{internalCheck: ic}, nil
}
// GetChecks returns the information for check `name`.
func (d *DocImpl) GetChecks() []CheckDoc {
var checks []CheckDoc
for k := range d.internaldoc.InternalChecks {
//nolint: errcheck
check, _ := d.GetCheck(k)
checks = append(checks, check)
}
return checks
}
// CheckExists returns whether the check `name` exists or not.
func (d DocImpl) CheckExists(name string) bool {
_, exists := d.internaldoc.InternalChecks[name]
return exists
}
// CheckDocImpl implementts `CheckDoc` interface and
// stores documentation about a check.
type CheckDocImpl struct {
internalCheck internal.Check
}
// GetName returns the name of the check.
func (c *CheckDocImpl) GetName() string {
return c.internalCheck.Name
}
// GetRisk returns the risk of the check.
func (c *CheckDocImpl) GetRisk() string {
return c.internalCheck.Risk
}
// GetShort returns the short description of the check.
func (c *CheckDocImpl) GetShort() string {
return c.internalCheck.Short
}
// GetDescription returns the full description of the check.
func (c *CheckDocImpl) GetDescription() string {
return c.internalCheck.Description
}
// GetRemediation returns the remediation of the check.
func (c *CheckDocImpl) GetRemediation() []string {
return c.internalCheck.Remediation
}
// GetTags returns the list of tags or the check.
func (c *CheckDocImpl) GetTags() []string {
l := strings.Split(c.internalCheck.Tags, ",")
for i := range l {
l[i] = strings.TrimSpace(l[i])
}
return l
}
// GetDocumentationURL returns the URL for the documentation of check `name`.
func (c *CheckDocImpl) GetDocumentationURL(commitish string) string {
com := commitish
if com == "" || com == "unknown" {
com = "main"
}
return fmt.Sprintf(c.internalCheck.URL, com)
}

View File

@ -14,6 +14,7 @@
package main
import (
"fmt"
"os"
"sort"
@ -21,17 +22,24 @@ import (
)
func main() {
if len(os.Args) != 2 {
// nolint: goerr113
panic(fmt.Errorf("usage: %s filename", os.Args[0]))
}
yamlFile := os.Args[1]
m, err := docs.Read()
if err != nil {
panic(err)
}
keys := make([]string, 0, len(m.Checks))
for k := range m.Checks {
keys = append(keys, k)
checks := m.GetChecks()
keys := make([]string, 0, len(checks))
for _, v := range checks {
keys = append(keys, v.GetName())
}
sort.Strings(keys)
f, err := os.Create("../../checks.md")
f, err := os.Create(yamlFile)
if err != nil {
panic(err)
}
@ -52,11 +60,15 @@ please contribute!
panic(err)
}
for _, k := range keys {
_, err = f.WriteString("## " + k + " \n\n")
_, err := f.WriteString("## " + k + " \n\n")
if err != nil {
panic(err)
}
_, err = f.WriteString(m.Checks[k].Description + " \n\n")
c, err := m.GetCheck(k)
if err != nil {
panic(err)
}
_, err = f.WriteString(c.GetDescription() + " \n\n")
if err != nil {
panic(err)
}
@ -64,7 +76,7 @@ please contribute!
if err != nil {
panic(err)
}
for _, r := range m.Checks[k].Remediation {
for _, r := range c.GetRemediation() {
_, err = f.WriteString("- " + r + "\n")
if err != nil {
panic(err)

View File

@ -1,4 +1,4 @@
// Copyright 2020 Security Scorecard Authors
// 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.
@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Package checks contains util fns for reading input YAML file.
package checks
// Package internal contains internal functions for reading input YAML file.
package internal
import (
@ -27,22 +27,25 @@ import (
//go:embed checks.yaml
var checksYAML []byte
// Check defines expected check definition in checks.yaml.
// Check stores a check's information.
// nolint:govet
type Check struct {
Risk string `yaml:"-"`
Short string `yaml:"short"`
Description string `yaml:"description"`
Tags string `yaml:"tags"`
Remediation []string `yaml:"remediation"`
Name string `yaml:"-"`
URL string `yaml:"-"`
}
// Doc maps to checks.yaml file.
// Doc stores the documentation for all checks.
type Doc struct {
Checks map[string]Check
InternalChecks map[string]Check `yaml:"checks"`
}
// Read parses `checks.yaml` file and returns a `Doc` struct.
func Read() (Doc, error) {
// ReadDoc reads documentation from the `checks.yaml` file.
func ReadDoc() (Doc, error) {
var m Doc
if err := yaml.Unmarshal(checksYAML, &m); err != nil {
return Doc{}, fmt.Errorf("yaml.Unmarshal: %w", err)

View File

@ -29,32 +29,32 @@ func main() {
allChecks := checks.AllChecks
for check := range allChecks {
doc, exists := m.Checks[check]
if !exists {
// nolint: goerr113
panic(fmt.Errorf("could not find checkName: %s in checks.yaml", check))
c, e := m.GetCheck(check)
if e != nil {
panic(fmt.Errorf("GetCheck: %w: %s", e, check))
}
if doc.Description == "" {
if c.GetDescription() == "" {
// nolint: goerr113
panic(fmt.Errorf("description for checkName: %s is empty", check))
}
if strings.TrimSpace(strings.Join(doc.Remediation, "")) == "" {
if strings.TrimSpace(strings.Join(c.GetRemediation(), "")) == "" {
// nolint: goerr113
panic(fmt.Errorf("remediation for checkName: %s is empty", check))
}
if doc.Short == "" {
if c.GetShort() == "" {
// nolint: goerr113
panic(fmt.Errorf("short for checkName: %s is empty", check))
}
if doc.Tags == "" {
if len(c.GetTags()) == 0 {
// nolint: goerr113
panic(fmt.Errorf("tags for checkName: %s is empty", check))
}
}
for check := range m.Checks {
if _, exists := allChecks[check]; !exists {
for _, check := range m.GetChecks() {
if _, exists := allChecks[check.GetName()]; !exists {
// nolint: goerr113
panic(fmt.Errorf("check present in checks.yaml is not part of `checks.AllChecks`: %s", check))
panic(fmt.Errorf("check present in checks.yaml is not part of `checks.AllChecks`: %s", check.GetName()))
}
}
}

View File

@ -81,11 +81,3 @@ func typeToString(cd checker.DetailType) string {
return "Debug"
}
}
func tagsAsList(tags string) []string {
l := strings.Split(tags, ",")
for i := range l {
l[i] = strings.TrimSpace(l[i])
}
return l
}

View File

@ -21,6 +21,7 @@ import (
"go.uber.org/zap/zapcore"
docs "github.com/ossf/scorecard/v2/docs/checks"
sce "github.com/ossf/scorecard/v2/errors"
)
@ -39,12 +40,19 @@ type jsonScorecardResult struct {
Metadata []string
}
type jsonCheckDocumentationV2 struct {
URL string `json:"url"`
Short string `json:"short"`
// Can be extended if needed.
}
//nolint
type jsonCheckResultV2 struct {
Details []string `json:"details"`
Score int `json:"score"`
Reason string `json:"reason"`
Name string `json:"name"`
Details []string `json:"details"`
Score int `json:"score"`
Reason string `json:"reason"`
Name string `json:"name"`
Doc jsonCheckDocumentationV2 `json:"documentation"`
}
type jsonRepoV2 struct {
@ -102,7 +110,8 @@ func (r *ScorecardResult) AsJSON(showDetails bool, logLevel zapcore.Level, write
}
// AsJSON2 exports results as JSON for new detail format.
func (r *ScorecardResult) AsJSON2(showDetails bool, logLevel zapcore.Level, writer io.Writer) error {
func (r *ScorecardResult) AsJSON2(showDetails bool,
logLevel zapcore.Level, checkDocs docs.Doc, writer io.Writer) error {
encoder := json.NewEncoder(writer)
out := jsonScorecardResultV2{
@ -120,8 +129,17 @@ func (r *ScorecardResult) AsJSON2(showDetails bool, logLevel zapcore.Level, writ
//nolint
for _, checkResult := range r.Checks {
doc, e := checkDocs.GetCheck(checkResult.Name)
if e != nil {
return sce.Create(sce.ErrScorecardInternal, fmt.Sprintf("GetCheck: %s: %v", checkResult.Name, e))
}
tmpResult := jsonCheckResultV2{
Name: checkResult.Name,
Name: checkResult.Name,
Doc: jsonCheckDocumentationV2{
URL: doc.GetDocumentationURL(r.Scorecard.CommitSHA),
Short: doc.GetShort(),
},
Reason: checkResult.Reason,
Score: checkResult.Score,
}

View File

@ -1,81 +1,97 @@
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"checks": {
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"checks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"details": {
"type": "array",
"items": {
"type": "object",
"properties": {
"details": {
"type": "array",
"items": {
"type": "string"
}
},
"name": {
"type": "string"
},
"reason": {
"type": "string"
},
"score": {
"type": "integer"
}
},
"required": [
"details",
"score",
"reason",
"name"
]
"type": "string"
}
},
"date": {
"type": "string"
},
"metadata": {
"type": "array",
"items": {
},
"documentation": {
"type": "object",
"properties": {
"short": {
"type": "string"
}
},
"repo": {
"type": "object",
"properties": {
"commit": {
"type": "string"
},
"name": {
"type": "string"
}
},
"url": {
"type": "string"
}
},
"required": [
"name",
"commit"
"url",
"short"
]
},
"name": {
"type": "string"
},
"reason": {
"type": "string"
},
"score": {
"type": "integer"
}
},
"scorecard": {
"type": "object",
"properties": {
"commit": {
"type": "string"
},
"version": {
"type": "string"
}
},
"required": [
"version",
"commit"
]
}
"required": [
"details",
"score",
"reason",
"name",
"documentation"
]
}
},
"required": [
"date",
"repo",
"scorecard",
"checks",
"metadata"
]
"date": {
"type": "string"
},
"metadata": {
"type": "array",
"items": {
"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": [
"date",
"repo",
"scorecard",
"checks",
"metadata"
]
}

View File

@ -30,6 +30,41 @@ import (
"github.com/ossf/scorecard/v2/checker"
)
func jsonMockDocRead() *mockDoc {
d := map[string]mockCheck{
"Check-Name": {
name: "Check-Name",
risk: "not used",
short: "short description for Check-Name",
description: "not used",
url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
tags: []string{"not-used1", "not-used2"},
remediation: []string{"not-used1", "not-used2"},
},
"Check-Name2": {
name: "Check-Name2",
risk: "not used",
short: "short description for Check-Name2",
description: "not used",
url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name2",
tags: []string{"not-used1", "not-used2"},
remediation: []string{"not-used1", "not-used2"},
},
"Check-Name3": {
name: "Check-Name3",
risk: "not used",
short: "short description for Check-Name3",
description: "not used",
url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name3",
tags: []string{"not-used1", "not-used2"},
remediation: []string{"not-used1", "not-used2"},
},
}
m := mockDoc{checks: d}
return &m
}
//nolint
func TestJSONOutput(t *testing.T) {
t.Parallel()
@ -37,12 +72,14 @@ func TestJSONOutput(t *testing.T) {
repoCommit := "68bc59901773ab4c051dfcea0cc4201a1567ab32"
scorecardCommit := "ccbc59901773ab4c051dfcea0cc4201a1567abdd"
scorecardVersion := "1.2.3"
repoName := "repo not used"
repoName := "org/name"
date, e := time.Parse("2006-01-02", "2021-08-25")
if e != nil {
panic(fmt.Errorf("time.Parse: %w", e))
}
checkDocs := jsonMockDocRead()
tests := []struct {
name string
expected string
@ -436,7 +473,7 @@ func TestJSONOutput(t *testing.T) {
}
var result bytes.Buffer
err = tt.result.AsJSON2(tt.showDetails, tt.logLevel, &result)
err = tt.result.AsJSON2(tt.showDetails, tt.logLevel, checkDocs, &result)
if err != nil {
t.Fatalf("%s: AsJSON2: %v", tt.name, err)
}

77
pkg/mock_doc.go Normal file
View File

@ -0,0 +1,77 @@
// 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 (
"strings"
docs "github.com/ossf/scorecard/v2/docs/checks"
)
type mockCheck struct {
name, risk, short, description, url string
tags, remediation []string
}
func (c *mockCheck) GetName() string {
return c.name
}
func (c *mockCheck) GetRisk() string {
return c.risk
}
func (c *mockCheck) GetShort() string {
return c.short
}
func (c *mockCheck) GetDescription() string {
return c.description
}
func (c *mockCheck) GetRemediation() []string {
return c.remediation
}
func (c *mockCheck) GetTags() []string {
l := make([]string, len(c.tags))
for i := range c.tags {
l[i] = strings.TrimSpace(c.tags[i])
}
return l
}
func (c *mockCheck) GetDocumentationURL(commitish string) string {
return c.url
}
type mockDoc struct {
checks map[string]mockCheck
}
func (d *mockDoc) GetCheck(name string) (docs.CheckDoc, error) {
// nolint: gosimple
m, _ := d.checks[name]
return &m, nil
}
func (d *mockDoc) GetChecks() []docs.CheckDoc {
return nil
}
func (d *mockDoc) CheckExists(name string) bool {
_, exists := d.checks[name]
return exists
}

View File

@ -29,6 +29,7 @@ import (
"github.com/ossf/scorecard/v2/checker"
docs "github.com/ossf/scorecard/v2/docs/checks"
sce "github.com/ossf/scorecard/v2/errors"
)
type text struct {
@ -403,10 +404,9 @@ func (r *ScorecardResult) AsSARIF(showDetails bool, logLevel zapcore.Level,
// nolint
for i, check := range r.Checks {
doc, exists := checkDocs.Checks[check.Name]
if !exists {
panic(fmt.Sprintf("invalid doc: %s not present", check.Name))
doc, e := checkDocs.GetCheck(check.Name)
if e != nil {
return sce.Create(sce.ErrScorecardInternal, fmt.Sprintf("GetCheck: %v: %s", e, check.Name))
}
// Unclear what to use for PartialFingerprints.
@ -430,9 +430,9 @@ func (r *ScorecardResult) AsSARIF(showDetails bool, logLevel zapcore.Level,
// Create a header's rule.
// TODO: verify `\n` is viewable in GitHub.
rule := createSARIFRule(check.Name, checkID,
fmt.Sprintf("https://github.com/ossf/scorecard/blob/main/docs/checks.md#%s", strings.ToLower(check.Name)),
doc.Description, doc.Short,
tagsAsList(doc.Tags))
doc.GetDocumentationURL(r.Scorecard.CommitSHA),
doc.GetDescription(), doc.GetShort(),
doc.GetTags())
rules = append(rules, rule)
// Add default location if no locations are present.
@ -453,7 +453,8 @@ func (r *ScorecardResult) AsSARIF(showDetails bool, logLevel zapcore.Level,
encoder := json.NewEncoder(writer)
encoder.SetIndent("", " ")
if err := encoder.Encode(sarif); err != nil {
panic(err.Error())
// nolint: wrapcheck
return sce.Create(sce.ErrScorecardInternal, err.Error())
}
return nil

View File

@ -24,9 +24,43 @@ import (
"go.uber.org/zap/zapcore"
"github.com/ossf/scorecard/v2/checker"
"github.com/ossf/scorecard/v2/docs/checks"
)
func sarifMockDocRead() *mockDoc {
d := map[string]mockCheck{
"Check-Name": {
name: "Check-Name",
risk: "not used",
short: "short description",
description: "long description\n other line",
url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
tags: []string{"tag1", "tag2"},
remediation: []string{"not-used1", "not-used2"},
},
"Check-Name2": {
name: "Check-Name2",
risk: "not used",
short: "short description 2",
description: "long description\n other line 2",
url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name2",
tags: []string{" tag1 ", " tag2 ", "tag3"},
remediation: []string{"not-used1", "not-used2"},
},
"Check-Name3": {
name: "Check-Name3",
risk: "not used",
short: "short description 3",
description: "long description\n other line 3",
url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name3",
tags: []string{" tag1", " tag2", "tag3", "tag 4 "},
remediation: []string{"not-used1", "not-used2"},
},
}
m := mockDoc{checks: d}
return &m
}
//nolint
func TestSARIFOutput(t *testing.T) {
t.Parallel()
@ -48,13 +82,14 @@ func TestSARIFOutput(t *testing.T) {
panic(fmt.Errorf("time.Parse: %w", e))
}
checkDocs := sarifMockDocRead()
tests := []struct {
name string
expected string
showDetails bool
logLevel zapcore.Level
result ScorecardResult
checkDocs checks.Doc
minScore int
}{
{
@ -63,17 +98,6 @@ func TestSARIFOutput(t *testing.T) {
expected: "./testdata/check1.sarif",
logLevel: zapcore.DebugLevel,
minScore: checker.MaxResultScore,
checkDocs: checks.Doc{
Checks: map[string]checks.Check{
"Check-Name": {
Risk: "risk not used",
Short: "short description",
Description: "long description\n other line",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2 ",
},
},
},
result: ScorecardResult{
Repo: RepoInfo{
Name: repoName,
@ -112,17 +136,6 @@ func TestSARIFOutput(t *testing.T) {
expected: "./testdata/check2.sarif",
logLevel: zapcore.DebugLevel,
minScore: checker.MaxResultScore,
checkDocs: checks.Doc{
Checks: map[string]checks.Check{
"Check-Name": {
Risk: "risk not used",
Short: "short description",
Description: "long description\n other line",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2 ",
},
},
},
result: ScorecardResult{
Repo: RepoInfo{
Name: repoName,
@ -160,31 +173,6 @@ func TestSARIFOutput(t *testing.T) {
expected: "./testdata/check3.sarif",
logLevel: zapcore.InfoLevel,
minScore: checker.MaxResultScore,
checkDocs: checks.Doc{
Checks: map[string]checks.Check{
"Check-Name": {
Risk: "risk not used",
Short: "short description",
Description: "long description\n other line",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2 ",
},
"Check-Name2": {
Risk: "risk not used",
Short: "short description 2",
Description: "long description\n other line 2",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2, tag3 ",
},
"Check-Name3": {
Risk: "risk not used",
Short: "short description 3",
Description: "long description\n other line 3",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2, tag3, tag4 ",
},
},
},
result: ScorecardResult{
Repo: RepoInfo{
Name: repoName,
@ -276,31 +264,6 @@ func TestSARIFOutput(t *testing.T) {
expected: "./testdata/check4.sarif",
logLevel: zapcore.DebugLevel,
minScore: checker.MaxResultScore,
checkDocs: checks.Doc{
Checks: map[string]checks.Check{
"Check-Name": {
Risk: "risk not used",
Short: "short description",
Description: "long description\n other line",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2 ",
},
"Check-Name2": {
Risk: "risk not used",
Short: "short description 2",
Description: "long description\n other line 2",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2, tag3 ",
},
"Check-Name3": {
Risk: "risk not used",
Short: "short description 3",
Description: "long description\n other line 3",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2, tag3, tag4 ",
},
},
},
result: ScorecardResult{
Repo: RepoInfo{
Name: repoName,
@ -392,17 +355,6 @@ func TestSARIFOutput(t *testing.T) {
expected: "./testdata/check5.sarif",
logLevel: zapcore.WarnLevel,
minScore: 5,
checkDocs: checks.Doc{
Checks: map[string]checks.Check{
"Check-Name": {
Risk: "risk not used",
Short: "short description",
Description: "long description\n other line",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2 ",
},
},
},
result: ScorecardResult{
Repo: RepoInfo{
Name: repoName,
@ -441,17 +393,6 @@ func TestSARIFOutput(t *testing.T) {
expected: "./testdata/check6.sarif",
logLevel: zapcore.WarnLevel,
minScore: checker.MaxResultScore,
checkDocs: checks.Doc{
Checks: map[string]checks.Check{
"Check-Name": {
Risk: "risk not used",
Short: "short description",
Description: "long description\n other line",
Remediation: []string{"remediation not used"},
Tags: "tag1, tag2 ",
},
},
},
result: ScorecardResult{
Repo: RepoInfo{
Name: repoName,
@ -504,7 +445,7 @@ func TestSARIFOutput(t *testing.T) {
}
var result bytes.Buffer
err = tt.result.AsSARIF(tt.showDetails, tt.logLevel, &result, tt.checkDocs, tt.minScore)
err = tt.result.AsSARIF(tt.showDetails, tt.logLevel, &result, checkDocs, tt.minScore)
if err != nil {
t.Fatalf("%s: AsSARIF: %v", tt.name, err)
}

View File

@ -100,6 +100,10 @@ func RunScorecards(ctx context.Context,
Name: repo.URL(),
CommitSHA: commitSHA,
},
Scorecard: ScorecardInfo{
Version: GetVersion(),
CommitSHA: GetCommit(),
},
Date: time.Now(),
}
resultsCh := make(chan checker.CheckResult)

View File

@ -14,7 +14,9 @@
package pkg
import "runtime"
import (
"runtime"
)
// Base version information.
//

View File

@ -1,7 +1,7 @@
{
"date": "2021-08-25",
"repo": {
"name": "repo not used",
"name": "org/name",
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
},
"scorecard": {
@ -15,7 +15,11 @@
],
"score": 5,
"reason": "half score reason",
"name": "Check-Name"
"name": "Check-Name",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
"short": "short description for Check-Name"
}
}
],
"metadata": []

View File

@ -1,7 +1,7 @@
{
"date": "2021-08-25",
"repo": {
"name": "repo not used",
"name": "org/name",
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
},
"scorecard": {
@ -15,7 +15,11 @@
],
"score": 0,
"reason": "min score reason",
"name": "Check-Name"
"name": "Check-Name",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
"short": "short description for Check-Name"
}
}
],
"metadata": []

View File

@ -1,7 +1,7 @@
{
"date": "2021-08-25",
"repo": {
"name": "repo not used",
"name": "org/name",
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
},
"scorecard": {
@ -15,7 +15,11 @@
],
"score": 0,
"reason": "min result reason",
"name": "Check-Name"
"name": "Check-Name",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
"short": "short description for Check-Name"
}
},
{
"details": [
@ -23,7 +27,11 @@
],
"score": 0,
"reason": "min result reason",
"name": "Check-Name2"
"name": "Check-Name2",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name2",
"short": "short description for Check-Name2"
}
},
{
"details": [
@ -32,7 +40,11 @@
],
"score": -1,
"reason": "inconclusive reason",
"name": "Check-Name3"
"name": "Check-Name3",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name3",
"short": "short description for Check-Name3"
}
}
],
"metadata": []

View File

@ -86,7 +86,7 @@
"tag1",
"tag2",
"tag3",
"tag4"
"tag 4"
]
}
}

View File

@ -1,7 +1,7 @@
{
"date": "2021-08-25",
"repo": {
"name": "repo not used",
"name": "org/name",
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
},
"scorecard": {
@ -15,7 +15,11 @@
],
"score": 0,
"reason": "min result reason",
"name": "Check-Name"
"name": "Check-Name",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
"short": "short description for Check-Name"
}
},
{
"details": [
@ -23,7 +27,11 @@
],
"score": 0,
"reason": "min result reason",
"name": "Check-Name2"
"name": "Check-Name2",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name2",
"short": "short description for Check-Name2"
}
},
{
"details": [
@ -33,7 +41,11 @@
],
"score": -1,
"reason": "inconclusive reason",
"name": "Check-Name3"
"name": "Check-Name3",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name3",
"short": "short description for Check-Name3"
}
}
],
"metadata": []

View File

@ -86,7 +86,7 @@
"tag1",
"tag2",
"tag3",
"tag4"
"tag 4"
]
}
}

View File

@ -1,7 +1,7 @@
{
"date": "2021-08-25",
"repo": {
"name": "repo not used",
"name": "org/name",
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
},
"scorecard": {
@ -15,7 +15,11 @@
],
"score": 6,
"reason": "six score reason",
"name": "Check-Name"
"name": "Check-Name",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
"short": "short description for Check-Name"
}
}
],
"metadata": []

View File

@ -1,7 +1,7 @@
{
"date": "2021-08-25",
"repo": {
"name": "repo not used",
"name": "org/name",
"commit": "68bc59901773ab4c051dfcea0cc4201a1567ab32"
},
"scorecard": {
@ -15,7 +15,11 @@
],
"score": 6,
"reason": "six score reason",
"name": "Check-Name"
"name": "Check-Name",
"documentation": {
"url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md#check-name",
"short": "short description for Check-Name"
}
}
],
"metadata": []