weed.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //go:generate statik -src=./static
  2. // install this first "go get github.com/rakyll/statik"
  3. package main
  4. import (
  5. "flag"
  6. "fmt"
  7. "io"
  8. "math/rand"
  9. "os"
  10. "strings"
  11. "sync"
  12. "text/template"
  13. "time"
  14. "unicode"
  15. "unicode/utf8"
  16. "github.com/chrislusf/seaweedfs/weed/command"
  17. "github.com/chrislusf/seaweedfs/weed/glog"
  18. )
  19. var IsDebug *bool
  20. var commands = command.Commands
  21. var exitStatus = 0
  22. var exitMu sync.Mutex
  23. func setExitStatus(n int) {
  24. exitMu.Lock()
  25. if exitStatus < n {
  26. exitStatus = n
  27. }
  28. exitMu.Unlock()
  29. }
  30. func main() {
  31. glog.MaxSize = 1024 * 1024 * 32
  32. rand.Seed(time.Now().UnixNano())
  33. flag.Usage = usage
  34. flag.Parse()
  35. args := flag.Args()
  36. if len(args) < 1 {
  37. usage()
  38. }
  39. if args[0] == "help" {
  40. help(args[1:])
  41. for _, cmd := range commands {
  42. if len(args) >= 2 && cmd.Name() == args[1] && cmd.Run != nil {
  43. fmt.Fprintf(os.Stderr, "Default Parameters:\n")
  44. cmd.Flag.PrintDefaults()
  45. }
  46. }
  47. return
  48. }
  49. for _, cmd := range commands {
  50. if cmd.Name() == args[0] && cmd.Run != nil {
  51. cmd.Flag.Usage = func() { cmd.Usage() }
  52. cmd.Flag.Parse(args[1:])
  53. args = cmd.Flag.Args()
  54. IsDebug = cmd.IsDebug
  55. if !cmd.Run(cmd, args) {
  56. fmt.Fprintf(os.Stderr, "\n")
  57. cmd.Flag.Usage()
  58. fmt.Fprintf(os.Stderr, "Default Parameters:\n")
  59. cmd.Flag.PrintDefaults()
  60. }
  61. exit()
  62. return
  63. }
  64. }
  65. fmt.Fprintf(os.Stderr, "weed: unknown subcommand %q\nRun 'weed help' for usage.\n", args[0])
  66. setExitStatus(2)
  67. exit()
  68. }
  69. var usageTemplate = `
  70. SeaweedFS: store billions of files and serve them fast!
  71. Usage:
  72. weed command [arguments]
  73. The commands are:
  74. {{range .}}{{if .Runnable}}
  75. {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
  76. Use "weed help [command]" for more information about a command.
  77. `
  78. var helpTemplate = `{{if .Runnable}}Usage: weed {{.UsageLine}}
  79. {{end}}
  80. {{.Long}}
  81. `
  82. // tmpl executes the given template text on data, writing the result to w.
  83. func tmpl(w io.Writer, text string, data interface{}) {
  84. t := template.New("top")
  85. t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
  86. template.Must(t.Parse(text))
  87. if err := t.Execute(w, data); err != nil {
  88. panic(err)
  89. }
  90. }
  91. func capitalize(s string) string {
  92. if s == "" {
  93. return s
  94. }
  95. r, n := utf8.DecodeRuneInString(s)
  96. return string(unicode.ToTitle(r)) + s[n:]
  97. }
  98. func printUsage(w io.Writer) {
  99. tmpl(w, usageTemplate, commands)
  100. }
  101. func usage() {
  102. printUsage(os.Stderr)
  103. fmt.Fprintf(os.Stderr, "For Logging, use \"weed [logging_options] [command]\". The logging options are:\n")
  104. flag.PrintDefaults()
  105. os.Exit(2)
  106. }
  107. // help implements the 'help' command.
  108. func help(args []string) {
  109. if len(args) == 0 {
  110. printUsage(os.Stdout)
  111. // not exit 2: succeeded at 'weed help'.
  112. return
  113. }
  114. if len(args) != 1 {
  115. fmt.Fprintf(os.Stderr, "usage: weed help command\n\nToo many arguments given.\n")
  116. os.Exit(2) // failed at 'weed help'
  117. }
  118. arg := args[0]
  119. for _, cmd := range commands {
  120. if cmd.Name() == arg {
  121. tmpl(os.Stdout, helpTemplate, cmd)
  122. // not exit 2: succeeded at 'weed help cmd'.
  123. return
  124. }
  125. }
  126. fmt.Fprintf(os.Stderr, "Unknown help topic %#q. Run 'weed help'.\n", arg)
  127. os.Exit(2) // failed at 'weed help cmd'
  128. }
  129. var atexitFuncs []func()
  130. func atexit(f func()) {
  131. atexitFuncs = append(atexitFuncs, f)
  132. }
  133. func exit() {
  134. for _, f := range atexitFuncs {
  135. f()
  136. }
  137. os.Exit(exitStatus)
  138. }
  139. func debug(params ...interface{}) {
  140. glog.V(4).Infoln(params...)
  141. }