gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2018 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. // Package cmd provides subcommands to the gitea binary - such as "web" or
  4. // "admin".
  5. package cmd
  6. import (
  7. "context"
  8. "errors"
  9. "fmt"
  10. "io"
  11. "os"
  12. "os/signal"
  13. "strings"
  14. "syscall"
  15. "code.gitea.io/gitea/models/db"
  16. "code.gitea.io/gitea/modules/log"
  17. "code.gitea.io/gitea/modules/setting"
  18. "github.com/urfave/cli/v3"
  19. )
  20. // argsSet checks that all the required arguments are set. args is a list of
  21. // arguments that must be set in the passed Context.
  22. func argsSet(c *cli.Command, args ...string) error {
  23. for _, a := range args {
  24. if !c.IsSet(a) {
  25. return errors.New(a + " is not set")
  26. }
  27. if c.Value(a) == nil {
  28. return errors.New(a + " is required")
  29. }
  30. }
  31. return nil
  32. }
  33. // confirm waits for user input which confirms an action
  34. func confirm() (bool, error) {
  35. var response string
  36. _, err := fmt.Scanln(&response)
  37. if err != nil {
  38. return false, err
  39. }
  40. switch strings.ToLower(response) {
  41. case "y", "yes":
  42. return true, nil
  43. case "n", "no":
  44. return false, nil
  45. default:
  46. return false, errors.New(response + " isn't a correct confirmation string")
  47. }
  48. }
  49. func initDB(ctx context.Context) error {
  50. setting.MustInstalled()
  51. setting.LoadDBSetting()
  52. setting.InitSQLLoggersForCli(log.INFO)
  53. if setting.Database.Type == "" {
  54. log.Fatal(`Database settings are missing from the configuration file: %q.
  55. Ensure you are running in the correct environment or set the correct configuration file with -c.
  56. If this is the intended configuration file complete the [database] section.`, setting.CustomConf)
  57. }
  58. if err := db.InitEngine(ctx); err != nil {
  59. return fmt.Errorf("unable to initialize the database using the configuration in %q. Error: %w", setting.CustomConf, err)
  60. }
  61. return nil
  62. }
  63. func installSignals() (context.Context, context.CancelFunc) {
  64. ctx, cancel := context.WithCancel(context.Background())
  65. go func() {
  66. // install notify
  67. signalChannel := make(chan os.Signal, 1)
  68. signal.Notify(
  69. signalChannel,
  70. syscall.SIGINT,
  71. syscall.SIGTERM,
  72. )
  73. select {
  74. case <-signalChannel:
  75. case <-ctx.Done():
  76. }
  77. cancel()
  78. signal.Reset()
  79. }()
  80. return ctx, cancel
  81. }
  82. func setupConsoleLogger(level log.Level, colorize bool, out io.Writer) {
  83. if out != os.Stdout && out != os.Stderr {
  84. panic("setupConsoleLogger can only be used with os.Stdout or os.Stderr")
  85. }
  86. writeMode := log.WriterMode{
  87. Level: level,
  88. Colorize: colorize,
  89. WriterOption: log.WriterConsoleOption{Stderr: out == os.Stderr},
  90. }
  91. writer := log.NewEventWriterConsole("console-default", writeMode)
  92. log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
  93. }
  94. func globalBool(c *cli.Command, name string) bool {
  95. for _, ctx := range c.Lineage() {
  96. if ctx.Bool(name) {
  97. return true
  98. }
  99. }
  100. return false
  101. }
  102. // PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout.
  103. // Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
  104. func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(context.Context, *cli.Command) (context.Context, error) {
  105. return func(ctx context.Context, c *cli.Command) (context.Context, error) {
  106. level := defaultLevel
  107. if globalBool(c, "quiet") {
  108. level = log.FATAL
  109. }
  110. if globalBool(c, "debug") || globalBool(c, "verbose") {
  111. level = log.TRACE
  112. }
  113. log.SetConsoleLogger(log.DEFAULT, "console-default", level)
  114. return ctx, nil
  115. }
  116. }
  117. func isValidDefaultSubCommand(cmd *cli.Command) (string, bool) {
  118. // Dirty patch for urfave/cli's strange design.
  119. // "./gitea bad-cmd" should not start the web server.
  120. rootArgs := cmd.Root().Args().Slice()
  121. if len(rootArgs) != 0 && rootArgs[0] != cmd.Name {
  122. return rootArgs[0], false
  123. }
  124. return "", true
  125. }