Просмотр исходного кода

Exitcode (#100)

* additional exit code, some more cleaning

* bump version
Zachary Rice 7 лет назад
Родитель
Сommit
d299b5aa7f
5 измененных файлов с 135 добавлено и 42 удалено
  1. 6 0
      CHANGELOG.md
  2. 1 0
      CONTRIBUTING.md
  3. 2 1
      README.md
  4. 89 0
      gitleaks_test.go
  5. 37 41
      main.go

+ 6 - 0
CHANGELOG.md

@@ -1,6 +1,12 @@
 CHANGELOG
 =========
 
+1.7.0
+-----
+- Exit code == 2 on error
+- Cleaning up some logs
+- Removing some unreachable code
+
 1.6.1
 -----
 - Recover from panic when diffing

+ 1 - 0
CONTRIBUTING.md

@@ -15,5 +15,6 @@ Make sure you pass this list of requirements.
 - You've ran `golint`.
 - Your Go changes are confined to `gitleaks_test.go` and `main.go`. This is subject to change as the project evolves. Stylistically, I like having a single go file considering the size of this project (its tiny).
 - You've added test cases for your changes.
+- You've updated [the changelog](CHANGELOG.md).
 - Your tests pass.
 

+ 2 - 1
README.md

@@ -52,8 +52,9 @@ Help Options:
 ```
 #### Exit Codes
 ```
-1: leaks present
 0: no leaks
+1: leaks present
+2: error encountered
 ```
 
 #### Additional Examples and Explanations

+ 89 - 0
gitleaks_test.go

@@ -165,6 +165,95 @@ func TestGetRepo(t *testing.T) {
 		})
 	}
 }
+func TestRunAudit(t *testing.T) {
+	err := loadToml()
+	configsDir := testTomlLoader()
+	defer os.RemoveAll(configsDir)
+
+	dir, err = ioutil.TempDir("", "gitleaksTestOwner")
+	defer os.RemoveAll(dir)
+	if err != nil {
+		panic(err)
+	}
+	git.PlainClone(dir+"/gronit", false, &git.CloneOptions{
+		URL: "https://github.com/gitleakstest/gronit",
+	})
+	git.PlainClone(dir+"/h1domains", false, &git.CloneOptions{
+		URL: "https://github.com/gitleakstest/h1domains",
+	})
+	var tests = []struct {
+		testOpts       Options
+		description    string
+		expectedErrMsg string
+		numLeaks       int
+	}{
+		{
+			testOpts: Options{
+				GithubUser: "gitleakstest",
+			},
+			description:    "test github user",
+			numLeaks:       2,
+			expectedErrMsg: "",
+		},
+		{
+			testOpts: Options{
+				GithubUser: "gitleakstest",
+				Disk:       true,
+			},
+			description:    "test github user on disk ",
+			numLeaks:       2,
+			expectedErrMsg: "",
+		},
+		{
+			testOpts: Options{
+				GithubOrg: "gitleakstestorg",
+			},
+			description:    "test github org",
+			numLeaks:       2,
+			expectedErrMsg: "",
+		},
+		{
+			testOpts: Options{
+				GithubOrg: "gitleakstestorg",
+				Disk:      true,
+			},
+			description:    "test org on disk",
+			numLeaks:       2,
+			expectedErrMsg: "",
+		},
+		{
+			testOpts: Options{
+				OwnerPath: dir,
+			},
+			description:    "test owner path",
+			numLeaks:       2,
+			expectedErrMsg: "",
+		},
+		{
+			testOpts: Options{
+				GithubOrg:      "gitleakstestorg",
+				IncludePrivate: true,
+				SSHKey:         "reallyreallyreallyreallywrongpath",
+			},
+			description:    "test private org no ssh",
+			numLeaks:       0,
+			expectedErrMsg: "unable to generate ssh key: open reallyreallyreallyreallywrongpath: no such file or directory",
+		},
+	}
+	g := goblin.Goblin(t)
+	for _, test := range tests {
+		g.Describe("TestRunAudit", func() {
+			g.It(test.description, func() {
+				opts = test.testOpts
+				leaks, err := run()
+				if err != nil {
+					g.Assert(err.Error()).Equal(test.expectedErrMsg)
+				}
+				g.Assert(len(leaks)).Equal(test.numLeaks)
+			})
+		})
+	}
+}
 
 func TestStartAudit(t *testing.T) {
 	err := loadToml()

+ 37 - 41
main.go

@@ -119,7 +119,9 @@ type Config struct {
 }
 
 const defaultGithubURL = "https://api.github.com/"
-const version = "1.6.1"
+const version = "1.7.0"
+const errExit = 2
+const leakExit = 1
 const defaultConfig = `
 title = "gitleaks config"
 # add regexes to the regex table
@@ -187,70 +189,63 @@ func init() {
 }
 
 func main() {
-	var (
-		leaks []Leak
-	)
 	_, err := flags.Parse(&opts)
 	if opts.Version {
 		fmt.Println(version)
 		os.Exit(0)
 	}
 	if err != nil {
-		os.Exit(1)
+		log.Error(err)
+		os.Exit(errExit)
 	}
-	setLogs()
-
-	err = optsGuard()
+	leaks, err := run()
 	if err != nil {
-		log.Fatal(err)
+		log.Error(err)
+		os.Exit(errExit)
+	}
+	if opts.Report != "" {
+		writeReport(leaks)
 	}
 
+	if len(leaks) != 0 {
+		log.Warnf("leaks detected")
+		os.Exit(leakExit)
+	}
+}
+
+// run parses options and kicks off the audit
+func run() ([]Leak, error) {
+	setLogs()
+	err := optsGuard()
+	if err != nil {
+		return nil, err
+	}
 	err = loadToml()
 	if err != nil {
-		log.Fatal(err)
+		return nil, err
 	}
-
 	if opts.IncludePrivate {
 		// if including private repos use ssh as authentication
 		sshAuth, err = getSSHAuth()
 		if err != nil {
-			log.Fatal(err)
+			return nil, err
 		}
 	}
-
 	if opts.Disk {
 		// temporary directory where all the gitleaks plain clones will reside
 		dir, err = ioutil.TempDir("", "gitleaks")
 		defer os.RemoveAll(dir)
 		if err != nil {
-			log.Fatal(err)
+			return nil, err
 		}
 	}
-	leaks, err = startAudits()
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	if opts.Report != "" {
-		writeReport(leaks)
-	}
-
-	if len(leaks) != 0 {
-		log.Errorf("leaks detected")
-		os.Exit(1)
-	}
+	return startAudits()
 }
 
 func startAudits() ([]Leak, error) {
 	var leaks []Leak
 	// start audits
-	if opts.Repo != "" || opts.RepoPath != "" {
-		repo, err := getRepo()
-		if err != nil {
-			return leaks, err
-		}
-		return auditRepo(repo)
-	} else if opts.OwnerPath != "" {
+	if opts.OwnerPath != "" {
 		repos, err := discoverRepos(opts.OwnerPath)
 		if err != nil {
 			return leaks, err
@@ -275,7 +270,7 @@ func startAudits() ([]Leak, error) {
 				log.Warnf("leaks found for repo %s", *githubRepo.Name)
 			}
 			if err != nil {
-				return leaks, err
+				log.Warn(err)
 			}
 			leaks = append(leaks, leaksFromRepo...)
 		}
@@ -505,7 +500,6 @@ func auditRepo(repo Repo) ([]Leak, error) {
 				return nil
 			})
 			if foundBranch == false {
-				log.Fatalf("No branch with name", opts.Branch)
 				return nil, nil
 			}
 		}
@@ -601,7 +595,7 @@ func getGithubRepos() ([]*github.Repository, error) {
 			githubClient.BaseURL = ghURL
 		}
 		githubOrgOptions = &github.RepositoryListByOrgOptions{
-			ListOptions: github.ListOptions{PerPage: 10},
+			ListOptions: github.ListOptions{PerPage: 100},
 		}
 	} else if opts.GithubUser != "" {
 		githubClient = github.NewClient(githubToken())
@@ -613,7 +607,7 @@ func getGithubRepos() ([]*github.Repository, error) {
 		githubOptions = &github.RepositoryListOptions{
 			Affiliation: "owner",
 			ListOptions: github.ListOptions{
-				PerPage: 10,
+				PerPage: 100,
 			},
 		}
 	}
@@ -634,7 +628,7 @@ func getGithubRepos() ([]*github.Repository, error) {
 				return githubRepos, err
 			}
 		} else if opts.GithubOrg != "" {
-			rs, resp, err := githubClient.Repositories.ListByOrg(ctx, opts.GithubOrg, githubOrgOptions)
+			rs, resp, err = githubClient.Repositories.ListByOrg(ctx, opts.GithubOrg, githubOrgOptions)
 			if err != nil {
 				return nil, err
 			}
@@ -644,8 +638,10 @@ func getGithubRepos() ([]*github.Repository, error) {
 				return githubRepos, err
 			}
 		}
-		for _, githubRepo := range githubRepos {
-			log.Infof("staging repo %s", *githubRepo.Name)
+		if opts.Log == "Debug" || opts.Log == "debug" {
+			for _, githubRepo := range rs {
+				log.Debugf("staging repos %s", *githubRepo.Name)
+			}
 		}
 	}
 }