summaryrefslogtreecommitdiffstats
path: root/modules/setting
diff options
context:
space:
mode:
Diffstat (limited to 'modules/setting')
-rw-r--r--modules/setting/config_provider.go80
-rw-r--r--modules/setting/config_provider_test.go11
-rw-r--r--modules/setting/path.go191
-rw-r--r--modules/setting/path_test.go151
-rw-r--r--modules/setting/server.go2
-rw-r--r--modules/setting/setting.go131
6 files changed, 398 insertions, 168 deletions
diff --git a/modules/setting/config_provider.go b/modules/setting/config_provider.go
index deec5cc586..94dd989850 100644
--- a/modules/setting/config_provider.go
+++ b/modules/setting/config_provider.go
@@ -55,15 +55,15 @@ type ConfigProvider interface {
DisableSaving()
PrepareSaving() (ConfigProvider, error)
+ IsLoadedFromEmpty() bool
}
type iniConfigProvider struct {
- opts *Options
+ file string
ini *ini.File
- disableSaving bool
-
- newFile bool // whether the file has not existed previously
+ disableSaving bool // disable the "Save" method because the config options could be polluted
+ loadedFromEmpty bool // whether the file has not existed previously
}
type iniConfigSection struct {
@@ -182,53 +182,43 @@ func NewConfigProviderFromData(configContent string) (ConfigProvider, error) {
}
cfg.NameMapper = ini.SnackCase
return &iniConfigProvider{
- ini: cfg,
- newFile: true,
+ ini: cfg,
+ loadedFromEmpty: true,
}, nil
}
-type Options struct {
- CustomConf string // the ini file path
- AllowEmpty bool // whether not finding configuration files is allowed
- ExtraConfig string
-
- DisableLoadCommonSettings bool // only used by "Init()", not used by "NewConfigProvider()"
-}
-
// NewConfigProviderFromFile load configuration from file.
// NOTE: do not print any log except error.
-func NewConfigProviderFromFile(opts *Options) (ConfigProvider, error) {
+func NewConfigProviderFromFile(file string, extraConfigs ...string) (ConfigProvider, error) {
cfg := ini.Empty(ini.LoadOptions{KeyValueDelimiterOnWrite: " = "})
- newFile := true
+ loadedFromEmpty := true
- if opts.CustomConf != "" {
- isFile, err := util.IsFile(opts.CustomConf)
+ if file != "" {
+ isFile, err := util.IsFile(file)
if err != nil {
- return nil, fmt.Errorf("unable to check if %s is a file. Error: %v", opts.CustomConf, err)
+ return nil, fmt.Errorf("unable to check if %q is a file. Error: %v", file, err)
}
if isFile {
- if err := cfg.Append(opts.CustomConf); err != nil {
- return nil, fmt.Errorf("failed to load custom conf '%s': %v", opts.CustomConf, err)
+ if err = cfg.Append(file); err != nil {
+ return nil, fmt.Errorf("failed to load config file %q: %v", file, err)
}
- newFile = false
+ loadedFromEmpty = false
}
}
- if newFile && !opts.AllowEmpty {
- return nil, fmt.Errorf("unable to find configuration file: %q, please ensure you are running in the correct environment or set the correct configuration file with -c", CustomConf)
- }
-
- if opts.ExtraConfig != "" {
- if err := cfg.Append([]byte(opts.ExtraConfig)); err != nil {
- return nil, fmt.Errorf("unable to append more config: %v", err)
+ if len(extraConfigs) > 0 {
+ for _, s := range extraConfigs {
+ if err := cfg.Append([]byte(s)); err != nil {
+ return nil, fmt.Errorf("unable to append more config: %v", err)
+ }
}
}
cfg.NameMapper = ini.SnackCase
return &iniConfigProvider{
- opts: opts,
- ini: cfg,
- newFile: newFile,
+ file: file,
+ ini: cfg,
+ loadedFromEmpty: loadedFromEmpty,
}, nil
}
@@ -266,20 +256,17 @@ func (p *iniConfigProvider) Save() error {
if p.disableSaving {
return errDisableSaving
}
- filename := p.opts.CustomConf
+ filename := p.file
if filename == "" {
- if !p.opts.AllowEmpty {
- return fmt.Errorf("custom config path must not be empty")
- }
- return nil
+ return fmt.Errorf("config file path must not be empty")
}
- if p.newFile {
+ if p.loadedFromEmpty {
if err := os.MkdirAll(filepath.Dir(filename), os.ModePerm); err != nil {
- return fmt.Errorf("failed to create '%s': %v", filename, err)
+ return fmt.Errorf("failed to create %q: %v", filename, err)
}
}
if err := p.ini.SaveTo(filename); err != nil {
- return fmt.Errorf("failed to save '%s': %v", filename, err)
+ return fmt.Errorf("failed to save %q: %v", filename, err)
}
// Change permissions to be more restrictive
@@ -313,11 +300,14 @@ func (p *iniConfigProvider) DisableSaving() {
// it makes the "Save" outputs a lot of garbage options
// After the INI package gets refactored, no "MustXxx" pollution, this workaround can be dropped.
func (p *iniConfigProvider) PrepareSaving() (ConfigProvider, error) {
- cfgFile := p.opts.CustomConf
- if cfgFile == "" {
+ if p.file == "" {
return nil, errors.New("no config file to save")
}
- return NewConfigProviderFromFile(p.opts)
+ return NewConfigProviderFromFile(p.file)
+}
+
+func (p *iniConfigProvider) IsLoadedFromEmpty() bool {
+ return p.loadedFromEmpty
}
func mustMapSetting(rootCfg ConfigProvider, sectionName string, setting any) {
@@ -356,8 +346,8 @@ func NewConfigProviderForLocale(source any, others ...any) (ConfigProvider, erro
}
iniFile.BlockMode = false
return &iniConfigProvider{
- ini: iniFile,
- newFile: true,
+ ini: iniFile,
+ loadedFromEmpty: true,
}, nil
}
diff --git a/modules/setting/config_provider_test.go b/modules/setting/config_provider_test.go
index c5c5196e04..7e7c6be2bb 100644
--- a/modules/setting/config_provider_test.go
+++ b/modules/setting/config_provider_test.go
@@ -67,13 +67,14 @@ key = 123
}
func TestNewConfigProviderFromFile(t *testing.T) {
- _, err := NewConfigProviderFromFile(&Options{CustomConf: "no-such.ini", AllowEmpty: false})
- assert.ErrorContains(t, err, "unable to find configuration file")
+ cfg, err := NewConfigProviderFromFile("no-such.ini")
+ assert.NoError(t, err)
+ assert.True(t, cfg.IsLoadedFromEmpty())
// load non-existing file and save
testFile := t.TempDir() + "/test.ini"
testFile1 := t.TempDir() + "/test1.ini"
- cfg, err := NewConfigProviderFromFile(&Options{CustomConf: testFile, AllowEmpty: true})
+ cfg, err = NewConfigProviderFromFile(testFile)
assert.NoError(t, err)
sec, _ := cfg.NewSection("foo")
@@ -91,7 +92,7 @@ func TestNewConfigProviderFromFile(t *testing.T) {
assert.Equal(t, "[foo]\nk1 = a\nk2 = b\n", string(bs))
// load existing file and save
- cfg, err = NewConfigProviderFromFile(&Options{CustomConf: testFile, AllowEmpty: true})
+ cfg, err = NewConfigProviderFromFile(testFile)
assert.NoError(t, err)
assert.Equal(t, "a", cfg.Section("foo").Key("k1").String())
sec, _ = cfg.NewSection("bar")
@@ -123,7 +124,7 @@ func TestNewConfigProviderForLocale(t *testing.T) {
func TestDisableSaving(t *testing.T) {
testFile := t.TempDir() + "/test.ini"
_ = os.WriteFile(testFile, []byte("k1=a\nk2=b"), 0o644)
- cfg, err := NewConfigProviderFromFile(&Options{CustomConf: testFile, AllowEmpty: true})
+ cfg, err := NewConfigProviderFromFile(testFile)
assert.NoError(t, err)
cfg.DisableSaving()
diff --git a/modules/setting/path.go b/modules/setting/path.go
new file mode 100644
index 0000000000..91bb2e9bb7
--- /dev/null
+++ b/modules/setting/path.go
@@ -0,0 +1,191 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package setting
+
+import (
+ "errors"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+
+ "code.gitea.io/gitea/modules/log"
+)
+
+var (
+ // AppPath represents the path to the gitea binary
+ AppPath string
+
+ // AppWorkPath is the "working directory" of Gitea. It maps to the environment variable GITEA_WORK_DIR.
+ // If that is not set it is the default set here by the linker or failing that the directory of AppPath.
+ // It is used as the base path for several other paths.
+ AppWorkPath string
+ CustomPath string // Custom directory path. Env: GITEA_CUSTOM
+ CustomConf string
+
+ appWorkPathBuiltin string
+ customPathBuiltin string
+ customConfBuiltin string
+
+ AppWorkPathMismatch bool
+)
+
+func getAppPath() (string, error) {
+ var appPath string
+ var err error
+ if IsWindows && filepath.IsAbs(os.Args[0]) {
+ appPath = filepath.Clean(os.Args[0])
+ } else {
+ appPath, err = exec.LookPath(os.Args[0])
+ }
+ if err != nil {
+ if !errors.Is(err, exec.ErrDot) {
+ return "", err
+ }
+ appPath, err = filepath.Abs(os.Args[0])
+ }
+ if err != nil {
+ return "", err
+ }
+ appPath, err = filepath.Abs(appPath)
+ if err != nil {
+ return "", err
+ }
+ // Note: (legacy code) we don't use path.Dir here because it does not handle case which path starts with two "/" in Windows: "//psf/Home/..."
+ return strings.ReplaceAll(appPath, "\\", "/"), err
+}
+
+func init() {
+ var err error
+ if AppPath, err = getAppPath(); err != nil {
+ log.Fatal("Failed to get app path: %v", err)
+ }
+
+ if AppWorkPath == "" {
+ AppWorkPath = filepath.Dir(AppPath)
+ }
+
+ appWorkPathBuiltin = AppWorkPath
+ customPathBuiltin = CustomPath
+ customConfBuiltin = CustomConf
+}
+
+type ArgWorkPathAndCustomConf struct {
+ WorkPath string
+ CustomPath string
+ CustomConf string
+}
+
+type stringWithDefault struct {
+ Value string
+ IsSet bool
+}
+
+func (s *stringWithDefault) Set(v string) {
+ s.Value = v
+ s.IsSet = true
+}
+
+// InitWorkPathAndCommonConfig will set AppWorkPath, CustomPath and CustomConf, init default config provider by CustomConf and load common settings,
+func InitWorkPathAndCommonConfig(getEnvFn func(name string) string, args ArgWorkPathAndCustomConf) {
+ tryAbsPath := func(paths ...string) string {
+ s := paths[len(paths)-1]
+ for i := len(paths) - 2; i >= 0; i-- {
+ if filepath.IsAbs(s) {
+ break
+ }
+ s = filepath.Join(paths[i], s)
+ }
+ return s
+ }
+
+ var err error
+ tmpWorkPath := stringWithDefault{Value: appWorkPathBuiltin}
+ if tmpWorkPath.Value == "" {
+ tmpWorkPath.Value = filepath.Dir(AppPath)
+ }
+ tmpCustomPath := stringWithDefault{Value: customPathBuiltin}
+ if tmpCustomPath.Value == "" {
+ tmpCustomPath.Value = "custom"
+ }
+ tmpCustomConf := stringWithDefault{Value: customConfBuiltin}
+ if tmpCustomConf.Value == "" {
+ tmpCustomConf.Value = "conf/app.ini"
+ }
+
+ readFromEnv := func() {
+ envWorkPath := getEnvFn("GITEA_WORK_DIR")
+ if envWorkPath != "" {
+ tmpWorkPath.Set(envWorkPath)
+ if !filepath.IsAbs(tmpWorkPath.Value) {
+ log.Fatal("GITEA_WORK_DIR (work path) must be absolute path")
+ }
+ }
+
+ envCustomPath := getEnvFn("GITEA_CUSTOM")
+ if envCustomPath != "" {
+ tmpCustomPath.Set(envCustomPath)
+ if !filepath.IsAbs(tmpCustomPath.Value) {
+ log.Fatal("GITEA_CUSTOM (custom path) must be absolute path")
+ }
+ }
+ }
+
+ readFromArgs := func() {
+ if args.WorkPath != "" {
+ tmpWorkPath.Set(args.WorkPath)
+ if !filepath.IsAbs(tmpWorkPath.Value) {
+ log.Fatal("--work-path must be absolute path")
+ }
+ }
+ if args.CustomPath != "" {
+ tmpCustomPath.Set(args.CustomPath) // if it is not abs, it will be based on work-path, it shouldn't happen
+ if !filepath.IsAbs(tmpCustomPath.Value) {
+ log.Error("--custom-path must be absolute path")
+ }
+ }
+ if args.CustomConf != "" {
+ tmpCustomConf.Set(args.CustomConf)
+ if !filepath.IsAbs(tmpCustomConf.Value) {
+ // the config path can be relative to the real current working path
+ if tmpCustomConf.Value, err = filepath.Abs(tmpCustomConf.Value); err != nil {
+ log.Fatal("Failed to get absolute path of config %q: %v", tmpCustomConf.Value, err)
+ }
+ }
+ }
+ }
+
+ readFromEnv()
+ readFromArgs()
+
+ if !tmpCustomConf.IsSet {
+ tmpCustomConf.Set(tryAbsPath(tmpWorkPath.Value, tmpCustomPath.Value, tmpCustomConf.Value))
+ }
+
+ // only read the config but do not load/init anything more, because the AppWorkPath and CustomPath are not ready
+ InitCfgProvider(tmpCustomConf.Value)
+ configWorkPath := ConfigSectionKeyString(CfgProvider.Section(""), "WORK_PATH")
+ if configWorkPath != "" {
+ if !filepath.IsAbs(configWorkPath) {
+ log.Fatal("WORK_PATH in %q must be absolute path", configWorkPath)
+ }
+ configWorkPath = filepath.Clean(configWorkPath)
+ if tmpWorkPath.Value != "" && (getEnvFn("GITEA_WORK_DIR") != "" || args.WorkPath != "") {
+ fi1, err1 := os.Stat(tmpWorkPath.Value)
+ fi2, err2 := os.Stat(configWorkPath)
+ if err1 != nil || err2 != nil || !os.SameFile(fi1, fi2) {
+ AppWorkPathMismatch = true
+ }
+ }
+ tmpWorkPath.Set(configWorkPath)
+ }
+
+ tmpCustomPath.Set(tryAbsPath(tmpWorkPath.Value, tmpCustomPath.Value))
+
+ AppWorkPath = tmpWorkPath.Value
+ CustomPath = tmpCustomPath.Value
+ CustomConf = tmpCustomConf.Value
+
+ LoadCommonSettings()
+}
diff --git a/modules/setting/path_test.go b/modules/setting/path_test.go
new file mode 100644
index 0000000000..fc6a2116dc
--- /dev/null
+++ b/modules/setting/path_test.go
@@ -0,0 +1,151 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package setting
+
+import (
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+type envVars map[string]string
+
+func (e envVars) Getenv(key string) string {
+ return e[key]
+}
+
+func TestInitWorkPathAndCommonConfig(t *testing.T) {
+ testInit := func(defaultWorkPath, defaultCustomPath, defaultCustomConf string) {
+ AppWorkPathMismatch = false
+ AppWorkPath = defaultWorkPath
+ appWorkPathBuiltin = defaultWorkPath
+ CustomPath = defaultCustomPath
+ customPathBuiltin = defaultCustomPath
+ CustomConf = defaultCustomConf
+ customConfBuiltin = defaultCustomConf
+ }
+
+ fp := filepath.Join
+
+ tmpDir := t.TempDir()
+ dirFoo := fp(tmpDir, "foo")
+ dirBar := fp(tmpDir, "bar")
+ dirXxx := fp(tmpDir, "xxx")
+ dirYyy := fp(tmpDir, "yyy")
+
+ t.Run("Default", func(t *testing.T) {
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ assert.Equal(t, fp(dirFoo, "custom"), CustomPath)
+ assert.Equal(t, fp(dirFoo, "custom/conf/app.ini"), CustomConf)
+ })
+
+ t.Run("WorkDir(env)", func(t *testing.T) {
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{"GITEA_WORK_DIR": dirBar}.Getenv, ArgWorkPathAndCustomConf{})
+ assert.Equal(t, dirBar, AppWorkPath)
+ assert.Equal(t, fp(dirBar, "custom"), CustomPath)
+ assert.Equal(t, fp(dirBar, "custom/conf/app.ini"), CustomConf)
+ })
+
+ t.Run("WorkDir(env,arg)", func(t *testing.T) {
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{"GITEA_WORK_DIR": dirBar}.Getenv, ArgWorkPathAndCustomConf{WorkPath: dirXxx})
+ assert.Equal(t, dirXxx, AppWorkPath)
+ assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
+ assert.Equal(t, fp(dirXxx, "custom/conf/app.ini"), CustomConf)
+ })
+
+ t.Run("CustomPath(env)", func(t *testing.T) {
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{"GITEA_CUSTOM": fp(dirBar, "custom1")}.Getenv, ArgWorkPathAndCustomConf{})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ assert.Equal(t, fp(dirBar, "custom1"), CustomPath)
+ assert.Equal(t, fp(dirBar, "custom1/conf/app.ini"), CustomConf)
+ })
+
+ t.Run("CustomPath(env,arg)", func(t *testing.T) {
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{"GITEA_CUSTOM": fp(dirBar, "custom1")}.Getenv, ArgWorkPathAndCustomConf{CustomPath: "custom2"})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ assert.Equal(t, fp(dirFoo, "custom2"), CustomPath)
+ assert.Equal(t, fp(dirFoo, "custom2/conf/app.ini"), CustomConf)
+ })
+
+ t.Run("CustomConf", func(t *testing.T) {
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: "app1.ini"})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ cwd, _ := os.Getwd()
+ assert.Equal(t, fp(cwd, "app1.ini"), CustomConf)
+
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: fp(dirBar, "app1.ini")})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ assert.Equal(t, fp(dirBar, "app1.ini"), CustomConf)
+ })
+
+ t.Run("CustomConfOverrideWorkPath", func(t *testing.T) {
+ iniWorkPath := fp(tmpDir, "app-workpath.ini")
+ _ = os.WriteFile(iniWorkPath, []byte("WORK_PATH="+dirXxx), 0o644)
+
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: iniWorkPath})
+ assert.Equal(t, dirXxx, AppWorkPath)
+ assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
+ assert.Equal(t, iniWorkPath, CustomConf)
+ assert.False(t, AppWorkPathMismatch)
+
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{"GITEA_WORK_DIR": dirBar}.Getenv, ArgWorkPathAndCustomConf{CustomConf: iniWorkPath})
+ assert.Equal(t, dirXxx, AppWorkPath)
+ assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
+ assert.Equal(t, iniWorkPath, CustomConf)
+ assert.True(t, AppWorkPathMismatch)
+
+ testInit(dirFoo, "", "")
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{WorkPath: dirBar, CustomConf: iniWorkPath})
+ assert.Equal(t, dirXxx, AppWorkPath)
+ assert.Equal(t, fp(dirXxx, "custom"), CustomPath)
+ assert.Equal(t, iniWorkPath, CustomConf)
+ assert.True(t, AppWorkPathMismatch)
+ })
+
+ t.Run("Builtin", func(t *testing.T) {
+ testInit(dirFoo, dirBar, dirXxx)
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ assert.Equal(t, dirBar, CustomPath)
+ assert.Equal(t, dirXxx, CustomConf)
+
+ testInit(dirFoo, "custom1", "cfg.ini")
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ assert.Equal(t, fp(dirFoo, "custom1"), CustomPath)
+ assert.Equal(t, fp(dirFoo, "custom1/cfg.ini"), CustomConf)
+
+ testInit(dirFoo, "custom1", "cfg.ini")
+ InitWorkPathAndCommonConfig(envVars{"GITEA_WORK_DIR": dirYyy}.Getenv, ArgWorkPathAndCustomConf{})
+ assert.Equal(t, dirYyy, AppWorkPath)
+ assert.Equal(t, fp(dirYyy, "custom1"), CustomPath)
+ assert.Equal(t, fp(dirYyy, "custom1/cfg.ini"), CustomConf)
+
+ testInit(dirFoo, "custom1", "cfg.ini")
+ InitWorkPathAndCommonConfig(envVars{"GITEA_CUSTOM": dirYyy}.Getenv, ArgWorkPathAndCustomConf{})
+ assert.Equal(t, dirFoo, AppWorkPath)
+ assert.Equal(t, dirYyy, CustomPath)
+ assert.Equal(t, fp(dirYyy, "cfg.ini"), CustomConf)
+
+ iniWorkPath := fp(tmpDir, "app-workpath.ini")
+ _ = os.WriteFile(iniWorkPath, []byte("WORK_PATH="+dirXxx), 0o644)
+ testInit(dirFoo, "custom1", "cfg.ini")
+ InitWorkPathAndCommonConfig(envVars{}.Getenv, ArgWorkPathAndCustomConf{CustomConf: iniWorkPath})
+ assert.Equal(t, dirXxx, AppWorkPath)
+ assert.Equal(t, fp(dirXxx, "custom1"), CustomPath)
+ assert.Equal(t, iniWorkPath, CustomConf)
+ })
+}
diff --git a/modules/setting/server.go b/modules/setting/server.go
index d937faca10..7c033bcc6b 100644
--- a/modules/setting/server.go
+++ b/modules/setting/server.go
@@ -61,6 +61,7 @@ var (
AssetVersion string
// Server settings
+
Protocol Scheme
UseProxyProtocol bool // `ini:"USE_PROXY_PROTOCOL"`
ProxyProtocolTLSBridging bool //`ini:"PROXY_PROTOCOL_TLS_BRIDGING"`
@@ -324,7 +325,6 @@ func loadServerFrom(rootCfg ConfigProvider) {
StaticCacheTime = sec.Key("STATIC_CACHE_TIME").MustDuration(6 * time.Hour)
AppDataPath = sec.Key("APP_DATA_PATH").MustString(path.Join(AppWorkPath, "data"))
if !filepath.IsAbs(AppDataPath) {
- log.Info("The provided APP_DATA_PATH: %s is not absolute - it will be made absolute against the work path: %s", AppDataPath, AppWorkPath)
AppDataPath = filepath.ToSlash(filepath.Join(AppWorkPath, AppDataPath))
}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 6eaddbe2b5..0d69847dbe 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -5,12 +5,8 @@
package setting
import (
- "errors"
"fmt"
"os"
- "os/exec"
- "path"
- "path/filepath"
"runtime"
"strings"
"time"
@@ -28,19 +24,9 @@ var (
// AppStartTime store time gitea has started
AppStartTime time.Time
- // AppPath represents the path to the gitea binary
- AppPath string
- // AppWorkPath is the "working directory" of Gitea. It maps to the environment variable GITEA_WORK_DIR.
- // If that is not set it is the default set here by the linker or failing that the directory of AppPath.
- //
- // AppWorkPath is used as the base path for several other paths.
- AppWorkPath string
-
// Other global setting objects
CfgProvider ConfigProvider
- CustomPath string // Custom directory path
- CustomConf string
RunMode string
RunUser string
IsProd bool
@@ -51,62 +37,6 @@ var (
IsInTesting = false
)
-func getAppPath() (string, error) {
- var appPath string
- var err error
- if IsWindows && filepath.IsAbs(os.Args[0]) {
- appPath = filepath.Clean(os.Args[0])
- } else {
- appPath, err = exec.LookPath(os.Args[0])
- }
-
- if err != nil {
- if !errors.Is(err, exec.ErrDot) {
- return "", err
- }
- appPath, err = filepath.Abs(os.Args[0])
- }
- if err != nil {
- return "", err
- }
- appPath, err = filepath.Abs(appPath)
- if err != nil {
- return "", err
- }
- // Note: we don't use path.Dir here because it does not handle case
- // which path starts with two "/" in Windows: "//psf/Home/..."
- return strings.ReplaceAll(appPath, "\\", "/"), err
-}
-
-func getWorkPath(appPath string) string {
- workPath := AppWorkPath
-
- if giteaWorkPath, ok := os.LookupEnv("GITEA_WORK_DIR"); ok {
- workPath = giteaWorkPath
- }
- if len(workPath) == 0 {
- i := strings.LastIndex(appPath, "/")
- if i == -1 {
- workPath = appPath
- } else {
- workPath = appPath[:i]
- }
- }
- workPath = strings.ReplaceAll(workPath, "\\", "/")
- if !filepath.IsAbs(workPath) {
- log.Info("Provided work path %s is not absolute - will be made absolute against the current working directory", workPath)
-
- absPath, err := filepath.Abs(workPath)
- if err != nil {
- log.Error("Unable to absolute %s against the current working directory %v. Will absolute against the AppPath %s", workPath, err, appPath)
- workPath = filepath.Join(appPath, workPath)
- } else {
- workPath = absPath
- }
- }
- return strings.ReplaceAll(workPath, "\\", "/")
-}
-
func init() {
IsWindows = runtime.GOOS == "windows"
if AppVer == "" {
@@ -116,12 +46,6 @@ func init() {
// We can rely on log.CanColorStdout being set properly because modules/log/console_windows.go comes before modules/setting/setting.go lexicographically
// By default set this logger at Info - we'll change it later, but we need to start with something.
log.SetConsoleLogger(log.DEFAULT, "console", log.INFO)
-
- var err error
- if AppPath, err = getAppPath(); err != nil {
- log.Fatal("Failed to get app path: %v", err)
- }
- AppWorkPath = getWorkPath(AppPath)
}
// IsRunUserMatchCurrentUser returns false if configured run user does not match
@@ -137,36 +61,6 @@ func IsRunUserMatchCurrentUser(runUser string) (string, bool) {
return currentUser, runUser == currentUser
}
-// SetCustomPathAndConf will set CustomPath and CustomConf with reference to the
-// GITEA_CUSTOM environment variable and with provided overrides before stepping
-// back to the default
-func SetCustomPathAndConf(providedCustom, providedConf, providedWorkPath string) {
- if len(providedWorkPath) != 0 {
- AppWorkPath = filepath.ToSlash(providedWorkPath)
- }
- if giteaCustom, ok := os.LookupEnv("GITEA_CUSTOM"); ok {
- CustomPath = giteaCustom
- }
- if len(providedCustom) != 0 {
- CustomPath = providedCustom
- }
- if len(CustomPath) == 0 {
- CustomPath = path.Join(AppWorkPath, "custom")
- } else if !filepath.IsAbs(CustomPath) {
- CustomPath = path.Join(AppWorkPath, CustomPath)
- }
-
- if len(providedConf) != 0 {
- CustomConf = providedConf
- }
- if len(CustomConf) == 0 {
- CustomConf = path.Join(CustomPath, "conf/app.ini")
- } else if !filepath.IsAbs(CustomConf) {
- CustomConf = path.Join(CustomPath, CustomConf)
- log.Warn("Using 'custom' directory as relative origin for configuration file: '%s'", CustomConf)
- }
-}
-
// PrepareAppDataPath creates app data directory if necessary
func PrepareAppDataPath() error {
// FIXME: There are too many calls to MkdirAll in old code. It is incorrect.
@@ -196,20 +90,23 @@ func PrepareAppDataPath() error {
return nil
}
-func Init(opts *Options) {
- if opts.CustomConf == "" {
- opts.CustomConf = CustomConf
- }
+func InitCfgProvider(file string, extraConfigs ...string) {
var err error
- CfgProvider, err = NewConfigProviderFromFile(opts)
+ if CfgProvider, err = NewConfigProviderFromFile(file, extraConfigs...); err != nil {
+ log.Fatal("Unable to init config provider from %q: %v", file, err)
+ }
CfgProvider.DisableSaving() // do not allow saving the CfgProvider into file, it will be polluted by the "MustXxx" calls
- if err != nil {
- log.Fatal("newConfigProviderFromFile[%v]: %v", opts, err)
+}
+
+func MustInstalled() {
+ if !InstallLock {
+ log.Fatal(`Unable to load config file for a installed Gitea instance, you should either use "--config" to set your config file (app.ini), or run "gitea web" command to install Gitea.`)
}
- if !opts.DisableLoadCommonSettings {
- if err := loadCommonSettingsFrom(CfgProvider); err != nil {
- log.Fatal("loadCommonSettingsFrom[%v]: %v", opts, err)
- }
+}
+
+func LoadCommonSettings() {
+ if err := loadCommonSettingsFrom(CfgProvider); err != nil {
+ log.Fatal("Unable to load settings from config: %v", err)
}
}