// mainConfig is the handle for "mc config" sub-command. writes configuration data in json format to config file. func mainConfig(ctx *cli.Context) { checkConfigSyntax(ctx) // set new custom coloring console.SetCustomTheme(map[string]*color.Color{ "Alias": color.New(color.FgCyan, color.Bold), "AliasMessage": color.New(color.FgGreen, color.Bold), "URL": color.New(color.FgWhite), }) arg := ctx.Args().First() tailArgs := ctx.Args().Tail() switch strings.TrimSpace(arg) { case "add": if strings.TrimSpace(tailArgs.First()) == "alias" { addAlias(tailArgs.Get(1), tailArgs.Get(2)) } case "remove": if strings.TrimSpace(tailArgs.First()) == "alias" { removeAlias(tailArgs.Get(1)) } case "list": if strings.TrimSpace(tailArgs.First()) == "alias" { listAliases() } } }
// mainDiff - is a handler for mc diff command func mainDiff(ctx *cli.Context) { checkDiffSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "DiffMessage": color.New(color.FgGreen, color.Bold), "DiffOnlyInFirst": color.New(color.FgRed, color.Bold), "DiffType": color.New(color.FgYellow, color.Bold), "DiffSize": color.New(color.FgMagenta, color.Bold), }) config := mustGetMcConfig() firstArg := ctx.Args().First() secondArg := ctx.Args().Last() firstURL, err := getCanonicalizedURL(firstArg, config.Aliases) fatalIf(err.Trace(firstArg), "Unable to parse first argument ‘"+firstArg+"’.") secondURL, err := getCanonicalizedURL(secondArg, config.Aliases) fatalIf(err.Trace(secondArg), "Unable to parse second argument ‘"+secondArg+"’.") newFirstURL := stripRecursiveURL(firstURL) for diff := range doDiffCmd(newFirstURL, secondURL, isURLRecursive(firstURL)) { fatalIf(diff.Error.Trace(newFirstURL, secondURL), "Failed to diff ‘"+firstURL+"’ and ‘"+secondURL+"’.") console.Println(diff.String()) } }
// mainCopy is bound to sub-command func mainCopy(ctx *cli.Context) { checkCopySyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "Copy": color.New(color.FgGreen, color.Bold), }) session := newSessionV2() var e error session.Header.CommandType = "cp" session.Header.RootPath, e = os.Getwd() if e != nil { session.Delete() fatalIf(probe.NewError(e), "Unable to get current working folder.") } // extract URLs. var err *probe.Error session.Header.CommandArgs, err = args2URLs(ctx.Args()) if err != nil { session.Delete() fatalIf(err.Trace(), "One or more unknown URL types passed.") } doCopyCmdSession(session) session.Delete() }
// mainList - is a handler for mc ls command func mainList(ctx *cli.Context) { checkListSyntax(ctx) args := ctx.Args() // Operating system tool behavior if globalMimicFlag && !ctx.Args().Present() { args = []string{"."} } console.SetCustomTheme(map[string]*color.Color{ "File": color.New(color.FgWhite), "Dir": color.New(color.FgCyan, color.Bold), "Size": color.New(color.FgYellow), "Time": color.New(color.FgGreen), }) targetURLs, err := args2URLs(args) fatalIf(err.Trace(args...), "One or more unknown URL types passed.") for _, targetURL := range targetURLs { // if recursive strip off the "..." var clnt client.Client clnt, err = target2Client(stripRecursiveURL(targetURL)) fatalIf(err.Trace(targetURL), "Unable to initialize target ‘"+targetURL+"’.") err = doList(clnt, isURLRecursive(targetURL), len(targetURLs) > 1) fatalIf(err.Trace(clnt.URL().String()), "Unable to list target ‘"+clnt.URL().String()+"’.") } }
// newProgressBar - instantiate a pbBar. func newProgressBar() barSend { console.SetCustomTheme(map[string]*color.Color{ "Bar": color.New(color.FgGreen, color.Bold), }) cmdCh := make(chan barMsg) finishCh := make(chan bool) go func(cmdCh <-chan barMsg, finishCh chan<- bool) { var started bool var totalBytesRead int64 // total amounts of bytes read bar := pb.New64(0) bar.SetUnits(pb.U_BYTES) bar.SetRefreshRate(time.Millisecond * 125) bar.NotPrint = true bar.ShowSpeed = true bar.Callback = func(s string) { console.Print(console.Colorize("Bar", "\r"+s)) } switch runtime.GOOS { case "linux": bar.Format("┃▓█░┃") // bar.Format("█▓▒░█") case "darwin": bar.Format(" ▓ ░ ") default: bar.Format("[=> ]") } for msg := range cmdCh { switch msg.Op { case pbBarSetCaption: bar.Prefix(fixateBarCaption(msg.Arg.(string), getFixedWidth(bar.GetWidth(), 18))) case pbBarExtend: atomic.AddInt64(&bar.Total, msg.Arg.(int64)) case pbBarProgress: if bar.Total > 0 && !started { started = true bar.Start() } if msg.Arg.(int64) > 0 { totalBytesRead += msg.Arg.(int64) bar.Add64(msg.Arg.(int64)) } case pbBarPutError: if totalBytesRead > msg.Arg.(int64) { bar.Set64(totalBytesRead - msg.Arg.(int64)) } case pbBarGetError: if msg.Arg.(int64) > 0 { bar.Add64(msg.Arg.(int64)) } case pbBarFinish: if started { bar.Finish() } finishCh <- true return } } }(cmdCh, finishCh) return barSend{cmdCh, finishCh} }
// mainList - is a handler for mc ls command func mainList(ctx *cli.Context) { checkListSyntax(ctx) args := ctx.Args() // Operating system tool behavior if globalMimicFlag && !ctx.Args().Present() { args = []string{"."} } console.SetCustomTheme(map[string]*color.Color{ "File": color.New(color.FgWhite), "Dir": color.New(color.FgCyan, color.Bold), "Size": color.New(color.FgYellow), "Time": color.New(color.FgGreen), }) config := mustGetMcConfig() for _, arg := range args { targetURL, err := getCanonicalizedURL(arg, config.Aliases) fatalIf(err.Trace(arg), "Unable to parse argument ‘"+arg+"’.") // if recursive strip off the "..." err = doListCmd(stripRecursiveURL(targetURL), isURLRecursive(targetURL)) fatalIf(err.Trace(targetURL), "Unable to list target ‘"+targetURL+"’.") } }
func mainVersion(ctx *cli.Context) { if ctx.Args().First() == "help" { cli.ShowCommandHelpAndExit(ctx, "version", 1) // last argument is exit code } console.SetCustomTheme(map[string]*color.Color{ "Version": color.New(color.FgGreen, color.Bold), }) if globalJSONFlag { tB, e := json.Marshal( struct { Version struct { Value string `json:"value"` Format string `json:"format"` } `json:"version"` }{ Version: struct { Value string `json:"value"` Format string `json:"format"` }{ Value: mcVersion, Format: "RFC2616", }, }, ) fatalIf(probe.NewError(e), "Unable to construct version string.") console.Println(string(tB)) return } msg := console.Colorize("Version", fmt.Sprintf("Version: %s\n", mcVersion)) msg += console.Colorize("Version", fmt.Sprintf("Release-Tag: %s", mcReleaseTag)) console.Println(msg) }
func mainMirror(ctx *cli.Context) { checkMirrorSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "Mirror": color.New(color.FgGreen, color.Bold), }) var e error session := newSessionV2() session.Header.CommandType = "mirror" session.Header.RootPath, e = os.Getwd() if e != nil { session.Close() session.Delete() fatalIf(probe.NewError(e), "Unable to get current working folder.") } // extract URLs. var err *probe.Error session.Header.CommandArgs, err = args2URLs(ctx.Args()) if err != nil { session.Close() session.Delete() fatalIf(err.Trace(ctx.Args()...), fmt.Sprintf("One or more unknown argument types found in ‘%s’.", ctx.Args())) } doMirrorCmdSession(session) session.Close() session.Delete() }
func mainSession(ctx *cli.Context) { checkSessionSyntax(ctx) if !isSessionDirExists() { fatalIf(createSessionDir().Trace(), "Unable to create session directory.") } console.SetCustomTheme(map[string]*color.Color{ "Command": color.New(color.FgWhite, color.Bold), "SessionID": color.New(color.FgYellow, color.Bold), "SessionTime": color.New(color.FgGreen), "ClearSession": color.New(color.FgGreen, color.Bold), }) switch strings.TrimSpace(ctx.Args().First()) { // list resumable sessions case "list": fatalIf(listSessions().Trace(), "Unable to list sessions.") case "resume": sid := strings.TrimSpace(ctx.Args().Tail().First()) if !isSession(sid) { fatalIf(errDummy().Trace(), "Session ‘"+sid+"’ not found.") } s, err := loadSessionV2(sid) fatalIf(err.Trace(sid), "Unable to load session.") // extra check for testing purposes if s == nil { return } savedCwd, e := os.Getwd() fatalIf(probe.NewError(e), "Unable to verify your current working folder.") if s.Header.RootPath != "" { // chdir to RootPath e = os.Chdir(s.Header.RootPath) fatalIf(probe.NewError(e), "Unable to change directory to root path while resuming session.") } sessionExecute(s) err = s.Close() fatalIf(err.Trace(), "Unable to close session file properly.") err = s.Delete() fatalIf(err.Trace(), "Unable to clear session files properly.") // chdir back to saved path e = os.Chdir(savedCwd) fatalIf(probe.NewError(e), "Unable to change directory to saved path ‘"+savedCwd+"’.") // purge a requested pending session, if "all" purge everything case "clear": clearSession(strings.TrimSpace(ctx.Args().Tail().First())) } }
// mainUpdate - func mainUpdate(ctx *cli.Context) { checkUpdateSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "UpdateMessage": color.New(color.FgGreen, color.Bold), }) arg := strings.TrimSpace(ctx.Args().First()) switch arg { case "release": getReleaseUpdate() case "experimental": getExperimentalUpdate() } }
// mainShare - is a handler for mc share command func mainShare(ctx *cli.Context) { checkShareSyntax(ctx) if !isSharedURLsDataDirExists() { shareDir, err := getSharedURLsDataDir() fatalIf(err.Trace(), "Unable to get shared URL data directory") fatalIf(createSharedURLsDataDir().Trace(), "Unable to create shared URL data directory ‘"+shareDir+"’.") } if !isSharedURLsDataFileExists() { shareFile, err := getSharedURLsDataFile() fatalIf(err.Trace(), "Unable to get shared URL data file") fatalIf(createSharedURLsDataFile().Trace(), "Unable to create shared URL data file ‘"+shareFile+"’.") } console.SetCustomTheme(map[string]*color.Color{ "Share": color.New(color.FgGreen, color.Bold), "Expires": color.New(color.FgRed, color.Bold), "URL": color.New(color.FgCyan, color.Bold), }) args := ctx.Args() config := mustGetMcConfig() // if its only list, return quickly if args.Get(0) == "list" { err := doShareList() fatalIf(err.Trace(), "Unable to list shared URLs.") return } /// get first and last arguments url := args.Get(0) // url to be shared // default expiration is 7days expires := time.Duration(604800) * time.Second if len(args) == 2 { var err error expires, err = time.ParseDuration(args.Get(1)) fatalIf(probe.NewError(err), "Unable to parse time argument.") } targetURL := getAliasURL(url, config.Aliases) // if recursive strip off the "..." err := doShareURL(stripRecursiveURL(targetURL), isURLRecursive(targetURL), expires) fatalIf(err.Trace(targetURL), "Unable to generate URL for sharing.") }
// mainMakeBucket is the handler for mc mb command func mainMakeBucket(ctx *cli.Context) { checkMakeBucketSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "MakeBucket": color.New(color.FgGreen, color.Bold), }) config := mustGetMcConfig() for _, arg := range ctx.Args() { targetURL := getAliasURL(arg, config.Aliases) fatalIf(doMakeBucket(targetURL).Trace(targetURL), "Unable to make bucket ‘"+targetURL+"’.") Prints("%s\n", MakeBucketMessage{ Status: "success", Bucket: targetURL, }) } }
// mainMakeBucket is the handler for mc mb command func mainMakeBucket(ctx *cli.Context) { checkMakeBucketSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "MakeBucket": color.New(color.FgGreen, color.Bold), }) config := mustGetMcConfig() for _, arg := range ctx.Args() { targetURL, err := getCanonicalizedURL(arg, config.Aliases) fatalIf(err.Trace(arg), "Unable to parse bucket ‘"+arg+"’.") fatalIf(doMakeBucketCmd(targetURL).Trace(targetURL), "Unable to make bucket ‘"+targetURL+"’.") console.Println(MakeBucketMessage{ Status: "success", Bucket: targetURL, }) } }
func mainAccess(ctx *cli.Context) { checkAccessSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "Access": color.New(color.FgGreen, color.Bold), }) config := mustGetMcConfig() switch ctx.Args().Get(0) { case "set": perms := bucketPerms(ctx.Args().Tail().Get(0)) for _, arg := range ctx.Args().Tail().Tail() { targetURL := getAliasURL(arg, config.Aliases) fatalIf(doSetAccess(targetURL, perms).Trace(targetURL, string(perms)), "Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.") Prints("%s\n", AccessMessage{ Operation: "set", Status: "success", Bucket: targetURL, Perms: perms, }) } case "get": for _, arg := range ctx.Args().Tail() { targetURL := getAliasURL(arg, config.Aliases) perms, err := doGetAccess(targetURL) fatalIf(err.Trace(targetURL), "Unable to get access permission for ‘"+targetURL+"’.") Prints("%s\n", AccessMessage{ Operation: "get", Status: "success", Bucket: targetURL, Perms: perms, }) } } }
func mainAccess(ctx *cli.Context) { checkAccessSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "Access": color.New(color.FgGreen, color.Bold), }) perms := bucketPerms(ctx.Args().First()) config := mustGetMcConfig() for _, arg := range ctx.Args().Tail() { targetURL, err := getCanonicalizedURL(arg, config.Aliases) fatalIf(err.Trace(arg), "Unable to parse argument ‘"+arg+"’.") fatalIf(doUpdateAccessCmd(targetURL, perms).Trace(targetURL, string(perms)), "Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.") console.Println(AccessMessage{ Status: "success", Bucket: targetURL, Perms: perms, }) } }
// mainDiff - is a handler for mc diff command func mainDiff(ctx *cli.Context) { checkDiffSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "DiffMessage": color.New(color.FgGreen, color.Bold), "DiffOnlyInFirst": color.New(color.FgRed, color.Bold), "DiffType": color.New(color.FgYellow, color.Bold), "DiffSize": color.New(color.FgMagenta, color.Bold), }) config := mustGetMcConfig() firstArg := ctx.Args().First() secondArg := ctx.Args().Last() firstURL := getAliasURL(firstArg, config.Aliases) secondURL := getAliasURL(secondArg, config.Aliases) newFirstURL := stripRecursiveURL(firstURL) for diff := range doDiff(newFirstURL, secondURL, isURLRecursive(firstURL)) { fatalIf(diff.Error.Trace(newFirstURL, secondURL), "Failed to diff ‘"+firstURL+"’ and ‘"+secondURL+"’.") Prints("%s\n", diff) } }
func mainConfigHost(ctx *cli.Context) { checkConfigHostSyntax(ctx) // set new custom coloring console.SetCustomTheme(map[string]*color.Color{ "Host": color.New(color.FgCyan, color.Bold), "API": color.New(color.FgYellow, color.Bold), "HostMessage": color.New(color.FgGreen, color.Bold), "AccessKeyID": color.New(color.FgBlue, color.Bold), "SecretAccessKey": color.New(color.FgRed, color.Bold), }) arg := ctx.Args().First() tailArgs := ctx.Args().Tail() switch strings.TrimSpace(arg) { case "add": addHost(tailArgs.Get(0), tailArgs.Get(1), tailArgs.Get(2), tailArgs.Get(3)) case "remove": removeHost(tailArgs.Get(0)) case "list": listHosts() } }