store popup version in state not config so that we never need to write to the user config

This commit is contained in:
Jesse Duffield 2020-10-04 08:45:08 +11:00
parent 4912205adb
commit ca31e5258f
4 changed files with 46 additions and 57 deletions

View file

@ -57,6 +57,7 @@ Default path for the config file:
confirmOnQuit: false confirmOnQuit: false
# determines whether hitting 'esc' will quit the application when there is nothing to cancel/close # determines whether hitting 'esc' will quit the application when there is nothing to cancel/close
quitOnTopLevelReturn: true quitOnTopLevelReturn: true
disableStartupPopups: false
keybinding: keybinding:
universal: universal:
quit: 'q' quit: 'q'

View file

@ -37,9 +37,7 @@ type AppConfigurer interface {
GetUserConfigDir() string GetUserConfigDir() string
GetUserConfigPath() string GetUserConfigPath() string
GetAppState() *AppState GetAppState() *AppState
WriteToUserConfig(func(*UserConfig) error) error
SaveAppState() error SaveAppState() error
LoadAppState() error
SetIsNewRepo(bool) SetIsNewRepo(bool)
GetIsNewRepo() bool GetIsNewRepo() bool
} }
@ -60,6 +58,11 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg
debuggingFlag = true debuggingFlag = true
} }
appState, err := loadAppState()
if err != nil {
return nil, err
}
appConfig := &AppConfig{ appConfig := &AppConfig{
Name: "lazygit", Name: "lazygit",
Version: version, Version: version,
@ -70,14 +73,10 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg
UserConfig: userConfig, UserConfig: userConfig,
UserConfigDir: configDir, UserConfigDir: configDir,
UserConfigPath: filepath.Join(configDir, "config.yml"), UserConfigPath: filepath.Join(configDir, "config.yml"),
AppState: &AppState{}, AppState: appState,
IsNewRepo: false, IsNewRepo: false,
} }
if err := appConfig.LoadAppState(); err != nil {
return nil, err
}
return appConfig, nil return appConfig, nil
} }
@ -195,28 +194,6 @@ func configFilePath(filename string) (string, error) {
return filepath.Join(folder, filename), nil return filepath.Join(folder, filename), nil
} }
// WriteToUserConfig allows you to set a value on the user config to be saved
// note that if you set a zero-value, it may be ignored e.g. a false or 0 or
// empty string this is because we are using the omitempty yaml directive so
// that we don't write a heap of zero values to the user's config.yml
func (c *AppConfig) WriteToUserConfig(updateConfig func(*UserConfig) error) error {
userConfig, err := loadUserConfig(c.UserConfigDir, &UserConfig{})
if err != nil {
return err
}
if err := updateConfig(userConfig); err != nil {
return err
}
file, err := os.OpenFile(c.ConfigFilename(), os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return err
}
return yaml.NewEncoder(file).Encode(userConfig)
}
// ConfigFilename returns the filename of the current config file // ConfigFilename returns the filename of the current config file
func (c *AppConfig) ConfigFilename() string { func (c *AppConfig) ConfigFilename() string {
return filepath.Join(c.UserConfigDir, "config.yml") return filepath.Join(c.UserConfigDir, "config.yml")
@ -237,20 +214,29 @@ func (c *AppConfig) SaveAppState() error {
return ioutil.WriteFile(filepath, marshalledAppState, 0644) return ioutil.WriteFile(filepath, marshalledAppState, 0644)
} }
// LoadAppState loads recorded AppState from file // loadAppState loads recorded AppState from file
func (c *AppConfig) LoadAppState() error { func loadAppState() (*AppState, error) {
filepath, err := configFilePath("state.yml") filepath, err := configFilePath("state.yml")
if err != nil { if err != nil {
return err return nil, err
} }
appStateBytes, err := ioutil.ReadFile(filepath) appStateBytes, err := ioutil.ReadFile(filepath)
if err != nil { if err != nil {
return err return nil, err
} }
if len(appStateBytes) == 0 { if len(appStateBytes) == 0 {
return yaml.Unmarshal(getDefaultAppState(), c.AppState) return getDefaultAppState(), nil
} }
return yaml.Unmarshal(appStateBytes, c.AppState)
appState := &AppState{}
err = yaml.Unmarshal(appStateBytes, appState)
if err != nil {
return nil, err
}
return appState, nil
} }
func GetDefaultConfig() *UserConfig { func GetDefaultConfig() *UserConfig {
@ -314,6 +300,7 @@ reporting: 'undetermined' # one of: 'on' | 'off' | 'undetermined'
splashUpdatesIndex: 0 splashUpdatesIndex: 0
confirmOnQuit: false confirmOnQuit: false
quitOnTopLevelReturn: true quitOnTopLevelReturn: true
disableStartupPopups: false
keybinding: keybinding:
universal: universal:
quit: 'q' quit: 'q'
@ -433,15 +420,17 @@ keybinding:
// AppState stores data between runs of the app like when the last update check // AppState stores data between runs of the app like when the last update check
// was performed and which other repos have been checked out // was performed and which other repos have been checked out
type AppState struct { type AppState struct {
LastUpdateCheck int64 LastUpdateCheck int64
RecentRepos []string RecentRepos []string
StartupPopupVersion int
} }
func getDefaultAppState() []byte { func getDefaultAppState() *AppState {
return []byte(` return &AppState{
lastUpdateCheck: 0 LastUpdateCheck: 0,
recentRepos: [] RecentRepos: []string{},
`) StartupPopupVersion: 0,
}
} }
func LogPath() (string, error) { func LogPath() (string, error) {

View file

@ -208,8 +208,8 @@ type UserConfig struct {
} `yaml:"submodules"` } `yaml:"submodules"`
} `yaml:"keybinding"` } `yaml:"keybinding"`
// OS determines what defaults are set for opening files and links // OS determines what defaults are set for opening files and links
OS OSConfig `yaml:"os,omitempty"` OS OSConfig `yaml:"os,omitempty"`
StartupPopupVersion int `yaml:"startupPopupVersion"` DisableStartupPopups bool `yaml:"disableStartupPopups"`
CustomCommands []CustomCommand `yaml:"customCommands"` CustomCommands []CustomCommand `yaml:"customCommands"`
Services map[string]string `yaml:"services"` Services map[string]string `yaml:"services"`
} }

