diff options
Diffstat (limited to 'modules/doctor/doctor.go')
-rw-r--r-- | modules/doctor/doctor.go | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/modules/doctor/doctor.go b/modules/doctor/doctor.go new file mode 100644 index 0000000000..8c0d467304 --- /dev/null +++ b/modules/doctor/doctor.go @@ -0,0 +1,105 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package doctor + +import ( + "fmt" + "sort" + "strings" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" +) + +// Check represents a Doctor check +type Check struct { + Title string + Name string + IsDefault bool + Run func(logger log.Logger, autofix bool) error + AbortIfFailed bool + SkipDatabaseInitialization bool + Priority int +} + +type wrappedLevelLogger struct { + log.LevelLogger +} + +func (w *wrappedLevelLogger) Log(skip int, level log.Level, format string, v ...interface{}) error { + return w.LevelLogger.Log( + skip+1, + level, + " - %s "+format, + append( + []interface{}{ + log.NewColoredValueBytes( + fmt.Sprintf("[%s]", strings.ToUpper(level.String()[0:1])), + level.Color()), + }, v...)...) +} + +func initDBDisableConsole(disableConsole bool) error { + setting.NewContext() + setting.InitDBConfig() + + setting.NewXORMLogService(disableConsole) + if err := models.SetEngine(); err != nil { + return fmt.Errorf("models.SetEngine: %v", err) + } + return nil +} + +// Checks is the list of available commands +var Checks []*Check + +// RunChecks runs the doctor checks for the provided list +func RunChecks(logger log.Logger, autofix bool, checks []*Check) error { + wrappedLogger := log.LevelLoggerLogger{ + LevelLogger: &wrappedLevelLogger{logger}, + } + + dbIsInit := false + for i, check := range checks { + if !dbIsInit && !check.SkipDatabaseInitialization { + // Only open database after the most basic configuration check + setting.EnableXORMLog = false + if err := initDBDisableConsole(true); err != nil { + logger.Error("Error whilst initializing the database: %v", err) + logger.Error("Check if you are using the right config file. You can use a --config directive to specify one.") + return nil + } + dbIsInit = true + } + logger.Info("[%d] %s", log.NewColoredIDValue(i+1), check.Title) + logger.Flush() + if err := check.Run(&wrappedLogger, autofix); err != nil { + if check.AbortIfFailed { + logger.Critical("FAIL") + return err + } + logger.Error("ERROR") + } else { + logger.Info("OK") + logger.Flush() + } + } + return nil +} + +// Register registers a command with the list +func Register(command *Check) { + Checks = append(Checks, command) + sort.SliceStable(Checks, func(i, j int) bool { + if Checks[i].Priority == Checks[j].Priority { + return Checks[i].Name < Checks[j].Name + } + if Checks[i].Priority == 0 { + return false + } + return Checks[i].Priority < Checks[j].Priority + }) +} |