| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package git
- import (
- "bufio"
- "io"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
- "time"
- "github.com/gitleaks/go-gitdiff/gitdiff"
- "github.com/rs/zerolog/log"
- )
- // GitLog returns a channel of gitdiff.File objects from the git log -p command for the given source.
- func GitLog(source string, logOpts string) (<-chan *gitdiff.File, error) {
- sourceClean := filepath.Clean(source)
- var cmd *exec.Cmd
- if logOpts != "" {
- args := []string{"-C", sourceClean, "log", "-p", "-U0"}
- args = append(args, strings.Split(logOpts, " ")...)
- cmd = exec.Command("git", args...)
- } else {
- cmd = exec.Command("git", "-C", sourceClean, "log", "-p", "-U0", "--full-history", "--all")
- }
- log.Debug().Msgf("executing: %s", cmd.String())
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- return nil, err
- }
- stderr, err := cmd.StderrPipe()
- if err != nil {
- return nil, err
- }
- if err := cmd.Start(); err != nil {
- return nil, err
- }
- go listenForStdErr(stderr)
- time.Sleep(50 * time.Millisecond) // HACK: to avoid https://github.com/zricethezav/gitleaks/issues/722
- return gitdiff.Parse(stdout)
- }
- // GitDiff returns a channel of gitdiff.File objects from the git diff command for the given source.
- func GitDiff(source string, staged bool) (<-chan *gitdiff.File, error) {
- sourceClean := filepath.Clean(source)
- var cmd *exec.Cmd
- cmd = exec.Command("git", "-C", sourceClean, "diff", "-U0", ".")
- if staged {
- cmd = exec.Command("git", "-C", sourceClean, "diff", "-U0", "--staged", ".")
- }
- log.Debug().Msgf("executing: %s", cmd.String())
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- return nil, err
- }
- stderr, err := cmd.StderrPipe()
- if err != nil {
- return nil, err
- }
- if err := cmd.Start(); err != nil {
- return nil, err
- }
- go listenForStdErr(stderr)
- time.Sleep(50 * time.Millisecond) // HACK: to avoid https://github.com/zricethezav/gitleaks/issues/722
- return gitdiff.Parse(stdout)
- }
- // listenForStdErr listens for stderr output from git and prints it to stdout
- // then exits with exit code 1
- func listenForStdErr(stderr io.ReadCloser) {
- scanner := bufio.NewScanner(stderr)
- errEncountered := false
- for scanner.Scan() {
- log.Error().Msg(scanner.Text())
- errEncountered = true
- }
- if errEncountered {
- os.Exit(1)
- }
- }
|