Skip to content

Commit

Permalink
✨ allow incomplete localdir checks (ossf#3832)
Browse files Browse the repository at this point in the history
  • Loading branch information
lharrison13 committed Nov 27, 2024
1 parent ea7cbdc commit d6cf58a
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 38 deletions.
2 changes: 1 addition & 1 deletion checks/dangerous_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const CheckDangerousWorkflow = "Dangerous-Workflow"
//nolint:gochecknoinits
func init() {
supportedRequestTypes := []checker.RequestType{
checker.FileBased,
checker.CommitBased,
checker.FileBased,
}
if err := registerCheck(CheckDangerousWorkflow, DangerousWorkflow, supportedRequestTypes); err != nil {
// this should never happen
Expand Down
5 changes: 4 additions & 1 deletion checks/fuzzing.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ const CheckFuzzing = "Fuzzing"

//nolint:gochecknoinits
func init() {
if err := registerCheck(CheckFuzzing, Fuzzing, nil); err != nil {
supportedRequestTypes := []checker.RequestType{
checker.FileBased,
}
if err := registerCheck(CheckFuzzing, Fuzzing, supportedRequestTypes); err != nil {
// this should never happen
panic(err)
}
Expand Down
1 change: 1 addition & 0 deletions checks/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const CheckLicense = "License"
func init() {
supportedRequestTypes := []checker.RequestType{
checker.CommitBased,
checker.FileBased,
}
if err := registerCheck(CheckLicense, License, supportedRequestTypes); err != nil {
// this should never happen
Expand Down
23 changes: 20 additions & 3 deletions checks/packaging.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/ossf/scorecard/v5/checks/raw/gitlab"
"github.com/ossf/scorecard/v5/clients/githubrepo"
"github.com/ossf/scorecard/v5/clients/gitlabrepo"
"github.com/ossf/scorecard/v5/clients/localdir"
sce "github.com/ossf/scorecard/v5/errors"
"github.com/ossf/scorecard/v5/probes"
"github.com/ossf/scorecard/v5/probes/zrunner"
Expand All @@ -31,18 +32,34 @@ const CheckPackaging = "Packaging"

//nolint:gochecknoinits
func init() {
if err := registerCheck(CheckPackaging, Packaging, nil); err != nil {
supportedRequestTypes := []checker.RequestType{
checker.FileBased,
}
if err := registerCheck(CheckPackaging, Packaging, supportedRequestTypes); err != nil {
// this should never happen
panic(err)
}
}

// Packaging runs Packaging check.
func Packaging(c *checker.CheckRequest) checker.CheckResult {
var rawData checker.PackagingData
var err error
var rawData, rawDataGithub, rawDataGitlab checker.PackagingData
var err, errG, errGL error

switch v := c.RepoClient.(type) {
case *localdir.LocalDirClient:
// Performing both packaging checks since we dont know when local
rawDataGithub, errG = github.Packaging(c)
rawDataGitlab, errGL = gitlab.Packaging(c)
// Appending results of checks
rawData.Packages = append(rawData.Packages, rawDataGithub.Packages...)
rawData.Packages = append(rawData.Packages, rawDataGitlab.Packages...)
// checking for errors
if errG != nil {
err = errG
} else if errGL != nil {
err = errGL
}
case *githubrepo.Client:
rawData, err = github.Packaging(c)
case *gitlabrepo.Client:
Expand Down
2 changes: 1 addition & 1 deletion checks/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const CheckTokenPermissions = "Token-Permissions"
//nolint:gochecknoinits
func init() {
supportedRequestTypes := []checker.RequestType{
checker.FileBased,
checker.CommitBased,
checker.FileBased,
}
if err := registerCheck(CheckTokenPermissions, TokenPermissions, supportedRequestTypes); err != nil {
// This should never happen.
Expand Down
2 changes: 1 addition & 1 deletion checks/pinned_dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const CheckPinnedDependencies = "Pinned-Dependencies"
//nolint:gochecknoinits
func init() {
supportedRequestTypes := []checker.RequestType{
checker.FileBased,
checker.CommitBased,
checker.FileBased,
}
if err := registerCheck(CheckPinnedDependencies, PinningDependencies, supportedRequestTypes); err != nil {
// This should never happen.
Expand Down
5 changes: 5 additions & 0 deletions checks/raw/fuzzing.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package raw

import (
"bytes"
"errors"
"fmt"
"regexp"
"strings"
Expand Down Expand Up @@ -208,6 +209,10 @@ func Fuzzing(c *checker.CheckRequest) (checker.FuzzingData, error) {

langs, err := c.RepoClient.ListProgrammingLanguages()
if err != nil {
// ListProgrammingLanguages is unsupported by local client so just return
if errors.Is(err, clients.ErrUnsupportedFeature) {
return checker.FuzzingData{Fuzzers: detectedFuzzers}, nil
}
return checker.FuzzingData{}, fmt.Errorf("cannot get langs of repo: %w", err)
}
prominentLangs := getProminentLanguages(langs)
Expand Down
9 changes: 8 additions & 1 deletion checks/raw/github/packaging.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package github

import (
"errors"
"fmt"
"io"
"path/filepath"
Expand All @@ -23,6 +24,7 @@ import (

"github.com/ossf/scorecard/v5/checker"
"github.com/ossf/scorecard/v5/checks/fileparser"
"github.com/ossf/scorecard/v5/clients"
"github.com/ossf/scorecard/v5/finding"
)

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

runs, err := c.RepoClient.ListSuccessfulWorkflowRuns(filepath.Base(fp))
if err != nil {
return data, fmt.Errorf("Client.Actions.ListWorkflowRunsByFileName: %w", err)
// appending empty run for localdir client
if errors.Is(err, clients.ErrUnsupportedFeature) {
runs = append(runs, clients.WorkflowRun{})
} else {
return data, fmt.Errorf("Client.Actions.ListWorkflowRunsByFileName: %w", err)
}
}

if len(runs) > 0 {
Expand Down
5 changes: 5 additions & 0 deletions checks/raw/sast.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (

"github.com/ossf/scorecard/v5/checker"
"github.com/ossf/scorecard/v5/checks/fileparser"
"github.com/ossf/scorecard/v5/clients"
sce "github.com/ossf/scorecard/v5/errors"
"github.com/ossf/scorecard/v5/finding"
)
Expand Down Expand Up @@ -92,6 +93,10 @@ func sastToolInCheckRuns(c *checker.CheckRequest) ([]checker.SASTCommit, error)
var sastCommits []checker.SASTCommit
commits, err := c.RepoClient.ListCommits()
if err != nil {
// ignoring check for local dir
if errors.Is(err, clients.ErrUnsupportedFeature) {
return sastCommits, nil
}
return sastCommits,
sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("RepoClient.ListCommits: %v", err))
}
Expand Down
4 changes: 3 additions & 1 deletion checks/raw/security_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ func SecurityPolicy(c *checker.CheckRequest) (checker.SecurityPolicyData, error)
case errors.Is(err, sce.ErrRepoUnreachable), errors.Is(err, clients.ErrUnsupportedFeature):
break
default:
return checker.SecurityPolicyData{}, err
if !errors.Is(err, clients.ErrUnsupportedFeature) {
return checker.SecurityPolicyData{}, err
}
}

// Return raw results.
Expand Down
5 changes: 4 additions & 1 deletion checks/sast.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ const CheckSAST = "SAST"

//nolint:gochecknoinits
func init() {
if err := registerCheck(CheckSAST, SAST, nil); err != nil {
supportedRequestTypes := []checker.RequestType{
checker.FileBased,
}
if err := registerCheck(CheckSAST, SAST, supportedRequestTypes); err != nil {
// This should never happen.
panic(err)
}
Expand Down
1 change: 1 addition & 0 deletions checks/security_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const CheckSecurityPolicy = "Security-Policy"
func init() {
supportedRequestTypes := []checker.RequestType{
checker.CommitBased,
checker.FileBased,
}
if err := registerCheck(CheckSecurityPolicy, SecurityPolicy, supportedRequestTypes); err != nil {
// This should never happen.
Expand Down
54 changes: 27 additions & 27 deletions clients/localdir/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ import (
)

var (
_ clients.RepoClient = &localDirClient{}
_ clients.RepoClient = &LocalDirClient{}
errInputRepoType = errors.New("input repo should be of type repoLocal")
)

//nolint:govet
type localDirClient struct {
type LocalDirClient struct {
logger *log.Logger
ctx context.Context
path string
Expand All @@ -50,7 +50,7 @@ type localDirClient struct {
}

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

// URI implements RepoClient.URI.
func (client *localDirClient) URI() string {
func (client *LocalDirClient) URI() string {
return fmt.Sprintf("file://%s", client.path)
}

// IsArchived implements RepoClient.IsArchived.
func (client *localDirClient) IsArchived() (bool, error) {
func (client *LocalDirClient) IsArchived() (bool, error) {
return false, fmt.Errorf("IsArchived: %w", clients.ErrUnsupportedFeature)
}

Expand Down Expand Up @@ -148,7 +148,7 @@ func applyPredicate(
}

// LocalPath implements RepoClient.LocalPath.
func (client *localDirClient) LocalPath() (string, error) {
func (client *LocalDirClient) LocalPath() (string, error) {
clientPath, err := filepath.Abs(client.path)
if err != nil {
return "", fmt.Errorf("error during filepath.Abs: %w", err)
Expand All @@ -157,7 +157,7 @@ func (client *localDirClient) LocalPath() (string, error) {
}

// ListFiles implements RepoClient.ListFiles.
func (client *localDirClient) ListFiles(predicate func(string) (bool, error)) ([]string, error) {
func (client *LocalDirClient) ListFiles(predicate func(string) (bool, error)) ([]string, error) {
client.once.Do(func() {
client.files, client.errFiles = listFiles(client.path)
})
Expand All @@ -175,102 +175,102 @@ func getFile(clientpath, filename string) (*os.File, error) {
}

// GetFileReader implements RepoClient.GetFileReader.
func (client *localDirClient) GetFileReader(filename string) (io.ReadCloser, error) {
func (client *LocalDirClient) GetFileReader(filename string) (io.ReadCloser, error) {
return getFile(client.path, filename)
}

// GetBranch implements RepoClient.GetBranch.
func (client *localDirClient) GetBranch(branch string) (*clients.BranchRef, error) {
func (client *LocalDirClient) GetBranch(branch string) (*clients.BranchRef, error) {
return nil, fmt.Errorf("ListBranches: %w", clients.ErrUnsupportedFeature)
}

// GetDefaultBranch implements RepoClient.GetDefaultBranch.
func (client *localDirClient) GetDefaultBranch() (*clients.BranchRef, error) {
func (client *LocalDirClient) GetDefaultBranch() (*clients.BranchRef, error) {
return nil, fmt.Errorf("GetDefaultBranch: %w", clients.ErrUnsupportedFeature)
}

// GetDefaultBranchName implements RepoClient.GetDefaultBranchName.
func (client *localDirClient) GetDefaultBranchName() (string, error) {
func (client *LocalDirClient) GetDefaultBranchName() (string, error) {
return "", fmt.Errorf("GetDefaultBranchName: %w", clients.ErrUnsupportedFeature)
}

// ListCommits implements RepoClient.ListCommits.
func (client *localDirClient) ListCommits() ([]clients.Commit, error) {
func (client *LocalDirClient) ListCommits() ([]clients.Commit, error) {
return nil, fmt.Errorf("ListCommits: %w", clients.ErrUnsupportedFeature)
}

// ListIssues implements RepoClient.ListIssues.
func (client *localDirClient) ListIssues() ([]clients.Issue, error) {
func (client *LocalDirClient) ListIssues() ([]clients.Issue, error) {
return nil, fmt.Errorf("ListIssues: %w", clients.ErrUnsupportedFeature)
}

// ListReleases implements RepoClient.ListReleases.
func (client *localDirClient) ListReleases() ([]clients.Release, error) {
func (client *LocalDirClient) ListReleases() ([]clients.Release, error) {
return nil, fmt.Errorf("ListReleases: %w", clients.ErrUnsupportedFeature)
}

// ListContributors implements RepoClient.ListContributors.
func (client *localDirClient) ListContributors() ([]clients.User, error) {
func (client *LocalDirClient) ListContributors() ([]clients.User, error) {
return nil, fmt.Errorf("ListContributors: %w", clients.ErrUnsupportedFeature)
}

// ListSuccessfulWorkflowRuns implements RepoClient.WorkflowRunsByFilename.
func (client *localDirClient) ListSuccessfulWorkflowRuns(filename string) ([]clients.WorkflowRun, error) {
func (client *LocalDirClient) ListSuccessfulWorkflowRuns(filename string) ([]clients.WorkflowRun, error) {
return nil, fmt.Errorf("ListSuccessfulWorkflowRuns: %w", clients.ErrUnsupportedFeature)
}

// ListCheckRunsForRef implements RepoClient.ListCheckRunsForRef.
func (client *localDirClient) ListCheckRunsForRef(ref string) ([]clients.CheckRun, error) {
func (client *LocalDirClient) ListCheckRunsForRef(ref string) ([]clients.CheckRun, error) {
return nil, fmt.Errorf("ListCheckRunsForRef: %w", clients.ErrUnsupportedFeature)
}

// ListStatuses implements RepoClient.ListStatuses.
func (client *localDirClient) ListStatuses(ref string) ([]clients.Status, error) {
func (client *LocalDirClient) ListStatuses(ref string) ([]clients.Status, error) {
return nil, fmt.Errorf("ListStatuses: %w", clients.ErrUnsupportedFeature)
}

// ListWebhooks implements RepoClient.ListWebhooks.
func (client *localDirClient) ListWebhooks() ([]clients.Webhook, error) {
func (client *LocalDirClient) ListWebhooks() ([]clients.Webhook, error) {
return nil, fmt.Errorf("ListWebhooks: %w", clients.ErrUnsupportedFeature)
}

// Search implements RepoClient.Search.
func (client *localDirClient) Search(request clients.SearchRequest) (clients.SearchResponse, error) {
func (client *LocalDirClient) Search(request clients.SearchRequest) (clients.SearchResponse, error) {
return clients.SearchResponse{}, fmt.Errorf("Search: %w", clients.ErrUnsupportedFeature)
}

// SearchCommits implements RepoClient.SearchCommits.
func (client *localDirClient) SearchCommits(request clients.SearchCommitsOptions) ([]clients.Commit, error) {
func (client *LocalDirClient) SearchCommits(request clients.SearchCommitsOptions) ([]clients.Commit, error) {
return nil, fmt.Errorf("Search: %w", clients.ErrUnsupportedFeature)
}

func (client *localDirClient) Close() error {
func (client *LocalDirClient) Close() error {
return nil
}

// ListProgrammingLanguages implements RepoClient.ListProgrammingLanguages.
// TODO: add ListProgrammingLanguages support for local directories.
func (client *localDirClient) ListProgrammingLanguages() ([]clients.Language, error) {
func (client *LocalDirClient) ListProgrammingLanguages() ([]clients.Language, error) {
return nil, fmt.Errorf("ListProgrammingLanguages: %w", clients.ErrUnsupportedFeature)
}

// ListLicenses implements RepoClient.ListLicenses.
// TODO: add ListLicenses support for local directories.
func (client *localDirClient) ListLicenses() ([]clients.License, error) {
func (client *LocalDirClient) ListLicenses() ([]clients.License, error) {
return nil, fmt.Errorf("ListLicenses: %w", clients.ErrUnsupportedFeature)
}

func (client *localDirClient) GetCreatedAt() (time.Time, error) {
func (client *LocalDirClient) GetCreatedAt() (time.Time, error) {
return time.Time{}, fmt.Errorf("GetCreatedAt: %w", clients.ErrUnsupportedFeature)
}

func (client *localDirClient) GetOrgRepoClient(ctx context.Context) (clients.RepoClient, error) {
func (client *LocalDirClient) GetOrgRepoClient(ctx context.Context) (clients.RepoClient, error) {
return nil, fmt.Errorf("GetOrgRepoClient: %w", clients.ErrUnsupportedFeature)
}

// CreateLocalDirClient returns a client which implements RepoClient interface.
func CreateLocalDirClient(ctx context.Context, logger *log.Logger) clients.RepoClient {
return &localDirClient{
return &LocalDirClient{
ctx: ctx,
logger: logger,
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,11 @@ func rootCmd(o *options.Options) error {
}

var requiredRequestTypes []checker.RequestType
// if local option not set add file based
if o.Local != "" {
requiredRequestTypes = append(requiredRequestTypes, checker.FileBased)
}
// if commit option set to anything other than HEAD add commit based
if !strings.EqualFold(o.Commit, clients.HeadSHA) {
requiredRequestTypes = append(requiredRequestTypes, checker.CommitBased)
}
Expand Down
2 changes: 1 addition & 1 deletion policy/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func TestGetEnabled(t *testing.T) {
name: "request types limit enabled checks",
argsChecks: []string{},
requiredRequestTypes: []checker.RequestType{checker.FileBased, checker.CommitBased},
expectedEnabledChecks: 5, // All checks which are FileBased and CommitBased
expectedEnabledChecks: 7, // All checks which are FileBased and CommitBased
expectedError: false,
},
{
Expand Down

0 comments on commit d6cf58a

Please sign in to comment.