Repository: openshift-pipelines/pipelines-as-code
Pull request #161 (2021-06-28 17:38:56)

Add test for git


Patch:
diff --git a/pkg/cmd/repository/create.go b/pkg/cmd/repository/create.go
index 946bb2ef..b9ceda33 100644
--- a/pkg/cmd/repository/create.go
+++ b/pkg/cmd/repository/create.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strings"
 
@@ -14,6 +13,7 @@ import (
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli/ui"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/flags"
+	"github.com/openshift-pipelines/pipelines-as-code/pkg/git"
 	"github.com/spf13/cobra"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -51,7 +51,11 @@ func CreateCommand(p cli.Params) *cobra.Command {
 				return err
 			}
 			createOpts.CurrentNS = p.GetNamespace()
-			return create(context.Background(), createOpts)
+			cwd, err := os.Getwd()
+			if err != nil {
+				return err
+			}
+			return create(context.Background(), cwd, createOpts)
 		},
 	}
 	cmd.PersistentFlags().StringVar(&createOpts.RepositoryName, "name", "", "The repository name")
@@ -63,37 +67,6 @@ func CreateCommand(p cli.Params) *cobra.Command {
 	return cmd
 }
 
-// getGitInfo try to detect the current remote for this URL
-func getGitInfo() (string, string) {
-	gitPath, err := exec.LookPath("git")
-	if err != nil {
-		return "", ""
-	}
-	cmd := exec.Command(gitPath, "remote", "get-url", "origin")
-	bgitURL, err := cmd.Output()
-	if err != nil {
-		cmd := exec.Command(gitPath, "remote", "get-url", "upstream")
-		bgitURL, err = cmd.Output()
-		if err != nil {
-			return "", ""
-		}
-	}
-	gitURL := strings.TrimSpace(string(bgitURL))
-	if strings.HasPrefix(gitURL, "git@") {
-		sp := strings.Split(gitURL, ":")
-		prefix := strings.ReplaceAll(sp[0], "git@", "https://")
-		gitURL = fmt.Sprintf("%s/%s", prefix, strings.Join(sp[1:], ":"))
-	}
-	gitURL = strings.TrimSuffix(gitURL, ".git")
-
-	cmd = exec.Command(gitPath, "rev-parse", "--show-toplevel")
-	brootdir, err := cmd.Output()
-	if err != nil {
-		return "", ""
-	}
-	return gitURL, strings.TrimSpace(string(brootdir))
-}
-
 // askToCreateSimplePipeline will try to create a basic pipeline in tekton
 // directory.
 func askToCreateSimplePipeline(gitRoot string, opts CreateOptions) error {
@@ -216,9 +189,9 @@ spec:
 }
 
 // create ...
