diff --git a/cmd/config-fix.go b/cmd/config-fix.go index 82d43209..df4beccf 100644 --- a/cmd/config-fix.go +++ b/cmd/config-fix.go @@ -18,6 +18,9 @@ package cmd import ( "fmt" + "os" + "path/filepath" + "runtime" "strings" "github.com/minio/mc/pkg/console" @@ -26,6 +29,8 @@ import ( ) func fixConfig() { + // Migrate config location on windows + fixConfigLocation() // Fix config V3 fixConfigV3() // Fix config V6 @@ -240,3 +245,45 @@ func fixConfigV6() { console.Infof("Successfully fixed %s broken config for version `6`.\n", mustGetMcConfigPath()) } } + +// fixConfigLocation will resolve the possible duplicate location of Windows config files. +// If there is duplicate configs, it will use the currently enabled config location and +// move it to the 'normalized' location. +// See https://github.com/minio/mc/pull/2898 +func fixConfigLocation() { + if runtime.GOOS != "windows" || mcCustomConfigDir != mustGetMcConfigDir() { + return + } + if !strings.HasSuffix(strings.ToLower(filepath.Base(os.Args[0])), ".exe") { + // Most likely scenario, command was called as 'mc'. + // If there is a config at legacyLoc+".exe", rename it. + legacyLoc := mcCustomConfigDir + ".exe" + unusedLoc := mcCustomConfigDir + ".unused" + _ = os.Rename(legacyLoc, unusedLoc) + return + } + + // mc was called with '.exe'; + // config can have changed location. + _, err := os.Stat(mcCustomConfigDir) + wantExists := !os.IsNotExist(err) + + legFileName := mcCustomConfigDir + ".exe" + _, err = os.Stat(legFileName) + legExists := !os.IsNotExist(err) + switch { + case legExists && wantExists: + // Both exist and mc was called with legacy path (.exe) + // Rename the 'mc' config and move the legacy location one to where we want it. + backupdir := fmt.Sprintf("%s.unused\\", mcCustomConfigDir) + _ = os.RemoveAll(backupdir) + err := os.Rename(mcCustomConfigDir, backupdir) + fatalIf(probe.NewError(err), fmt.Sprintln("Renaming unused config", mcCustomConfigDir, "->", backupdir, "failed. Please rename/remove file.")) + fallthrough + case !wantExists && legExists: + err := os.Rename(legFileName, mcCustomConfigDir) + fatalIf(probe.NewError(err), fmt.Sprintln("Migrating config location", legFileName, "->", mcCustomConfigDir, "failed. Please move config file.")) + default: + // Legacy does not exist. + } +} diff --git a/cmd/config.go b/cmd/config.go index b7f3a2b6..98e3a3f2 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -23,6 +23,7 @@ import ( "path/filepath" "regexp" "runtime" + "strings" "github.com/minio/mc/pkg/probe" @@ -46,16 +47,24 @@ func getMcConfigDir() (string, *probe.Error) { if e != nil { return "", probe.NewError(e) } - var configDir string - // For windows the path is slightly different - if runtime.GOOS == "windows" { - configDir = filepath.Join(homeDir, globalMCConfigWindowsDir) - } else { - configDir = filepath.Join(homeDir, globalMCConfigDir) - } + configDir := filepath.Join(homeDir, defaultMCConfigDir()) return configDir, nil } +// Return default default mc config directory. +// Generally you want to use getMcConfigDir which returns custom overrides. +func defaultMCConfigDir() string { + if runtime.GOOS == "windows" { + // For windows the path is slightly different + cmd := filepath.Base(os.Args[0]) + if strings.HasSuffix(strings.ToLower(cmd), ".exe") { + cmd = cmd[:strings.LastIndex(cmd, ".")] + } + return fmt.Sprintf("%s\\", cmd) + } + return fmt.Sprintf(".%s/", filepath.Base(os.Args[0])) +} + // mustGetMcConfigDir - construct MinIO Client config folder or fail func mustGetMcConfigDir() (configDir string) { configDir, err := getMcConfigDir() diff --git a/cmd/globals.go b/cmd/globals.go index 88865ca5..a837d61e 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -19,20 +19,11 @@ package cmd import ( "crypto/x509" - "fmt" - "os" - "path/filepath" "github.com/minio/cli" "github.com/minio/mc/pkg/console" ) -// mc configuration related constants. -var ( - globalMCConfigDir = fmt.Sprintf(".%s/", filepath.Base(os.Args[0])) - globalMCConfigWindowsDir = fmt.Sprintf("%s\\", filepath.Base(os.Args[0])) -) - const ( globalMCConfigVersion = "9" diff --git a/cmd/main.go b/cmd/main.go index 27a0374b..9f7b7222 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -105,7 +105,10 @@ func Main(args []string) { // Set the mc app name. appName := filepath.Base(args[0]) - + if runtime.GOOS == "windows" && strings.HasSuffix(strings.ToLower(appName), ".exe") { + // Trim ".exe" from Windows executable. + appName = appName[:strings.LastIndex(appName, ".")] + } // Run the app - exit on error. if err := registerApp(appName).Run(args); err != nil { os.Exit(1) diff --git a/pkg/console/console.go b/pkg/console/console.go index 6192c409..47e44bbe 100644 --- a/pkg/console/console.go +++ b/pkg/console/console.go @@ -20,11 +20,10 @@ package console import ( "fmt" "os" + "path/filepath" "strings" "sync" - "path/filepath" - "github.com/fatih/color" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty"