1
0
mirror of https://github.com/minio/mc.git synced 2025-11-16 11:02:34 +03:00

Deprecate bash-completion support

This commit is contained in:
Harshavardhana
2015-04-17 19:42:32 -07:00
parent 07ddad4b1c
commit 5f4d89ccd5
7 changed files with 60 additions and 101 deletions

View File

@@ -37,7 +37,7 @@ func aliasExpand(aliasedURL string, aliases map[string]string) (newURL string, e
url, err := url.Parse(aliasedURL) url, err := url.Parse(aliasedURL)
if err != nil { if err != nil {
// Not a valid URL. Return error // Not a valid URL. Return error
return "", iodine.New(errInvalidURL{aliasedURL}, nil) return "", iodine.New(errInvalidURL{url: aliasedURL}, nil)
} }
// Not an aliased URL // Not an aliased URL
@@ -47,7 +47,7 @@ func aliasExpand(aliasedURL string, aliases map[string]string) (newURL string, e
for aliasName, expandedURL := range aliases { for aliasName, expandedURL := range aliases {
if !isValidAliasName(aliasName) { if !isValidAliasName(aliasName) {
return "", iodine.New(errInvalidAliasName{alias: aliasName}, nil) return "", iodine.New(errInvalidAliasName{name: aliasName}, nil)
} }
if strings.HasPrefix(aliasedURL, aliasName) { if strings.HasPrefix(aliasedURL, aliasName) {
// Match found. Expand it. // Match found. Expand it.

View File

@@ -18,7 +18,6 @@ package main
import ( import (
"net/url" "net/url"
"path"
"time" "time"
"io" "io"
@@ -47,19 +46,6 @@ func startBar(size int64) *pb.ProgressBar {
return bar return bar
} }
func getMcBashCompletionFilename() (string, error) {
configDir, err := getMcConfigDir()
if err != nil {
return "", err
}
return path.Join(configDir, "mc.bash_completion"), nil
}
func mustGetMcBashCompletionFilename() string {
p, _ := getMcBashCompletionFilename()
return p
}
type clientManager interface { type clientManager interface {
getSourceReader(urlStr string) (reader io.ReadCloser, length int64, md5hex string, err error) getSourceReader(urlStr string) (reader io.ReadCloser, length int64, md5hex string, err error)
getTargetWriter(urlStr string, md5Hex string, length int64) (io.WriteCloser, error) getTargetWriter(urlStr string, md5Hex string, length int64) (io.WriteCloser, error)
@@ -104,8 +90,7 @@ func (manager mcClientManager) getTargetWriter(urlStr string, md5Hex string, len
return targetClnt.Put(bucket, object, md5Hex, length) return targetClnt.Put(bucket, object, md5Hex, length)
} }
// getNewClient gets a new client // getNewClient gives a new client interface
// TODO refactor this to be more testable
func (manager mcClientManager) getNewClient(urlStr string, debug bool) (clnt client.Client, err error) { func (manager mcClientManager) getNewClient(urlStr string, debug bool) (clnt client.Client, err error) {
u, err := url.Parse(urlStr) u, err := url.Parse(urlStr)
if err != nil { if err != nil {

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"strings"
"time" "time"
"github.com/cheggaaa/pb" "github.com/cheggaaa/pb"
@@ -35,13 +34,3 @@ func (s *MySuite) TestStatusBar(c *C) {
c.Assert(bar.NotPrint, Equals, true) c.Assert(bar.NotPrint, Equals, true)
c.Assert(bar.ShowSpeed, Equals, true) c.Assert(bar.ShowSpeed, Equals, true)
} }
func (s *MySuite) TestBashCompletionFilename(c *C) {
file, err := getMcBashCompletionFilename()
c.Assert(err, IsNil)
c.Assert(file, Not(Equals), "mc.bash_completion")
c.Assert(strings.HasSuffix(file, "mc.bash_completion"), Equals, true)
file2 := mustGetMcBashCompletionFilename()
c.Assert(file, Equals, file2)
}

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"bytes"
"net/url" "net/url"
"os" "os"
"path" "path"
@@ -141,11 +140,21 @@ func writeConfig(config qdb.Store) error {
func saveConfig(ctx *cli.Context) error { func saveConfig(ctx *cli.Context) error {
switch ctx.Args().Get(0) { switch ctx.Args().Get(0) {
case "generate": case "generate":
err := writeConfig(generateNewConfig()) if isMcConfigExist() {
return iodine.New(errConfigExists{}, nil)
}
err := writeConfig(newConfig())
if err != nil { if err != nil {
return iodine.New(err, nil) return iodine.New(err, nil)
} }
return nil return nil
case "check":
// verify if the binary can load config file
configStore, err := getMcConfig()
if err != nil || configStore == nil {
return iodine.New(err, nil)
}
return nil
default: default:
configStore, err := parseConfigInput(ctx) configStore, err := parseConfigInput(ctx)
if err != nil { if err != nil {
@@ -155,9 +164,8 @@ func saveConfig(ctx *cli.Context) error {
} }
} }
func generateNewConfig() (config qdb.Store) { func newConfig() (config qdb.Store) {
configStore := qdb.NewStore(mcCurrentConfigVersion) configStore := qdb.NewStore(mcCurrentConfigVersion)
s3Auth := make(map[string]string) s3Auth := make(map[string]string)
localAuth := make(map[string]string) localAuth := make(map[string]string)
@@ -192,12 +200,15 @@ func parseConfigInput(ctx *cli.Context) (config qdb.Store, err error) {
aliasName := alias[0] aliasName := alias[0]
url := strings.TrimSuffix(alias[1], "/") url := strings.TrimSuffix(alias[1], "/")
if strings.HasPrefix(aliasName, "http") { if strings.HasPrefix(aliasName, "http") {
return nil, iodine.New(errInvalidAliasName{alias: aliasName}, nil) return nil, iodine.New(errInvalidAliasName{name: aliasName}, nil)
} }
if !strings.HasPrefix(url, "http") { if !strings.HasPrefix(url, "http") {
return nil, iodine.New(errInvalidURL{url: url}, nil) return nil, iodine.New(errInvalidURL{url: url}, nil)
} }
aliases := configStore.GetMapString("Aliases") aliases := configStore.GetMapString("Aliases")
if _, ok := aliases[aliasName]; ok {
return nil, iodine.New(errAliasExists{name: aliasName}, nil)
}
aliases[aliasName] = url aliases[aliasName] = url
configStore.SetMapString("Aliases", aliases) configStore.SetMapString("Aliases", aliases)
return configStore, nil return configStore, nil
@@ -233,8 +244,8 @@ func getHostConfig(requestURL string) (map[string]string, error) {
return nil, iodine.New(errNoMatchingHost{}, nil) return nil, iodine.New(errNoMatchingHost{}, nil)
} }
// saveConfigCmd writes config file to disk // doConfigCmd is the handler for "mc config" sub-command.
func saveConfigCmd(ctx *cli.Context) { func doConfigCmd(ctx *cli.Context) {
// show help if nothing is set // show help if nothing is set
if len(ctx.Args()) < 1 && !ctx.IsSet("completion") && !ctx.IsSet("alias") { if len(ctx.Args()) < 1 && !ctx.IsSet("completion") && !ctx.IsSet("alias") {
cli.ShowCommandHelpAndExit(ctx, "config", 1) // last argument is exit code cli.ShowCommandHelpAndExit(ctx, "config", 1) // last argument is exit code
@@ -245,49 +256,14 @@ func saveConfigCmd(ctx *cli.Context) {
console.Fatalln("mc: Unable to identify config file path") console.Fatalln("mc: Unable to identify config file path")
} }
err = saveConfig(ctx) err = saveConfig(ctx)
if os.IsExist(iodine.ToError(err)) { switch iodine.ToError(err).(type) {
case errConfigExists:
log.Debug.Println(iodine.New(err, nil)) log.Debug.Println(iodine.New(err, nil))
console.Fatalln("mc: Configuration file " + configPath + " already exists") console.Fatalln("mc: Configuration file " + configPath + " already exists")
} default:
if err != nil { // unexpected error
log.Debug.Println(iodine.New(err, nil)) log.Debug.Println(iodine.New(err, nil))
console.Fatalln("mc: Unable to generate config file", configPath) console.Fatalln("mc: Unable to generate config file", configPath)
} }
console.Infoln("mc: Configuration written to " + configPath + ". Please update your access credentials.") console.Infoln("mc: Configuration written to " + configPath + ". Please update your access credentials.")
} }
// doConfigCmd is the handler for "mc config" sub-command.
func doConfigCmd(ctx *cli.Context) {
// treat bash completion separately here
switch true {
case ctx.Bool("completion") == true:
var b bytes.Buffer
if os.Getenv("SHELL") != "/bin/bash" {
console.Fatalln("mc: Unsupported shell for bash completion detected.. exiting")
}
b.WriteString(mcBashCompletion)
f, err := getMcBashCompletionFilename()
if err != nil {
log.Debug.Println(iodine.New(err, nil))
console.Fatalln("mc: Unable to identify bash completion path")
}
fl, err := os.OpenFile(f, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
defer fl.Close()
if err != nil {
log.Debug.Println(iodine.New(err, nil))
console.Fatalln("mc: Unable to create bash completion file")
}
_, err = fl.Write(b.Bytes())
if err != nil {
log.Debug.Println(iodine.New(err, nil))
console.Fatalln("mc: Unable to write to bash completion file")
}
msg := "\nConfiguration written to " + f
msg = msg + "\n\n$ source ${HOME}/.mc/mc.bash_completion\n"
msg = msg + "$ echo 'source ${HOME}/.mc/mc.bash_completion' >> ${HOME}/.bashrc"
console.Infoln(msg)
default:
// rest of the arguments get passed down
saveConfigCmd(ctx)
}
}

View File

@@ -152,10 +152,6 @@ EXAMPLES:
Name: "alias", Name: "alias",
Usage: "Add URL aliases into config", Usage: "Add URL aliases into config",
}, },
cli.BoolFlag{
Name: "completion",
Usage: "Generate bash completion \"" + mustGetMcBashCompletionFilename() + "\" file.",
},
}, },
CustomHelpTemplate: `NAME: CustomHelpTemplate: `NAME:
mc {{.Name}} - {{.Usage}} mc {{.Name}} - {{.Usage}}
@@ -173,8 +169,8 @@ EXAMPLES:
1. Generate mc config 1. Generate mc config
$ mc config generate $ mc config generate
2. Generate bash completion 2. Verify configuration
$ mc config --completion $ mc config check
3. Add alias URLs 3. Add alias URLs
$ mc config --alias "zek https://s3.amazonaws.com/" $ mc config --alias "zek https://s3.amazonaws.com/"
@@ -229,20 +225,3 @@ var (
}, },
} }
) )
var (
mcBashCompletion = `#!/bin/bash
_mc_completion() {
local cur prev opts base
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -F _mc_completion mc
`
)

View File

@@ -50,11 +50,11 @@ func (e errInvalidGlobURL) Error() string {
} }
type errInvalidAliasName struct { type errInvalidAliasName struct {
alias string name string
} }
func (e errInvalidAliasName) Error() string { func (e errInvalidAliasName) Error() string {
return "Not a valid alias name: " + e.alias + " Valid examples are: Area51, Grand-Nagus.." return "Not a valid alias name: " + e.name + " Valid examples are: Area51, Grand-Nagus.."
} }
type errInvalidAuth struct{} type errInvalidAuth struct{}
@@ -68,3 +68,34 @@ type errNoMatchingHost struct{}
func (e errNoMatchingHost) Error() string { func (e errNoMatchingHost) Error() string {
return "No matching host found." return "No matching host found."
} }
type errConfigExists struct{}
func (e errConfigExists) Error() string {
return "Config exists"
}
// errAliasExists - alias exists
type errAliasExists struct {
name string
}
func (e errAliasExists) Error() string {
return fmt.Sprintf("alias: %s exists", e.name)
}
// errAliasNotFound - alias not found
type errAliasNotFound struct {
name string
}
func (e errAliasNotFound) Error() string {
return fmt.Sprintf("alias: %s exists", e.name)
}
// errInvalidAuthKeys - invalid authorization keys
type errInvalidAuthKeys struct{}
func (e errInvalidAuthKeys) Error() string {
return fmt.Sprintf("invalid authorization keys")
}

View File

@@ -86,7 +86,6 @@ func main() {
app.Commands = options app.Commands = options
app.Flags = flags app.Flags = flags
app.Author = "Minio.io" app.Author = "Minio.io"
app.EnableBashCompletion = false
app.Before = func(ctx *cli.Context) error { app.Before = func(ctx *cli.Context) error {
globalQuietFlag = ctx.GlobalBool("quiet") globalQuietFlag = ctx.GlobalBool("quiet")
globalDebugFlag = ctx.GlobalBool("debug") globalDebugFlag = ctx.GlobalBool("debug")