diff --git a/internal/commands/artifact/run.go b/internal/commands/artifact/run.go index 22f0b1fa0..c65f4a075 100644 --- a/internal/commands/artifact/run.go +++ b/internal/commands/artifact/run.go @@ -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" @@ -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 { @@ -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 @@ -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) @@ -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 @@ -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) } @@ -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) @@ -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 } @@ -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, @@ -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 { @@ -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") } @@ -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 @@ -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) @@ -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() diff --git a/internal/commands/artifact/scanid/scanid.go b/internal/commands/artifact/scanid/scanid.go index bc4813034..0dbfef123 100644 --- a/internal/commands/artifact/scanid/scanid.go +++ b/internal/commands/artifact/scanid/scanid.go @@ -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) @@ -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 { @@ -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 } diff --git a/internal/commands/ignore.go b/internal/commands/ignore.go index eced3fdf8..c20b2a541 100644 --- a/internal/commands/ignore.go +++ b/internal/commands/ignore.go @@ -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" @@ -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 } diff --git a/internal/commands/process/gitrepository/context.go b/internal/commands/process/gitrepository/context.go new file mode 100644 index 000000000..2889afe87 --- /dev/null +++ b/internal/commands/process/gitrepository/context.go @@ -0,0 +1,261 @@ +package gitrepository + +import ( + "context" + "errors" + "fmt" + "net/url" + "strings" + + "github.com/gitsight/go-vcsurl" + "github.com/google/go-github/github" + "github.com/rs/zerolog/log" + "golang.org/x/oauth2" + + "github.com/bearer/bearer/internal/flag" + "github.com/bearer/bearer/internal/git" +) + +type Context struct { + RootDir string + CurrentBranch, + DefaultBranch, + BaseBranch string + CurrentCommitHash, + BaseCommitHash string + OriginURL string + ID, + Host, + Owner, + Name, + FullName string + HasUncommittedChanges bool +} + +func NewContext(options *flag.Options) (*Context, error) { + rootDir := git.GetRoot(options.Target) + if rootDir == "" { + return nil, nil + } + + currentBranch, err := getCurrentBranch(options, rootDir) + if err != nil { + return nil, fmt.Errorf("error getting current branch name: %w", err) + } + + defaultBranch, err := getDefaultBranch(options, rootDir) + if err != nil { + return nil, fmt.Errorf("error getting default branch name: %w", err) + } + + baseBranch, err := getBaseBranch(options) + if err != nil { + return nil, fmt.Errorf("error getting base branch name: %w", err) + } + + currentCommitHash, err := getCurrentCommitHash(options, rootDir) + if err != nil { + return nil, fmt.Errorf("error getting current commit hash: %w", err) + } + + baseCommitHash, err := getBaseCommitHash(options, rootDir, baseBranch, currentCommitHash) + if err != nil { + return nil, fmt.Errorf("error getting base commit hash: %w", err) + } + + hasUncommittedChanges, err := git.HasUncommittedChanges(rootDir) + if err != nil { + return nil, fmt.Errorf("error checking for uncommitted changes: %w", err) + } + + originURL, err := getOriginURL(options, rootDir) + if err != nil { + return nil, fmt.Errorf("error getting origin url: %w", err) + } + + var id, host, owner, name, fullName string + if originURL != "" { + urlInfo, err := vcsurl.Parse(originURL) + if err != nil { + return nil, fmt.Errorf("couldn't parse origin url: %w", err) + } + + id = urlInfo.ID + host = string(urlInfo.Host) + owner = urlInfo.Username + name = urlInfo.Name + fullName = urlInfo.FullName + } + + return &Context{ + RootDir: rootDir, + CurrentBranch: currentBranch, + DefaultBranch: defaultBranch, + BaseBranch: baseBranch, + CurrentCommitHash: currentCommitHash, + BaseCommitHash: baseCommitHash, + OriginURL: originURL, + ID: id, + Host: host, + Owner: owner, + Name: name, + FullName: fullName, + HasUncommittedChanges: hasUncommittedChanges, + }, nil +} + +func getCurrentBranch(options *flag.Options, rootDir string) (string, error) { + if options.CurrentBranch != "" { + return options.CurrentBranch, nil + } + + name, err := git.GetCurrentBranch(rootDir) + if err != nil { + return "", err + } + + return name, err +} + +func getDefaultBranch(options *flag.Options, rootDir string) (string, error) { + if options.DefaultBranch != "" { + return options.DefaultBranch, nil + } + + return git.GetDefaultBranch(rootDir) +} + +func getBaseBranch(options *flag.Options) (string, error) { + if !options.Diff { + return "", nil + } + + if options.DiffBaseBranch != "" { + return options.DiffBaseBranch, nil + } + + return "", errors.New( + "couldn't determine base branch for diff scanning. " + + "please set the 'BEARER_DIFF_BASE_BRANCH' environment variable", + ) +} + +func getCurrentCommitHash(options *flag.Options, rootDir string) (string, error) { + if options.CurrentCommit != "" { + return options.CurrentCommit, nil + } + + return git.GetCurrentCommit(rootDir) +} + +func getBaseCommitHash( + options *flag.Options, + rootDir string, + baseBranch string, + currentCommitHash string, +) (string, error) { + if baseBranch == "" { + return "", nil + } + + if options.DiffBaseCommit != "" { + return options.DiffBaseCommit, nil + } + + if hash, err := lookupBaseCommitHashFromGithub(options, baseBranch, currentCommitHash); hash != "" || err != nil { + return hash, err + } + + log.Debug().Msg("finding merge base using local repository") + hash, err := git.GetMergeBase(rootDir, "origin/"+baseBranch, currentCommitHash) + if err != nil { + if !strings.Contains(err.Error(), "Not a valid object name") { + return "", fmt.Errorf("invalid ref: %w", err) + } + } + + if hash != "" { + return hash, nil + } + + log.Debug().Msg("remote ref not found, trying local ref") + hash, err = git.GetMergeBase(rootDir, baseBranch, currentCommitHash) + if err != nil { + return "", fmt.Errorf("invalid ref: %w", err) + } + + if hash != "" { + return hash, nil + } + + return "", fmt.Errorf( + "could not find common ancestor between the current and %s branch. "+ + "please check that the base branch is correct, and that you have "+ + "fetched enough git history to include the latest common ancestor", + baseBranch, + ) +} + +func lookupBaseCommitHashFromGithub(options *flag.Options, baseBranch string, currentCommitHash string) (string, error) { + if options.GithubToken == "" || options.GithubRepository == "" { + return "", nil + } + + log.Debug().Msg("finding merge base using github api") + + splitRepository := strings.SplitN(options.GithubRepository, "/", 2) + if len(splitRepository) != 2 { + return "", fmt.Errorf("invalid github repository name '%s'", options.GithubRepository) + } + + client, err := newGithubClient(options) + if err != nil { + return "", err + } + + comparison, _, err := client.Repositories.CompareCommits( + context.Background(), + splitRepository[0], + splitRepository[1], + baseBranch, + currentCommitHash, + ) + if err != nil { + return "", fmt.Errorf("error calling github compare api: %w", err) + } + + if comparison.MergeBaseCommit == nil { + return "", nil + } + + return *comparison.MergeBaseCommit.SHA, nil +} + +func getOriginURL(options *flag.Options, rootDir string) (string, error) { + if options.OriginURL != "" { + return options.OriginURL, nil + } + + return git.GetOriginURL(rootDir) +} + +func newGithubClient(options *flag.Options) (*github.Client, error) { + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: options.GithubToken}) + httpClient := oauth2.NewClient(context.Background(), tokenSource) + client := github.NewClient(httpClient) + + if options.GithubAPIURL != "" { + parsedURL, err := url.Parse(options.GithubAPIURL) + if err != nil { + return nil, fmt.Errorf("failed to parse github api url: %w", err) + } + + if !strings.HasSuffix(parsedURL.Path, "/") { + parsedURL.Path += "/" + } + + client.BaseURL = parsedURL + } + + return client, nil +} diff --git a/internal/commands/process/gitrepository/gitrepository.go b/internal/commands/process/gitrepository/gitrepository.go index 7b6b08729..05bb36519 100644 --- a/internal/commands/process/gitrepository/gitrepository.go +++ b/internal/commands/process/gitrepository/gitrepository.go @@ -2,17 +2,13 @@ package gitrepository import ( "context" - "errors" "fmt" - "net/url" "os" "path/filepath" "strings" - "github.com/google/go-github/github" "github.com/hhatto/gocloc" "github.com/rs/zerolog/log" - "golang.org/x/oauth2" "github.com/bearer/bearer/internal/commands/process/filelist/files" "github.com/bearer/bearer/internal/commands/process/filelist/ignore" @@ -28,59 +24,31 @@ type Repository struct { rootPath, targetPath, gitTargetPath string - headBranch string - headCommitHash, - mergeBaseCommitHash string - githubToken string + context *Context } -func New( - ctx context.Context, - config settings.Config, - targetPath string, - baseBranch string, -) (*Repository, error) { - rootPath := git.GetRoot(targetPath) - if rootPath == "" { +func New(ctx context.Context, config settings.Config, targetPath string, context *Context) (*Repository, error) { + if context == nil { log.Debug().Msg("no git repository found") - - if baseBranch != "" { - return nil, errors.New("base branch specified but no git repository found") - } - return nil, nil } - gitTargetPath, err := filepath.Rel(rootPath, targetPath) + gitTargetPath, err := filepath.Rel(context.RootDir, targetPath) if err != nil { return nil, fmt.Errorf("failed to get relative target: %w", err) } - log.Debug().Msgf("git target: [%s/]%s", rootPath, gitTargetPath) - - headCommitHash, err := git.GetCurrentCommit(rootPath) - if err != nil { - return nil, fmt.Errorf("error getting head ref: %w", err) - } - - headBranch, err := git.GetCurrentBranch(rootPath) - if err != nil { - return nil, fmt.Errorf("error getting head ref: %w", err) - } + log.Debug().Msgf("git target: [%s/]%s", context.RootDir, gitTargetPath) repository := &Repository{ - ctx: ctx, - config: config, - rootPath: rootPath, - targetPath: targetPath, - gitTargetPath: gitTargetPath, - headBranch: headBranch, - headCommitHash: headCommitHash, - githubToken: config.Scan.GithubToken, + ctx: ctx, + config: config, + targetPath: targetPath, + gitTargetPath: gitTargetPath, + context: context, } - repository.mergeBaseCommitHash, err = repository.fetchMergeBaseCommit(baseBranch) - if err != nil { + if err = repository.fetchMergeBaseCommit(); err != nil { return nil, err } @@ -95,57 +63,43 @@ func (repository *Repository) ListFiles( return nil, nil } - if repository.mergeBaseCommitHash == "" { - return repository.getTreeFiles(ignore, goclocResult, repository.headCommitHash) + if repository.context.BaseCommitHash == "" { + return repository.getCurrentFiles(ignore, goclocResult) } return repository.getDiffFiles(ignore, goclocResult) } -func (repository *Repository) fetchMergeBaseCommit(baseBranch string) (string, error) { - if baseBranch == "" { - return "", nil - } - - hash, err := repository.lookupMergeBaseHash(baseBranch) - if err != nil { - return "", fmt.Errorf("error looking up hash: %w", err) - } - +func (repository *Repository) fetchMergeBaseCommit() error { + hash := repository.context.BaseCommitHash if hash == "" { - return "", fmt.Errorf( - "could not find common ancestor between the current and %s branch. "+ - "please check that the base branch is correct, and that you have "+ - "fetched enough git history to include the latest common ancestor", - baseBranch, - ) + return nil } log.Debug().Msgf("merge base commit: %s", hash) if git.CommitPresent(repository.rootPath, hash) { - return hash, nil + return nil } log.Debug().Msgf("merge base commit not present, fetching") if err := git.FetchRef(repository.ctx, repository.rootPath, hash); err != nil { - return "", err + return err } log.Debug().Msgf("merge base commit fetched") - return hash, nil + return nil } -func (repository *Repository) getTreeFiles( +func (repository *Repository) getCurrentFiles( ignore *ignore.FileIgnore, goclocResult *gocloc.Result, - commitSHA string, ) (*files.List, error) { var headFiles []files.File - gitFiles, err := git.ListTree(repository.rootPath, commitSHA) + gitFiles, err := git.ListTree(repository.rootPath, repository.context.CurrentCommitHash) if err != nil { return nil, err } @@ -171,7 +125,7 @@ func (repository *Repository) getDiffFiles( renames := make(map[string]string) chunks := make(map[string]git.Chunks) - filePatches, err := git.Diff(repository.rootPath, repository.mergeBaseCommitHash) + filePatches, err := git.Diff(repository.rootPath, repository.context.BaseCommitHash) if err != nil { return nil, err } @@ -218,17 +172,17 @@ func (repository *Repository) getDiffFiles( } func (repository *Repository) WithBaseBranch(body func() error) error { - if repository == nil || repository.mergeBaseCommitHash == "" { + if repository == nil || !repository.config.Scan.Diff { return nil } - if err := git.Switch(repository.rootPath, repository.mergeBaseCommitHash, true); err != nil { + if err := git.Switch(repository.rootPath, repository.context.BaseCommitHash, true); err != nil { return fmt.Errorf("error switching to base branch: %w", err) } err := body() - if restoreErr := repository.restoreHead(); restoreErr != nil { + if restoreErr := repository.restoreCurrent(); restoreErr != nil { wrappedErr := fmt.Errorf("error restoring to current commit: %w", restoreErr) if err == nil { return wrappedErr @@ -240,12 +194,12 @@ func (repository *Repository) WithBaseBranch(body func() error) error { return err } -func (repository *Repository) restoreHead() error { - if repository.headBranch == "" { - return git.Switch(repository.rootPath, repository.headCommitHash, true) +func (repository *Repository) restoreCurrent() error { + if repository.context.CurrentBranch == "" { + return git.Switch(repository.rootPath, repository.context.CurrentCommitHash, true) } - return git.Switch(repository.rootPath, repository.headBranch, false) + return git.Switch(repository.rootPath, repository.context.CurrentBranch, false) } func (repository *Repository) fileFor( @@ -280,95 +234,3 @@ func (repository *Repository) fileFor( FilePath: relativePath, } } - -func (repository *Repository) lookupMergeBaseHash(baseBranch string) (string, error) { - if sha := os.Getenv("DIFF_BASE_COMMIT"); sha != "" { - return sha, nil - } - - if sha, err := repository.lookupMergeBaseHashFromGithub(baseBranch); sha != "" || err != nil { - return sha, err - } - - log.Debug().Msg("finding merge base using local repository") - - sha, err := git.GetMergeBase(repository.rootPath, "origin/"+baseBranch, repository.headCommitHash) - if err != nil { - if !strings.Contains(err.Error(), "Not a valid object name") { - return "", fmt.Errorf("invalid ref: %w", err) - } - } - - if sha != "" { - return sha, nil - } - - log.Debug().Msg("remote ref not found, trying local ref") - sha, err = git.GetMergeBase(repository.rootPath, baseBranch, repository.headCommitHash) - if err != nil { - return "", fmt.Errorf("invalid ref: %w", err) - } - - return sha, nil -} - -func (repository *Repository) lookupMergeBaseHashFromGithub(baseBranch string) (string, error) { - if repository.githubToken == "" { - return "", nil - } - - githubRepository := os.Getenv("GITHUB_REPOSITORY") - if githubRepository == "" { - return "", nil - } - - log.Debug().Msg("finding merge base using github api") - - splitRepository := strings.SplitN(githubRepository, "/", 2) - if len(splitRepository) != 2 { - return "", fmt.Errorf("invalid github repository name '%s'", githubRepository) - } - - client, err := repository.newGithubClient() - if err != nil { - return "", err - } - - comparison, _, err := client.Repositories.CompareCommits( - context.Background(), - splitRepository[0], - splitRepository[1], - baseBranch, - repository.headCommitHash, - ) - if err != nil { - return "", fmt.Errorf("error calling github compare api: %w", err) - } - - if comparison.MergeBaseCommit == nil { - return "", nil - } - - return *comparison.MergeBaseCommit.SHA, nil -} - -func (repository *Repository) newGithubClient() (*github.Client, error) { - tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: repository.githubToken}) - httpClient := oauth2.NewClient(context.Background(), tokenSource) - client := github.NewClient(httpClient) - - if githubAPIURL := os.Getenv("GITHUB_API_URL"); githubAPIURL != "" { - parsedURL, err := url.Parse(githubAPIURL) - if err != nil { - return nil, fmt.Errorf("failed to parse github api url: %w", err) - } - - if !strings.HasSuffix(parsedURL.Path, "/") { - parsedURL.Path += "/" - } - - client.BaseURL = parsedURL - } - - return client, nil -} diff --git a/internal/commands/process/settings/settings.go b/internal/commands/process/settings/settings.go index 959cfbeb0..33d06aa0f 100644 --- a/internal/commands/process/settings/settings.go +++ b/internal/commands/process/settings/settings.go @@ -369,7 +369,7 @@ func FromOptions(opts flag.Options, versionMeta *version_check.VersionMeta) (Con BearerRulesVersion: result.BearerRulesVersion, } - if config.Scan.DiffBaseBranch != "" { + if config.Scan.Diff { if !slices.Contains([]string{flag.ReportSecurity, flag.ReportSaaS}, config.Report.Report) { return Config{}, errors.New("diff base branch is only supported for the security report") } diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 8425cf876..988056347 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -34,6 +34,7 @@ var ScanFlags = flag.Flags{ flag.ReportFlagGroup, flag.RuleFlagGroup, flag.ScanFlagGroup, + flag.RepositoryFlagGroup, flag.GeneralFlagGroup, } diff --git a/internal/flag/options.go b/internal/flag/options.go index f125144eb..9db2c1969 100644 --- a/internal/flag/options.go +++ b/internal/flag/options.go @@ -42,6 +42,9 @@ type Flag struct { // Deprecated represents if the flag is deprecated Deprecated bool + + // Additional environment variables to read the value from, in addition to the default + EnvironmentVariables []string } type flagGroupBase struct { @@ -62,6 +65,7 @@ type Options struct { ReportOptions RuleOptions ScanOptions + RepositoryOptions GeneralOptions IgnoreAddOptions IgnoreShowOptions @@ -110,7 +114,11 @@ func bind(cmd *cobra.Command, flag *Flag) error { // viper.SetEnvPrefix("bearer") // replacer := strings.NewReplacer("-", "_") // viper.SetEnvKeyReplacer(replacer) - if err := viper.BindEnv(flag.ConfigName, strings.ToUpper("bearer_"+strings.ReplaceAll(flag.Name, "-", "_"))); err != nil { + arguments := append( + []string{flag.ConfigName, strings.ToUpper("bearer_" + strings.ReplaceAll(flag.Name, "-", "_"))}, + flag.EnvironmentVariables..., + ) + if err := viper.BindEnv(arguments...); err != nil { return err } diff --git a/internal/flag/repository_flags.go b/internal/flag/repository_flags.go new file mode 100644 index 000000000..a1121a564 --- /dev/null +++ b/internal/flag/repository_flags.go @@ -0,0 +1,141 @@ +package flag + +type repositoryFlagGroup struct{ flagGroupBase } + +var RepositoryFlagGroup = &repositoryFlagGroup{flagGroupBase{name: "Repository"}} + +var ( + RepositoryURLFlag = RepositoryFlagGroup.add(Flag{ + Name: "repository-url", + ConfigName: "repository.url", + Value: "", + Usage: "The remote URL of the repository.", + EnvironmentVariables: []string{ + "ORIGIN_URL", // legacy + "CI_REPOSITORY_URL", // gitlab + }, + DisableInConfig: true, + Hide: true, + }) + CurrentBranchFlag = RepositoryFlagGroup.add(Flag{ + Name: "current-branch", + ConfigName: "repository.current-branch", + Value: "", + Usage: "The name of the current branch.", + EnvironmentVariables: []string{ + "CURRENT_BRANCH", // legacy + "CI_COMMIT_REF_NAME", // gitlab + }, + DisableInConfig: true, + Hide: true, + }) + CurrentCommitFlag = RepositoryFlagGroup.add(Flag{ + Name: "current-commit", + ConfigName: "repository.current-commit", + Value: "", + Usage: "The hash of the current commit.", + EnvironmentVariables: []string{ + "SHA", // legacy + "CI_COMMIT_SHA", // gitlab + }, + DisableInConfig: true, + Hide: true, + }) + DefaultBranchFlag = RepositoryFlagGroup.add(Flag{ + Name: "default-branch", + ConfigName: "repository.default-branch", + Value: "", + Usage: "The name of the default branch.", + EnvironmentVariables: []string{ + "DEFAULT_BRANCH", // legacy + "CI_DEFAULT_BRANCH", // gitlab + }, + DisableInConfig: true, + Hide: true, + }) + DiffBaseBranchFlag = RepositoryFlagGroup.add(Flag{ + Name: "diff-base-branch", + ConfigName: "repository.diff-base-branch", + Value: "", + Usage: "The name of the base branch to use for diff scanning.", + EnvironmentVariables: []string{ + "DIFF_BASE_BRANCH", // legacy + "CI_MERGE_REQUEST_TARGET_BRANCH_NAME", // gitlab + }, + DisableInConfig: true, + Hide: true, + }) + DiffBaseCommitFlag = RepositoryFlagGroup.add(Flag{ + Name: "diff-base-commit", + ConfigName: "repository.diff-base-commit", + Value: "", + Usage: "The hash of the base commit to use for diff scanning.", + EnvironmentVariables: []string{ + "DIFF_BASE_COMMIT", // legacy + "CI_MERGE_REQUEST_DIFF_BASE_SHA", // gitlab + }, + DisableInConfig: true, + Hide: true, + }) + GithubTokenFlag = RepositoryFlagGroup.add(Flag{ + Name: "github-token", + ConfigName: "repository.github-token", + Value: "", + Usage: "An access token for the Github API.", + EnvironmentVariables: []string{ + "GITHUB_TOKEN", // github + }, + DisableInConfig: true, + Hide: true, + }) + GithubRepositoryFlag = RepositoryFlagGroup.add(Flag{ + Name: "github-repository", + ConfigName: "repository.github-repository", + Value: "", + Usage: "The owner and name of the repository on Github. eg. Bearer/bearer", + EnvironmentVariables: []string{ + "GITHUB_REPOSITORY", // github + }, + DisableInConfig: true, + Hide: true, + }) + GithubAPIURLFlag = RepositoryFlagGroup.add(Flag{ + Name: "github-api-url", + ConfigName: "repository.github-api-url", + Value: "", + Usage: "A non-standard URL to use for the Github API", + EnvironmentVariables: []string{ + "GITHUB_API_URL", // github + }, + DisableInConfig: true, + Hide: true, + }) +) + +type RepositoryOptions struct { + OriginURL string + CurrentBranch string + CurrentCommit string + DefaultBranch string + DiffBaseBranch string + DiffBaseCommit string + GithubToken string + GithubRepository string + GithubAPIURL string +} + +func (repositoryFlagGroup) SetOptions(options *Options, args []string) error { + options.RepositoryOptions = RepositoryOptions{ + OriginURL: getString(RepositoryURLFlag), + CurrentBranch: getString(CurrentBranchFlag), + CurrentCommit: getString(CurrentCommitFlag), + DefaultBranch: getString(DefaultBranchFlag), + DiffBaseBranch: getString(DiffBaseBranchFlag), + DiffBaseCommit: getString(DiffBaseCommitFlag), + GithubToken: getString(GithubTokenFlag), + GithubRepository: getString(GithubRepositoryFlag), + GithubAPIURL: getString(GithubAPIURLFlag), + } + + return nil +} diff --git a/internal/flag/scan_flags.go b/internal/flag/scan_flags.go index ff893ae40..2c631e201 100644 --- a/internal/flag/scan_flags.go +++ b/internal/flag/scan_flags.go @@ -107,6 +107,13 @@ var ( Value: -1, Usage: "Force a given exit code for the scan command. Set this to 0 (success) to always return a success exit code despite any findings from the scan.", }) + DiffFlag = ScanFlagGroup.add(Flag{ + Name: "diff", + ConfigName: "scan.diff", + Value: false, + Usage: "Only report differences in findings relative to a base branch.", + DisableInConfig: true, + }) ) type ScanOptions struct { @@ -124,8 +131,7 @@ type ScanOptions struct { Scanner []string `mapstructure:"scanner" json:"scanner" yaml:"scanner"` Parallel int `mapstructure:"parallel" json:"parallel" yaml:"parallel"` ExitCode int `mapstructure:"exit-code" json:"exit-code" yaml:"exit-code"` - DiffBaseBranch string `mapstructure:"diff_base_branch" json:"diff_base_branch" yaml:"diff_base_branch"` - GithubToken string `mapstructure:"github_token" json:"github_token" yaml:"github_token"` + Diff bool `mapstructure:"diff" json:"diff" yaml:"diff"` } func (scanFlagGroup) SetOptions(options *Options, args []string) error { @@ -151,6 +157,9 @@ func (scanFlagGroup) SetOptions(options *Options, args []string) error { } } + // DIFF_BASE_BRANCH is used for backwards compatibilty + diff := getBool(DiffFlag) || os.Getenv("DIFF_BASE_BRANCH") != "" + options.ScanOptions = ScanOptions{ SkipPath: getStringSlice(SkipPathFlag), DisableDomainResolution: getBool(DisableDomainResolutionFlag), @@ -166,8 +175,7 @@ func (scanFlagGroup) SetOptions(options *Options, args []string) error { Scanner: scanners, Parallel: viper.GetInt(ParallelFlag.ConfigName), ExitCode: viper.GetInt(ExitCodeFlag.ConfigName), - DiffBaseBranch: os.Getenv("DIFF_BASE_BRANCH"), - GithubToken: os.Getenv("GITHUB_TOKEN"), + Diff: diff, } return nil diff --git a/internal/git/branch.go b/internal/git/branch.go new file mode 100644 index 000000000..7c4a73981 --- /dev/null +++ b/internal/git/branch.go @@ -0,0 +1,37 @@ +package git + +import ( + "context" + "strings" +) + +func GetDefaultBranch(dir string) (string, error) { + name, err := getRevParseAbbrevRef(dir, "origin/HEAD") + if err != nil { + return "", err + } + + return strings.TrimPrefix(name, "origin/"), nil +} + +// GetCurrentBranch gets the branch name. It is blank when detached. +func GetCurrentBranch(dir string) (string, error) { + name, err := getRevParseAbbrevRef(dir, "HEAD") + if name == "HEAD" || err != nil { + return "", err + } + + return name, nil +} + +func getRevParseAbbrevRef(dir string, ref string) (name string, err error) { + output, err := captureCommandBasic( + context.TODO(), + dir, + "rev-parse", + "--abbrev-ref", + ref, + ) + + return strings.TrimSpace(output), err +} diff --git a/internal/git/commits.go b/internal/git/commits.go index 39db4f4e5..c1877daa4 100644 --- a/internal/git/commits.go +++ b/internal/git/commits.go @@ -2,61 +2,31 @@ package git import ( "context" - "io" "strings" ) // GetCurrentCommit gets a current commit from a HEAD for a local directory -func GetCurrentCommit(dir string) (sha string, err error) { - err = captureCommand(context.TODO(), dir, []string{"rev-parse", "HEAD"}, func(stdout io.Reader) error { - data, err := io.ReadAll(stdout) - if err != nil { - return err - } - - sha = strings.TrimSpace(string(data)) - return nil - }) - - return -} - -// GetCurrentBranch gets the branch name. It is blank when detached. -func GetCurrentBranch(dir string) (name string, err error) { - err = captureCommand( +func GetCurrentCommit(dir string) (string, error) { + output, err := captureCommandBasic( context.TODO(), dir, - []string{"rev-parse", "--abbrev-ref", "HEAD"}, - func(stdout io.Reader) error { - data, err := io.ReadAll(stdout) - if err != nil { - return err - } - - name = strings.TrimSpace(string(data)) - if name == "HEAD" { - name = "" - } - - return nil - }, + "rev-parse", + "HEAD", ) - return + return strings.TrimSpace(output), err } func GetMergeBase(dir string, ref1, ref2 string) (sha string, err error) { - err = captureCommand(context.TODO(), dir, []string{"merge-base", ref1, ref2}, func(stdout io.Reader) error { - data, err := io.ReadAll(stdout) - if err != nil { - return err - } - - sha = strings.TrimSpace(string(data)) - return nil - }) + output, err := captureCommandBasic( + context.TODO(), + dir, + "merge-base", + ref1, + ref2, + ) - return + return strings.TrimSpace(output), err } func CommitPresent(rootDir, sha string) bool { diff --git a/internal/git/git.go b/internal/git/git.go index 60169d9e0..a63c6a208 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -108,6 +108,16 @@ func captureCommand(ctx context.Context, workingDir string, args []string, captu return nil } +func captureCommandBasic(ctx context.Context, workingDir string, args ...string) (output string, err error) { + err = captureCommand(ctx, workingDir, args, func(r io.Reader) error { + outputBytes, readErr := io.ReadAll(r) + output = string(outputBytes) + return readErr + }) + + return +} + var regexpDefunctProcess = regexp.MustCompile(" git ") var regexpPID = regexp.MustCompile("[0-9]+ ") diff --git a/internal/git/remote.go b/internal/git/remote.go new file mode 100644 index 000000000..6b4141d58 --- /dev/null +++ b/internal/git/remote.go @@ -0,0 +1,18 @@ +package git + +import ( + "context" + "strings" +) + +func GetOriginURL(dir string) (string, error) { + output, err := captureCommandBasic( + context.TODO(), + dir, + "remote", + "get-url", + "origin", + ) + + return strings.TrimSpace(output), err +} diff --git a/internal/git/tree.go b/internal/git/tree.go index 07488d912..b14940ac4 100644 --- a/internal/git/tree.go +++ b/internal/git/tree.go @@ -48,6 +48,18 @@ func GetRoot(targetPath string) string { return canonicalPath } +func HasUncommittedChanges(rootDir string) (bool, error) { + output, err := captureCommandBasic( + context.TODO(), + rootDir, + "status", + " --porcelain=v1", + " --no-renames", + ) + + return strings.Count(output, "\n") > 0, err +} + func GetTree(rootDir string) (*Tree, error) { commit, err := getHeadCommitIdentifier(rootDir) if err != nil { diff --git a/internal/languages/testhelper/testhelper.go b/internal/languages/testhelper/testhelper.go index 8c3d9043c..1a201b79f 100644 --- a/internal/languages/testhelper/testhelper.go +++ b/internal/languages/testhelper/testhelper.go @@ -160,6 +160,7 @@ func (runner *Runner) scanSingleFile(t *testing.T, testDataPath string, fileRela }, runner.config, nil, + nil, ) if err != nil { t.Fatalf("failed to get output: %s", err) diff --git a/internal/report/output/output.go b/internal/report/output/output.go index 8728da1e9..bf9da13ca 100644 --- a/internal/report/output/output.go +++ b/internal/report/output/output.go @@ -9,6 +9,7 @@ import ( "github.com/hhatto/gocloc" "golang.org/x/exp/slices" + "github.com/bearer/bearer/internal/commands/process/gitrepository" "github.com/bearer/bearer/internal/commands/process/settings" "github.com/bearer/bearer/internal/flag" "github.com/bearer/bearer/internal/report/basebranchfindings" @@ -27,6 +28,7 @@ var ErrUndefinedFormat = errors.New("undefined output format") func GetData( report globaltypes.Report, config settings.Config, + gitContext *gitrepository.Context, baseBranchFindings *basebranchfindings.Findings, ) (*types.ReportData, error) { data := &types.ReportData{} @@ -61,7 +63,7 @@ func GetData( if err = security.AddReportData(data, config, baseBranchFindings, report.HasFiles); err != nil { return nil, err } - err = saas.GetReport(data, config, false) + err = saas.GetReport(data, config, gitContext, false) case flag.ReportPrivacy: err = privacy.AddReportData(data, config) case flag.ReportStats: @@ -73,10 +75,10 @@ func GetData( return data, err } -func UploadReportToCloud(report *types.ReportData, config settings.Config) { +func UploadReportToCloud(report *types.ReportData, config settings.Config, gitContext *gitrepository.Context) { if slices.Contains([]string{flag.ReportSecurity, flag.ReportSaaS}, config.Report.Report) { if config.Client != nil && config.Client.Error == nil { - saas.SendReport(config, report) + saas.SendReport(config, report, gitContext) } } } diff --git a/internal/report/output/saas/saas.go b/internal/report/output/saas/saas.go index 29490a166..f48fb3bf2 100644 --- a/internal/report/output/saas/saas.go +++ b/internal/report/output/saas/saas.go @@ -2,18 +2,18 @@ package saas import ( "compress/gzip" + "errors" "fmt" "os" - "os/exec" "strings" - "github.com/gitsight/go-vcsurl" "github.com/rs/zerolog/log" "golang.org/x/exp/maps" "github.com/bearer/bearer/api" "github.com/bearer/bearer/api/s3" "github.com/bearer/bearer/cmd/bearer/build" + "github.com/bearer/bearer/internal/commands/process/gitrepository" "github.com/bearer/bearer/internal/commands/process/settings" saas "github.com/bearer/bearer/internal/report/output/saas/types" securitytypes "github.com/bearer/bearer/internal/report/output/security/types" @@ -23,14 +23,14 @@ import ( pointer "github.com/bearer/bearer/internal/util/pointers" ) -var ShaEnvVarNames = [2]string{"SHA", "CI_COMMIT_SHA"} -var CurrentBranchEnvVarNames = [2]string{"CURRENT_BRANCH", "CI_COMMIT_REF_NAME"} -var DefaultBranchEnvVarNames = [2]string{"DEFAULT_BRANCH", "CI_DEFAULT_BRANCH"} -var OriginUrlEnvVarNames = [2]string{"ORIGIN_URL", "CI_REPOSITORY_URL"} - -func GetReport(reportData *types.ReportData, config settings.Config, ensureMeta bool) error { +func GetReport( + reportData *types.ReportData, + config settings.Config, + gitContext *gitrepository.Context, + ensureMeta bool, +) error { var meta *saas.Meta - meta, err := getMeta(reportData, config) + meta, err := getMeta(reportData, config, gitContext) if err != nil { if ensureMeta { return err @@ -58,24 +58,9 @@ func GetReport(reportData *types.ReportData, config settings.Config, ensureMeta return nil } -func GetVCSInfo(target string) (*vcsurl.VCS, error) { - gitRemote, err := getRemote(target) - if err != nil { - return nil, err - } - - info, err := vcsurl.Parse(*gitRemote) - if err != nil { - log.Debug().Msgf("couldn't parse origin url %s", err) - return nil, err - } - - return info, nil -} - -func SendReport(config settings.Config, reportData *types.ReportData) { +func SendReport(config settings.Config, reportData *types.ReportData, gitContext *gitrepository.Context) { if reportData.SaasReport == nil { - err := GetReport(reportData, config, true) + err := GetReport(reportData, config, gitContext, true) if err != nil { errorMessage := fmt.Sprintf("Unable to calculate Metadata. %s", err) log.Debug().Msgf(errorMessage) @@ -173,105 +158,59 @@ func createBearerGzipFileReport( return &tempDir, &filename, nil } -func getMeta(reportData *types.ReportData, config settings.Config) (*saas.Meta, error) { - sha, err := getSha(config.Scan.Target) - if err != nil { - return nil, err +func getMeta( + reportData *types.ReportData, + config settings.Config, + gitContext *gitrepository.Context, +) (*saas.Meta, error) { + if gitContext == nil { + return nil, errors.New("not a git repository") } - currentBranch, err := getCurrentBranch(config.Scan.Target) - if err != nil { - return nil, err + var messages []string + if gitContext.CurrentBranch == "" { + messages = append(messages, + "Couldn't determine the current branch of the repository. "+ + "Please set the 'BEARER_CURRENT_BRANCH' environment variable.", + ) } - - defaultBranch, err := getDefaultBranch(config.Scan.Target) - if err != nil { - return nil, err + if gitContext.DefaultBranch == "" { + messages = append(messages, + "Couldn't determine the default branch of the repository. "+ + "Please set the 'BEARER_DEFAULT_BRANCH' environment variable.", + ) + } + if gitContext.CurrentCommitHash == "" { + messages = append(messages, + "Couldn't determine the hash of the current commit of the repository. "+ + "Please set the 'BEARER_CURRENT_COMMIT' environment variable.", + ) + } + if gitContext.OriginURL == "" { + messages = append(messages, + "Couldn't determine the origin URL of the repository. "+ + "Please set the 'BEARER_REPOSITORY_URL' environment variable.", + ) } - info, err := GetVCSInfo(config.Scan.Target) - if err != nil { - return nil, err + if len(messages) != 0 { + return nil, errors.New(strings.Join(messages, "\n")) } return &saas.Meta{ - ID: info.ID, - Host: string(info.Host), - Username: info.Username, - Name: info.Name, - FullName: info.FullName, - URL: info.Raw, + ID: gitContext.ID, + Host: gitContext.Host, + Username: gitContext.Owner, + Name: gitContext.Name, + FullName: gitContext.FullName, + URL: gitContext.OriginURL, Target: config.Scan.Target, - SHA: *sha, - CurrentBranch: *currentBranch, - DefaultBranch: *defaultBranch, - DiffBaseBranch: config.Scan.DiffBaseBranch, + SHA: gitContext.CurrentCommitHash, + CurrentBranch: gitContext.CurrentBranch, + DefaultBranch: gitContext.DefaultBranch, + DiffBaseBranch: gitContext.BaseBranch, BearerRulesVersion: config.BearerRulesVersion, BearerVersion: build.Version, FoundLanguages: reportData.FoundLanguages, }, nil } - -func getSha(target string) (*string, error) { - for _, key := range ShaEnvVarNames { - env := os.Getenv(key) - if env != "" { - return pointer.String(env), nil - } - } - - bytes, err := exec.Command("git", "-C", target, "rev-parse", "HEAD").Output() - if err != nil { - log.Error().Msg("Couldn't extract git info for commit sha please set 'SHA' environment variable.") - return nil, err - } - return pointer.String(strings.TrimSuffix(string(bytes), "\n")), nil -} - -func getCurrentBranch(target string) (*string, error) { - for _, key := range CurrentBranchEnvVarNames { - env := os.Getenv(key) - if env != "" { - return pointer.String(env), nil - } - } - - bytes, err := exec.Command("git", "-C", target, "rev-parse", "--abbrev-ref", "HEAD").Output() - if err != nil { - log.Error().Msg("Couldn't extract git info for current branch please set 'CURRENT_BRANCH' environment variable.") - return nil, err - } - return pointer.String(strings.TrimSuffix(string(bytes), "\n")), nil -} - -func getDefaultBranch(target string) (*string, error) { - for _, key := range DefaultBranchEnvVarNames { - env := os.Getenv(key) - if env != "" { - return pointer.String(env), nil - } - } - - bytes, err := exec.Command("git", "-C", target, "rev-parse", "--abbrev-ref", "origin/HEAD").Output() - if err != nil { - log.Error().Msg("Couldn't extract the default branch of this repository. Please set 'DEFAULT_BRANCH' environment variable.") - return nil, err - } - return pointer.String(strings.TrimPrefix(strings.TrimSuffix(string(bytes), "\n"), "origin/")), nil -} - -func getRemote(target string) (*string, error) { - for _, key := range OriginUrlEnvVarNames { - env := os.Getenv(key) - if env != "" { - return pointer.String(env), nil - } - } - - bytes, err := exec.Command("git", "-C", target, "remote", "get-url", "origin").Output() - if err != nil { - log.Error().Msg("Couldn't extract git info for origin url please set 'ORIGIN_URL' environment variable.") - return nil, err - } - return pointer.String(strings.TrimSuffix(string(bytes), "\n")), nil -} diff --git a/internal/report/output/security/security.go b/internal/report/output/security/security.go index 3e7c66ea0..b5cb35378 100644 --- a/internal/report/output/security/security.go +++ b/internal/report/output/security/security.go @@ -113,7 +113,7 @@ func AddReportData( config.Report.ExcludeFingerprint, config.IgnoredFingerprints, config.StaleIgnoredFingerprintIds, - config.Scan.DiffBaseBranch != "", + config.Scan.Diff, ) }