1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-05-31 23:19:40 +02:00

Introduce ConfigFile struct

This makes it more explicit how to deal with the different types of config
files: a user-supplied config file (via the LG_CONFIG_FILE env var) is required
to exist, whereas the default config file will be created if it is missing.

We will later extend this with repo-specific config files, which will be skipped
if missing.
This commit is contained in:
Stefan Haller 2024-07-13 18:07:48 +02:00
parent be0fa98d11
commit 940700dc56

View File

@ -8,6 +8,7 @@ import (
"github.com/adrg/xdg" "github.com/adrg/xdg"
"github.com/jesseduffield/lazygit/pkg/utils/yaml_utils" "github.com/jesseduffield/lazygit/pkg/utils/yaml_utils"
"github.com/samber/lo"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@ -19,7 +20,7 @@ type AppConfig struct {
name string `long:"name" env:"NAME" default:"lazygit"` name string `long:"name" env:"NAME" default:"lazygit"`
buildSource string `long:"build-source" env:"BUILD_SOURCE" default:""` buildSource string `long:"build-source" env:"BUILD_SOURCE" default:""`
userConfig *UserConfig userConfig *UserConfig
userConfigPaths []string userConfigFiles []*ConfigFile
userConfigDir string userConfigDir string
tempDir string tempDir string
appState *AppState appState *AppState
@ -42,6 +43,18 @@ type AppConfigurer interface {
SaveAppState() error SaveAppState() error
} }
type ConfigFilePolicy int
const (
ConfigFilePolicyCreateIfMissing ConfigFilePolicy = iota
ConfigFilePolicyErrorIfMissing
)
type ConfigFile struct {
Path string
Policy ConfigFilePolicy
}
// NewAppConfig makes a new app config // NewAppConfig makes a new app config
func NewAppConfig( func NewAppConfig(
name string, name string,
@ -57,17 +70,22 @@ func NewAppConfig(
return nil, err return nil, err
} }
var userConfigPaths []string var configFiles []*ConfigFile
customConfigFiles := os.Getenv("LG_CONFIG_FILE") customConfigFiles := os.Getenv("LG_CONFIG_FILE")
if customConfigFiles != "" { if customConfigFiles != "" {
// Load user defined config files // Load user defined config files
userConfigPaths = strings.Split(customConfigFiles, ",") userConfigPaths := strings.Split(customConfigFiles, ",")
configFiles = lo.Map(userConfigPaths, func(path string, _ int) *ConfigFile {
return &ConfigFile{Path: path, Policy: ConfigFilePolicyErrorIfMissing}
})
} else { } else {
// Load default config files // Load default config files
userConfigPaths = []string{filepath.Join(configDir, ConfigFilename)} path := filepath.Join(configDir, ConfigFilename)
configFile := &ConfigFile{Path: path, Policy: ConfigFilePolicyCreateIfMissing}
configFiles = []*ConfigFile{configFile}
} }
userConfig, err := loadUserConfigWithDefaults(userConfigPaths) userConfig, err := loadUserConfigWithDefaults(configFiles)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -95,7 +113,7 @@ func NewAppConfig(
debug: debuggingFlag, debug: debuggingFlag,
buildSource: buildSource, buildSource: buildSource,
userConfig: userConfig, userConfig: userConfig,
userConfigPaths: userConfigPaths, userConfigFiles: configFiles,
userConfigDir: configDir, userConfigDir: configDir,
tempDir: tempDir, tempDir: tempDir,
appState: appState, appState: appState,
@ -104,10 +122,6 @@ func NewAppConfig(
return appConfig, nil return appConfig, nil
} }
func isCustomConfigFile(path string) bool {
return path != filepath.Join(ConfigDir(), ConfigFilename)
}
func ConfigDir() string { func ConfigDir() string {
_, filePath := findConfigFile("config.yml") _, filePath := findConfigFile("config.yml")
@ -119,32 +133,33 @@ func findOrCreateConfigDir() (string, error) {
return folder, os.MkdirAll(folder, 0o755) return folder, os.MkdirAll(folder, 0o755)
} }
func loadUserConfigWithDefaults(configFiles []string) (*UserConfig, error) { func loadUserConfigWithDefaults(configFiles []*ConfigFile) (*UserConfig, error) {
return loadUserConfig(configFiles, GetDefaultConfig()) return loadUserConfig(configFiles, GetDefaultConfig())
} }
func loadUserConfig(configFiles []string, base *UserConfig) (*UserConfig, error) { func loadUserConfig(configFiles []*ConfigFile, base *UserConfig) (*UserConfig, error) {
for _, path := range configFiles { for _, configFile := range configFiles {
path := configFile.Path
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
return nil, err return nil, err
} }
// if use has supplied their own custom config file path(s), we assume switch configFile.Policy {
// the files have already been created, so we won't go and create them here. case ConfigFilePolicyErrorIfMissing:
if isCustomConfigFile(path) {
return nil, err return nil, err
}
file, err := os.Create(path) case ConfigFilePolicyCreateIfMissing:
if err != nil { file, err := os.Create(path)
if os.IsPermission(err) { if err != nil {
// apparently when people have read-only permissions they prefer us to fail silently if os.IsPermission(err) {
continue // apparently when people have read-only permissions they prefer us to fail silently
continue
}
return nil, err
} }
return nil, err file.Close()
} }
file.Close()
} }
content, err := os.ReadFile(path) content, err := os.ReadFile(path)
@ -244,7 +259,9 @@ func (c *AppConfig) GetAppState() *AppState {
} }
func (c *AppConfig) GetUserConfigPaths() []string { func (c *AppConfig) GetUserConfigPaths() []string {
return c.userConfigPaths return lo.Map(c.userConfigFiles, func(f *ConfigFile, _ int) string {
return f.Path
})
} }
func (c *AppConfig) GetUserConfigDir() string { func (c *AppConfig) GetUserConfigDir() string {