-func create(ctx context.Context, opts CreateOptions) error {
+func create(ctx context.Context, gitdir string, opts CreateOptions) error {
 	var qs []*survey.Question
-	detectedGitRemoteURL, gitRoot := getGitInfo()
+	gitinfo := git.GetGitInfo(gitdir)
 
 	if opts.TargetNamespace == "" {
 		qs = append(qs, &survey.Question{
@@ -228,8 +201,8 @@ func create(ctx context.Context, opts CreateOptions) error {
 	}
 	if opts.TargetURL == "" {
 		prompt := "Enter the target url: "
-		if detectedGitRemoteURL != "" {
-			prompt = fmt.Sprintf("Enter the target url (default: %s): ", detectedGitRemoteURL)
+		if gitinfo.TargetURL != "" {
+			prompt = fmt.Sprintf("Enter the target url (default: %s): ", gitinfo.TargetURL)
 		}
 		qs = append(qs, &survey.Question{
 			Name:   "TargetURL",
@@ -262,8 +235,8 @@ func create(ctx context.Context, opts CreateOptions) error {
 	if opts.TargetNamespace == "" {
 		opts.TargetNamespace = opts.CurrentNS
 	}
-	if opts.TargetURL == "" && detectedGitRemoteURL != "" {
-		opts.TargetURL = detectedGitRemoteURL
+	if opts.TargetURL == "" && gitinfo.TargetURL != "" {
+		opts.TargetURL = gitinfo.TargetURL
 	} else if opts.TargetURL == "" {
 		return fmt.Errorf("we didn't get a target URL")
 	}
@@ -304,7 +277,7 @@ func create(ctx context.Context, opts CreateOptions) error {
 		opts.TargetNamespace,
 	)
 
-	if err := askToCreateSimplePipeline(gitRoot, opts); err != nil {
+	if err := askToCreateSimplePipeline(gitinfo.TopLevelPath, opts); err != nil {
 		return err
 	}
 
diff --git a/pkg/git/git.go b/pkg/git/git.go
new file mode 100644
index 00000000..6690b42e
--- /dev/null
+++ b/pkg/git/git.go
@@ -0,0 +1,63 @@
+package git
+
+import (
+	"bytes"
+	"fmt"
+	"os/exec"
+	"strings"
+)
+
+type Info struct {
+	TargetURL    string
+	TopLevelPath string
+}
+
+func RunGit(dir string, args ...string) (string, error) {
+	gitPath, err := exec.LookPath("git")
+	if err != nil {
+		// nolint: nilerr
+		return "", nil
+	}
+	c := exec.Command(gitPath, args...)
+	var output bytes.Buffer
+	c.Stderr = &output
+	c.Stdout = &output
+	// This is the optional working directory. If not set, it defaults to the current
+	// working directory of the process.
+	if dir != "" {
+		c.Dir = dir
+	}
+	if err := c.Run(); err != nil {
+		return "", err
+	}
+	return output.String(), nil
+}
+
+// GetGitInfo try to detect the current remote for this URL return the origin url transformed and the topdir
+func GetGitInfo(dir string) Info {
+	gitURL, err := RunGit(dir, "remote", "get-url", "origin")
+	if err != nil {
+		gitURL, err = RunGit(dir, "remote", "get-url", "upstream")
+		if err != nil {
+			return Info{}
+		}
+	}
+	gitURL = strings.TrimSpace(gitURL)
+	gitURL = strings.TrimSuffix(gitURL, ".git")
+
+	if strings.HasPrefix(gitURL, "git@") {
+		sp := strings.Split(gitURL, ":")
+		prefix := strings.ReplaceAll(sp[0], "git@", "https://")
+		gitURL = fmt.Sprintf("%s/%s", prefix, strings.Join(sp[1:], ":"))
+	}
+
+	brootdir, err := RunGit(dir, "rev-parse", "--show-toplevel")
+	if err != nil {
+		return Info{}
+	}
+
+	return Info{
+		TargetURL:    gitURL,
+		TopLevelPath: strings.TrimSpace(brootdir),
+	}
+}


Test patch:
diff --git a/pkg/git/git_test.go b/pkg/git/git_test.go
new file mode 100644
index 00000000..bd6dfa5f
--- /dev/null
+++ b/pkg/git/git_test.go
@@ -0,0 +1,61 @@
+package git
+
+import (
+	"testing"
+
+	"gotest.tools/v3/assert"
+	"gotest.tools/v3/fs"
+)
+
+func TestGetGitInfo(t *testing.T) {
+	tests := []struct {
+		name         string
+		want         Info
+		gitURL       string
+		remoteTarget string
+	}{
+		{
+			name:         "Get git info",
+			gitURL:       "https://github.com/chmouel/demo",
+			remoteTarget: "origin",
+			want: Info{
+				TargetURL: "https://github.com/chmouel/demo",
+			},
+		},
+		{
+			name:         "Get git info remove .git suffix",
+			gitURL:       "git@github.com:chmouel/demo.git",
+			remoteTarget: "origin",
+			want: Info{
+				TargetURL: "https://github.com/chmouel/demo",
+			},
+		},
+		{
+			name:         "Transform SSH info",
+			gitURL:       "git@github.com:chmouel/demo",
+			remoteTarget: "origin",
+			want: Info{
+				TargetURL: "https://github.com/chmouel/demo",
+			},
+		},
+		{
+			name:         "Transform SSH info from upstream",
+			gitURL:       "git@github.com:chmouel/demo",
+			remoteTarget: "upstream",
+			want: Info{
+				TargetURL: "https://github.com/chmouel/demo",
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			nd := fs.NewDir(t, "TestGetGitInfo")
+			defer nd.Remove()
+			gitDir := nd.Path()
+			_, _ = RunGit(gitDir, "init")
+			_, _ = RunGit(gitDir, "remote", "add", tt.remoteTarget, tt.gitURL)
+
+			assert.Equal(t, GetGitInfo(gitDir).TargetURL, tt.want.TargetURL)
+		})
+	}
+}