projectBranches function

Makes use of canBranchProject and projectBranchName (last two CLs) to
create a list of branch names for all branchable projects.

BUG=chromium:980346
TEST=run_tests.sh

Change-Id: I6f12f370cfebb513964dbc6eb5b0db01aadd93c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/go/+/1696107
Reviewed-by: Jack Neus <jackneus@google.com>
Commit-Queue: Jack Neus <jackneus@google.com>
Tested-by: Jack Neus <jackneus@google.com>
diff --git a/cmd/branch_util/branch.go b/cmd/branch_util/branch.go
index be43f16..19022de 100644
--- a/cmd/branch_util/branch.go
+++ b/cmd/branch_util/branch.go
@@ -86,7 +86,7 @@
 }
 
 // projectBranchName determines the git branch name for the project.
-func (c *createBranchRun) projectBranchName(branch string, project repo.Project, original string) string {
+func projectBranchName(branch string, project repo.Project, original string) string {
 	// If the project has only one checkout, then the base branch name is fine.
 	var checkouts []string
 	manifest := checkout.Manifest()
@@ -118,3 +118,20 @@
 	}
 	return branch + suffix
 }
+
+// projectBranches returns a list of ProjectBranch structs:
+// one for each branchable project.
+func projectBranches(branch, original string) []ProjectBranch {
+	var projectBranches []ProjectBranch
+	manifest := checkout.Manifest()
+	for _, project := range manifest.Projects {
+		if canBranchProject(manifest, project) {
+			projectBranches = append(projectBranches,
+				ProjectBranch{
+					project:    project,
+					branchName: projectBranchName(branch, project, original),
+				})
+		}
+	}
+	return projectBranches
+}
diff --git a/cmd/branch_util/branch_test.go b/cmd/branch_util/branch_test.go
index 9aae654..6a1afd7 100644
--- a/cmd/branch_util/branch_test.go
+++ b/cmd/branch_util/branch_test.go
@@ -4,11 +4,13 @@
 package main
 
 import (
+	"reflect"
+	"testing"
+
 	"github.com/golang/mock/gomock"
 	mock_checkout "go.chromium.org/chromiumos/infra/go/internal/checkout/mock"
 	"go.chromium.org/chromiumos/infra/go/internal/repo"
 	"gotest.tools/assert"
-	"testing"
 )
 
 var branchNameTestManifest = repo.Manifest{
@@ -64,15 +66,14 @@
 
 	m := mock_checkout.NewMockCheckout(ctl)
 	checkout = m
-	c := &createBranchRun{}
 	manifest := branchNameTestManifest
 	m.EXPECT().
 		Manifest().
 		Return(manifest).
 		AnyTimes()
-	assert.Equal(t, c.projectBranchName("mybranch", manifest.Projects[0], ""), "mybranch")
-	assert.Equal(t, c.projectBranchName("mybranch", manifest.Projects[1], ""), "mybranch-factory-100")
-	assert.Equal(t, c.projectBranchName("mybranch", manifest.Projects[2], ""), "mybranch-101")
+	assert.Equal(t, projectBranchName("mybranch", manifest.Projects[0], ""), "mybranch")
+	assert.Equal(t, projectBranchName("mybranch", manifest.Projects[1], ""), "mybranch-factory-100")
+	assert.Equal(t, projectBranchName("mybranch", manifest.Projects[2], ""), "mybranch-101")
 }
 
 func TestProjectBranchName_withOriginal(t *testing.T) {
@@ -81,14 +82,13 @@
 
 	m := mock_checkout.NewMockCheckout(ctl)
 	checkout = m
-	c := &createBranchRun{}
 	manifest := branchNameTestManifest
 	m.EXPECT().
 		Manifest().
 		Return(manifest).
 		AnyTimes()
-	assert.Equal(t, c.projectBranchName("mybranch", manifest.Projects[3], "oldbranch"), "mybranch-factory-100")
-	assert.Equal(t, c.projectBranchName("mybranch", manifest.Projects[4], "oldbranch"), "mybranch-factory-101")
+	assert.Equal(t, projectBranchName("mybranch", manifest.Projects[3], "oldbranch"), "mybranch-factory-100")
+	assert.Equal(t, projectBranchName("mybranch", manifest.Projects[4], "oldbranch"), "mybranch-factory-101")
 }
 
 func TestCanBranchProject_annotation(t *testing.T) {
@@ -111,3 +111,45 @@
 	// project is not branchable.
 	assert.Assert(t, !canBranchProject(manifest, manifest.Projects[5]))
 }
+
+var branchesTestManifest = repo.Manifest{
+	Projects: []repo.Project{
+		// Basic project. Only one checkout, so we can just use the branch name.
+		{Path: "bar/", Name: "chromiumos/bar", Revision: "100", RemoteName: "cros"},
+		// Project with multiple checkouts. Upstream/revision will be used as a suffix.
+		{Path: "foo1/", Name: "foo", Upstream: "refs/heads/factory-100",
+			Annotations: []repo.Annotation{
+				{Name: "branch-mode", Value: "create"},
+			},
+		},
+		{Path: "foo2/", Name: "foo",
+			Annotations: []repo.Annotation{
+				{Name: "branch-mode", Value: "pin"},
+			},
+		},
+	},
+	Remotes: []repo.Remote{
+		{Name: "cros"},
+	},
+}
+
+func TestProjectBranches(t *testing.T) {
+	ctl := gomock.NewController(t)
+	defer ctl.Finish()
+
+	m := mock_checkout.NewMockCheckout(ctl)
+	checkout = m
+	manifest := branchesTestManifest
+	m.EXPECT().
+		Manifest().
+		Return(manifest).
+		AnyTimes()
+
+	expected := []ProjectBranch{
+		{project: manifest.Projects[0], branchName: "mybranch"},
+		{project: manifest.Projects[1], branchName: "mybranch-factory-100"},
+	}
+
+	branchNames := projectBranches("mybranch", "oldbranch")
+	assert.Assert(t, reflect.DeepEqual(expected, branchNames))
+}