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