diff --git a/CHANGELOG.md b/CHANGELOG.md index fc92b07..38419e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) ### Removed ### Fixed - Gitlab token length requirements; thanks @dschafhauser +- Appending trailing slashes on urls and filepaths; thanks @dschafhauser ### Security ## [1.7.5] - 12/11/21 diff --git a/cmd/clone.go b/cmd/clone.go index 79cdef9..6146748 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -30,7 +30,7 @@ var cloneCmd = &cobra.Command{ func cloneFunc(cmd *cobra.Command, argz []string) { if cmd.Flags().Changed("path") { - absolutePath := configs.EnsureTrailingSlash((cmd.Flag("path").Value.String())) + absolutePath := configs.EnsureTrailingSlashOnFilePath((cmd.Flag("path").Value.String())) os.Setenv("GHORG_ABSOLUTE_PATH_TO_CLONE_TO", absolutePath) } diff --git a/cmd/root.go b/cmd/root.go index 00a4768..44456e0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -109,8 +109,10 @@ func getOrSetDefaults(envVar string) { } else { s := viper.GetString(envVar) // envs that need a trailing slash - if envVar == "GHORG_SCM_BASE_URL" || envVar == "GHORG_ABSOLUTE_PATH_TO_CLONE_TO" { - os.Setenv(envVar, configs.EnsureTrailingSlash(s)) + if envVar == "GHORG_SCM_BASE_URL" { + os.Setenv(envVar, configs.EnsureTrailingSlashOnURL(s)) + } else if envVar == "GHORG_ABSOLUTE_PATH_TO_CLONE_TO" { + os.Setenv(envVar, configs.EnsureTrailingSlashOnFilePath(s)) } else { os.Setenv(envVar, s) } diff --git a/configs/configs.go b/configs/configs.go index ae80c01..647c923 100644 --- a/configs/configs.go +++ b/configs/configs.go @@ -61,14 +61,25 @@ func isZero(value interface{}) bool { return value == reflect.Zero(reflect.TypeOf(value)).Interface() } +// EnsureTrailingSlashOnURL takes a url and ensures a single / is appened +func EnsureTrailingSlashOnURL(s string) string { + trailing := "/" + + if !strings.HasSuffix(s, trailing) { + s = s + trailing + } + + return s +} + func GetAbsolutePathToCloneTo() string { path := HomeDir() path = filepath.Join(path, "ghorg") - return EnsureTrailingSlash(path) + return EnsureTrailingSlashOnFilePath(path) } -// EnsureTrailingSlash takes a string and ensures a single / is appened -func EnsureTrailingSlash(s string) string { +// EnsureTrailingSlashOnFilePath takes a filepath and ensures a single / is appened +func EnsureTrailingSlashOnFilePath(s string) string { trailing := GetCorrectFilePathSeparator() if !strings.HasSuffix(s, trailing) { diff --git a/configs/configs_test.go b/configs/configs_test.go index 31e8101..61398e5 100644 --- a/configs/configs_test.go +++ b/configs/configs_test.go @@ -2,6 +2,7 @@ package configs_test import ( "os" + "runtime" "testing" "github.com/gabrie30/ghorg/configs" @@ -95,3 +96,81 @@ func TestVerifyConfigsSetCorrectly(t *testing.T) { }) } + +func TestVerifyTrialingSlashes(t *testing.T) { + + t.Run("When cloning github", func(tt *testing.T) { + os.Setenv("GHORG_SCM_TYPE", "github") + os.Setenv("GHORG_GITHUB_TOKEN", "") + + err := configs.VerifyTokenSet() + if err != configs.ErrNoGitHubToken { + tt.Errorf("Expected ErrNoGitHubTokenError, got: %v", err) + } + + }) + + t.Run("When cloning gitlab", func(tt *testing.T) { + os.Setenv("GHORG_SCM_TYPE", "gitlab") + os.Setenv("GHORG_GITLAB_TOKEN", "") + + err := configs.VerifyTokenSet() + if err != configs.ErrNoGitLabToken { + tt.Errorf("Expected ErrNoGitLabTokenError, got: %v", err) + } + + }) + + t.Run("When cloning bitbucket with no username", func(tt *testing.T) { + os.Setenv("GHORG_SCM_TYPE", "bitbucket") + os.Setenv("GHORG_BITBUCKET_USERNAME", "") + os.Setenv("GHORG_BITBUCKET_APP_PASSWORD", "12345678912345678901") + err := configs.VerifyTokenSet() + if err != configs.ErrNoBitbucketUsername { + tt.Errorf("Expected ErrNoBitbucketUsername, got: %v", err) + } + + }) + + t.Run("When cloning bitbucket with username but no app password", func(tt *testing.T) { + os.Setenv("GHORG_SCM_TYPE", "bitbucket") + os.Setenv("GHORG_BITBUCKET_USERNAME", "bitbucketuser") + os.Setenv("GHORG_BITBUCKET_APP_PASSWORD", "") + err := configs.VerifyTokenSet() + if err != configs.ErrNoBitbucketAppPassword { + tt.Errorf("Expected ErrNoBitbucketAppPassword, got: %v", err) + } + + }) +} + +func TestTrailingSlashes(t *testing.T) { + t.Run("URL's with no trailing slash should get one", func(tt *testing.T) { + got := configs.EnsureTrailingSlashOnURL("github.com") + want := "github.com/" + if got != want { + tt.Errorf("Expected %v, got: %v", want, got) + } + + }) + + t.Run("URL's with a trailing slash should only have one", func(tt *testing.T) { + got := configs.EnsureTrailingSlashOnURL("github.com/") + want := "github.com/" + if got != want { + tt.Errorf("Expected %v, got: %v", want, got) + } + + }) + + t.Run("Filepaths should be correctly appeneded", func(tt *testing.T) { + got := configs.EnsureTrailingSlashOnFilePath("foo") + want := "foo/" + if runtime.GOOS == "windows" { + want = "foo\\" + } + if got != want { + tt.Errorf("Expected %v, got: %v", want, got) + } + }) +}