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  }