Skip to content

Commit cdfb58b

Browse files
authored
✨ Allow incomplete local checks (#4423)
* ✨ allow incomplete localdir checks (#3832) Signed-off-by: Luke Harrison <[email protected]> * ✨ fixes as per @spencerschrock (#3832) Signed-off-by: Luke Harrison <[email protected]> * ✨ fixed linting issues (#3832) Signed-off-by: Luke Harrison <[email protected]> --------- Signed-off-by: Luke Harrison <[email protected]> Signed-off-by: Luke Harrison <[email protected]>
1 parent cae6d48 commit cdfb58b

14 files changed

+88
-38
lines changed

checks/dangerous_workflow.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ const CheckDangerousWorkflow = "Dangerous-Workflow"
2929
//nolint:gochecknoinits
3030
func init() {
3131
supportedRequestTypes := []checker.RequestType{
32-
checker.FileBased,
3332
checker.CommitBased,
33+
checker.FileBased,
3434
}
3535
if err := registerCheck(CheckDangerousWorkflow, DangerousWorkflow, supportedRequestTypes); err != nil {
3636
// this should never happen

checks/fuzzing.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ const CheckFuzzing = "Fuzzing"
2828

2929
//nolint:gochecknoinits
3030
func init() {
31-
if err := registerCheck(CheckFuzzing, Fuzzing, nil); err != nil {
31+
supportedRequestTypes := []checker.RequestType{
32+
checker.FileBased,
33+
}
34+
if err := registerCheck(CheckFuzzing, Fuzzing, supportedRequestTypes); err != nil {
3235
// this should never happen
3336
panic(err)
3437
}

checks/license.go

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const CheckLicense = "License"
3030
func init() {
3131
supportedRequestTypes := []checker.RequestType{
3232
checker.CommitBased,
33+
checker.FileBased,
3334
}
3435
if err := registerCheck(CheckLicense, License, supportedRequestTypes); err != nil {
3536
// this should never happen

checks/packaging.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/ossf/scorecard/v5/checks/raw/gitlab"
2222
"github.com/ossf/scorecard/v5/clients/githubrepo"
2323
"github.com/ossf/scorecard/v5/clients/gitlabrepo"
24+
"github.com/ossf/scorecard/v5/clients/localdir"
2425
sce "github.com/ossf/scorecard/v5/errors"
2526
"github.com/ossf/scorecard/v5/probes"
2627
"github.com/ossf/scorecard/v5/probes/zrunner"
@@ -31,18 +32,34 @@ const CheckPackaging = "Packaging"
3132

3233
//nolint:gochecknoinits
3334
func init() {
34-
if err := registerCheck(CheckPackaging, Packaging, nil); err != nil {
35+
supportedRequestTypes := []checker.RequestType{
36+
checker.FileBased,
37+
}
38+
if err := registerCheck(CheckPackaging, Packaging, supportedRequestTypes); err != nil {
3539
// this should never happen
3640
panic(err)
3741
}
3842
}
3943

4044
// Packaging runs Packaging check.
4145
func Packaging(c *checker.CheckRequest) checker.CheckResult {
42-
var rawData checker.PackagingData
43-
var err error
46+
var rawData, rawDataGithub, rawDataGitlab checker.PackagingData
47+
var err, errGithub, errGitlab error
4448

4549
switch v := c.RepoClient.(type) {
50+
case *localdir.Client:
51+
// Performing both packaging checks since we dont know when local
52+
rawDataGithub, errGithub = github.Packaging(c)
53+
rawDataGitlab, errGitlab = gitlab.Packaging(c)
54+
// Appending results of checks
55+
rawData.Packages = append(rawData.Packages, rawDataGithub.Packages...)
56+
rawData.Packages = append(rawData.Packages, rawDataGitlab.Packages...)
57+
// checking for errors
58+
if errGithub != nil {
59+
err = errGithub
60+
} else if errGitlab != nil {
61+
err = errGitlab
62+
}
4663
case *githubrepo.Client:
4764
rawData, err = github.Packaging(c)
4865
case *gitlabrepo.Client:

checks/permissions.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ const CheckTokenPermissions = "Token-Permissions"
2929
//nolint:gochecknoinits
3030
func init() {
3131
supportedRequestTypes := []checker.RequestType{
32-
checker.FileBased,
3332
checker.CommitBased,
33+
checker.FileBased,
3434
}
3535
if err := registerCheck(CheckTokenPermissions, TokenPermissions, supportedRequestTypes); err != nil {
3636
// This should never happen.

checks/pinned_dependencies.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ const CheckPinnedDependencies = "Pinned-Dependencies"
2929
//nolint:gochecknoinits
3030
func init() {
3131
supportedRequestTypes := []checker.RequestType{
32-
checker.FileBased,
3332
checker.CommitBased,
33+
checker.FileBased,
3434
}
3535
if err := registerCheck(CheckPinnedDependencies, PinningDependencies, supportedRequestTypes); err != nil {
3636
// This should never happen.

checks/raw/fuzzing.go

+10
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ func getProminentLanguages(langs []clients.Language) []clients.LanguageName {
338338
numLangs := len(langs)
339339
if numLangs == 0 {
340340
return nil
341+
} else if len(langs) == 1 && langs[0].Name == clients.All {
342+
return getAllLanguages()
341343
}
342344
totalLoC := 0
343345
// Use a map to record languages and their lines of code to drop potential duplicates.
@@ -361,6 +363,14 @@ func getProminentLanguages(langs []clients.Language) []clients.LanguageName {
361363
return ret
362364
}
363365

366+
func getAllLanguages() []clients.LanguageName {
367+
allLanguages := make([]clients.LanguageName, 0, len(languageFuzzSpecs))
368+
for l := range languageFuzzSpecs {
369+
allLanguages = append(allLanguages, l)
370+
}
371+
return allLanguages
372+
}
373+
364374
func propertyBasedDescription(language string) *string {
365375
s := fmt.Sprintf("Property-based testing in %s generates test instances randomly or exhaustively "+
366376
"and test that specific properties are satisfied.", language)

checks/raw/github/packaging.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package github
1616

1717
import (
18+
"errors"
1819
"fmt"
1920
"io"
2021
"path/filepath"
@@ -23,6 +24,7 @@ import (
2324

2425
"github.com/ossf/scorecard/v5/checker"
2526
"github.com/ossf/scorecard/v5/checks/fileparser"
27+
"github.com/ossf/scorecard/v5/clients"
2628
"github.com/ossf/scorecard/v5/finding"
2729
)
2830

@@ -73,7 +75,12 @@ func Packaging(c *checker.CheckRequest) (checker.PackagingData, error) {
7375

7476
runs, err := c.RepoClient.ListSuccessfulWorkflowRuns(filepath.Base(fp))
7577
if err != nil {
76-
return data, fmt.Errorf("Client.Actions.ListWorkflowRunsByFileName: %w", err)
78+
// assume the workflow will have run for localdir client
79+
if errors.Is(err, clients.ErrUnsupportedFeature) {
80+
runs = append(runs, clients.WorkflowRun{})
81+
} else {
82+
return data, fmt.Errorf("Client.Actions.ListWorkflowRunsByFileName: %w", err)
83+
}
7784
}
7885

7986
if len(runs) > 0 {

checks/raw/sast.go

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
"github.com/ossf/scorecard/v5/checker"
3030
"github.com/ossf/scorecard/v5/checks/fileparser"
31+
"github.com/ossf/scorecard/v5/clients"
3132
sce "github.com/ossf/scorecard/v5/errors"
3233
"github.com/ossf/scorecard/v5/finding"
3334
)
@@ -92,6 +93,10 @@ func sastToolInCheckRuns(c *checker.CheckRequest) ([]checker.SASTCommit, error)
9293
var sastCommits []checker.SASTCommit
9394
commits, err := c.RepoClient.ListCommits()
9495
if err != nil {
96+
// ignoring check for local dir
97+
if errors.Is(err, clients.ErrUnsupportedFeature) {
98+
return sastCommits, nil
99+
}
95100
return sastCommits,
96101
sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("RepoClient.ListCommits: %v", err))
97102
}

checks/sast.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ const CheckSAST = "SAST"
2828

2929
//nolint:gochecknoinits
3030
func init() {
31-
if err := registerCheck(CheckSAST, SAST, nil); err != nil {
31+
supportedRequestTypes := []checker.RequestType{
32+
checker.FileBased,
33+
}
34+
if err := registerCheck(CheckSAST, SAST, supportedRequestTypes); err != nil {
3235
// This should never happen.
3336
panic(err)
3437
}

checks/security_policy.go

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const CheckSecurityPolicy = "Security-Policy"
3030
func init() {
3131
supportedRequestTypes := []checker.RequestType{
3232
checker.CommitBased,
33+
checker.FileBased,
3334
}
3435
if err := registerCheck(CheckSecurityPolicy, SecurityPolicy, supportedRequestTypes); err != nil {
3536
// This should never happen.

clients/localdir/client.go

+29-28
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ import (
3434
)
3535

3636
var (
37-
_ clients.RepoClient = &localDirClient{}
37+
_ clients.RepoClient = &Client{}
3838
errInputRepoType = errors.New("input repo should be of type repoLocal")
3939
)
4040

4141
//nolint:govet
42-
type localDirClient struct {
42+
type Client struct {
4343
logger *log.Logger
4444
ctx context.Context
4545
path string
@@ -50,7 +50,7 @@ type localDirClient struct {
5050
}
5151

5252
// InitRepo sets up the local repo.
53-
func (client *localDirClient) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth int) error {
53+
func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth int) error {
5454
localRepo, ok := inputRepo.(*Repo)
5555
if !ok {
5656
return fmt.Errorf("%w: %v", errInputRepoType, inputRepo)
@@ -66,12 +66,12 @@ func (client *localDirClient) InitRepo(inputRepo clients.Repo, commitSHA string,
6666
}
6767

6868
// URI implements RepoClient.URI.
69-
func (client *localDirClient) URI() string {
69+
func (client *Client) URI() string {
7070
return fmt.Sprintf("file://%s", client.path)
7171
}
7272

7373
// IsArchived implements RepoClient.IsArchived.
74-
func (client *localDirClient) IsArchived() (bool, error) {
74+
func (client *Client) IsArchived() (bool, error) {
7575
return false, fmt.Errorf("IsArchived: %w", clients.ErrUnsupportedFeature)
7676
}
7777

@@ -148,7 +148,7 @@ func applyPredicate(
148148
}
149149

150150
// LocalPath implements RepoClient.LocalPath.
151-
func (client *localDirClient) LocalPath() (string, error) {
151+
func (client *Client) LocalPath() (string, error) {
152152
clientPath, err := filepath.Abs(client.path)
153153
if err != nil {
154154
return "", fmt.Errorf("error during filepath.Abs: %w", err)
@@ -157,7 +157,7 @@ func (client *localDirClient) LocalPath() (string, error) {
157157
}
158158

159159
// ListFiles implements RepoClient.ListFiles.
160-
func (client *localDirClient) ListFiles(predicate func(string) (bool, error)) ([]string, error) {
160+
func (client *Client) ListFiles(predicate func(string) (bool, error)) ([]string, error) {
161161
client.once.Do(func() {
162162
client.files, client.errFiles = listFiles(client.path)
163163
})
@@ -175,102 +175,103 @@ func getFile(clientpath, filename string) (*os.File, error) {
175175
}
176176

177177
// GetFileReader implements RepoClient.GetFileReader.
178-
func (client *localDirClient) GetFileReader(filename string) (io.ReadCloser, error) {
178+
func (client *Client) GetFileReader(filename string) (io.ReadCloser, error) {
179179
return getFile(client.path, filename)
180180
}
181181

182182
// GetBranch implements RepoClient.GetBranch.
183-
func (client *localDirClient) GetBranch(branch string) (*clients.BranchRef, error) {
183+
func (client *Client) GetBranch(branch string) (*clients.BranchRef, error) {
184184
return nil, fmt.Errorf("ListBranches: %w", clients.ErrUnsupportedFeature)
185185
}
186186

187187
// GetDefaultBranch implements RepoClient.GetDefaultBranch.
188-
func (client *localDirClient) GetDefaultBranch() (*clients.BranchRef, error) {
188+
func (client *Client) GetDefaultBranch() (*clients.BranchRef, error) {
189189
return nil, fmt.Errorf("GetDefaultBranch: %w", clients.ErrUnsupportedFeature)
190190
}
191191

192192
// GetDefaultBranchName implements RepoClient.GetDefaultBranchName.
193-
func (client *localDirClient) GetDefaultBranchName() (string, error) {
193+
func (client *Client) GetDefaultBranchName() (string, error) {
194194
return "", fmt.Errorf("GetDefaultBranchName: %w", clients.ErrUnsupportedFeature)
195195
}
196196

197197
// ListCommits implements RepoClient.ListCommits.
198-
func (client *localDirClient) ListCommits() ([]clients.Commit, error) {
198+
func (client *Client) ListCommits() ([]clients.Commit, error) {
199199
return nil, fmt.Errorf("ListCommits: %w", clients.ErrUnsupportedFeature)
200200
}
201201

202202
// ListIssues implements RepoClient.ListIssues.
203-
func (client *localDirClient) ListIssues() ([]clients.Issue, error) {
203+
func (client *Client) ListIssues() ([]clients.Issue, error) {
204204
return nil, fmt.Errorf("ListIssues: %w", clients.ErrUnsupportedFeature)
205205
}
206206

207207
// ListReleases implements RepoClient.ListReleases.
208-
func (client *localDirClient) ListReleases() ([]clients.Release, error) {
208+
func (client *Client) ListReleases() ([]clients.Release, error) {
209209
return nil, fmt.Errorf("ListReleases: %w", clients.ErrUnsupportedFeature)
210210
}
211211

212212
// ListContributors implements RepoClient.ListContributors.
213-
func (client *localDirClient) ListContributors() ([]clients.User, error) {
213+
func (client *Client) ListContributors() ([]clients.User, error) {
214214
return nil, fmt.Errorf("ListContributors: %w", clients.ErrUnsupportedFeature)
215215
}
216216

217217
// ListSuccessfulWorkflowRuns implements RepoClient.WorkflowRunsByFilename.
218-
func (client *localDirClient) ListSuccessfulWorkflowRuns(filename string) ([]clients.WorkflowRun, error) {
218+
func (client *Client) ListSuccessfulWorkflowRuns(filename string) ([]clients.WorkflowRun, error) {
219219
return nil, fmt.Errorf("ListSuccessfulWorkflowRuns: %w", clients.ErrUnsupportedFeature)
220220
}
221221

222222
// ListCheckRunsForRef implements RepoClient.ListCheckRunsForRef.
223-
func (client *localDirClient) ListCheckRunsForRef(ref string) ([]clients.CheckRun, error) {
223+
func (client *Client) ListCheckRunsForRef(ref string) ([]clients.CheckRun, error) {
224224
return nil, fmt.Errorf("ListCheckRunsForRef: %w", clients.ErrUnsupportedFeature)
225225
}
226226

227227
// ListStatuses implements RepoClient.ListStatuses.
228-
func (client *localDirClient) ListStatuses(ref string) ([]clients.Status, error) {
228+
func (client *Client) ListStatuses(ref string) ([]clients.Status, error) {
229229
return nil, fmt.Errorf("ListStatuses: %w", clients.ErrUnsupportedFeature)
230230
}
231231

232232
// ListWebhooks implements RepoClient.ListWebhooks.
233-
func (client *localDirClient) ListWebhooks() ([]clients.Webhook, error) {
233+
func (client *Client) ListWebhooks() ([]clients.Webhook, error) {
234234
return nil, fmt.Errorf("ListWebhooks: %w", clients.ErrUnsupportedFeature)
235235
}
236236

237237
// Search implements RepoClient.Search.
238-
func (client *localDirClient) Search(request clients.SearchRequest) (clients.SearchResponse, error) {
238+
func (client *Client) Search(request clients.SearchRequest) (clients.SearchResponse, error) {
239239
return clients.SearchResponse{}, fmt.Errorf("Search: %w", clients.ErrUnsupportedFeature)
240240
}
241241

242242
// SearchCommits implements RepoClient.SearchCommits.
243-
func (client *localDirClient) SearchCommits(request clients.SearchCommitsOptions) ([]clients.Commit, error) {
243+
func (client *Client) SearchCommits(request clients.SearchCommitsOptions) ([]clients.Commit, error) {
244244
return nil, fmt.Errorf("Search: %w", clients.ErrUnsupportedFeature)
245245
}
246246

247-
func (client *localDirClient) Close() error {
247+
func (client *Client) Close() error {
248248
return nil
249249
}
250250

251251
// ListProgrammingLanguages implements RepoClient.ListProgrammingLanguages.
252252
// TODO: add ListProgrammingLanguages support for local directories.
253-
func (client *localDirClient) ListProgrammingLanguages() ([]clients.Language, error) {
254-
return nil, fmt.Errorf("ListProgrammingLanguages: %w", clients.ErrUnsupportedFeature)
253+
func (client *Client) ListProgrammingLanguages() ([]clients.Language, error) {
254+
// for now just return all programming languages
255+
return []clients.Language{{Name: clients.All, NumLines: 1}}, nil
255256
}
256257

257258
// ListLicenses implements RepoClient.ListLicenses.
258259
// TODO: add ListLicenses support for local directories.
259-
func (client *localDirClient) ListLicenses() ([]clients.License, error) {
260+
func (client *Client) ListLicenses() ([]clients.License, error) {
260261
return nil, fmt.Errorf("ListLicenses: %w", clients.ErrUnsupportedFeature)
261262
}
262263

263-
func (client *localDirClient) GetCreatedAt() (time.Time, error) {
264+
func (client *Client) GetCreatedAt() (time.Time, error) {
264265
return time.Time{}, fmt.Errorf("GetCreatedAt: %w", clients.ErrUnsupportedFeature)
265266
}
266267

267-
func (client *localDirClient) GetOrgRepoClient(ctx context.Context) (clients.RepoClient, error) {
268+
func (client *Client) GetOrgRepoClient(ctx context.Context) (clients.RepoClient, error) {
268269
return nil, fmt.Errorf("GetOrgRepoClient: %w", clients.ErrUnsupportedFeature)
269270
}
270271

271272
// CreateLocalDirClient returns a client which implements RepoClient interface.
272273
func CreateLocalDirClient(ctx context.Context, logger *log.Logger) clients.RepoClient {
273-
return &localDirClient{
274+
return &Client{
274275
ctx: ctx,
275276
logger: logger,
276277
}

cmd/root.go

+2
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,11 @@ func rootCmd(o *options.Options) error {
118118
}
119119

120120
var requiredRequestTypes []checker.RequestType
121+
// if local option not set add file based
121122
if o.Local != "" {
122123
requiredRequestTypes = append(requiredRequestTypes, checker.FileBased)
123124
}
125+
// if commit option set to anything other than HEAD add commit based
124126
if !strings.EqualFold(o.Commit, clients.HeadSHA) {
125127
requiredRequestTypes = append(requiredRequestTypes, checker.CommitBased)
126128
}

policy/policy_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func TestGetEnabled(t *testing.T) {
333333
name: "request types limit enabled checks",
334334
argsChecks: []string{},
335335
requiredRequestTypes: []checker.RequestType{checker.FileBased, checker.CommitBased},
336-
expectedEnabledChecks: 5, // All checks which are FileBased and CommitBased
336+
expectedEnabledChecks: 7, // All checks which are FileBased and CommitBased
337337
expectedError: false,
338338
},
339339
{

0 commit comments

Comments
 (0)