diff --git a/docs/USAGE.md b/docs/USAGE.md index 758b7d5..968154b 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -53,6 +53,8 @@ Usage of go-earlybird: Output format [ console | json | csv ] (default "console") -git string Full URL to a git repo to scan e.g. github.com/user/repo + -git-branch string + Name of branch to be scanned -git-commit-stream Use stream IO of Git commit log as input instead of file(s) -- e.g., 'cat secrets.text > go-earlybird' -git-project string diff --git a/go-earlybird.go b/go-earlybird.go index b52cd92..3bc5845 100644 --- a/go-earlybird.go +++ b/go-earlybird.go @@ -42,6 +42,7 @@ func main() { gitcfg.Project = flag.String("git-project", "", "Full URL to a github organization to scan e.g. github.com/org") gitcfg.Repo = flag.String("git", "", "Full URL to a git repo to scan e.g. github.com/user/repo") gitcfg.RepoUser = flag.String("git-user", os.Getenv("gituser"), "If the git repository is private, enter an authorized username") + gitcfg.RepoBranch = flag.String("git-branch", "", "Name of branch to be scanned") //Load CLI params and Earlybird config eb.ConfigInit() diff --git a/pkg/api/api.go b/pkg/api/api.go index 3510372..f62d5e5 100755 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -97,8 +97,9 @@ func GITScan(cfg cfgreader.EarlybirdConfig) http.HandlerFunc { } giturl := giturls[0] + gitbranch := r.URL.Query().Get("branch") utils.GetGitURL(&giturl, &blank) - mycfg.SearchDir, err = git.CloneGitRepos([]string{giturl}, os.Getenv("gituser"), os.Getenv("gitpassword"), (cfg.OutputFormat == "json")) + mycfg.SearchDir, err = git.CloneGitRepos([]string{giturl}, os.Getenv("gituser"), os.Getenv("gitpassword"), gitbranch, (cfg.OutputFormat == "json")) if err != nil { if err == transport.ErrAuthenticationRequired { http.Error(w, "Failed to clone, repository is private. Please enter a public repository URL.", http.StatusInternalServerError) diff --git a/pkg/core/core.go b/pkg/core/core.go index 0e291a9..fe59d24 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -71,9 +71,9 @@ func (eb *EarlybirdCfg) GitClone(ptr PTRGitConfig) { } var err error if *ptr.RepoUser != "" { // use auth - eb.Config.SearchDir, err = git.CloneGitRepos(scanRepos, *ptr.RepoUser, gitPassword, (eb.Config.OutputFormat == "json")) + eb.Config.SearchDir, err = git.CloneGitRepos(scanRepos, *ptr.RepoUser, gitPassword, *ptr.RepoBranch, (eb.Config.OutputFormat == "json")) } else { - eb.Config.SearchDir, err = git.CloneGitRepos(scanRepos, "", "", (eb.Config.OutputFormat == "json")) //Blank no auth + eb.Config.SearchDir, err = git.CloneGitRepos(scanRepos, "", "", *ptr.RepoBranch, (eb.Config.OutputFormat == "json")) //Blank no auth } if err != nil { log.Println("Failed to clone repository:", err) diff --git a/pkg/core/structures.go b/pkg/core/structures.go index 8541353..54ad577 100644 --- a/pkg/core/structures.go +++ b/pkg/core/structures.go @@ -43,7 +43,8 @@ type PTRHTTPConfig struct { //PTRGitConfig is the configuration definition for Earlybird git scans type PTRGitConfig struct { - Repo *string - RepoUser *string - Project *string + Repo *string + RepoUser *string + RepoBranch *string + Project *string } diff --git a/pkg/git/cloner.go b/pkg/git/cloner.go index 0e66806..da17adc 100755 --- a/pkg/git/cloner.go +++ b/pkg/git/cloner.go @@ -18,6 +18,8 @@ package git import ( "context" + "fmt" + "gopkg.in/src-d/go-git.v4/plumbing" "io/ioutil" "log" "os" @@ -76,7 +78,7 @@ func ReposPerProject(projectURL, username, password string) (scanRepos []string) } //CloneGitRepos Clones a Git repo into a random temporary folder -func CloneGitRepos(repoURLs []string, username, password string, json bool) (tmpDir string, err error) { +func CloneGitRepos(repoURLs []string, username, password string, branch string, json bool) (tmpDir string, err error) { tmpDir, err = ioutil.TempDir("", "ebgit") if err != nil { return "", err @@ -96,8 +98,15 @@ func CloneGitRepos(repoURLs []string, username, password string, json bool) (tmp options.Auth = auth } + if branch != "" { + options.ReferenceName = plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", branch)) + } + if !json { log.Println("Cloning Repository:", repo) + if branch != "" { + log.Println("Cloning Branch:", branch) + } options.Progress = os.Stdout } diff --git a/pkg/git/cloner_test.go b/pkg/git/cloner_test.go index 564013d..e17530d 100644 --- a/pkg/git/cloner_test.go +++ b/pkg/git/cloner_test.go @@ -38,7 +38,7 @@ func TestCloneGitRepos(t *testing.T) { t.Skip("If test cases not running locally, skip cloning external repositories for CI/CD purposes.") } - SearchDir, err := CloneGitRepos([]string{FakeRepo}, "", "", true) + SearchDir, err := CloneGitRepos([]string{FakeRepo}, "", "", "", true) if err != nil { t.Errorf("Failed to clone repository: %s", FakeRepo) }