options.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "strconv"
  6. )
  7. const usage = `usage: gitleaks [options] <url>
  8. Options:
  9. -c --concurrency Upper bound on concurrent diffs
  10. -u --user Git user url
  11. -r --repo Git repo url
  12. -o --org Git organization url
  13. -s --since Commit to stop at
  14. -b --b64Entropy Base64 entropy cutoff (default is 70)
  15. -x --hexEntropy Hex entropy cutoff (default is 40)
  16. -e --entropy Enable entropy
  17. -j --json Output gitleaks report
  18. -h --help Display this message
  19. --token Github API token
  20. --strict Enables stopwords
  21. `
  22. // Options for gitleaks
  23. type Options struct {
  24. Concurrency int
  25. B64EntropyCutoff int
  26. HexEntropyCutoff int
  27. UserURL string
  28. OrgURL string
  29. RepoURL string
  30. Strict bool
  31. Entropy bool
  32. SinceCommit string
  33. Persist bool
  34. IncludeForks bool
  35. Tmp bool
  36. EnableJSON bool
  37. Token string
  38. Verbose bool
  39. }
  40. // help prints the usage string and exits
  41. func help() {
  42. os.Stderr.WriteString(usage)
  43. os.Exit(1)
  44. }
  45. // optionsNextInt is a parseOptions helper that returns the value (int) of an option if valid
  46. func optionsNextInt(args []string, i *int) int {
  47. if len(args) > *i+1 {
  48. *i++
  49. } else {
  50. help()
  51. }
  52. argInt, err := strconv.Atoi(args[*i])
  53. if err != nil {
  54. fmt.Printf("Invalid %s option: %s\n", args[*i-1], args[*i])
  55. help()
  56. }
  57. return argInt
  58. }
  59. // optionsNextString is a parseOptions helper that returns the value (string) of an option if valid
  60. func optionsNextString(args []string, i *int) string {
  61. if len(args) > *i+1 {
  62. *i++
  63. } else {
  64. fmt.Printf("Invalid %s option: %s\n", args[*i-1], args[*i])
  65. help()
  66. }
  67. return args[*i]
  68. }
  69. // parseOptions
  70. func parseOptions(args []string) *Options {
  71. opts := &Options{
  72. Concurrency: 10,
  73. B64EntropyCutoff: 70,
  74. HexEntropyCutoff: 40,
  75. }
  76. if len(args) == 0 {
  77. help()
  78. }
  79. for i := 0; i < len(args); i++ {
  80. arg := args[i]
  81. switch arg {
  82. case "-s", "--since":
  83. opts.SinceCommit = optionsNextString(args, &i)
  84. case "--strict":
  85. opts.Strict = true
  86. case "-b", "--b64Entropy":
  87. opts.B64EntropyCutoff = optionsNextInt(args, &i)
  88. case "-x", "--hexEntropy":
  89. opts.HexEntropyCutoff = optionsNextInt(args, &i)
  90. case "-e", "--entropy":
  91. opts.Entropy = true
  92. case "-c", "--concurrency":
  93. opts.Concurrency = optionsNextInt(args, &i)
  94. case "-o", "--org":
  95. opts.OrgURL = optionsNextString(args, &i)
  96. case "-u", "--user":
  97. opts.UserURL = optionsNextString(args, &i)
  98. case "-r", "--repo":
  99. opts.RepoURL = optionsNextString(args, &i)
  100. case "-t", "--temporary":
  101. opts.Tmp = true
  102. case "--token":
  103. opts.Token = optionsNextString(args, &i)
  104. case "-j", "--json":
  105. opts.EnableJSON = true
  106. case "-h", "--help":
  107. help()
  108. return nil
  109. default:
  110. if i == len(args)-1 && opts.OrgURL == "" && opts.RepoURL == "" &&
  111. opts.UserURL == "" {
  112. opts.RepoURL = arg
  113. } else {
  114. fmt.Printf("Unknown option %s\n\n", arg)
  115. help()
  116. }
  117. }
  118. }
  119. // "guards"
  120. if opts.Tmp && opts.EnableJSON {
  121. fmt.Println("Report generation with temporary clones not supported")
  122. }
  123. return opts
  124. }