Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ scdiff: generate cmd skeleton #3275

Merged
merged 11 commits into from
Jul 18, 2023
34 changes: 34 additions & 0 deletions cmd/internal/scdiff/app/format/format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2023 OpenSSF 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 format

import (
"os"

"github.com/ossf/scorecard/v4/docs/checks"
"github.com/ossf/scorecard/v4/log"
"github.com/ossf/scorecard/v4/pkg"
)

//nolint:wrapcheck
func JSON(r *pkg.ScorecardResult) error {
const details = true
docs, err := checks.Read()
if err != nil {
return err
}
// TODO standardize the input, and output it to a file
spencerschrock marked this conversation as resolved.
Show resolved Hide resolved
return r.AsJSON2(details, log.DefaultLevel, docs, os.Stdout)
}
64 changes: 64 additions & 0 deletions cmd/internal/scdiff/app/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2023 OpenSSF 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 app

import (
"bufio"
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/ossf/scorecard/v4/cmd/internal/scdiff/app/format"
"github.com/ossf/scorecard/v4/cmd/internal/scdiff/app/runner"
)

//nolint:gochecknoinits // common for cobra apps
func init() {
rootCmd.AddCommand(generateCmd)
generateCmd.PersistentFlags().StringVarP(&repoFile, "repos", "r", "", "path to newline-delimited repo file")
}

var (
repoFile string

generateCmd = &cobra.Command{
Use: "generate [flags] repofile",
Short: "Generate Scorecard results for diffing",
Long: `Generate Scorecard results for diffing`,
RunE: func(cmd *cobra.Command, args []string) error {
f, err := os.Open(repoFile)
if err != nil {
return fmt.Errorf("unable to open repo file: %w", err)
}
scorecardRunner := runner.New()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
results, err := scorecardRunner.Run(scanner.Text())
if err != nil {
return fmt.Errorf("running scorecard on %s: %w", scanner.Text(), err)
}
err = format.JSON(&results)
if err != nil {
return fmt.Errorf("formatting results: %w", err)
}
}
if err := scanner.Err(); err != nil {
return fmt.Errorf("reading repo file: %w", err)
}
return nil
},
}
)
35 changes: 35 additions & 0 deletions cmd/internal/scdiff/app/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2023 OpenSSF 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 app

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "scdiff",
Short: "Scorecard Diff",
Long: `Scorecard result diffing command line interface tool`,
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
67 changes: 67 additions & 0 deletions cmd/internal/scdiff/app/runner/runner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2023 OpenSSF 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 runner

import (
"context"
"fmt"
"os"

"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/checks"
"github.com/ossf/scorecard/v4/clients"
"github.com/ossf/scorecard/v4/clients/githubrepo"
"github.com/ossf/scorecard/v4/clients/ossfuzz"
"github.com/ossf/scorecard/v4/log"
"github.com/ossf/scorecard/v4/pkg"
)

const (
commit = clients.HeadSHA
commitDepth = 0 // default
)

type Runner struct {
spencerschrock marked this conversation as resolved.
Show resolved Hide resolved
ctx context.Context
enabledChecks checker.CheckNameToFnMap
repoClient clients.RepoClient
ossFuzz clients.RepoClient
cii clients.CIIBestPracticesClient
vuln clients.VulnerabilitiesClient
}

func New() Runner {
ctx := context.Background()
logger := log.NewLogger(log.DefaultLevel)
return Runner{
ctx: ctx,
repoClient: githubrepo.CreateGithubRepoClient(ctx, logger),
ossFuzz: ossfuzz.CreateOSSFuzzClient(ossfuzz.StatusURL),
cii: clients.DefaultCIIBestPracticesClient(),
vuln: clients.DefaultVulnerabilitiesClient(),
enabledChecks: checks.GetAll(),
}
}

//nolint:wrapcheck
func (r *Runner) Run(repoURI string) (pkg.ScorecardResult, error) {
fmt.Fprintf(os.Stdout, "running for repo: %v\n", repoURI)
spencerschrock marked this conversation as resolved.
Show resolved Hide resolved
// TODO (gitlab?)
repo, err := githubrepo.MakeGithubRepo(repoURI)
if err != nil {
return pkg.ScorecardResult{}, err
}
return pkg.RunScorecard(r.ctx, repo, commit, commitDepth, r.enabledChecks, r.repoClient, r.ossFuzz, r.cii, r.vuln)
}
54 changes: 54 additions & 0 deletions cmd/internal/scdiff/app/runner/runner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2023 OpenSSF 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 runner

import (
"testing"

"github.com/golang/mock/gomock"

"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/clients"
mockrepo "github.com/ossf/scorecard/v4/clients/mockclients"
)

func TestNew(t *testing.T) {
r := New()
if len(r.enabledChecks) == 0 {
t.Errorf("runner has no checks to run: %v", r.enabledChecks)
}
}

func TestRunner_Run(t *testing.T) {
ctrl := gomock.NewController(t)
mockRepo := mockrepo.NewMockRepoClient(ctrl)
commit := []clients.Commit{{SHA: "foo"}}
mockRepo.EXPECT().ListCommits().Return(commit, nil)
mockRepo.EXPECT().InitRepo(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
mockRepo.EXPECT().GetDefaultBranchName().Return("main", nil)
mockRepo.EXPECT().Close().Return(nil)
r := Runner{
enabledChecks: checker.CheckNameToFnMap{},
repoClient: mockRepo,
}
const repo = "github.com/foo/bar"
result, err := r.Run(repo)
if err != nil {
t.Errorf("unexpected test error: %v", err)
}
if result.Repo.Name != repo {
t.Errorf("got: %v, wanted: %v", result.Repo.Name, repo)
}
}
21 changes: 21 additions & 0 deletions cmd/internal/scdiff/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2023 OpenSSF 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 main

import "github.com/ossf/scorecard/v4/cmd/internal/scdiff/app"

func main() {
app.Execute()
}