mirror of
https://github.com/minio/mc.git
synced 2025-11-12 01:02:26 +03:00
Refactoring console printing style, supports --json even for error messages now - fixes #418
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -31,42 +32,51 @@ func runAccessCmd(ctx *cli.Context) {
|
||||
cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
|
||||
}
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
config, err := getMcConfig()
|
||||
if err != nil {
|
||||
console.Fatalf("loading config file failed with following reason: [%s]\n", iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "loading config file failed",
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
targetURLConfigMap := make(map[string]*hostConfig)
|
||||
targetURLs, err := getExpandedURLs(ctx.Args(), config.Aliases)
|
||||
if err != nil {
|
||||
switch e := iodine.ToError(err).(type) {
|
||||
case errUnsupportedScheme:
|
||||
console.Fatalf("Unknown type of URL ‘%s’. Reason: %s.\n", e.url, e)
|
||||
default:
|
||||
console.Fatalf("reading URLs failed with following Reason: %s\n", e)
|
||||
}
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Unknown type of URL ",
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
acl := bucketACL(ctx.Args().First())
|
||||
if !acl.isValidBucketACL() {
|
||||
console.Fatalf("Access type ‘%s’ is not supported. Valid types are [private, public, readonly].\n", acl)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Valid types are [private, public, readonly].",
|
||||
Error: iodine.New(errors.New("Invalid ACL Type ‘"+acl.String()+"’"), nil),
|
||||
})
|
||||
}
|
||||
targetURLs = targetURLs[1:] // 1 or more target URLs
|
||||
for _, targetURL := range targetURLs {
|
||||
targetConfig, err := getHostConfig(targetURL)
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read configuration for host ‘%s’. Reason: %s.\n", targetURL, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Unable to read configuration for host " + "‘" + targetURL + "’",
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
targetURLConfigMap[targetURL] = targetConfig
|
||||
}
|
||||
for targetURL, targetConfig := range targetURLConfigMap {
|
||||
errorMsg, err := doUpdateAccessCmd(targetURL, acl.String(), targetConfig)
|
||||
err = iodine.New(err, nil)
|
||||
if err != nil {
|
||||
if errorMsg == "" {
|
||||
errorMsg = "Empty error message. Please rerun this command with --debug and file a bug report."
|
||||
}
|
||||
console.Errorf("%s", errorMsg)
|
||||
console.Errorln(console.ErrorMessage{
|
||||
Message: errorMsg,
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,10 +86,8 @@ func doUpdateAccessCmd(targetURL, targetACL string, targetConfig *hostConfig) (s
|
||||
var clnt client.Client
|
||||
clnt, err = getNewClient(targetURL, targetConfig)
|
||||
if err != nil {
|
||||
err := iodine.New(err, nil)
|
||||
msg := fmt.Sprintf("Unable to initialize client for ‘%s’. Reason: %s.\n",
|
||||
targetURL, iodine.ToError(err))
|
||||
return msg, err
|
||||
msg := fmt.Sprintf("Unable to initialize client for ‘%s’", targetURL)
|
||||
return msg, iodine.New(err, nil)
|
||||
}
|
||||
return doUpdateAccess(clnt, targetURL, targetACL)
|
||||
}
|
||||
@@ -87,15 +95,14 @@ func doUpdateAccessCmd(targetURL, targetACL string, targetConfig *hostConfig) (s
|
||||
func doUpdateAccess(clnt client.Client, targetURL, targetACL string) (string, error) {
|
||||
err := clnt.SetBucketACL(targetACL)
|
||||
for i := 0; i < globalMaxRetryFlag && err != nil && isValidRetry(err); i++ {
|
||||
fmt.Println(console.Retry("Retrying ... %d", i))
|
||||
console.Retry("Retrying ...", i)
|
||||
// Progressively longer delays
|
||||
time.Sleep(time.Duration(i*i) * time.Second)
|
||||
err = clnt.SetBucketACL(targetACL)
|
||||
}
|
||||
if err != nil {
|
||||
err := iodine.New(err, nil)
|
||||
msg := fmt.Sprintf("Failed to add bucket access policy for URL ‘%s’. Reason: %s.\n", targetURL, iodine.ToError(err))
|
||||
return msg, err
|
||||
msg := fmt.Sprintf("Failed to add bucket access policy for URL ‘%s’", targetURL)
|
||||
return msg, iodine.New(err, nil)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
32
cmd-cat.go
32
cmd-cat.go
@@ -18,6 +18,7 @@ package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
@@ -31,33 +32,42 @@ func runCatCmd(ctx *cli.Context) {
|
||||
cli.ShowCommandHelpAndExit(ctx, "cat", 1) // last argument is exit code
|
||||
}
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
config, err := getMcConfig()
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read config file ‘%s’. Reason: %s.\n", mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read config file ‘%s’", mustGetMcConfigPath()),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
|
||||
// Convert arguments to URLs: expand alias, fix format...
|
||||
urls, err := getExpandedURLs(ctx.Args(), config.Aliases)
|
||||
if err != nil {
|
||||
switch e := iodine.ToError(err).(type) {
|
||||
case errUnsupportedScheme:
|
||||
console.Fatalf("Unknown type of URL ‘%s’. Reason: %s.\n", e.url, e)
|
||||
default:
|
||||
console.Fatalf("Unable to parse arguments. Reason: %s.\n", iodine.ToError(err))
|
||||
}
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unknown type of URL ‘%s’", urls),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
|
||||
sourceURLs := urls
|
||||
sourceURLConfigMap, err := getHostConfigs(sourceURLs)
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read host configuration for ‘%s’ from config file ‘%s’. Reason: %s.\n",
|
||||
sourceURLs, mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read host configuration for ‘%s’ from config file ‘%s’", sourceURLs, mustGetMcConfigPath()),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
humanReadable, err := doCatCmd(sourceURLConfigMap)
|
||||
if err != nil {
|
||||
console.Fatalln(humanReadable)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: humanReadable,
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,13 +34,19 @@ func runConfigCmd(ctx *cli.Context) {
|
||||
arg := ctx.Args().First()
|
||||
tailArgs := ctx.Args().Tail()
|
||||
if len(tailArgs) > 2 {
|
||||
console.Fatalln("Incorrect number of arguments, please use \"mc config help\"")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Incorrect number of arguments, please use \"mc config help\"",
|
||||
Error: iodine.New(errInvalidArgument{}, nil),
|
||||
})
|
||||
}
|
||||
msg, err := doConfig(arg, tailArgs)
|
||||
if err != nil {
|
||||
console.Fatalln(msg)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: msg,
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
console.Infoln(msg)
|
||||
console.Infoln(console.Message(msg))
|
||||
}
|
||||
|
||||
// saveConfig writes configuration data in json format to config file.
|
||||
|
||||
21
cmd-cp.go
21
cmd-cp.go
@@ -17,6 +17,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
@@ -33,7 +35,7 @@ func doCopy(sourceURL string, sourceConfig *hostConfig, targetURL string, target
|
||||
}
|
||||
switch globalQuietFlag {
|
||||
case true:
|
||||
console.Infof("‘%s’ -> ‘%s’\n", sourceURL, targetURL)
|
||||
console.Infoln(console.Message(fmt.Sprintf("‘%s’ -> ‘%s’", sourceURL, targetURL)))
|
||||
default:
|
||||
// set up progress
|
||||
reader = bar.NewProxyReader(reader)
|
||||
@@ -117,13 +119,21 @@ func runCopyCmd(ctx *cli.Context) {
|
||||
if len(ctx.Args()) < 2 || ctx.Args().First() == "help" {
|
||||
cli.ShowCommandHelpAndExit(ctx, "cp", 1) // last argument is exit code
|
||||
}
|
||||
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
|
||||
// extract URLs.
|
||||
URLs, err := args2URLs(ctx.Args())
|
||||
if err != nil {
|
||||
console.Fatalln(iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unknown URL types: ‘%s’", URLs),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
|
||||
// Separate source and target. 'cp' can take only one target,
|
||||
@@ -138,7 +148,10 @@ func runCopyCmd(ctx *cli.Context) {
|
||||
}
|
||||
for err := range doCopyCmd(sourceURLs, targetURL, bar) {
|
||||
if err != nil {
|
||||
console.Errorln(iodine.ToError(err))
|
||||
console.Errorln(console.ErrorMessage{
|
||||
Message: "Failed with",
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
}
|
||||
if !globalQuietFlag {
|
||||
|
||||
52
cmd-diff.go
52
cmd-diff.go
@@ -17,6 +17,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/cli"
|
||||
"github.com/minio/mc/pkg/console"
|
||||
"github.com/minio/minio/pkg/iodine"
|
||||
@@ -28,11 +31,17 @@ func runDiffCmd(ctx *cli.Context) {
|
||||
cli.ShowCommandHelpAndExit(ctx, "diff", 1) // last argument is exit code
|
||||
}
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
config, err := getMcConfig()
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read config file ‘%s’. Reason: %s.\n", mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read config file ‘%s’", mustGetMcConfigPath()),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
|
||||
firstURL := ctx.Args().First()
|
||||
@@ -42,40 +51,59 @@ func runDiffCmd(ctx *cli.Context) {
|
||||
if err != nil {
|
||||
switch iodine.ToError(err).(type) {
|
||||
case errUnsupportedScheme:
|
||||
console.Fatalf("Unknown type of URL ‘%s’.\n", firstURL)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unknown type of URL ‘%s’.", firstURL),
|
||||
Error: err,
|
||||
})
|
||||
default:
|
||||
console.Fatalf("Unable to parse argument ‘%s’. Reason: %s.\n", firstURL, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to parse argument ‘%s’.", firstURL),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
_, err = getHostConfig(firstURL)
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read host configuration for ‘%s’ from config file ‘%s’. Reason: %s.\n",
|
||||
firstURL, mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read host configuration for ‘%s’ from config file ‘%s’.", firstURL, mustGetMcConfigPath()),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
|
||||
_, err = getHostConfig(secondURL)
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read host configuration for ‘%s’ from config file ‘%s’. Reason: %s.\n",
|
||||
secondURL, mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read host configuration for ‘%s’ from config file ‘%s’. Reason: %s.", secondURL, mustGetMcConfigPath()),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
|
||||
secondURL, err = getExpandedURL(secondURL, config.Aliases)
|
||||
if err != nil {
|
||||
switch iodine.ToError(err).(type) {
|
||||
case errUnsupportedScheme:
|
||||
console.Fatalf("Unknown type of URL ‘%s’. Reason: %s.\n", secondURL, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unknown type of URL ‘%s’.", secondURL),
|
||||
Error: err,
|
||||
})
|
||||
default:
|
||||
console.Fatalf("Unable to parse argument ‘%s’. Reason: %s.\n", secondURL, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to parse argument ‘%s’.", secondURL),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
// TODO recursive is not working yet
|
||||
newFirstURL := stripRecursiveURL(firstURL)
|
||||
for diff := range doDiffCmd(newFirstURL, secondURL, isURLRecursive(firstURL)) {
|
||||
if diff.err != nil {
|
||||
console.Fatalln(diff.message)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: diff.message,
|
||||
Error: diff.err,
|
||||
})
|
||||
}
|
||||
console.Infoln(diff.message)
|
||||
console.Infoln(console.Message(diff.message))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
cmd-ls.go
37
cmd-ls.go
@@ -17,6 +17,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/cli"
|
||||
"github.com/minio/mc/pkg/console"
|
||||
"github.com/minio/minio/pkg/iodine"
|
||||
@@ -27,12 +30,20 @@ func runListCmd(ctx *cli.Context) {
|
||||
if !ctx.Args().Present() || ctx.Args().First() == "help" {
|
||||
cli.ShowCommandHelpAndExit(ctx, "ls", 1) // last argument is exit code
|
||||
}
|
||||
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
|
||||
config, err := getMcConfig()
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read config file ‘%s’. Reason: %s.\n", mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read config file ‘%s’", mustGetMcConfigPath()),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
targetURLConfigMap := make(map[string]*hostConfig)
|
||||
for _, arg := range ctx.Args() {
|
||||
@@ -40,15 +51,23 @@ func runListCmd(ctx *cli.Context) {
|
||||
if err != nil {
|
||||
switch e := iodine.ToError(err).(type) {
|
||||
case errUnsupportedScheme:
|
||||
console.Fatalf("Unknown type of URL ‘%s’. Reason: %s.\n", e.url, e)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unknown type of URL ‘%s’", e.url),
|
||||
Error: iodine.New(e, nil),
|
||||
})
|
||||
default:
|
||||
console.Fatalf("Unable to parse argument ‘%s’. Reason: %s.\n", arg, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to parse argument ‘%s’", arg),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
}
|
||||
targetConfig, err := getHostConfig(targetURL)
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read host configuration for ‘%s’ from config file ‘%s’. Reason: %s.\n",
|
||||
targetURL, mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read host configuration for ‘%s’ from config file ‘%s’", targetURL, mustGetMcConfigPath()),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
targetURLConfigMap[targetURL] = targetConfig
|
||||
}
|
||||
@@ -56,9 +75,11 @@ func runListCmd(ctx *cli.Context) {
|
||||
// if recursive strip off the "..."
|
||||
newTargetURL := stripRecursiveURL(targetURL)
|
||||
err = doListCmd(newTargetURL, targetConfig, isURLRecursive(targetURL))
|
||||
err = iodine.New(err, nil)
|
||||
if err != nil {
|
||||
console.Fatalf("Failed to list ‘%s’. Reason: %s.\n", targetURL, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Failed to list ‘%s’", targetURL),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
52
cmd-mb.go
52
cmd-mb.go
@@ -17,6 +17,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -32,37 +33,51 @@ func runMakeBucketCmd(ctx *cli.Context) {
|
||||
cli.ShowCommandHelpAndExit(ctx, "mb", 1) // last argument is exit code
|
||||
}
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: errors.New("\"mc\" is not configured"),
|
||||
})
|
||||
}
|
||||
config, err := getMcConfig()
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read config file ‘%s’. Reason: %s\n", mustGetMcConfigPath(), iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Unable to read config file ‘" + mustGetMcConfigPath() + "’",
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
targetURLConfigMap := make(map[string]*hostConfig)
|
||||
targetURLs, err := getExpandedURLs(ctx.Args(), config.Aliases)
|
||||
for _, arg := range ctx.Args() {
|
||||
targetURL, err := getExpandedURL(arg, config.Aliases)
|
||||
if err != nil {
|
||||
switch e := iodine.ToError(err).(type) {
|
||||
case errUnsupportedScheme:
|
||||
console.Fatalf("Unknown URL type ‘%s’ passed. Reason: %s.\n", e.url, e)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unknown type of URL ‘%s’", e.url),
|
||||
Error: e,
|
||||
})
|
||||
default:
|
||||
console.Fatalf("Error in parsing path or URL. Reason: %s.\n", e)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to parse argument ‘%s’", arg),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
for _, targetURL := range targetURLs {
|
||||
targetConfig, err := getHostConfig(targetURL)
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read configuration for host ‘%s’. Reason: %s.\n", targetURL, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read host configuration for ‘%s’ from config file ‘%s’", targetURL, mustGetMcConfigPath()),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
targetURLConfigMap[targetURL] = targetConfig
|
||||
}
|
||||
for targetURL, targetConfig := range targetURLConfigMap {
|
||||
errorMsg, err := doMakeBucketCmd(targetURL, targetConfig)
|
||||
err = iodine.New(err, nil)
|
||||
if err != nil {
|
||||
if errorMsg == "" {
|
||||
errorMsg = "Empty error message. Please rerun this command with --debug and file a bug report."
|
||||
}
|
||||
console.Errorf("%s", errorMsg)
|
||||
console.Errorln(console.ErrorMessage{
|
||||
Message: errorMsg,
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,10 +88,8 @@ func doMakeBucketCmd(targetURL string, targetConfig *hostConfig) (string, error)
|
||||
var clnt client.Client
|
||||
clnt, err = getNewClient(targetURL, targetConfig)
|
||||
if err != nil {
|
||||
err := iodine.New(err, nil)
|
||||
msg := fmt.Sprintf("Unable to initialize client for ‘%s’. Reason: %s.\n",
|
||||
targetURL, iodine.ToError(err))
|
||||
return msg, err
|
||||
msg := fmt.Sprintf("Unable to initialize client for ‘%s’", targetURL)
|
||||
return msg, iodine.New(err, nil)
|
||||
}
|
||||
return doMakeBucket(clnt, targetURL)
|
||||
}
|
||||
@@ -85,15 +98,14 @@ func doMakeBucketCmd(targetURL string, targetConfig *hostConfig) (string, error)
|
||||
func doMakeBucket(clnt client.Client, targetURL string) (string, error) {
|
||||
err := clnt.MakeBucket()
|
||||
for i := 0; i < globalMaxRetryFlag && err != nil && isValidRetry(err); i++ {
|
||||
fmt.Println(console.Retry("Retrying ... %d", i))
|
||||
console.Retry("Retrying ...", i)
|
||||
// Progressively longer delays
|
||||
time.Sleep(time.Duration(i*i) * time.Second)
|
||||
err = clnt.MakeBucket()
|
||||
}
|
||||
if err != nil {
|
||||
err := iodine.New(err, nil)
|
||||
msg := fmt.Sprintf("Failed to create bucket for URL ‘%s’. Reason: %s.\n", targetURL, iodine.ToError(err))
|
||||
return msg, err
|
||||
msg := fmt.Sprintf("Failed to create bucket for URL ‘%s’", targetURL)
|
||||
return msg, iodine.New(err, nil)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
34
cmd-sync.go
34
cmd-sync.go
@@ -17,6 +17,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
@@ -29,12 +31,20 @@ func runSyncCmd(ctx *cli.Context) {
|
||||
if len(ctx.Args()) < 2 || ctx.Args().First() == "help" {
|
||||
cli.ShowCommandHelpAndExit(ctx, "sync", 1) // last argument is exit code
|
||||
}
|
||||
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
|
||||
URLs, err := args2URLs(ctx.Args())
|
||||
if err != nil {
|
||||
console.Fatalln(iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unknown URL types found: ‘%s’", URLs),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
|
||||
// Separate source and target. 'sync' can take only one source.
|
||||
@@ -66,7 +76,10 @@ func runSyncCmd(ctx *cli.Context) {
|
||||
|
||||
for syncURLs := range prepareSyncURLs(sourceURL, targetURLs) {
|
||||
if syncURLs.Error != nil {
|
||||
console.Errorln(iodine.ToError(syncURLs.Error))
|
||||
console.Errorln(console.ErrorMessage{
|
||||
Message: "Failed with",
|
||||
Error: iodine.New(syncURLs.Error, nil),
|
||||
})
|
||||
continue
|
||||
}
|
||||
syncQueue <- true
|
||||
@@ -75,16 +88,25 @@ func runSyncCmd(ctx *cli.Context) {
|
||||
defer wg.Done()
|
||||
srcConfig, err := getHostConfig(syncURLs.SourceContent.Name)
|
||||
if err != nil {
|
||||
console.Errorln(iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Failed with",
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
return
|
||||
}
|
||||
tgtConfig, err := getHostConfig(syncURLs.TargetContent.Name)
|
||||
if err != nil {
|
||||
console.Errorln(iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Failed with",
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
return
|
||||
}
|
||||
if err := doCopy(syncURLs.SourceContent.Name, srcConfig, syncURLs.TargetContent.Name, tgtConfig, bar); err != nil {
|
||||
console.Errorln(iodine.ToError(err))
|
||||
console.Errorln(console.ErrorMessage{
|
||||
Message: "Failed with",
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
<-syncQueue
|
||||
}(syncURLs, &bar)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
@@ -56,17 +58,24 @@ func runUpdateCmd(ctx *cli.Context) {
|
||||
cli.ShowCommandHelpAndExit(ctx, "update", 1) // last argument is exit code
|
||||
}
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
hostConfig, err := getHostConfig(mcUpdateURL)
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read configuration for host ‘%s’. Reason: %s.\n", mcUpdateURL, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read configuration for host ‘%s’", mcUpdateURL),
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
msg, err := doUpdateCheck(hostConfig)
|
||||
if err != nil {
|
||||
console.Fatalln(msg)
|
||||
}
|
||||
if msg != "" {
|
||||
console.Infoln(msg)
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: msg,
|
||||
Error: iodine.New(err, nil),
|
||||
})
|
||||
}
|
||||
console.Infoln(console.Message(msg))
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ func getMcConfig() (*configV1, error) {
|
||||
|
||||
}
|
||||
|
||||
// isMcConfigExist returns true/false if config exists
|
||||
// isMcConfigExist returns err if config doesn't exist
|
||||
func isMcConfigExist() bool {
|
||||
configFile, err := getMcConfigPath()
|
||||
if err != nil {
|
||||
|
||||
59
ls.go
59
ls.go
@@ -17,11 +17,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/minio/mc/pkg/client"
|
||||
@@ -36,49 +32,22 @@ const (
|
||||
printDate = "2006-01-02 15:04:05 MST"
|
||||
)
|
||||
|
||||
// printJSON rather than colored output
|
||||
func printJSON(content *client.Content) {
|
||||
type jsonContent struct {
|
||||
Filetype string `json:"content-type"`
|
||||
Date string `json:"last-modified"`
|
||||
Size string `json:"size"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
contentJSON := new(jsonContent)
|
||||
contentJSON.Date = content.Time.Local().Format(printDate)
|
||||
contentJSON.Size = humanize.IBytes(uint64(content.Size))
|
||||
contentJSON.Filetype = func() string {
|
||||
if content.Type.IsDir() {
|
||||
// printContent prints content meta-data
|
||||
func printContent(c *client.Content) {
|
||||
content := console.Content{}
|
||||
content.Filetype = func() string {
|
||||
if c.Type.IsDir() {
|
||||
return "inode/directory"
|
||||
}
|
||||
if content.Type.IsRegular() {
|
||||
if c.Type.IsRegular() {
|
||||
return "application/octet-stream"
|
||||
}
|
||||
return "application/octet-stream"
|
||||
}()
|
||||
contentJSON.Name = content.Name
|
||||
contentBytes, _ := json.MarshalIndent(contentJSON, "", "\t")
|
||||
fmt.Println(string(contentBytes))
|
||||
}
|
||||
|
||||
// printContent prints content meta-data
|
||||
func printContent(date time.Time, size int64, name string, fileType os.FileMode) {
|
||||
fmt.Printf(console.Time("[%s] ", date.Local().Format(printDate)))
|
||||
fmt.Printf(console.Size("%6s ", humanize.IBytes(uint64(size))))
|
||||
|
||||
// just making it explicit
|
||||
switch {
|
||||
case fileType.IsDir() == true:
|
||||
// if one finds a prior suffix no need to append a new one
|
||||
switch {
|
||||
case strings.HasSuffix(name, "/") == true:
|
||||
fmt.Println(console.Dir("%s", name))
|
||||
default:
|
||||
fmt.Println(console.Dir("%s/", name))
|
||||
}
|
||||
default:
|
||||
fmt.Println(console.File("%s", name))
|
||||
}
|
||||
content.Size = humanize.IBytes(uint64(c.Size))
|
||||
content.Name = strings.TrimSuffix(c.Name, "/")
|
||||
content.Time = c.Time.Local().Format(printDate)
|
||||
console.ContentInfo(content)
|
||||
}
|
||||
|
||||
// doList - list all entities inside a folder
|
||||
@@ -97,12 +66,8 @@ func doList(clnt client.Client, targetURL string, recursive bool) error {
|
||||
// To be consistent we have to filter them out
|
||||
contentName = strings.TrimPrefix(contentName, strings.TrimSuffix(targetURL, "/")+"/")
|
||||
}
|
||||
switch {
|
||||
case globalJSONFlag == true:
|
||||
printJSON(contentCh.Content)
|
||||
default:
|
||||
printContent(contentCh.Content.Time, contentCh.Content.Size, contentName, contentCh.Content.Type)
|
||||
}
|
||||
contentCh.Content.Name = contentName
|
||||
printContent(contentCh.Content)
|
||||
}
|
||||
if err != nil {
|
||||
return iodine.New(err, map[string]string{"Target": targetURL})
|
||||
|
||||
29
main.go
29
main.go
@@ -17,6 +17,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/user"
|
||||
@@ -34,7 +35,10 @@ import (
|
||||
func checkConfig() {
|
||||
_, err := user.Current()
|
||||
if err != nil {
|
||||
console.Fatalln("Unable to determine current user")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Unable to determine current user",
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
|
||||
// If config doesn't exist, do not attempt to read it
|
||||
@@ -45,7 +49,10 @@ func checkConfig() {
|
||||
// Ensures config file is sane
|
||||
_, err = getMcConfig()
|
||||
if err != nil {
|
||||
console.Fatalf("Unable to read config file: %s\n", mustGetMcConfigPath())
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Unable to read config file: %s", mustGetMcConfigPath()),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,14 +114,23 @@ func main() {
|
||||
app.ExtraInfo = getSystemData()
|
||||
console.NoDebugPrint = false
|
||||
}
|
||||
if globalJSONFlag {
|
||||
console.NoJSONPrint = false
|
||||
}
|
||||
themeName := ctx.GlobalString("theme")
|
||||
switch {
|
||||
case console.IsValidTheme(themeName) != true:
|
||||
console.Fatalf("Theme ‘%s’ is not supported. Please choose from this list: %s.\n", themeName, console.GetThemeNames())
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Please choose from this list: %s.", console.GetThemeNames()),
|
||||
Error: fmt.Errorf("Theme ‘%s’ is not supported.", themeName),
|
||||
})
|
||||
default:
|
||||
err := console.SetTheme(themeName)
|
||||
if err != nil {
|
||||
console.Fatalf("Failed to set theme ‘%s’. Reason: %s.\n", themeName, iodine.ToError(err))
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: fmt.Sprintf("Failed to set theme ‘%s’.", themeName),
|
||||
Error: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
checkConfig()
|
||||
@@ -122,7 +138,10 @@ func main() {
|
||||
}
|
||||
app.After = func(ctx *cli.Context) error {
|
||||
if !isMcConfigExist() {
|
||||
console.Fatalln("\"mc\" is not configured. Please run \"mc config generate\".")
|
||||
console.Fatalln(console.ErrorMessage{
|
||||
Message: "Please run \"mc config generate\"",
|
||||
Error: iodine.New(errors.New("\"mc\" is not configured"), nil),
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ func (c *s3Client) listInRoutine(contentCh chan client.ContentOnChannel) {
|
||||
content := new(client.Content)
|
||||
content.Name = object.Data.Key
|
||||
switch {
|
||||
case object.Data.Size == 0:
|
||||
case strings.HasSuffix(object.Data.Key, "/"):
|
||||
content.Time = time.Now()
|
||||
content.Type = os.ModeDir
|
||||
default:
|
||||
|
||||
@@ -75,9 +75,10 @@ func (t Trace) Response(res *http.Response) (err error) {
|
||||
|
||||
// print HTTP Response
|
||||
func (t Trace) print(data []byte) {
|
||||
if t.Writer != nil {
|
||||
switch {
|
||||
case t.Writer != nil:
|
||||
fmt.Fprintf(t.Writer, "%s", data)
|
||||
} else {
|
||||
console.Debugf("%s", data)
|
||||
default:
|
||||
console.Debugln(string(data))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package console
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
@@ -31,6 +32,40 @@ import (
|
||||
// NoDebugPrint defines if the input should be printed in debug or not. By default it's set to true.
|
||||
var NoDebugPrint = true
|
||||
|
||||
// NoJsonPrint defines if the input should be printed in json formatted or not. By default it's set to true.
|
||||
var NoJSONPrint = true
|
||||
|
||||
// Message info string
|
||||
type Message string
|
||||
|
||||
// ErrorMessage error message structure
|
||||
type ErrorMessage struct {
|
||||
Message string `json:"Message"`
|
||||
Error error `json:"Reason"`
|
||||
}
|
||||
|
||||
// Content content message structure
|
||||
type Content struct {
|
||||
Filetype string `json:"ContentType"`
|
||||
Time string `json:"LastModified"`
|
||||
Size string `json:"Size"`
|
||||
Name string `json:"Name"`
|
||||
}
|
||||
|
||||
// Theme holds console color scheme
|
||||
type Theme struct {
|
||||
Fatal *color.Color
|
||||
Error *color.Color
|
||||
Info *color.Color
|
||||
Debug *color.Color
|
||||
Size *color.Color
|
||||
Time *color.Color
|
||||
File *color.Color
|
||||
Dir *color.Color
|
||||
Retry *color.Color
|
||||
JSON *color.Color
|
||||
}
|
||||
|
||||
var (
|
||||
mutex = &sync.RWMutex{}
|
||||
|
||||
@@ -54,78 +89,134 @@ var (
|
||||
return theme
|
||||
}()
|
||||
|
||||
// Print prints a error message and exits
|
||||
// Print prints a message
|
||||
Print = themesDB[currThemeName].Info.Print
|
||||
// Println prints a error message with a new line and exits
|
||||
Println = themesDB[currThemeName].Info.Println
|
||||
// Printf prints a error message with formatting and exits
|
||||
Printf = themesDB[currThemeName].Info.Printf
|
||||
|
||||
// Fatal prints a error message and exits
|
||||
Fatal = func(a ...interface{}) { print(themesDB[currThemeName].Error, a...); os.Exit(1) }
|
||||
Fatal = func(msg ErrorMessage) {
|
||||
defer os.Exit(1)
|
||||
if msg.Error != nil {
|
||||
if NoJSONPrint {
|
||||
reason := "Reason: " + iodine.ToError(msg.Error).Error()
|
||||
message := msg.Message + ", " + reason
|
||||
print(themesDB[currThemeName].Error, message)
|
||||
if !NoDebugPrint {
|
||||
print(themesDB[currThemeName].Error, msg.Error)
|
||||
}
|
||||
return
|
||||
}
|
||||
errorMessageBytes, _ := json.Marshal(&msg)
|
||||
print(themesDB[currThemeName].JSON, string(errorMessageBytes))
|
||||
}
|
||||
}
|
||||
// Fatalln prints a error message with a new line and exits
|
||||
Fatalln = func(a ...interface{}) { println(themesDB[currThemeName].Error, a...); os.Exit(1) }
|
||||
// Fatalf prints a error message with formatting and exits
|
||||
Fatalf = func(f string, a ...interface{}) { printf(themesDB[currThemeName].Error, f, a...); os.Exit(1) }
|
||||
Fatalln = func(msg ErrorMessage) {
|
||||
defer os.Exit(1)
|
||||
if msg.Error != nil {
|
||||
if NoJSONPrint {
|
||||
reason := "Reason: " + iodine.ToError(msg.Error).Error()
|
||||
message := msg.Message + ", " + reason
|
||||
println(themesDB[currThemeName].Error, message)
|
||||
if !NoDebugPrint {
|
||||
println(themesDB[currThemeName].Error, msg.Error)
|
||||
}
|
||||
return
|
||||
}
|
||||
errorMessageBytes, _ := json.Marshal(&msg)
|
||||
println(themesDB[currThemeName].JSON, string(errorMessageBytes))
|
||||
}
|
||||
}
|
||||
|
||||
// Error prints a error message
|
||||
Error = func(a ...interface{}) { print(themesDB[currThemeName].Error, a...) }
|
||||
Error = func(msg ErrorMessage) {
|
||||
if msg.Error != nil {
|
||||
if NoJSONPrint {
|
||||
reason := "Reason: " + iodine.ToError(msg.Error).Error()
|
||||
message := msg.Message + ", " + reason
|
||||
print(themesDB[currThemeName].Error, message)
|
||||
if !NoDebugPrint {
|
||||
print(themesDB[currThemeName].Error, msg.Error)
|
||||
}
|
||||
return
|
||||
}
|
||||
errorMessageBytes, _ := json.Marshal(&msg)
|
||||
print(themesDB[currThemeName].JSON, string(errorMessageBytes))
|
||||
}
|
||||
}
|
||||
// Errorln prints a error message with a new line
|
||||
Errorln = func(a ...interface{}) { println(themesDB[currThemeName].Error, a...) }
|
||||
// Errorf prints a error message with formatting
|
||||
Errorf = func(f string, a ...interface{}) { printf(themesDB[currThemeName].Error, f, a...) }
|
||||
Errorln = func(msg ErrorMessage) {
|
||||
if msg.Error != nil {
|
||||
if NoJSONPrint {
|
||||
reason := "Reason: " + iodine.ToError(msg.Error).Error()
|
||||
message := msg.Message + ", " + reason
|
||||
println(themesDB[currThemeName].Error, message)
|
||||
if !NoDebugPrint {
|
||||
println(themesDB[currThemeName].Error, msg.Error)
|
||||
}
|
||||
return
|
||||
}
|
||||
errorMessageBytes, _ := json.Marshal(&msg)
|
||||
println(themesDB[currThemeName].JSON, string(errorMessageBytes))
|
||||
}
|
||||
}
|
||||
|
||||
// Info prints a informational message
|
||||
Info = func(a ...interface{}) { print(themesDB[currThemeName].Info, a...) }
|
||||
// Infoln prints a informational message with a new line
|
||||
Infoln = func(a ...interface{}) { println(themesDB[currThemeName].Info, a...) }
|
||||
// Infof prints a informational message with formatting
|
||||
Infof = func(f string, a ...interface{}) { printf(themesDB[currThemeName].Info, f, a...) }
|
||||
Info = func(msg Message) {
|
||||
if NoJSONPrint {
|
||||
print(themesDB[currThemeName].Info, msg)
|
||||
return
|
||||
}
|
||||
infoBytes, _ := json.Marshal(&msg)
|
||||
print(themesDB[currThemeName].JSON, string(infoBytes))
|
||||
}
|
||||
|
||||
// Infoln prints a informational message with a new line
|
||||
Infoln = func(msg Message) {
|
||||
if NoJSONPrint {
|
||||
println(themesDB[currThemeName].Info, msg)
|
||||
return
|
||||
}
|
||||
infoBytes, _ := json.Marshal(&msg)
|
||||
println(themesDB[currThemeName].JSON, string(infoBytes))
|
||||
}
|
||||
|
||||
// Debug prints a debug message without a new line
|
||||
// Debug prints a debug message
|
||||
Debug = func(a ...interface{}) {
|
||||
if !NoDebugPrint {
|
||||
print(themesDB[currThemeName].Debug, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// Debugln prints a debug message with a new line
|
||||
Debugln = func(a ...interface{}) {
|
||||
if !NoDebugPrint {
|
||||
println(themesDB[currThemeName].Debug, a...)
|
||||
}
|
||||
}
|
||||
// Debugf prints a debug message with formatting
|
||||
Debugf = func(f string, a ...interface{}) {
|
||||
if !NoDebugPrint {
|
||||
printf(themesDB[currThemeName].Debug, f, a...)
|
||||
// ContentInfo prints a structure Content
|
||||
ContentInfo = func(c Content) {
|
||||
if NoJSONPrint {
|
||||
print(themesDB[currThemeName].Time, c.Time)
|
||||
print(themesDB[currThemeName].Size, c.Size)
|
||||
switch c.Filetype {
|
||||
case "inode/directory":
|
||||
println(themesDB[currThemeName].Dir, c.Name)
|
||||
case "application/octet-stream":
|
||||
println(themesDB[currThemeName].File, c.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
contentBytes, _ := json.Marshal(&c)
|
||||
println(themesDB[currThemeName].JSON, string(contentBytes))
|
||||
}
|
||||
|
||||
// File - File("foo.txt")
|
||||
File = themesDB[currThemeName].File.SprintfFunc()
|
||||
// Dir - Dir("dir/")
|
||||
Dir = themesDB[currThemeName].Dir.SprintfFunc()
|
||||
// Size - Size("12GB")
|
||||
Size = themesDB[currThemeName].Size.SprintfFunc()
|
||||
// Time - Time("12 Hours")
|
||||
Time = themesDB[currThemeName].Time.SprintfFunc()
|
||||
// Retry - Retry message number
|
||||
Retry = themesDB[currThemeName].Retry.SprintfFunc()
|
||||
// Retry prints a retry message
|
||||
Retry = func(a ...interface{}) {
|
||||
println(themesDB[currThemeName].Retry, a...)
|
||||
}
|
||||
)
|
||||
|
||||
// Theme holds console color scheme
|
||||
type Theme struct {
|
||||
Fatal *color.Color
|
||||
Error *color.Color
|
||||
Info *color.Color
|
||||
Debug *color.Color
|
||||
Size *color.Color
|
||||
Time *color.Color
|
||||
File *color.Color
|
||||
Dir *color.Color
|
||||
Retry *color.Color
|
||||
}
|
||||
|
||||
var (
|
||||
// wrap around standard fmt functions
|
||||
// print prints a message prefixed with message type and program name
|
||||
@@ -155,11 +246,24 @@ var (
|
||||
c.Print(a...)
|
||||
color.Output = output
|
||||
mutex.Unlock()
|
||||
default:
|
||||
case themesDB[currThemeName].Info:
|
||||
mutex.Lock()
|
||||
c.Print(ProgramName() + ": ")
|
||||
c.Print(a...)
|
||||
mutex.Unlock()
|
||||
// special cases only for Content where it requires custom formatting
|
||||
case themesDB[currThemeName].Time:
|
||||
mutex.Lock()
|
||||
c.Print(fmt.Sprintf("[%s]", a...))
|
||||
mutex.Unlock()
|
||||
case themesDB[currThemeName].Size:
|
||||
mutex.Lock()
|
||||
c.Printf(fmt.Sprintf("%6s ", a...))
|
||||
mutex.Unlock()
|
||||
default:
|
||||
mutex.Lock()
|
||||
c.Print(a...)
|
||||
mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,45 +294,23 @@ var (
|
||||
c.Println(a...)
|
||||
color.Output = output
|
||||
mutex.Unlock()
|
||||
default:
|
||||
case themesDB[currThemeName].Info:
|
||||
mutex.Lock()
|
||||
c.Print(ProgramName() + ": ")
|
||||
c.Println(a...)
|
||||
mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// printf - same as print, but takes a format specifier
|
||||
printf = func(c *color.Color, f string, a ...interface{}) {
|
||||
switch c {
|
||||
case themesDB[currThemeName].Debug:
|
||||
case themesDB[currThemeName].Dir:
|
||||
mutex.Lock()
|
||||
output := color.Output
|
||||
color.Output = stderrColoredOutput
|
||||
c.Print(ProgramName() + ": <DEBUG> ")
|
||||
c.Printf(f, a...)
|
||||
color.Output = output
|
||||
// ugly but its needed
|
||||
c.Printf("%s/\n", a...)
|
||||
mutex.Unlock()
|
||||
case themesDB[currThemeName].Fatal:
|
||||
case themesDB[currThemeName].File:
|
||||
mutex.Lock()
|
||||
output := color.Output
|
||||
color.Output = stderrColoredOutput
|
||||
c.Print(ProgramName() + ": <FATAL> ")
|
||||
c.Printf(f, a...)
|
||||
color.Output = output
|
||||
mutex.Unlock()
|
||||
case themesDB[currThemeName].Error:
|
||||
mutex.Lock()
|
||||
output := color.Output
|
||||
color.Output = stderrColoredOutput
|
||||
c.Print(ProgramName() + ": <ERROR> ")
|
||||
c.Printf(f, a...)
|
||||
color.Output = output
|
||||
c.Println(a...)
|
||||
mutex.Unlock()
|
||||
default:
|
||||
mutex.Lock()
|
||||
c.Print(ProgramName() + ": ")
|
||||
c.Printf(f, a...)
|
||||
c.Println(a...)
|
||||
mutex.Unlock()
|
||||
}
|
||||
}
|
||||
@@ -262,46 +344,6 @@ func SetTheme(themeName string) error {
|
||||
}
|
||||
|
||||
currThemeName = themeName
|
||||
theme := themesDB[currThemeName]
|
||||
|
||||
// Error prints a error message
|
||||
Error = func(a ...interface{}) { print(theme.Error, a...) }
|
||||
// Errorln prints a error message with a new line
|
||||
Errorln = func(a ...interface{}) { println(theme.Error, a...) }
|
||||
// Errorf prints a error message with formatting
|
||||
Errorf = func(f string, a ...interface{}) { printf(theme.Error, f, a...) }
|
||||
|
||||
// Info prints a informational message
|
||||
Info = func(a ...interface{}) { print(theme.Info, a...) }
|
||||
// Infoln prints a informational message with a new line
|
||||
Infoln = func(a ...interface{}) { println(theme.Info, a...) }
|
||||
// Infof prints a informational message with formatting
|
||||
Infof = func(f string, a ...interface{}) { printf(theme.Info, f, a...) }
|
||||
|
||||
// Debug prints a debug message
|
||||
Debug = func(a ...interface{}) {
|
||||
if !NoDebugPrint {
|
||||
print(theme.Debug, a...)
|
||||
}
|
||||
}
|
||||
// Debugln prints a debug message with a new line
|
||||
Debugln = func(a ...interface{}) {
|
||||
if !NoDebugPrint {
|
||||
println(theme.Debug, a...)
|
||||
}
|
||||
}
|
||||
// Debugf prints a debug message with formatting
|
||||
Debugf = func(f string, a ...interface{}) {
|
||||
if !NoDebugPrint {
|
||||
printf(theme.Debug, f, a...)
|
||||
}
|
||||
}
|
||||
|
||||
Dir = theme.Dir.SprintfFunc()
|
||||
File = theme.File.SprintfFunc()
|
||||
Size = theme.Size.SprintfFunc()
|
||||
Time = theme.Time.SprintfFunc()
|
||||
Retry = theme.Retry.SprintfFunc()
|
||||
|
||||
mutex.Unlock()
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ var MiniTheme = Theme{
|
||||
Size: (color.New(color.FgYellow)),
|
||||
Time: (color.New(color.FgGreen)),
|
||||
Retry: (color.New(color.FgMagenta, color.Bold)),
|
||||
JSON: (color.New(color.FgWhite, color.Italic)),
|
||||
}
|
||||
|
||||
// WhiteTheme - All white color theme
|
||||
@@ -42,6 +43,7 @@ var WhiteTheme = Theme{
|
||||
Size: (color.New(color.FgWhite, color.Bold)),
|
||||
Time: (color.New(color.FgWhite, color.Bold)),
|
||||
Retry: (color.New(color.FgWhite, color.Bold)),
|
||||
JSON: (color.New(color.FgWhite, color.Bold, color.Italic)),
|
||||
}
|
||||
|
||||
// NoColorTheme - Disables color theme
|
||||
@@ -55,4 +57,5 @@ var NoColorTheme = Theme{
|
||||
Size: (color.New()),
|
||||
Time: (color.New()),
|
||||
Retry: (color.New()),
|
||||
JSON: (color.New()),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user