Skip to content

Commit

Permalink
fix: load git context info centrally
Browse files Browse the repository at this point in the history
  • Loading branch information
didroe committed Nov 20, 2023
1 parent 9e30d5f commit 1f15253
Show file tree
Hide file tree
Showing 19 changed files with 649 additions and 384 deletions.
57 changes: 27 additions & 30 deletions internal/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"github.com/bearer/bearer/internal/flag"
"github.com/bearer/bearer/internal/report/basebranchfindings"
reportoutput "github.com/bearer/bearer/internal/report/output"
"github.com/bearer/bearer/internal/report/output/saas"
"github.com/bearer/bearer/internal/report/output/stats"
outputtypes "github.com/bearer/bearer/internal/report/output/types"
scannerstats "github.com/bearer/bearer/internal/scanner/stats"
Expand Down Expand Up @@ -60,8 +59,6 @@ type Runner interface {
Scan(ctx context.Context, opts flag.Options) ([]files.File, *basebranchfindings.Findings, error)
// Report a writes a report
Report(files []files.File, baseBranchFindings *basebranchfindings.Findings) (bool, error)
// Close closes runner
Close(ctx context.Context) error
}

type runner struct {
Expand All @@ -71,26 +68,29 @@ type runner struct {
goclocResult *gocloc.Result
scanSettings settings.Config
stats *scannerstats.Stats
gitContext *gitrepository.Context
}

// NewRunner initializes Runner that provides scanning functionalities.
func NewRunner(
ctx context.Context,
scanSettings settings.Config,
gitContext *gitrepository.Context,
targetPath string,
goclocResult *gocloc.Result,
stats *scannerstats.Stats,
) Runner {
) (Runner, error) {
r := &runner{
scanSettings: scanSettings,
targetPath: targetPath,
goclocResult: goclocResult,
stats: stats,
gitContext: gitContext,
}

scanID, err := scanid.Build(scanSettings)
scanID, err := scanid.Build(scanSettings, gitContext)
if err != nil {
log.Error().Msgf("failed to build scan id for caching %s", err)
return nil, fmt.Errorf("failed to build scan id for caching: %w", err)
}

path := os.TempDir() + "/bearer" + scanID
Expand All @@ -101,13 +101,13 @@ func NewRunner(
log.Debug().Msgf("creating report %s", path)

if _, err := os.Stat(completedPath); err == nil {
if !scanSettings.Scan.Force && scanSettings.Scan.DiffBaseBranch == "" {
if !scanSettings.Scan.Force {
// force is not set, and we are not running a diff scan
r.reuseDetection = true
log.Debug().Msgf("reuse detection for %s", path)
r.reportPath = completedPath

return r
return r, nil
} else {
if _, err = os.Stat(path); err == nil {
err := os.Remove(path)
Expand All @@ -131,18 +131,13 @@ func NewRunner(
log.Error().Msgf("failed to create path %s, %s, %#v", path, err.Error(), pathCreated)
}

return r
return r, nil
}

func (r *runner) CacheUsed() bool {
return r.reuseDetection
}

// Close closes everything
func (r *runner) Close(ctx context.Context) error {
return nil
}

func (r *runner) Scan(ctx context.Context, opts flag.Options) ([]files.File, *basebranchfindings.Findings, error) {
if r.reuseDetection {
return nil, nil, nil
Expand All @@ -152,7 +147,7 @@ func (r *runner) Scan(ctx context.Context, opts flag.Options) ([]files.File, *ba
outputhandler.StdErrLog(fmt.Sprintf("Scanning target %s", opts.Target))
}

repository, err := gitrepository.New(ctx, r.scanSettings, r.targetPath, opts.DiffBaseBranch)
repository, err := gitrepository.New(ctx, r.scanSettings, r.targetPath, r.gitContext)
if err != nil {
return nil, nil, fmt.Errorf("git repository error: %w", err)
}
Expand All @@ -176,7 +171,7 @@ func (r *runner) Scan(ctx context.Context, opts flag.Options) ([]files.File, *ba
var baseBranchFindings *basebranchfindings.Findings
if err := repository.WithBaseBranch(func() error {
if !opts.Quiet {
outputhandler.StdErrLog(fmt.Sprintf("\nScanning base branch %s", opts.DiffBaseBranch))
outputhandler.StdErrLog(fmt.Sprintf("\nScanning base branch %s", r.gitContext.BaseBranch))
}

baseBranchFindings, err = r.scanBaseBranch(orchestrator, fileList)
Expand Down Expand Up @@ -220,7 +215,7 @@ func (r *runner) scanBaseBranch(
HasFiles: len(fileList.BaseFiles) != 0,
}

reportData, err := reportoutput.GetData(report, r.scanSettings, nil)
reportData, err := reportoutput.GetData(report, r.scanSettings, r.gitContext, nil)
if err != nil {
return nil, err
}
Expand All @@ -234,7 +229,7 @@ func (r *runner) scanBaseBranch(
return result, nil
}

func getIgnoredFingerprints(client *api.API, settings settings.Config) (
func getIgnoredFingerprints(client *api.API, settings settings.Config, gitContext *gitrepository.Context) (
useCloudIgnores bool,
ignoredFingerprints map[string]ignoretypes.IgnoredFingerprint,
staleIgnoredFingerprintIds []string,
Expand All @@ -246,15 +241,9 @@ func getIgnoredFingerprints(client *api.API, settings settings.Config) (
}

if client != nil && client.Error == nil {
// get ignores from Cloud
vcsInfo, err := saas.GetVCSInfo(settings.Scan.Target)
if err != nil {
return useCloudIgnores, ignoredFingerprints, staleIgnoredFingerprintIds, err
}

useCloudIgnores, ignoredFingerprints, staleIgnoredFingerprintIds, err = ignore.GetIgnoredFingerprintsFromCloud(
client,
vcsInfo.FullName,
gitContext.FullName,
localIgnoredFingerprints,
)
if err != nil {
Expand Down Expand Up @@ -296,6 +285,11 @@ func Run(ctx context.Context, opts flag.Options) (err error) {
version_check.DisplayBinaryVersionWarning(versionMeta, opts.ScanOptions.Quiet)
}

gitContext, err := gitrepository.NewContext(&opts)
if err != nil {
return fmt.Errorf("failed to get git context: %w", err)
}

if !opts.Quiet {
outputhandler.StdErrLog("Loading rules")
}
Expand All @@ -308,6 +302,7 @@ func Run(ctx context.Context, opts flag.Options) (err error) {
scanSettings.CloudIgnoresUsed, scanSettings.IgnoredFingerprints, scanSettings.StaleIgnoredFingerprintIds, err = getIgnoredFingerprints(
opts.GeneralOptions.Client,
scanSettings,
gitContext,
)
if err != nil {
return err
Expand All @@ -327,12 +322,14 @@ func Run(ctx context.Context, opts flag.Options) (err error) {
stats = scannerstats.New()
}

r := NewRunner(ctx, scanSettings, targetPath, inputgocloc, stats)
defer r.Close(ctx)
r, err := NewRunner(ctx, scanSettings, gitContext, targetPath, inputgocloc, stats)
if err != nil {
return err
}

files, baseBranchFindings, err := r.Scan(ctx, opts)
if err != nil {
return fmt.Errorf("scan error: %w", err)
return err
}

reportFailed, err := r.Report(files, baseBranchFindings)
Expand Down Expand Up @@ -393,11 +390,11 @@ func (r *runner) Report(
outputhandler.StdErrLog("Using cached data")
}

reportData, err := reportoutput.GetData(report, r.scanSettings, baseBranchFindings)
reportData, err := reportoutput.GetData(report, r.scanSettings, r.gitContext, baseBranchFindings)
if err != nil {
return false, err
}
reportoutput.UploadReportToCloud(reportData, r.scanSettings)
reportoutput.UploadReportToCloud(reportData, r.scanSettings, r.gitContext)

endTime := time.Now()

Expand Down
25 changes: 12 additions & 13 deletions internal/commands/artifact/scanid/scanid.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,29 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"os/exec"
"sort"
"strings"

"github.com/google/uuid"
"github.com/rs/zerolog/log"

"github.com/bearer/bearer/cmd/bearer/build"
"github.com/bearer/bearer/internal/commands/process/gitrepository"
"github.com/bearer/bearer/internal/commands/process/settings"
"github.com/bearer/bearer/internal/util/file"
)

func Build(scanSettings settings.Config) (string, error) {
// we want head as project may contain new changes
cmd := exec.Command("git", "-C", scanSettings.Scan.Target, "rev-parse", "HEAD")
sha, err := cmd.Output()
func Build(scanSettings settings.Config, gitContext *gitrepository.Context) (string, error) {
var sha string
if gitContext != nil && !gitContext.HasUncommittedChanges {
if gitContext.BaseCommitHash == "" {
sha = gitContext.CurrentCommitHash
} else {
sha = gitContext.BaseCommitHash + "_" + gitContext.CurrentCommitHash
}
}

if err != nil {
log.Debug().Msgf("error getting git sha %s", err.Error())
sha = []byte(uuid.NewString())
if sha == "" {
sha = uuid.NewString()
}

configHash, err := hashConfig(scanSettings)
Expand Down Expand Up @@ -56,7 +59,6 @@ func hashConfig(scanSettings settings.Config) (string, error) {
}

targetHash := md5.Sum([]byte(absTarget))
baseBranchHash := md5.Sum([]byte(scanSettings.Scan.DiffBaseBranch))

hashBuilder := md5.New()
if _, err := hashBuilder.Write(targetHash[:]); err != nil {
Expand All @@ -68,9 +70,6 @@ func hashConfig(scanSettings settings.Config) (string, error) {
if _, err := hashBuilder.Write(scannersHash); err != nil {
return "", err
}
if _, err := hashBuilder.Write(baseBranchHash[:]); err != nil {
return "", err
}

return hex.EncodeToString(hashBuilder.Sum(nil)[:]), nil
}
Expand Down
13 changes: 6 additions & 7 deletions internal/commands/ignore.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/bearer/bearer/internal/commands/process/gitrepository"
"github.com/bearer/bearer/internal/flag"
"github.com/bearer/bearer/internal/report/output/saas"
"github.com/bearer/bearer/internal/util/ignore"
ignoretypes "github.com/bearer/bearer/internal/util/ignore/types"
"github.com/bearer/bearer/internal/util/output"
Expand Down Expand Up @@ -345,27 +345,26 @@ $ bearer ignore pull /path/to/your_project --api-key=XXXXX`,
}
}

// get project full name
vcsInfo, err := saas.GetVCSInfo(options.Target)
gitContext, err := gitrepository.NewContext(&options)
if err != nil {
return fmt.Errorf("error fetching project info: %s", err)
return fmt.Errorf("failed to get git context: %w", err)
}

data, err := options.GeneralOptions.Client.FetchIgnores(vcsInfo.FullName, []string{})
data, err := options.GeneralOptions.Client.FetchIgnores(gitContext.FullName, []string{})
if err != nil {
return fmt.Errorf("cloud error: %s", err)
}

if !data.ProjectFound {
// no project
cmd.Printf("Project %s not found in Cloud. Pull cancelled.", vcsInfo.FullName)
cmd.Printf("Project %s not found in Cloud. Pull cancelled.", gitContext.FullName)
return nil
}

cloudIgnoresCount := len(data.CloudIgnoredFingerprints)
if cloudIgnoresCount == 0 {
// project found but no ignores
cmd.Printf("No ignores for project %s found in the Cloud. Pull cancelled", vcsInfo.FullName)
cmd.Printf("No ignores for project %s found in the Cloud. Pull cancelled", gitContext.FullName)
return nil
}

Expand Down
Loading

0 comments on commit 1f15253

Please sign in to comment.