git.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package cmd
  2. import (
  3. "context"
  4. "time"
  5. "github.com/spf13/cobra"
  6. "github.com/zricethezav/gitleaks/v8/cmd/scm"
  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. initDiagnostics()
  38. cfg := Config(cmd)
  39. // create detector
  40. detector := Detector(cmd, cfg, source)
  41. // parse flags
  42. exitCode := mustGetIntFlag(cmd, "exit-code")
  43. logOpts := mustGetStringFlag(cmd, "log-opts")
  44. staged := mustGetBoolFlag(cmd, "staged")
  45. preCommit := mustGetBoolFlag(cmd, "pre-commit")
  46. var (
  47. findings []report.Finding
  48. err error
  49. gitCmd *sources.GitCmd
  50. scmPlatform scm.Platform
  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. scmPlatform = 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. }
  66. findings, err = detector.DetectSource(
  67. context.Background(),
  68. &sources.Git{
  69. Cmd: gitCmd,
  70. Config: &detector.Config,
  71. Remote: sources.NewRemoteInfo(scmPlatform, source),
  72. Sema: detector.Sema,
  73. MaxArchiveDepth: detector.MaxArchiveDepth,
  74. },
  75. )
  76. if err != nil {
  77. // don't exit on error, just log it
  78. logging.Error().Err(err).Msg("failed to scan Git repository")
  79. }
  80. findingSummaryAndExit(detector, findings, exitCode, start, err)
  81. }