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

restructure globals and some bug fixes related to globals

This commit is contained in:
Anand Babu (AB) Periasamy
2015-11-21 11:48:25 -08:00
parent c78b6e6645
commit 052f73f348
12 changed files with 146 additions and 115 deletions

View File

@@ -167,7 +167,7 @@ func getNewClient(urlStr string, auth hostConfig) (client.Client, *probe.Error)
s3Config.AppVersion = mcVersion
s3Config.AppComments = []string{os.Args[0], runtime.GOOS, runtime.GOARCH}
s3Config.HostURL = urlStr
s3Config.Debug = globalDebugFlag
s3Config.Debug = globalDebug
s3Client, err := s3.New(s3Config)
if err != nil {

View File

@@ -61,7 +61,7 @@ func mainConfigVersion(ctx *cli.Context) {
// convert interface{} back to its original struct
newConf := config.Data().(*configV6)
type Version string
if globalJSONFlag {
if globalJSON {
tB, e := json.Marshal(
struct {
Version Version `json:"version"`

View File

@@ -139,13 +139,13 @@ func doCopy(cpURLs copyURLs, progressReader *barSend, accountingReader *accounte
return
}
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.SetCaption(cpURLs.SourceContent.URL.String() + ": ")
}
reader, length, err := getSource(cpURLs.SourceContent.URL.String())
if err != nil {
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.ErrorGet(length)
}
cpURLs.Error = err.Trace(cpURLs.SourceContent.URL.String())
@@ -154,18 +154,18 @@ func doCopy(cpURLs copyURLs, progressReader *barSend, accountingReader *accounte
}
var newReader io.ReadCloser
if globalQuietFlag || globalJSONFlag {
if globalQuiet || globalJSON {
printMsg(copyMessage{
Source: cpURLs.SourceContent.URL.String(),
Target: cpURLs.TargetContent.URL.String(),
Length: cpURLs.SourceContent.Size,
})
// No accounting necessary for JSON output.
if globalJSONFlag {
if globalJSON {
newReader = reader
}
// Proxy reader to accounting reader only during quiet mode.
if globalQuietFlag {
if globalQuiet {
newReader = accountingReader.NewProxyReader(reader)
}
} else {
@@ -175,7 +175,7 @@ func doCopy(cpURLs copyURLs, progressReader *barSend, accountingReader *accounte
defer newReader.Close()
if err := putTarget(cpURLs.TargetContent.URL.String(), length, newReader); err != nil {
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.ErrorPut(length)
}
cpURLs.Error = err.Trace(cpURLs.TargetContent.URL.String())
@@ -189,7 +189,7 @@ func doCopy(cpURLs copyURLs, progressReader *barSend, accountingReader *accounte
// doCopyFake - Perform a fake copy to update the progress bar appropriately.
func doCopyFake(cURLs copyURLs, progressReader *barSend) {
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.Progress(cURLs.SourceContent.Size)
}
}
@@ -211,7 +211,7 @@ func doPrepareCopyURLs(session *sessionV5, trapCh <-chan bool) {
dataFP := session.NewDataWriter()
var scanBar scanBarFunc
if !globalQuietFlag && !globalJSONFlag { // set up progress bar
if !globalQuiet && !globalJSON { // set up progress bar
scanBar = scanBarFactory()
}
@@ -227,7 +227,7 @@ func doPrepareCopyURLs(session *sessionV5, trapCh <-chan bool) {
}
if cpURLs.Error != nil {
// Print in new line and adjust to top so that we don't print over the ongoing scan bar
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
if strings.Contains(cpURLs.Error.ToGoError().Error(), " is a folder.") {
@@ -244,7 +244,7 @@ func doPrepareCopyURLs(session *sessionV5, trapCh <-chan bool) {
fatalIf(probe.NewError(err), "Unable to prepare URL for copying. Error in JSON marshaling.")
}
fmt.Fprintln(dataFP, string(jsonData))
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
scanBar(cpURLs.SourceContent.URL.String())
}
@@ -252,7 +252,7 @@ func doPrepareCopyURLs(session *sessionV5, trapCh <-chan bool) {
totalObjects++
case <-trapCh:
// Print in new line and adjust to top so that we don't print over the ongoing scan bar
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
session.Delete() // If we are interrupted during the URL scanning, we drop the session.
@@ -276,7 +276,7 @@ func doCopySession(session *sessionV5) {
// Enable progress bar reader only during default mode.
var progressReader *barSend
if !globalQuietFlag && !globalJSONFlag { // set up progress bar
if !globalQuiet && !globalJSON { // set up progress bar
progressReader = newProgressBar(session.Header.TotalBytes)
}
@@ -302,10 +302,10 @@ func doCopySession(session *sessionV5) {
select {
case cpURLs, ok := <-statusCh: // Receive status.
if !ok { // We are done here. Top level function has returned.
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.Finish()
}
if globalQuietFlag {
if globalQuiet {
accntStat := accntReader.Stat()
cpStatMessage := copyStatMessage{
Total: accntStat.Total,
@@ -321,7 +321,7 @@ func doCopySession(session *sessionV5) {
session.Save()
} else {
// Print in new line and adjust to top so that we don't print over the ongoing progress bar
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
errorIf(cpURLs.Error.Trace(cpURLs.SourceContent.URL.String()),
@@ -342,7 +342,7 @@ func doCopySession(session *sessionV5) {
session.CloseAndDie()
}
case <-trapCh: // Receive interrupt notification.
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
session.CloseAndDie()

View File

@@ -44,7 +44,7 @@ func fatalIf(err *probe.Error, msg string) {
if err == nil {
return
}
if globalJSONFlag {
if globalJSON {
errorMsg := errorMessage{
Message: msg,
Type: "fatal",
@@ -54,7 +54,7 @@ func fatalIf(err *probe.Error, msg string) {
},
SysInfo: err.SysInfo,
}
if globalDebugFlag {
if globalDebug {
errorMsg.CallTrace = err.CallTrace
}
json, err := json.Marshal(struct {
@@ -70,7 +70,7 @@ func fatalIf(err *probe.Error, msg string) {
console.Println(string(json))
console.Fatalln()
}
if !globalDebugFlag {
if !globalDebug {
console.Fatalln(fmt.Sprintf("%s %s", msg, err.ToGoError()))
}
console.Fatalln(fmt.Sprintf("%s %s", msg, err))
@@ -81,7 +81,7 @@ func errorIf(err *probe.Error, msg string) {
if err == nil {
return
}
if globalJSONFlag {
if globalJSON {
errorMsg := errorMessage{
Message: msg,
Type: "error",
@@ -91,7 +91,7 @@ func errorIf(err *probe.Error, msg string) {
},
SysInfo: err.SysInfo,
}
if globalDebugFlag {
if globalDebug {
errorMsg.CallTrace = err.CallTrace
}
json, err := json.Marshal(struct {
@@ -107,7 +107,7 @@ func errorIf(err *probe.Error, msg string) {
console.Println(string(json))
return
}
if !globalDebugFlag {
if !globalDebug {
console.Errorln(fmt.Sprintf("%s %s", msg, err.ToGoError()))
return
}

View File

@@ -17,11 +17,7 @@
// This package contains all the global variables and constants. ONLY TO BE ACCESSED VIA GET/SET FUNCTIONS.
package main
var (
globalQuietFlag = false // Quiet flag set via command line
globalJSONFlag = false // Json flag set via command line
globalDebugFlag = false // Debug flag set via command line
)
import "github.com/minio/mc/pkg/console"
// mc configuration related constants.
const (
@@ -44,3 +40,29 @@ const (
// default host
globalExampleHostURL = "YOUR-EXAMPLE.COM"
)
var (
globalQuiet = false // Quiet flag set via command line
globalJSON = false // Json flag set via command line
globalDebug = false // Debug flag set via command line
globalNoColor = false // Debug flag set via command line
// WHEN YOU ADD NEXT GLOBAL FLAG, MAKE SURE TO ALSO UPDATE SESSION CODE AND CODE BELOW.
)
// Set global states. NOTE: It is deliberately kept monolithic to ensure we dont miss out any flags.
func setGlobals(quiet, debug, json, noColor bool) {
globalQuiet = quiet
globalDebug = debug
globalJSON = json
globalNoColor = noColor
// Enable debug messages if requested.
if globalDebug == true {
console.DebugPrint = true
}
// Disable colorified messages if requested.
if globalNoColor == true {
console.SetColorOff()
}
}

21
main.go
View File

@@ -24,7 +24,6 @@ import (
"strconv"
"github.com/minio/cli"
"github.com/minio/mc/pkg/console"
"github.com/minio/minio-xl/pkg/probe"
"github.com/minio/pb"
"github.com/olekukonko/ts"
@@ -110,18 +109,12 @@ func getSystemData() map[string]string {
func registerBefore(ctx *cli.Context) error {
setMcConfigDir(ctx.GlobalString("config-folder"))
globalQuietFlag = ctx.GlobalBool("quiet")
globalDebugFlag = ctx.GlobalBool("debug")
globalJSONFlag = ctx.GlobalBool("json")
if globalDebugFlag {
console.NoDebugPrint = false
}
// Disable color themes.
if ctx.GlobalBool("no-color") == true {
console.SetColorOff()
}
// Set global states from global flags.
setGlobals(ctx.GlobalBool("quiet"),
ctx.GlobalBool("debug"),
ctx.GlobalBool("json"),
ctx.GlobalBool("no-color"))
// Verify golang runtime.
verifyMCRuntime()
@@ -190,10 +183,10 @@ func main() {
app.ExtraInfo = func() map[string]string {
if _, e := ts.GetSize(); e != nil {
globalQuietFlag = true
globalQuiet = true
}
if globalDebugFlag {
if globalDebug {
return getSystemData()
}
return make(map[string]string)

View File

@@ -50,7 +50,7 @@ func (s *TestSuite) SetUpSuite(c *C) {
console.IsTesting = true
// do not set it elsewhere, leads to data races since this is a global flag
globalQuietFlag = true // quiet is set to turn of progress bar
globalQuiet = true // quiet is set to turn of progress bar
tmpDir, e := ioutil.TempDir(os.TempDir(), "cmd-")
c.Assert(e, IsNil)

View File

@@ -128,13 +128,13 @@ func doMirror(sURLs mirrorURLs, progressReader *barSend, accountingReader *accou
return
}
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.SetCaption(sURLs.SourceContent.URL.String() + ": ")
}
reader, length, err := getSource(sURLs.SourceContent.URL.String())
if err != nil {
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.ErrorGet(int64(length))
}
sURLs.Error = err.Trace(sURLs.SourceContent.URL.String())
@@ -148,15 +148,15 @@ func doMirror(sURLs mirrorURLs, progressReader *barSend, accountingReader *accou
}
var newReader io.ReadCloser
if globalQuietFlag || globalJSONFlag {
if globalQuiet || globalJSON {
printMsg(mirrorMessage{
Source: sURLs.SourceContent.URL.String(),
Targets: targetURLs,
})
if globalJSONFlag {
if globalJSON {
newReader = reader
}
if globalQuietFlag {
if globalQuiet {
newReader = accountingReader.NewProxyReader(reader)
}
} else {
@@ -167,7 +167,7 @@ func doMirror(sURLs mirrorURLs, progressReader *barSend, accountingReader *accou
err = putTargets(targetURLs, length, newReader)
if err != nil {
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.ErrorPut(int64(length))
}
sURLs.Error = err.Trace(targetURLs...)
@@ -181,7 +181,7 @@ func doMirror(sURLs mirrorURLs, progressReader *barSend, accountingReader *accou
// doMirrorFake - Perform a fake mirror to update the progress bar appropriately.
func doMirrorFake(sURLs mirrorURLs, progressReader *barSend) {
if !globalDebugFlag && !globalJSONFlag {
if !globalDebug && !globalJSON {
progressReader.Progress(sURLs.SourceContent.Size)
}
}
@@ -197,7 +197,7 @@ func doPrepareMirrorURLs(session *sessionV5, isForce bool, trapCh <-chan bool) {
dataFP := session.NewDataWriter()
var scanBar scanBarFunc
if !globalQuietFlag && !globalJSONFlag { // set up progress bar
if !globalQuiet && !globalJSON { // set up progress bar
scanBar = scanBarFactory()
}
@@ -212,7 +212,7 @@ func doPrepareMirrorURLs(session *sessionV5, isForce bool, trapCh <-chan bool) {
}
if sURLs.Error != nil {
// Print in new line and adjust to top so that we don't print over the ongoing scan bar
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
errorIf(sURLs.Error.Trace(), "Unable to prepare URLs for mirroring.")
@@ -227,7 +227,7 @@ func doPrepareMirrorURLs(session *sessionV5, isForce bool, trapCh <-chan bool) {
fatalIf(probe.NewError(err), "Unable to marshal URLs into JSON.")
}
fmt.Fprintln(dataFP, string(jsonData))
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
scanBar(sURLs.SourceContent.URL.String())
}
@@ -235,7 +235,7 @@ func doPrepareMirrorURLs(session *sessionV5, isForce bool, trapCh <-chan bool) {
totalObjects++
case <-trapCh:
// Print in new line and adjust to top so that we don't print over the ongoing scan bar
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
session.Delete() // If we are interrupted during the URL scanning, we drop the session.
@@ -261,7 +261,7 @@ func doMirrorSession(session *sessionV5) {
// Set up progress bar.
var progressReader *barSend
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader = newProgressBar(session.Header.TotalBytes)
}
@@ -286,7 +286,7 @@ func doMirrorSession(session *sessionV5) {
select {
case sURLs, ok := <-statusCh: // Receive status.
if !ok { // We are done here. Top level function has returned.
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
progressReader.Finish()
} else {
accntStat := accntReader.Stat()
@@ -304,7 +304,7 @@ func doMirrorSession(session *sessionV5) {
session.Save()
} else {
// Print in new line and adjust to top so that we don't print over the ongoing progress bar
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
errorIf(sURLs.Error.Trace(), fmt.Sprintf("Failed to mirror %s.", sURLs.SourceContent.URL.String()))
@@ -325,7 +325,7 @@ func doMirrorSession(session *sessionV5) {
}
case <-trapCh: // Receive interrupt notification.
// Print in new line and adjust to top so that we don't print over the ongoing progress bar
if !globalQuietFlag && !globalJSONFlag {
if !globalQuiet && !globalJSON {
console.Eraseline()
}
session.CloseAndDie()

View File

@@ -29,9 +29,9 @@ import (
)
var (
// NoDebugPrint defines if the input should be printed in debug or not. By default it's set to true.
NoDebugPrint = true
// IsTesting this flag indicates if IsExited should be set or not, false by default.
// DebugPrint enables/disables console debug printing.
DebugPrint = false
// IsTesting this flag indicates if IsExited should be set or not.
IsTesting = false
// IsExited sets this boolean value if Fatal is called when IsTesting is enabled.
IsExited = false
@@ -153,21 +153,21 @@ var (
// Debug prints a debug message without a new line
// Debug prints a debug message.
Debug = func(data ...interface{}) {
if !NoDebugPrint {
if !DebugPrint {
consolePrint("Debug", Theme["Debug"], data...)
}
}
// Debugf prints a debug message with a new line.
Debugf = func(format string, data ...interface{}) {
if !NoDebugPrint {
if !DebugPrint {
consolePrintf("Debug", Theme["Debug"], format, data...)
}
}
// Debugln prints a debug message with a new line.
Debugln = func(data ...interface{}) {
if !NoDebugPrint {
if !DebugPrint {
consolePrintln("Debug", Theme["Debug"], data...)
}
}

View File

@@ -26,7 +26,7 @@ type message interface {
// printMsg prints message string or JSON structure depending on the type of output console.
func printMsg(msg message) {
if !globalJSONFlag {
if !globalJSON {
console.Println(msg.String())
} else {
console.Println(msg.JSON())

View File

@@ -230,7 +230,7 @@ func mainSession(ctx *cli.Context) {
fatalIf(errDummy().Trace(), "Loaded session is nil.")
// Restore the state of global variables from this previous session.
s.RestoreGlobals()
s.restoreGlobals()
savedCwd, e := os.Getwd()
fatalIf(probe.NewError(e), "Unable to determine current working folder.")

View File

@@ -127,6 +127,50 @@ func (s sessionV5) JSON() string {
return string(sessionBytes)
}
// loadSessionV5 - reads session file if exists and re-initiates internal variables
func loadSessionV5(sid string) (*sessionV5, *probe.Error) {
if !isSessionDirExists() {
return nil, errInvalidArgument().Trace()
}
sessionFile, err := getSessionFile(sid)
if err != nil {
return nil, err.Trace(sid)
}
if _, err := os.Stat(sessionFile); err != nil {
return nil, probe.NewError(err)
}
s := &sessionV5{}
s.Header = &sessionV5Header{}
s.SessionID = sid
s.Header.Version = "5"
qs, err := quick.New(s.Header)
if err != nil {
return nil, err.Trace(sid, s.Header.Version)
}
err = qs.Load(sessionFile)
if err != nil {
return nil, err.Trace(sid, s.Header.Version)
}
s.mutex = new(sync.Mutex)
s.Header = qs.Data().(*sessionV5Header)
sessionDataFile, err := getSessionDataFile(s.SessionID)
if err != nil {
return nil, err.Trace(sid, s.Header.Version)
}
var e error
dataFile, e := os.Open(sessionDataFile)
fatalIf(probe.NewError(e), "Unable to open session data file \""+sessionDataFile+"\".")
s.DataFP = &sessionDataFP{false, dataFile}
return s, nil
}
// newSessionV5 provides a new session.
func newSessionV5() *sessionV5 {
s := &sessionV5{}
@@ -151,6 +195,10 @@ func newSessionV5() *sessionV5 {
fatalIf(probe.NewError(e), "Unable to create session data file \""+sessionDataFile+"\".")
s.DataFP = &sessionDataFP{false, dataFile}
// Capture state of global flags.
s.setGlobals()
return s
}
@@ -200,11 +248,23 @@ func (s *sessionV5) Save() *probe.Error {
return qs.Save(sessionFile).Trace(sessionFile)
}
// setGlobals captures the state of global variables into session header.
// Used by newSession.
func (s *sessionV5) setGlobals() {
s.Header.GlobalBoolFlags["quiet"] = globalQuiet
s.Header.GlobalBoolFlags["debug"] = globalDebug
s.Header.GlobalBoolFlags["json"] = globalJSON
s.Header.GlobalBoolFlags["noColor"] = globalNoColor
}
// RestoreGlobals restores the state of global variables.
func (s *sessionV5) RestoreGlobals() {
globalQuietFlag = s.Header.GlobalBoolFlags["quiet"]
globalJSONFlag = s.Header.GlobalBoolFlags["json"]
globalDebugFlag = s.Header.GlobalBoolFlags["debug"]
// Used by resumeSession.
func (s sessionV5) restoreGlobals() {
quiet := s.Header.GlobalBoolFlags["quiet"]
debug := s.Header.GlobalBoolFlags["debug"]
json := s.Header.GlobalBoolFlags["json"]
noColor := s.Header.GlobalBoolFlags["noColor"]
setGlobals(quiet, debug, json, noColor)
}
// Close ends this session and removes all associated session files.
@@ -265,50 +325,6 @@ func (s sessionV5) CloseAndDie() {
os.Exit(0)
}
// loadSessionV5 - reads session file if exists and re-initiates internal variables
func loadSessionV5(sid string) (*sessionV5, *probe.Error) {
if !isSessionDirExists() {
return nil, errInvalidArgument().Trace()
}
sessionFile, err := getSessionFile(sid)
if err != nil {
return nil, err.Trace(sid)
}
if _, err := os.Stat(sessionFile); err != nil {
return nil, probe.NewError(err)
}
s := &sessionV5{}
s.Header = &sessionV5Header{}
s.SessionID = sid
s.Header.Version = "5"
qs, err := quick.New(s.Header)
if err != nil {
return nil, err.Trace(sid, s.Header.Version)
}
err = qs.Load(sessionFile)
if err != nil {
return nil, err.Trace(sid, s.Header.Version)
}
s.mutex = new(sync.Mutex)
s.Header = qs.Data().(*sessionV5Header)
sessionDataFile, err := getSessionDataFile(s.SessionID)
if err != nil {
return nil, err.Trace(sid, s.Header.Version)
}
var e error
dataFile, e := os.Open(sessionDataFile)
fatalIf(probe.NewError(e), "Unable to open session data file \""+sessionDataFile+"\".")
s.DataFP = &sessionDataFP{false, dataFile}
return s, nil
}
// Create a factory function to simplify checking if an
// object has been copied or not.
// isCopied(URL) -> true or false