⚠️ Simplify RunScorecard with functional optionals (#4106)

* add options for other clients

Signed-off-by: Spencer Schrock <sschrock@google.com>

* set clients to defaults if not provided?

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix shadowing

Signed-off-by: Spencer Schrock <sschrock@google.com>

* call the underlying run function

Signed-off-by: Spencer Schrock <sschrock@google.com>

* add package client

Signed-off-by: Spencer Schrock <sschrock@google.com>

* run all checks if no checks or probes provided

Signed-off-by: Spencer Schrock <sschrock@google.com>

* add WithProbes option

Signed-off-by: Spencer Schrock <sschrock@google.com>

* make github repo type public

Signed-off-by: Spencer Schrock <sschrock@google.com>

* make gitlab repo type public

Signed-off-by: Spencer Schrock <sschrock@google.com>

* make local repo type public

Signed-off-by: Spencer Schrock <sschrock@google.com>

* switch WithChecks to accepting []string

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix linter

Signed-off-by: Spencer Schrock <sschrock@google.com>

* fix linter

Signed-off-by: Spencer Schrock <sschrock@google.com>

---------

Signed-off-by: Spencer Schrock <sschrock@google.com>
This commit is contained in:
Spencer Schrock 2024-06-10 15:59:29 -07:00 committed by GitHub
parent 2ed7e5e9fa
commit 6d8f701a9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
61 changed files with 300 additions and 167 deletions

View File

@ -228,13 +228,13 @@ type branchesHandler struct {
once *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
repourl *Repo
defaultBranchRef *clients.BranchRef
defaultBranchName string
ruleSets []*repoRuleSet
}
func (handler *branchesHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *branchesHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
handler.errSetup = nil

View File

@ -36,7 +36,7 @@ var _ = Describe("E2E TEST: githubrepo.branchesHandler", func() {
It("Should not have increased for HEAD query", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -51,7 +51,7 @@ var _ = Describe("E2E TEST: githubrepo.branchesHandler", func() {
It("Should fail for non-HEAD query", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: "de5224bbc56eceb7a25aece55d2d53bbc561ed2d",
@ -66,7 +66,7 @@ var _ = Describe("E2E TEST: githubrepo.branchesHandler", func() {
It("Should return the correct default branch", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -83,7 +83,7 @@ var _ = Describe("E2E TEST: githubrepo.branchesHandler", func() {
It("Should return a branch", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -98,7 +98,7 @@ var _ = Describe("E2E TEST: githubrepo.branchesHandler", func() {
It("Should return an error for nonexistent branch", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -114,7 +114,7 @@ var _ = Describe("E2E TEST: githubrepo.branchesHandler", func() {
It("Should return a branch", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -126,7 +126,7 @@ var _ = Describe("E2E TEST: githubrepo.branchesHandler", func() {
It("Should fail for non-HEAD query", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: "de5224bbc56eceb7a25aece55d2d53bbc561ed2d",

View File

@ -71,7 +71,7 @@ type checkRunsByRef = map[string][]clients.CheckRun
type checkrunsHandler struct {
client *github.Client
graphClient *githubv4.Client
repourl *repoURL
repourl *Repo
logger *log.Logger
checkData *checkRunsGraphqlData
setupOnce *sync.Once
@ -81,7 +81,7 @@ type checkrunsHandler struct {
errSetup error
}
func (handler *checkrunsHandler) init(ctx context.Context, repourl *repoURL, commitDepth int) {
func (handler *checkrunsHandler) init(ctx context.Context, repourl *Repo, commitDepth int) {
handler.ctx = ctx
handler.repourl = repourl
handler.commitDepth = commitDepth

View File

@ -40,7 +40,7 @@ var _ = Describe("E2E TEST: githubrepo.checkrunsHandler", func() {
Context("E2E TEST: Validate query cost", func() {
It("Should not have increased query cost", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -54,7 +54,7 @@ var _ = Describe("E2E TEST: githubrepo.checkrunsHandler", func() {
})
Context("E2E TEST: listCheckRunsForRef", func() {
It("Should return check runs for a valid ref", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -75,7 +75,7 @@ var _ = Describe("E2E TEST: githubrepo.checkrunsHandler", func() {
})
})
It("Should return an error for an invalid ref", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,

View File

@ -42,7 +42,7 @@ var (
// Client is GitHub-specific implementation of RepoClient.
type Client struct {
repourl *repoURL
repourl *Repo
repo *github.Repository
repoClient *github.Client
graphClient *graphqlHandler
@ -66,7 +66,7 @@ const defaultGhHost = "github.com"
// InitRepo sets up the GitHub repo in local storage for improving performance and GitHub token usage efficiency.
func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth int) error {
ghRepo, ok := inputRepo.(*repoURL)
ghRepo, ok := inputRepo.(*Repo)
if !ok {
return fmt.Errorf("%w: %v", errInputRepoType, inputRepo)
}
@ -81,7 +81,7 @@ func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitD
}
client.commitDepth = commitDepth
client.repo = repo
client.repourl = &repoURL{
client.repourl = &Repo{
owner: repo.Owner.GetLogin(),
repo: repo.GetName(),
defaultBranch: repo.GetDefaultBranch(),

View File

@ -30,11 +30,11 @@ type contributorsHandler struct {
once *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
repourl *Repo
contributors []clients.User
}
func (handler *contributorsHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *contributorsHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
handler.errSetup = nil

View File

@ -45,7 +45,7 @@ var _ = Describe("E2E TEST: githubrepo.contributorsHandler", func() {
Context("getContributors()", func() {
skipIfTokenIsNot(patTokenType, "PAT only")
It("returns contributors for valid HEAD query", func() {
repoURL := repoURL{
repoURL := Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,

View File

@ -140,14 +140,14 @@ type graphqlHandler struct {
setupOnce *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
repourl *Repo
commits []clients.Commit
issues []clients.Issue
archived bool
commitDepth int
}
func (handler *graphqlHandler) init(ctx context.Context, repourl *repoURL, commitDepth int) {
func (handler *graphqlHandler) init(ctx context.Context, repourl *Repo, commitDepth int) {
handler.ctx = ctx
handler.repourl = repourl
handler.data = new(graphqlData)

View File

@ -38,7 +38,7 @@ var _ = Describe("E2E TEST: githubrepo.graphqlHandler", func() {
Context("E2E TEST: Confirm Paging Commits Works", func() {
It("Should only have 1 commit", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -71,7 +71,7 @@ var _ = Describe("E2E TEST: githubrepo.graphqlHandler", func() {
Expect(len(commits)).Should(BeEquivalentTo(1))
})
It("Should have 30 commits", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -104,7 +104,7 @@ var _ = Describe("E2E TEST: githubrepo.graphqlHandler", func() {
Expect(len(commits)).Should(BeEquivalentTo(30))
})
It("Should have 101 commits", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -140,7 +140,7 @@ var _ = Describe("E2E TEST: githubrepo.graphqlHandler", func() {
Context("E2E TEST: Validate query cost", func() {
It("Should not have increased for HEAD query", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,
@ -152,7 +152,7 @@ var _ = Describe("E2E TEST: githubrepo.graphqlHandler", func() {
Expect(*graphqlhandler.data.RateLimit.Cost).Should(BeNumerically("<=", 1))
})
It("Should not have increased for commit query", func() {
repourl := &repoURL{
repourl := &Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: "de5224bbc56eceb7a25aece55d2d53bbc561ed2d",

View File

@ -43,7 +43,7 @@ func Test_getCommits_retry(t *testing.T) {
Transport: rt,
}),
}
handler.init(context.Background(), &repoURL{}, 1)
handler.init(context.Background(), &Repo{}, 1)
_, err := handler.getCommits()
if err == nil {
t.Error("expected error")

View File

@ -30,11 +30,11 @@ type languagesHandler struct {
once *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
repourl *Repo
languages []clients.Language
}
func (handler *languagesHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *languagesHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
handler.errSetup = nil

View File

@ -41,7 +41,7 @@ var _ = Describe("E2E TEST: githubrepo.languagesHandler", func() {
})
Context("listProgrammingLanguages()", func() {
It("returns a list of programming languages for a valid repository", func() {
repoURL := repoURL{
repoURL := Repo{
owner: "ossf",
repo: "scorecard",
}

View File

@ -31,11 +31,11 @@ type licensesHandler struct {
once *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
repourl *Repo
licenses []clients.License
}
func (handler *licensesHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *licensesHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
handler.errSetup = nil

View File

@ -44,7 +44,7 @@ var _ = Describe("E2E TEST: githubrepo.licensesHandler", func() {
})
Context("listLicenses()", func() {
It("returns licenses", func() {
repoURL := repoURL{
repoURL := Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,

View File

@ -31,11 +31,11 @@ type releasesHandler struct {
once *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
repourl *Repo
releases []clients.Release
}
func (handler *releasesHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *releasesHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
handler.errSetup = nil

View File

@ -44,7 +44,7 @@ var _ = Describe("E2E TEST: githubrepo.releasesHandler", func() {
})
Context("getReleases()", func() {
It("returns releases", func() {
repoURL := repoURL{
repoURL := Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,

View File

@ -24,14 +24,14 @@ import (
sce "github.com/ossf/scorecard/v5/errors"
)
type repoURL struct {
type Repo struct {
host, owner, repo, defaultBranch, commitSHA string
metadata []string
}
// Parses input string into repoURL struct.
// Accepts "owner/repo" or "github.com/owner/repo".
func (r *repoURL) parse(input string) error {
func (r *Repo) parse(input string) error {
var t string
const two = 2
@ -73,21 +73,21 @@ func (r *repoURL) parse(input string) error {
}
// URI implements Repo.URI().
func (r *repoURL) URI() string {
func (r *Repo) URI() string {
return fmt.Sprintf("%s/%s/%s", r.host, r.owner, r.repo)
}
func (r *repoURL) Host() string {
func (r *Repo) Host() string {
return r.host
}
// String implements Repo.String.
func (r *repoURL) String() string {
func (r *Repo) String() string {
return fmt.Sprintf("%s-%s-%s", r.host, r.owner, r.repo)
}
// IsValid implements Repo.IsValid.
func (r *repoURL) IsValid() error {
func (r *Repo) IsValid() error {
githubHost := os.Getenv("GH_HOST")
switch r.host {
case "github.com":
@ -103,16 +103,16 @@ func (r *repoURL) IsValid() error {
return nil
}
func (r *repoURL) AppendMetadata(metadata ...string) {
func (r *Repo) AppendMetadata(metadata ...string) {
r.metadata = append(r.metadata, metadata...)
}
// Metadata implements Repo.Metadata.
func (r *repoURL) Metadata() []string {
func (r *Repo) Metadata() []string {
return r.metadata
}
func (r *repoURL) commitExpression() string {
func (r *Repo) commitExpression() string {
if strings.EqualFold(r.commitSHA, clients.HeadSHA) {
// TODO(#575): Confirm that this works as expected.
return fmt.Sprintf("heads/%s", r.defaultBranch)
@ -123,7 +123,7 @@ func (r *repoURL) commitExpression() string {
// MakeGithubRepo takes input of form "owner/repo" or "github.com/owner/repo"
// and returns an implementation of clients.Repo interface.
func MakeGithubRepo(input string) (clients.Repo, error) {
var repo repoURL
var repo Repo
if err := repo.parse(input); err != nil {
return nil, fmt.Errorf("error during parse: %w", err)
}
@ -134,6 +134,6 @@ func MakeGithubRepo(input string) (clients.Repo, error) {
}
// Path() implements RepoClient.Path.
func (r *repoURL) Path() string {
func (r *Repo) Path() string {
return fmt.Sprintf("%s/%s", r.owner, r.repo)
}

View File

@ -24,13 +24,13 @@ func TestRepoURL_IsValid(t *testing.T) {
tests := []struct {
name string
inputURL string
expected repoURL
expected Repo
wantErr bool
ghHost bool
}{
{
name: "Valid http address",
expected: repoURL{
expected: Repo{
host: "github.com",
owner: "foo",
repo: "kubeflow",
@ -40,7 +40,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "Valid http address with trailing slash",
expected: repoURL{
expected: Repo{
host: "github.com",
owner: "foo",
repo: "kubeflow",
@ -50,7 +50,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "Non GitHub repository",
expected: repoURL{
expected: Repo{
host: "gitlab.com",
owner: "foo",
repo: "kubeflow",
@ -60,7 +60,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "GitHub repository",
expected: repoURL{
expected: Repo{
host: "github.com",
owner: "foo",
repo: "kubeflow",
@ -70,7 +70,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "GitHub repository with host",
expected: repoURL{
expected: Repo{
host: "github.com",
owner: "foo",
repo: "kubeflow",
@ -80,7 +80,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "Enterprise github repository with host",
expected: repoURL{
expected: Repo{
host: "github.corp.com",
owner: "corpfoo",
repo: "kubeflow",
@ -91,7 +91,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "Enterprise github repository",
expected: repoURL{
expected: Repo{
host: "github.corp.com",
owner: "corpfoo",
repo: "kubeflow",
@ -108,7 +108,7 @@ func TestRepoURL_IsValid(t *testing.T) {
t.Setenv("GH_HOST", "github.corp.com")
}
r := repoURL{
r := Repo{
host: tt.expected.host,
owner: tt.expected.owner,
repo: tt.expected.repo,
@ -119,7 +119,7 @@ func TestRepoURL_IsValid(t *testing.T) {
if err := r.IsValid(); (err != nil) != tt.wantErr {
t.Errorf("repoURL.IsValid() error = %v, wantErr %v", err, tt.wantErr)
}
if !tt.wantErr && !cmp.Equal(tt.expected, r, cmp.AllowUnexported(repoURL{})) {
if !tt.wantErr && !cmp.Equal(tt.expected, r, cmp.AllowUnexported(Repo{})) {
t.Errorf("Got diff: %s", cmp.Diff(tt.expected, r))
}
if !cmp.Equal(r.Host(), tt.expected.host) {

View File

@ -30,10 +30,10 @@ var errEmptyQuery = errors.New("search query is empty")
type searchHandler struct {
ghClient *github.Client
ctx context.Context
repourl *repoURL
repourl *Repo
}
func (handler *searchHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *searchHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
}

View File

@ -27,10 +27,10 @@ import (
type searchCommitsHandler struct {
ghClient *github.Client
ctx context.Context
repourl *repoURL
repourl *Repo
}
func (handler *searchCommitsHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *searchCommitsHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
}

View File

@ -27,13 +27,13 @@ func TestSearchCommitsBuildQuery(t *testing.T) {
searchReq clients.SearchCommitsOptions
expectedErrType error
name string
repourl *repoURL
repourl *Repo
expectedQuery string
hasError bool
}{
{
name: "Basic",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},
@ -44,7 +44,7 @@ func TestSearchCommitsBuildQuery(t *testing.T) {
},
{
name: "EmptyQuery",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},

View File

@ -27,13 +27,13 @@ func TestBuildQuery(t *testing.T) {
searchReq clients.SearchRequest
expectedErrType error
name string
repourl *repoURL
repourl *Repo
expectedQuery string
hasError bool
}{
{
name: "Basic",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},
@ -44,7 +44,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "EmptyQuery",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},
@ -54,7 +54,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithFilename",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},
@ -66,7 +66,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithPath",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},
@ -78,7 +78,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithFilenameAndPath",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},
@ -91,7 +91,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithFilenameAndPathWithSeparator",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
repo: "testrepo",
},

View File

@ -27,10 +27,10 @@ import (
type statusesHandler struct {
client *github.Client
ctx context.Context
repourl *repoURL
repourl *Repo
}
func (handler *statusesHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *statusesHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
}

View File

@ -44,7 +44,7 @@ var _ = Describe("E2E TEST: githubrepo.statusesHandler", func() {
})
Context("listStatuses()", func() {
It("returns statuses", func() {
repoURL := repoURL{
repoURL := Repo{
owner: "ossf",
repo: "scorecard",
commitSHA: clients.HeadSHA,

View File

@ -30,11 +30,11 @@ type webhookHandler struct {
once *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
repourl *Repo
webhook []clients.Webhook
}
func (handler *webhookHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *webhookHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
handler.errSetup = nil

View File

@ -78,7 +78,7 @@ func Test_listWebhooks(t *testing.T) {
ctx: ctx,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
repo: "foo",
commitSHA: clients.HeadSHA,

View File

@ -28,10 +28,10 @@ import (
type workflowsHandler struct {
client *github.Client
ctx context.Context
repourl *repoURL
repourl *Repo
}
func (handler *workflowsHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *workflowsHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
}

View File

@ -29,7 +29,7 @@ type branchesHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
defaultBranchRef *clients.BranchRef
queryProject fnProject
queryBranch fnQueryBranch
@ -38,7 +38,7 @@ type branchesHandler struct {
getApprovalConfiguration fnGetApprovalConfiguration
}
func (handler *branchesHandler) init(repourl *repoURL) {
func (handler *branchesHandler) init(repourl *Repo) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -83,7 +83,7 @@ func TestGetBranches(t *testing.T) {
handler := branchesHandler{
once: new(sync.Once),
repourl: &repoURL{
repourl: &Repo{
projectID: "5000",
},
queryBranch: func(pid interface{}, branch string,

View File

@ -27,10 +27,10 @@ var gitCommitHashRegex = regexp.MustCompile(`^[a-fA-F0-9]{40}$`)
type checkrunsHandler struct {
glClient *gitlab.Client
repourl *repoURL
repourl *Repo
}
func (handler *checkrunsHandler) init(repourl *repoURL) {
func (handler *checkrunsHandler) init(repourl *Repo) {
handler.repourl = repourl
}

View File

@ -76,7 +76,7 @@ func Test_CheckRuns(t *testing.T) {
glClient: client,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
commitSHA: clients.HeadSHA,
}

View File

@ -36,7 +36,7 @@ var (
)
type Client struct {
repourl *repoURL
repourl *Repo
repo *gitlab.Project
glClient *gitlab.Client
contributors *contributorsHandler
@ -74,7 +74,7 @@ func checkRepoInaccessible(repo *gitlab.Project) error {
// InitRepo sets up the GitLab project in local storage for improving performance and GitLab token usage efficiency.
func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth int) error {
glRepo, ok := inputRepo.(*repoURL)
glRepo, ok := inputRepo.(*Repo)
if !ok {
return fmt.Errorf("%w: %v", errInputRepoType, inputRepo)
}
@ -97,7 +97,7 @@ func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitD
client.commitDepth = commitDepth
}
client.repo = repo
client.repourl = &repoURL{
client.repourl = &Repo{
scheme: glRepo.scheme,
host: glRepo.host,
owner: glRepo.owner,

View File

@ -53,7 +53,7 @@ var _ = Describe("E2E TEST: gitlabrepo.client", func() {
client, err := CreateGitlabClient(context.Background(), repo.Host())
Expect(err).Should(BeNil())
glRepo, ok := repo.(*repoURL)
glRepo, ok := repo.(*Repo)
Expect(ok).Should(BeTrue())
// Sanity check.

View File

@ -117,7 +117,7 @@ func TestListCommits(t *testing.T) {
glClient: glclient,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
commitSHA: clients.HeadSHA,
}

View File

@ -30,12 +30,12 @@ type commitsHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
commitsRaw []*gitlab.Commit
commitDepth int
}
func (handler *commitsHandler) init(repourl *repoURL, commitDepth int) {
func (handler *commitsHandler) init(repourl *Repo, commitDepth int) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -121,7 +121,7 @@ func TestListRawCommits(t *testing.T) {
glClient: client,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
commitSHA: clients.HeadSHA,
}

View File

@ -30,11 +30,11 @@ type contributorsHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
contributors []clients.User
}
func (handler *contributorsHandler) init(repourl *repoURL) {
func (handler *contributorsHandler) init(repourl *Repo) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -64,7 +64,7 @@ func TestContributors(t *testing.T) {
return tt.users, nil
},
once: new(sync.Once),
repourl: &repoURL{
repourl: &Repo{
commitSHA: "HEAD",
},
}

View File

@ -33,10 +33,10 @@ type graphqlHandler struct {
client *http.Client
graphClient *graphql.Client
ctx context.Context
repourl *repoURL
repourl *Repo
}
func (handler *graphqlHandler) init(ctx context.Context, repourl *repoURL) {
func (handler *graphqlHandler) init(ctx context.Context, repourl *Repo) {
handler.ctx = ctx
handler.repourl = repourl
handler.err = nil

View File

@ -31,7 +31,7 @@ var _ = Describe("E2E TEST: gitlabrepo.graphqlHandler", func() {
repo, err := MakeGitlabRepo("gitlab.com/gitlab-org/gitlab")
Expect(err).Should(BeNil())
graphqlhandler.init(context.Background(), repo.(*repoURL))
graphqlhandler.init(context.Background(), repo.(*Repo))
data := graphqlData{}
path := fmt.Sprintf("%s/%s", graphqlhandler.repourl.owner, graphqlhandler.repourl.project)
@ -51,7 +51,7 @@ var _ = Describe("E2E TEST: gitlabrepo.graphqlHandler", func() {
repo, err := MakeGitlabRepo("gitlab.com/gitlab-org/gitlab")
Expect(err).Should(BeNil())
graphqlhandler.init(context.Background(), repo.(*repoURL))
graphqlhandler.init(context.Background(), repo.(*Repo))
data := graphqlData{}
path := fmt.Sprintf("%s/%s", graphqlhandler.repourl.owner, graphqlhandler.repourl.project)

View File

@ -28,11 +28,11 @@ type issuesHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
issues []clients.Issue
}
func (handler *issuesHandler) init(repourl *repoURL) {
func (handler *issuesHandler) init(repourl *Repo) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -109,7 +109,7 @@ func Test_listIssues(t *testing.T) {
glClient: client,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
commitSHA: clients.HeadSHA,
}

View File

@ -27,11 +27,11 @@ type languagesHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
languages []clients.Language
}
func (handler *languagesHandler) init(repourl *repoURL) {
func (handler *languagesHandler) init(repourl *Repo) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -29,11 +29,11 @@ type licensesHandler struct {
glProject *gitlab.Project
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
licenses []clients.License
}
func (handler *licensesHandler) init(repourl *repoURL, project *gitlab.Project) {
func (handler *licensesHandler) init(repourl *Repo, project *gitlab.Project) {
handler.repourl = repourl
handler.glProject = project
handler.errSetup = nil

View File

@ -26,12 +26,12 @@ type projectHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
createdAt time.Time
archived bool
}
func (handler *projectHandler) init(repourl *repoURL) {
func (handler *projectHandler) init(repourl *Repo) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -28,11 +28,11 @@ type releasesHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
releases []clients.Release
}
func (handler *releasesHandler) init(repourl *repoURL) {
func (handler *releasesHandler) init(repourl *Repo) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -30,7 +30,7 @@ import (
sce "github.com/ossf/scorecard/v5/errors"
)
type repoURL struct {
type Repo struct {
scheme string
host string
owner string
@ -52,7 +52,7 @@ var errInvalidGitlabRepoURL = errors.New("repo is not a gitlab repo")
The following input format is not supported:
* https://gitlab.<companyDomain:string>.com/projects/<projectID:int>
*/
func (r *repoURL) parse(input string) error {
func (r *Repo) parse(input string) error {
var t string
c := strings.Split(input, "/")
switch l := len(c); {
@ -104,21 +104,21 @@ func withDefaultScheme(uri string) string {
}
// URI implements Repo.URI().
func (r *repoURL) URI() string {
func (r *Repo) URI() string {
return fmt.Sprintf("%s/%s/%s", r.host, r.owner, r.project)
}
func (r *repoURL) Host() string {
func (r *Repo) Host() string {
return r.host
}
// String implements Repo.String.
func (r *repoURL) String() string {
func (r *Repo) String() string {
return fmt.Sprintf("%s-%s_%s", r.host, r.owner, r.project)
}
// IsValid implements Repo.IsValid.
func (r *repoURL) IsValid() error {
func (r *Repo) IsValid() error {
if strings.TrimSpace(r.owner) == "" || strings.TrimSpace(r.project) == "" {
return sce.WithMessage(sce.ErrInvalidURL, "expected full project url: "+r.URI())
}
@ -157,24 +157,24 @@ func (r *repoURL) IsValid() error {
return nil
}
func (r *repoURL) AppendMetadata(metadata ...string) {
func (r *Repo) AppendMetadata(metadata ...string) {
r.metadata = append(r.metadata, metadata...)
}
// Metadata implements Repo.Metadata.
func (r *repoURL) Metadata() []string {
func (r *Repo) Metadata() []string {
return r.metadata
}
// Path() implements RepoClient.Path.
func (r *repoURL) Path() string {
func (r *Repo) Path() string {
return fmt.Sprintf("%s/%s", r.owner, r.project)
}
// MakeGitlabRepo takes input of forms in parse and returns and implementation
// of clients.Repo interface.
func MakeGitlabRepo(input string) (clients.Repo, error) {
var repo repoURL
var repo Repo
if err := repo.parse(input); err != nil {
return nil, fmt.Errorf("error during parse: %w", err)
}

View File

@ -27,13 +27,13 @@ func TestRepoURL_IsValid(t *testing.T) {
tests := []struct {
name string
inputURL string
expected repoURL
expected Repo
wantErr bool
flagRequired bool
}{
{
name: "github repository",
expected: repoURL{
expected: Repo{
scheme: "https",
host: "https://github.com",
owner: "ossf",
@ -44,7 +44,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "GitHub project with 'gitlab.' in the title",
expected: repoURL{
expected: Repo{
scheme: "http",
host: "github.com",
owner: "foo",
@ -55,7 +55,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "valid gitlab project",
expected: repoURL{
expected: Repo{
host: "gitlab.com",
owner: "ossf-test",
project: "scorecard-check-binary-artifacts-e2e",
@ -65,7 +65,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "valid gitlab project",
expected: repoURL{
expected: Repo{
host: "gitlab.com",
owner: "ossf-test",
project: "scorecard-check-binary-artifacts-e2e",
@ -75,7 +75,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "valid https address with trailing slash",
expected: repoURL{
expected: Repo{
scheme: "https",
host: "gitlab.haskell.org",
owner: "haskell",
@ -86,7 +86,7 @@ func TestRepoURL_IsValid(t *testing.T) {
},
{
name: "valid hosted gitlab project",
expected: repoURL{
expected: Repo{
scheme: "https",
host: "salsa.debian.org",
owner: "webmaster-team",
@ -104,7 +104,7 @@ func TestRepoURL_IsValid(t *testing.T) {
}
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
r := repoURL{
r := Repo{
host: tt.expected.host,
owner: tt.expected.owner,
project: tt.expected.project,
@ -119,7 +119,7 @@ func TestRepoURL_IsValid(t *testing.T) {
return
}
t.Log(r.URI())
if !tt.wantErr && !cmp.Equal(tt.expected, r, cmpopts.IgnoreUnexported(repoURL{})) {
if !tt.wantErr && !cmp.Equal(tt.expected, r, cmpopts.IgnoreUnexported(Repo{})) {
t.Logf("expected: %s GOT: %s", tt.expected.host, r.host)
t.Logf("expected: %s GOT: %s", tt.expected.owner, r.owner)
t.Logf("expected: %s GOT: %s", tt.expected.project, r.project)
@ -244,7 +244,7 @@ func TestRepoURL_parse_GL_HOST(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Setenv("GL_HOST", tt.glHost)
var r repoURL
var r Repo
err := r.parse(tt.url)
if (err != nil) != tt.wantErr {
t.Fatalf("wanted err: %t, got: %v", tt.wantErr, err)

View File

@ -28,10 +28,10 @@ var errEmptyQuery = errors.New("search query is empty")
type searchHandler struct {
glClient *gitlab.Client
repourl *repoURL
repourl *Repo
}
func (handler *searchHandler) init(repourl *repoURL) {
func (handler *searchHandler) init(repourl *Repo) {
handler.repourl = repourl
}

View File

@ -25,10 +25,10 @@ import (
type searchCommitsHandler struct {
glClient *gitlab.Client
repourl *repoURL
repourl *Repo
}
func (handler *searchCommitsHandler) init(repourl *repoURL) {
func (handler *searchCommitsHandler) init(repourl *Repo) {
handler.repourl = repourl
}

View File

@ -27,13 +27,13 @@ func TestSearchCommitsBuildQuery(t *testing.T) {
searchReq clients.SearchCommitsOptions
expectedErrType error
name string
repourl *repoURL
repourl *Repo
expectedQuery string
hasError bool
}{
{
name: "Basic",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},
@ -44,7 +44,7 @@ func TestSearchCommitsBuildQuery(t *testing.T) {
},
{
name: "EmptyQuery:",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},

View File

@ -31,13 +31,13 @@ func TestBuildQuery(t *testing.T) {
searchReq clients.SearchRequest
expectedErrType error
name string
repourl *repoURL
repourl *Repo
expectedQuery string
hasError bool
}{
{
name: "Basic",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},
@ -48,7 +48,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "EmptyQuery",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},
@ -58,7 +58,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithFilename",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},
@ -70,7 +70,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithPath",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},
@ -82,7 +82,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithFilenameAndPath",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},
@ -95,7 +95,7 @@ func TestBuildQuery(t *testing.T) {
},
{
name: "WithFilenameAndPathWithSeparator",
repourl: &repoURL{
repourl: &Repo{
owner: "testowner",
projectID: "1234",
},
@ -184,7 +184,7 @@ func Test_search(t *testing.T) {
glClient: client,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
commitSHA: clients.HeadSHA,
}

View File

@ -24,10 +24,10 @@ import (
type statusesHandler struct {
glClient *gitlab.Client
repourl *repoURL
repourl *Repo
}
func (handler *statusesHandler) init(repourl *repoURL) {
func (handler *statusesHandler) init(repourl *Repo) {
handler.repourl = repourl
}

View File

@ -69,7 +69,7 @@ func Test_listStatuses(t *testing.T) {
glClient: client,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
commitSHA: clients.HeadSHA,
}

View File

@ -69,7 +69,7 @@ type tarballHandler struct {
once *sync.Once
ctx context.Context
repo *gitlab.Project
repourl *repoURL
repourl *Repo
commitSHA string
tempDir string
tempTarFile string
@ -83,7 +83,7 @@ type gitLabLint struct {
Valid bool `json:"valid"`
}
func (handler *tarballHandler) init(ctx context.Context, repourl *repoURL, repo *gitlab.Project, commitSHA string) {
func (handler *tarballHandler) init(ctx context.Context, repourl *Repo, repo *gitlab.Project, commitSHA string) {
handler.errSetup = nil
handler.once = new(sync.Once)
handler.ctx = ctx

View File

@ -27,11 +27,11 @@ type webhookHandler struct {
glClient *gitlab.Client
once *sync.Once
errSetup error
repourl *repoURL
repourl *Repo
webhooks []clients.Webhook
}
func (handler *webhookHandler) init(repourl *repoURL) {
func (handler *webhookHandler) init(repourl *Repo) {
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)

View File

@ -85,7 +85,7 @@ func Test_listWebhooks(t *testing.T) {
glClient: client,
}
repoURL := repoURL{
repoURL := Repo{
owner: "ossf-tests",
commitSHA: clients.HeadSHA,
}

View File

@ -25,10 +25,10 @@ import (
type workflowsHandler struct {
glClient *gitlab.Client
repourl *repoURL
repourl *Repo
}
func (handler *workflowsHandler) init(repourl *repoURL) {
func (handler *workflowsHandler) init(repourl *Repo) {
handler.repourl = repourl
}

View File

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

View File

@ -27,27 +27,27 @@ import (
var errNotDirectory = errors.New("not a directory")
type repoLocal struct {
type Repo struct {
path string
metadata []string
}
// URI implements Repo.URI().
func (r *repoLocal) URI() string {
func (r *Repo) URI() string {
return fmt.Sprintf("file://%s", r.path)
}
func (r *repoLocal) Host() string {
func (r *Repo) Host() string {
return ""
}
// String implements Repo.String.
func (r *repoLocal) String() string {
func (r *Repo) String() string {
return r.URI()
}
// IsValid implements Repo.IsValid.
func (r *repoLocal) IsValid() error {
func (r *Repo) IsValid() error {
f, err := os.Stat(r.path)
if err != nil {
return fmt.Errorf("%w", err)
@ -60,24 +60,24 @@ func (r *repoLocal) IsValid() error {
}
// Metadata implements Repo.Metadata.
func (r *repoLocal) Metadata() []string {
func (r *Repo) Metadata() []string {
return []string{}
}
// AppendMetadata implements Repo.AppendMetadata.
func (r *repoLocal) AppendMetadata(m ...string) {
func (r *Repo) AppendMetadata(m ...string) {
r.metadata = append(r.metadata, m...)
}
// Path() implements RepoClient.Path.
func (r *repoLocal) Path() string {
func (r *Repo) Path() string {
return r.path
}
// MakeLocalDirRepo returns an implementation of clients.Repo interface.
func MakeLocalDirRepo(pathfn string) (clients.Repo, error) {
p := path.Clean(pathfn)
repo := &repoLocal{
repo := &Repo{
path: p,
}

View File

@ -29,6 +29,10 @@ import (
"github.com/ossf/scorecard/v5/checker"
"github.com/ossf/scorecard/v5/clients"
"github.com/ossf/scorecard/v5/clients/githubrepo"
"github.com/ossf/scorecard/v5/clients/gitlabrepo"
"github.com/ossf/scorecard/v5/clients/localdir"
"github.com/ossf/scorecard/v5/clients/ossfuzz"
"github.com/ossf/scorecard/v5/config"
sce "github.com/ossf/scorecard/v5/errors"
"github.com/ossf/scorecard/v5/finding"
@ -36,6 +40,7 @@ import (
proberegistration "github.com/ossf/scorecard/v5/internal/probes"
sclog "github.com/ossf/scorecard/v5/log"
"github.com/ossf/scorecard/v5/options"
"github.com/ossf/scorecard/v5/policy"
)
// errEmptyRepository indicates the repository is empty.
@ -293,3 +298,131 @@ func ExperimentalRunProbes(ctx context.Context,
projectClient,
)
}
type runConfig struct {
client clients.RepoClient
vulnClient clients.VulnerabilitiesClient
ciiClient clients.CIIBestPracticesClient
projectClient packageclient.ProjectPackageClient
ossfuzzClient clients.RepoClient
checks []string
commit string
probes []string
commitDepth int
}
type Option func(*runConfig) error
func WithCommitDepth(depth int) Option {
return func(c *runConfig) error {
c.commitDepth = depth
return nil
}
}
func WithCommitSHA(sha string) Option {
return func(c *runConfig) error {
c.commit = sha
return nil
}
}
func WithChecks(checks []string) Option {
return func(c *runConfig) error {
c.checks = checks
return nil
}
}
func WithProbes(probes []string) Option {
return func(c *runConfig) error {
c.probes = probes
return nil
}
}
func WithRepoClient(client clients.RepoClient) Option {
return func(c *runConfig) error {
c.client = client
return nil
}
}
func WithOSSFuzzClient(client clients.RepoClient) Option {
return func(c *runConfig) error {
c.ossfuzzClient = client
return nil
}
}
func WithVulnerabilitiesClient(client clients.VulnerabilitiesClient) Option {
return func(c *runConfig) error {
c.vulnClient = client
return nil
}
}
func WithOpenSSFBestPraticesClient(client clients.CIIBestPracticesClient) Option {
return func(c *runConfig) error {
c.ciiClient = client
return nil
}
}
func Run(ctx context.Context, repo clients.Repo, opts ...Option) (ScorecardResult, error) {
// TODO logger
logger := sclog.NewLogger(sclog.InfoLevel)
c := runConfig{
commit: clients.HeadSHA,
}
for _, option := range opts {
if err := option(&c); err != nil {
return ScorecardResult{}, err
}
}
if c.ciiClient == nil {
c.ciiClient = clients.DefaultCIIBestPracticesClient()
}
if c.ossfuzzClient == nil {
c.ossfuzzClient = ossfuzz.CreateOSSFuzzClient(ossfuzz.StatusURL)
}
if c.vulnClient == nil {
c.vulnClient = clients.DefaultVulnerabilitiesClient()
}
if c.projectClient == nil {
c.projectClient = packageclient.CreateDepsDevClient()
}
var requiredRequestTypes []checker.RequestType
var err error
switch repo.(type) {
case *localdir.Repo:
requiredRequestTypes = append(requiredRequestTypes, checker.FileBased)
if c.client == nil {
c.client = localdir.CreateLocalDirClient(ctx, logger)
}
case *githubrepo.Repo:
if c.client == nil {
c.client = githubrepo.CreateGithubRepoClient(ctx, logger)
}
case *gitlabrepo.Repo:
if c.client == nil {
c.client, err = gitlabrepo.CreateGitlabClient(ctx, repo.Host())
if err != nil {
return ScorecardResult{}, fmt.Errorf("creating gitlab client: %w", err)
}
}
}
if !strings.EqualFold(c.commit, clients.HeadSHA) {
requiredRequestTypes = append(requiredRequestTypes, checker.CommitBased)
}
checksToRun, err := policy.GetEnabled(nil, c.checks, requiredRequestTypes)
if err != nil {
return ScorecardResult{}, fmt.Errorf("getting enabled checks: %w", err)
}
return runScorecard(ctx, repo, c.commit, c.commitDepth, checksToRun, c.probes,
c.client, c.ossfuzzClient, c.ciiClient, c.vulnClient, c.projectClient)
}