1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-12 11:15:00 +02:00
lazygit/pkg/app/app.go

195 lines
5.0 KiB
Go
Raw Normal View History

package app
import (
"bufio"
"fmt"
"io"
"io/ioutil"
2018-08-13 13:16:21 +02:00
"os"
2018-12-08 07:54:54 +02:00
"path/filepath"
"strings"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/config"
2018-08-13 12:26:02 +02:00
"github.com/jesseduffield/lazygit/pkg/gui"
"github.com/jesseduffield/lazygit/pkg/i18n"
2018-08-19 15:28:29 +02:00
"github.com/jesseduffield/lazygit/pkg/updates"
"github.com/jesseduffield/rollrus"
2018-12-08 07:54:54 +02:00
"github.com/shibukawa/configdir"
2018-08-25 07:55:49 +02:00
"github.com/sirupsen/logrus"
)
// App struct
type App struct {
closers []io.Closer
Config config.AppConfigurer
Log *logrus.Entry
OSCommand *commands.OSCommand
GitCommand *commands.GitCommand
Gui *gui.Gui
Tr *i18n.Localizer
Updater *updates.Updater // may only need this on the Gui
ClientContext string
2018-08-13 13:16:21 +02:00
}
2018-08-26 07:46:18 +02:00
func newProductionLogger(config config.AppConfigurer) *logrus.Logger {
2018-08-13 13:16:21 +02:00
log := logrus.New()
2018-08-26 07:46:18 +02:00
log.Out = ioutil.Discard
2019-03-16 01:37:31 +02:00
log.SetLevel(logrus.ErrorLevel)
2018-08-26 07:46:18 +02:00
return log
}
2018-12-08 07:54:54 +02:00
func globalConfigDir() string {
configDirs := configdir.New("jesseduffield", "lazygit")
configDir := configDirs.QueryFolders(configdir.Global)[0]
return configDir.Path
}
2019-03-16 01:37:31 +02:00
func getLogLevel() logrus.Level {
strLevel := os.Getenv("LOG_LEVEL")
level, err := logrus.ParseLevel(strLevel)
if err != nil {
return logrus.DebugLevel
}
return level
}
2018-12-08 07:54:54 +02:00
func newDevelopmentLogger(config config.AppConfigurer) *logrus.Logger {
2018-08-26 07:46:18 +02:00
log := logrus.New()
2019-03-16 01:37:31 +02:00
log.SetLevel(getLogLevel())
2018-12-08 07:54:54 +02:00
file, err := os.OpenFile(filepath.Join(globalConfigDir(), "development.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
2018-08-13 13:16:21 +02:00
if err != nil {
panic("unable to log to file") // TODO: don't panic (also, remove this call to the `panic` function)
}
log.SetOutput(file)
2018-08-13 13:16:21 +02:00
return log
}
2018-08-26 07:46:18 +02:00
func newLogger(config config.AppConfigurer) *logrus.Entry {
var log *logrus.Logger
environment := "production"
2019-02-18 12:29:43 +02:00
if config.GetDebug() || os.Getenv("DEBUG") == "TRUE" {
environment = "development"
2018-12-08 07:54:54 +02:00
log = newDevelopmentLogger(config)
2018-08-26 07:46:18 +02:00
} else {
log = newProductionLogger(config)
}
2018-12-07 09:52:31 +02:00
// highly recommended: tail -f development.log | humanlog
// https://github.com/aybabtme/humanlog
log.Formatter = &logrus.JSONFormatter{}
if config.GetUserConfig().GetString("reporting") == "on" {
// this isn't really a secret token: it only has permission to push new rollbar items
hook := rollrus.NewHook("23432119147a4367abf7c0de2aa99a2d", environment)
log.Hooks.Add(hook)
}
2018-08-26 07:46:18 +02:00
return log.WithFields(logrus.Fields{
"debug": config.GetDebug(),
"version": config.GetVersion(),
"commit": config.GetCommit(),
"buildDate": config.GetBuildDate(),
})
}
// NewApp bootstrap a new application
func NewApp(config config.AppConfigurer) (*App, error) {
app := &App{
closers: []io.Closer{},
Config: config,
}
var err error
2018-08-13 13:16:21 +02:00
app.Log = newLogger(config)
app.Tr = i18n.NewLocalizer(app.Log)
2019-02-18 12:29:43 +02:00
// if we are being called in 'demon' mode, we can just return here
app.ClientContext = os.Getenv("LAZYGIT_CLIENT_COMMAND")
if app.ClientContext != "" {
2019-02-18 12:29:43 +02:00
return app, nil
}
app.OSCommand = commands.NewOSCommand(app.Log, config)
2018-09-07 01:41:15 +02:00
app.Updater, err = updates.NewUpdater(app.Log, config, app.OSCommand, app.Tr)
if err != nil {
2018-08-18 11:43:58 +02:00
return app, err
}
if err := app.setupRepo(); err != nil {
return app, err
}
2019-02-18 12:29:43 +02:00
app.GitCommand, err = commands.NewGitCommand(app.Log, app.OSCommand, app.Tr, app.Config)
2018-08-19 15:28:29 +02:00
if err != nil {
return app, err
}
app.Gui, err = gui.NewGui(app.Log, app.GitCommand, app.OSCommand, app.Tr, config, app.Updater)
2018-08-13 12:26:02 +02:00
if err != nil {
2018-08-18 11:43:58 +02:00
return app, err
2018-08-13 12:26:02 +02:00
}
return app, nil
}
func (app *App) setupRepo() error {
// if we are not in a git repo, we ask if we want to `git init`
if err := app.OSCommand.RunCommand("git status"); err != nil {
if !strings.Contains(err.Error(), "Not a git repository") {
return err
}
fmt.Print(app.Tr.SLocalize("CreateRepo"))
response, _ := bufio.NewReader(os.Stdin).ReadString('\n')
if strings.Trim(response, " \n") != "y" {
os.Exit(1)
}
if err := app.OSCommand.RunCommand("git init"); err != nil {
return err
}
}
return nil
}
func (app *App) Run() error {
if app.ClientContext == "INTERACTIVE_REBASE" {
2019-02-18 12:29:43 +02:00
return app.Rebase()
}
if app.ClientContext == "EXIT_IMMEDIATELY" {
os.Exit(0)
}
return app.Gui.RunWithSubprocesses()
}
// Rebase contains logic for when we've been run in demon mode, meaning we've
// given lazygit as a command for git to call e.g. to edit a file
2019-02-18 12:29:43 +02:00
func (app *App) Rebase() error {
app.Log.Info("Lazygit invoked as interactive rebase demon")
app.Log.Info("args: ", os.Args)
if strings.HasSuffix(os.Args[1], "git-rebase-todo") {
2019-03-02 04:22:02 +02:00
if err := ioutil.WriteFile(os.Args[1], []byte(os.Getenv("LAZYGIT_REBASE_TODO")), 0644); err != nil {
return err
}
} else if strings.HasSuffix(os.Args[1], ".git/COMMIT_EDITMSG") {
// if we are rebasing and squashing, we'll see a COMMIT_EDITMSG
// but in this case we don't need to edit it, so we'll just return
} else {
app.Log.Info("Lazygit demon did not match on any use cases")
}
2019-02-18 12:29:43 +02:00
return nil
}
// Close closes any resources
func (app *App) Close() error {
for _, closer := range app.closers {
err := closer.Close()
if err != nil {
return err
}
}
return nil
}