git.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package cmd
  2. import (
  3. "time"
  4. "github.com/spf13/cobra"
  5. "github.com/zricethezav/gitleaks/v8/cmd/scm"
  6. "github.com/zricethezav/gitleaks/v8/detect"
  7. "github.com/zricethezav/gitleaks/v8/logging"
  8. "github.com/zricethezav/gitleaks/v8/report"
  9. "github.com/zricethezav/gitleaks/v8/sources"
  10. )
  11. func init() {
  12. rootCmd.AddCommand(gitCmd)
  13. gitCmd.Flags().String("platform", "", "the target platform used to generate links (github, gitlab)")
  14. gitCmd.Flags().Bool("staged", false, "scan staged commits (good for pre-commit)")
  15. gitCmd.Flags().Bool("pre-commit", false, "scan using git diff")
  16. gitCmd.Flags().String("log-opts", "", "git log options")
  17. }
  18. var gitCmd = &cobra.Command{
  19. Use: "git [flags] [repo]",
  20. Short: "scan git repositories for secrets",
  21. Args: cobra.MaximumNArgs(1),
  22. Run: runGit,
  23. }
  24. func runGit(cmd *cobra.Command, args []string) {
  25. // start timer
  26. start := time.Now()
  27. // grab source
  28. source := "."
  29. if len(args) == 1 {
  30. source = args[0]
  31. if source == "" {
  32. source = "."
  33. }
  34. }
  35. // setup config (aka, the thing that defines rules)
  36. initConfig(source)
  37. cfg := Config(cmd)
  38. // create detector
  39. detector := Detector(cmd, cfg, source)
  40. // parse flags
  41. exitCode := mustGetIntFlag(cmd, "exit-code")
  42. logOpts := mustGetStringFlag(cmd, "log-opts")
  43. staged := mustGetBoolFlag(cmd, "staged")
  44. preCommit := mustGetBoolFlag(cmd, "pre-commit")
  45. var (
  46. findings []report.Finding
  47. err error
  48. gitCmd *sources.GitCmd
  49. scmPlatform scm.Platform
  50. remote *detect.RemoteInfo
  51. )
  52. if preCommit || staged {
  53. if gitCmd, err = sources.NewGitDiffCmd(source, staged); err != nil {
  54. logging.Fatal().Err(err).Msg("could not create Git diff cmd")
  55. }
  56. // Remote info + links are irrelevant for staged changes.
  57. remote = &detect.RemoteInfo{Platform: scm.NoPlatform}
  58. } else {
  59. if gitCmd, err = sources.NewGitLogCmd(source, logOpts); err != nil {
  60. logging.Fatal().Err(err).Msg("could not create Git log cmd")
  61. }
  62. if scmPlatform, err = scm.PlatformFromString(mustGetStringFlag(cmd, "platform")); err != nil {
  63. logging.Fatal().Err(err).Send()
  64. }
  65. if remote, err = detect.NewRemoteInfo(scmPlatform, source); err != nil {
  66. logging.Fatal().Err(err).Msg("failed to scan Git repository")
  67. }
  68. }
  69. findings, err = detector.DetectGit(gitCmd, remote)
  70. if err != nil {
  71. // don't exit on error, just log it
  72. logging.Error().Err(err).Msg("failed to scan Git repository")
  73. }
  74. findingSummaryAndExit(detector, findings, exitCode, start, err)
  75. }