2018-01-12 23:16:49 +01:00
// Copyright 2018 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2018-01-12 23:16:49 +01:00
// Package cmd provides subcommands to the gitea binary - such as "web" or
// "admin".
package cmd
import (
2021-07-14 15:43:13 +01:00
"context"
2018-01-12 23:16:49 +01:00
"errors"
"fmt"
2023-05-22 06:35:11 +08:00
"io"
2021-07-14 15:43:13 +01:00
"os"
"os/signal"
2020-10-24 23:38:14 +03:00
"strings"
2021-07-14 15:43:13 +01:00
"syscall"
2018-01-12 23:16:49 +01:00
2021-09-19 19:49:59 +08:00
"code.gitea.io/gitea/models/db"
2021-12-01 15:50:01 +08:00
"code.gitea.io/gitea/modules/log"
2018-01-12 23:16:49 +01:00
"code.gitea.io/gitea/modules/setting"
2019-01-21 12:45:32 +01:00
2025-06-10 14:35:12 +02:00
"github.com/urfave/cli/v3"
2018-01-12 23:16:49 +01:00
)
// argsSet checks that all the required arguments are set. args is a list of
// arguments that must be set in the passed Context.
2025-06-10 14:35:12 +02:00
func argsSet ( c * cli . Command , args ... string ) error {
2018-01-12 23:16:49 +01:00
for _ , a := range args {
if ! c . IsSet ( a ) {
return errors . New ( a + " is not set" )
}
2018-12-27 13:38:38 +01:00
2025-06-10 14:35:12 +02:00
if c . Value ( a ) == nil {
2018-12-27 13:38:38 +01:00
return errors . New ( a + " is required" )
}
2018-01-12 23:16:49 +01:00
}
return nil
}
2020-10-24 23:38:14 +03:00
// confirm waits for user input which confirms an action
func confirm ( ) ( bool , error ) {
var response string
_ , err := fmt . Scanln ( & response )
if err != nil {
return false , err
}
switch strings . ToLower ( response ) {
case "y" , "yes" :
return true , nil
case "n" , "no" :
return false , nil
default :
return false , errors . New ( response + " isn't a correct confirmation string" )
}
}
2021-11-07 11:11:27 +08:00
func initDB ( ctx context . Context ) error {
2023-06-21 13:50:26 +08:00
setting . MustInstalled ( )
2023-02-20 00:12:01 +08:00
setting . LoadDBSetting ( )
2023-05-22 06:35:11 +08:00
setting . InitSQLLoggersForCli ( log . INFO )
2021-12-01 15:50:01 +08:00
if setting . Database . Type == "" {
log . Fatal ( ` Database settings are missing from the configuration file: %q.
Ensure you are running in the correct environment or set the correct configuration file with -c.
If this is the intended configuration file complete the [database] section. ` , setting . CustomConf )
}
2021-11-07 11:11:27 +08:00
if err := db . InitEngine ( ctx ) ; err != nil {
2022-10-24 21:29:17 +02:00
return fmt . Errorf ( "unable to initialize the database using the configuration in %q. Error: %w" , setting . CustomConf , err )
2018-01-12 23:16:49 +01:00
}
return nil
}
2021-07-14 15:43:13 +01:00
func installSignals ( ) ( context . Context , context . CancelFunc ) {
ctx , cancel := context . WithCancel ( context . Background ( ) )
go func ( ) {
// install notify
signalChannel := make ( chan os . Signal , 1 )
signal . Notify (
signalChannel ,
syscall . SIGINT ,
syscall . SIGTERM ,
)
select {
case <- signalChannel :
case <- ctx . Done ( ) :
}
cancel ( )
signal . Reset ( )
} ( )
return ctx , cancel
}
2023-05-22 06:35:11 +08:00
func setupConsoleLogger ( level log . Level , colorize bool , out io . Writer ) {
if out != os . Stdout && out != os . Stderr {
panic ( "setupConsoleLogger can only be used with os.Stdout or os.Stderr" )
}
writeMode := log . WriterMode {
Level : level ,
Colorize : colorize ,
WriterOption : log . WriterConsoleOption { Stderr : out == os . Stderr } ,
}
writer := log . NewEventWriterConsole ( "console-default" , writeMode )
2023-06-28 14:02:06 +08:00
log . GetManager ( ) . GetLogger ( log . DEFAULT ) . ReplaceAllWriters ( writer )
}
2025-06-10 14:35:12 +02:00
func globalBool ( c * cli . Command , name string ) bool {
2023-07-21 17:28:19 +08:00
for _ , ctx := range c . Lineage ( ) {
if ctx . Bool ( name ) {
return true
}
}
return false
}
2023-06-28 14:02:06 +08:00
// PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout.
// Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
2025-06-10 14:35:12 +02:00
func PrepareConsoleLoggerLevel ( defaultLevel log . Level ) func ( context . Context , * cli . Command ) ( context . Context , error ) {
return func ( ctx context . Context , c * cli . Command ) ( context . Context , error ) {
2025-11-01 02:12:03 +08:00
if setting . InstallLock {
// During config loading, there might also be logs (for example: deprecation warnings).
// It must make sure that console logger is set up before config is loaded.
log . Error ( "Config is loaded before console logger is setup, it will cause bugs. Please fix it." )
return nil , errors . New ( "console logger must be setup before config is loaded" )
}
2023-06-28 14:02:06 +08:00
level := defaultLevel
2023-07-21 17:28:19 +08:00
if globalBool ( c , "quiet" ) {
2023-06-28 14:02:06 +08:00
level = log . FATAL
}
2023-07-21 17:28:19 +08:00
if globalBool ( c , "debug" ) || globalBool ( c , "verbose" ) {
2023-06-28 14:02:06 +08:00
level = log . TRACE
}
log . SetConsoleLogger ( log . DEFAULT , "console-default" , level )
2025-06-10 14:35:12 +02:00
return ctx , nil
2023-06-28 14:02:06 +08:00
}
2023-05-22 06:35:11 +08:00
}
2025-06-18 23:25:11 +08:00
func isValidDefaultSubCommand ( cmd * cli . Command ) ( string , bool ) {
// Dirty patch for urfave/cli's strange design.
// "./gitea bad-cmd" should not start the web server.
rootArgs := cmd . Root ( ) . Args ( ) . Slice ( )
if len ( rootArgs ) != 0 && rootArgs [ 0 ] != cmd . Name {
return rootArgs [ 0 ] , false
}
return "" , true
}