From d60ade667f2e5d9e77a2e13af6ad09165dc6bab8 Mon Sep 17 00:00:00 2001 From: HarikrishnanBalagopal Date: Fri, 9 Jun 2023 15:44:52 +0530 Subject: [PATCH] fix: git url parse (#1042) Signed-off-by: Harikrishnan Balagopal --- common/utils.go | 67 ++++++++++++------- .../kubernetes/apiresource/buildconfig.go | 2 +- .../kubernetes/apiresource/pipeline.go | 2 +- .../kubernetes/buildconfigtransformer.go | 5 +- transformer/kubernetes/tektontransformer.go | 1 + 5 files changed, 51 insertions(+), 26 deletions(-) diff --git a/common/utils.go b/common/utils.go index b57a4febc..217a1eb60 100644 --- a/common/utils.go +++ b/common/utils.go @@ -1200,21 +1200,32 @@ func ConvertInterfaceToSliceOfStrings(xI interface{}) ([]string, error) { // GatherGitInfo tries to find the git repo for the path if one exists. func GatherGitInfo(path string) (repoName, repoDir, repoHostName, repoURL, repoBranch string, err error) { if finfo, err := os.Stat(path); err != nil { - logrus.Errorf("Failed to stat the path %q Error %q", path, err) - return "", "", "", "", "", err + return "", "", "", "", "", fmt.Errorf("failed to stat the path '%s' . Error %w", path, err) } else if !finfo.IsDir() { pathDir := filepath.Dir(path) - logrus.Debugf("The path %q is not a directory. Using %q instead.", path, pathDir) + logrus.Debugf("The path '%s' is not a directory. Using the path '%s' instead.", path, pathDir) path = pathDir } repo, err := git.PlainOpenWithOptions(path, &git.PlainOpenOptions{DetectDotGit: true}) if err != nil { - logrus.Debugf("Unable to open the path %q as a git repo. Error: %q", path, err) - return "", "", "", "", "", err + return "", "", "", "", "", fmt.Errorf("failed to open the path '%s' as a git repo. Error: %w", path, err) } + workTree, err := repo.Worktree() + if err != nil { + return "", "", "", "", "", fmt.Errorf("failed to get the repo working tree/directory. Error: %w", err) + } + repoDir = workTree.Filesystem.Root() + ref, err := repo.Head() + if err != nil { + return "", "", "", "", "", fmt.Errorf("failed to get the current branch. Error: %w", err) + } + logrus.Debugf("current branch/tag: %#v", ref) + repoBranch = filepath.Base(string(ref.Name())) remotes, err := repo.Remotes() if err != nil || len(remotes) == 0 { - logrus.Debugf("No remotes found at path %q Error: %q", path, err) + logrus.Debugf("failed to find any remote repo urls for the repo at path '%s' . Error: %q", path, err) + logrus.Debugf("git no remotes case - repoName '%s', repoDir '%s', repoHostName '%s', repoURL '%s', repoBranch '%s'", repoName, repoDir, repoHostName, repoURL, repoBranch) + return repoName, repoDir, repoHostName, repoURL, repoBranch, nil } var preferredRemote *git.Remote if preferredRemote = getGitRemoteByName(remotes, "upstream"); preferredRemote == nil { @@ -1222,35 +1233,45 @@ func GatherGitInfo(path string) (repoName, repoDir, repoHostName, repoURL, repoB preferredRemote = remotes[0] } } - if workTree, err := repo.Worktree(); err == nil { - repoDir = workTree.Filesystem.Root() - } else { - logrus.Debugf("Unable to get the repo directory. Error: %q", err) - } - if ref, err := repo.Head(); err == nil { - repoBranch = filepath.Base(string(ref.Name())) - } else { - logrus.Debugf("Unable to get the current branch. Error: %q", err) - } if len(preferredRemote.Config().URLs) == 0 { err = fmt.Errorf("unable to get origins") logrus.Debugf("%s", err) } u := preferredRemote.Config().URLs[0] - if strings.HasPrefix(u, "git") { - parts := strings.Split(u, ":") - if len(parts) == 2 { - u = parts[1] + repoURL = u + if strings.HasPrefix(u, "git@") { + // Example: git@github.com:konveyor/move2kube.git + withoutGitAt := strings.TrimPrefix(u, "git@") + idx := strings.Index(withoutGitAt, ":") + if idx < 0 { + return "", "", "", "", "", fmt.Errorf("failed to parse the remote host url '%s' as a git ssh url. Error: %w", u, err) } + domain := withoutGitAt[:idx] + rest := withoutGitAt[idx+1:] + newUrl := "https://" + domain + "/" + rest + logrus.Debugf("final parsed git ssh url to normal url: '%s'", newUrl) + giturl, err := url.Parse(newUrl) + if err != nil { + return "", "", "", "", "", fmt.Errorf("failed to parse the remote host url '%s' . Error: %w", newUrl, err) + } + logrus.Debugf("parsed ssh case - giturl: %#v", giturl) + repoHostName = giturl.Host + repoName = filepath.Base(giturl.Path) + repoName = strings.TrimSuffix(repoName, filepath.Ext(repoName)) + logrus.Debugf("git ssh case - repoName '%s', repoDir '%s', repoHostName '%s', repoURL '%s', repoBranch '%s'", repoName, repoDir, repoHostName, repoURL, repoBranch) + return repoName, repoDir, repoHostName, repoURL, repoBranch, nil } + giturl, err := url.Parse(u) if err != nil { - logrus.Debugf("Unable to get origin remote host : %s", err) + return "", "", "", "", "", fmt.Errorf("failed to parse the remote host url '%s' . Error: %w", u, err) } + logrus.Errorf("parsed normal case - giturl: %#v", giturl) + repoHostName = giturl.Host repoName = filepath.Base(giturl.Path) repoName = strings.TrimSuffix(repoName, filepath.Ext(repoName)) - err = nil - return + logrus.Debugf("git normal case - repoName '%s', repoDir '%s', repoHostName '%s', repoURL '%s', repoBranch '%s'", repoName, repoDir, repoHostName, repoURL, repoBranch) + return repoName, repoDir, repoHostName, repoURL, repoBranch, nil } func getGitRemoteByName(remotes []*git.Remote, remoteName string) *git.Remote { diff --git a/transformer/kubernetes/apiresource/buildconfig.go b/transformer/kubernetes/apiresource/buildconfig.go index 860c46a1f..27775ab8d 100644 --- a/transformer/kubernetes/apiresource/buildconfig.go +++ b/transformer/kubernetes/apiresource/buildconfig.go @@ -106,7 +106,7 @@ func (*BuildConfig) getBuildSource(irBuildConfig irtypes.BuildConfig, ir irtypes if contextPath != "" { _, repoDir, _, repoURL, repoBranchName, err = common.GatherGitInfo(irBuildConfig.ContainerBuild.ContextPath) if err != nil { - logrus.Debugf("Unable to identify git repo for %s : %s", irBuildConfig.ContainerBuild.ContextPath, err) + logrus.Debugf("failed to find a git repo at the path '%s' . Error: %q", irBuildConfig.ContainerBuild.ContextPath, err) } } if repoDir != "" { diff --git a/transformer/kubernetes/apiresource/pipeline.go b/transformer/kubernetes/apiresource/pipeline.go index b2f8d5e1b..83b651c30 100644 --- a/transformer/kubernetes/apiresource/pipeline.go +++ b/transformer/kubernetes/apiresource/pipeline.go @@ -83,7 +83,7 @@ func (*Pipeline) createNewResource(irpipeline irtypes.Pipeline, ir irtypes.Enhan if container.Build.ContainerBuildType == irtypes.DockerfileContainerBuildType { _, repoDir, _, gitRepoURL, branchName, err := common.GatherGitInfo(container.Build.ContextPath) if err != nil { - logrus.Debugf("failed to identify the git repo in the directory '%s' . Error: %q", container.Build.ContextPath, err) + logrus.Debugf("failed to find a git repo at the path '%s' . Error: %q", container.Build.ContextPath, err) } cloneTaskName := fmt.Sprintf("clone-%d", containerIndex) if gitRepoURL == "" { diff --git a/transformer/kubernetes/buildconfigtransformer.go b/transformer/kubernetes/buildconfigtransformer.go index d035448f4..0b32bfa03 100644 --- a/transformer/kubernetes/buildconfigtransformer.go +++ b/transformer/kubernetes/buildconfigtransformer.go @@ -188,7 +188,10 @@ func (t *BuildConfig) setupEnhancedIR(oldir irtypes.IR, planName string) irtypes continue } imageStreamName, imageStreamTag := new(apiresource.ImageStream).GetImageStreamNameAndTag(imageName) - _, _, gitHostName, gitURL, _, _ := common.GatherGitInfo(irContainer.Build.ContextPath) + _, _, gitHostName, gitURL, _, err := common.GatherGitInfo(irContainer.Build.ContextPath) + if err != nil { + logrus.Debugf("failed to gather git info. Error: %q", err) + } if gitURL == "" { // No git repo. Create build config and secrets anyway with placeholders. gitDomain := "generic" diff --git a/transformer/kubernetes/tektontransformer.go b/transformer/kubernetes/tektontransformer.go index 12d6ddc07..6ea775e84 100644 --- a/transformer/kubernetes/tektontransformer.go +++ b/transformer/kubernetes/tektontransformer.go @@ -269,6 +269,7 @@ func (t *Tekton) setupEnhancedIR(oldir irtypes.IR, name string) irtypes.Enhanced } _, _, gitRepoHostName, gitRepoURL, _, err := common.GatherGitInfo(container.Build.ContextPath) if err != nil { + logrus.Debugf("failed to gather git info. Error: %q", err) if gitRepoURL != "" { logrus.Warnf("Failed to parse git repo url %q Error: %q", gitRepoURL, err) }