View file

@ -41,7 +41,7 @@ const (
SCREEN_FULL SCREEN_FULL
) )
const StartupPopupVersion = 1 const StartupPopupVersion = 2
// OverlappingEdges determines if panel edges overlap // OverlappingEdges determines if panel edges overlap
var OverlappingEdges = false var OverlappingEdges = false
@ -450,13 +450,14 @@ func (gui *Gui) Run() error {
return err return err
} }
popupTasks := []func(chan struct{}) error{} if !gui.Config.GetUserConfig().DisableStartupPopups {
configPopupVersion := gui.Config.GetUserConfig().StartupPopupVersion popupTasks := []func(chan struct{}) error{}
// -1 means we've disabled these popups storedPopupVersion := gui.Config.GetAppState().StartupPopupVersion
if configPopupVersion != -1 && configPopupVersion < StartupPopupVersion { if storedPopupVersion < StartupPopupVersion {
popupTasks = append(popupTasks, gui.showIntroPopupMessage) popupTasks = append(popupTasks, gui.showIntroPopupMessage)
}
gui.showInitialPopups(popupTasks)
} }
gui.showInitialPopups(popupTasks)
gui.waitForIntro.Add(1) gui.waitForIntro.Add(1)
if gui.Config.GetUserConfig().Git.AutoFetch { if gui.Config.GetUserConfig().Git.AutoFetch {
@ -573,10 +574,8 @@ func (gui *Gui) showInitialPopups(tasks []func(chan struct{}) error) {
func (gui *Gui) showIntroPopupMessage(done chan struct{}) error { func (gui *Gui) showIntroPopupMessage(done chan struct{}) error {
onConfirm := func() error { onConfirm := func() error {
done <- struct{}{} done <- struct{}{}
return gui.Config.WriteToUserConfig(func(userConfig *config.UserConfig) error { gui.Config.GetAppState().StartupPopupVersion = StartupPopupVersion
userConfig.StartupPopupVersion = StartupPopupVersion return gui.Config.SaveAppState()
return nil
})
} }
return gui.ask(askOpts{ return gui.ask(askOpts{