mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-10-24 19:12:24 +00:00
FORGEJO_* environment variables are set to the corresponding GITEA_* variable when the cli starts. This approach is intended to minimize the conflicts on rebase. All occurences of GITEA_* are left untouched in the codebase and they are only changed to FORGEJO_* if exposed to the user. (cherry picked from commite466f9d10e) (cherry picked from commite33e95931b) (cherry picked from commit2cfc6519b7) (cherry picked from commitaf8864373a) (cherry picked from commita0550ff339) (cherry picked from commit24dc0a5191) (cherry picked from commite255eea2b4) (cherry picked from commit0c4f5afa7a) (cherry picked from commit42fce708d0) (cherry picked from commite7278c3c22) (cherry picked from commit0fb9ed7e0e) (cherry picked from commita98308aa4d) (cherry picked from commitb8695fcbe0) (cherry picked from commit4aee8719f5) (cherry picked from commit1c503c1ba7) (cherry picked from commitcf1ed8551e) (cherry picked from commitc52459b088) (cherry picked from commit92cac277b2) (cherry picked from commit2c744f1118) (cherry picked from commit989a98a8c5) (cherry picked from commit9cf7052bd4) (cherry picked from commita13c9667e0) Conflicts: main.go https://codeberg.org/forgejo/forgejo/pulls/1216 (cherry picked from commita9c3cf060d) (cherry picked from commiteb6d904b23)
214 lines
6 KiB
Go
214 lines
6 KiB
Go
// 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: WORK_PATH in app.ini, "--work-path" flag, 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) {
|
|
InitWorkPathAndCfgProvider(getEnvFn, args)
|
|
LoadCommonSettings()
|
|
}
|
|
|
|
// InitWorkPathAndCfgProvider will set AppWorkPath, CustomPath and CustomConf, init default config provider by CustomConf
|
|
func InitWorkPathAndCfgProvider(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")
|
|
}
|
|
}
|
|
|
|
envWorkPath = getEnvFn("FORGEJO_WORK_DIR")
|
|
if envWorkPath != "" {
|
|
tmpWorkPath.Set(envWorkPath)
|
|
if !filepath.IsAbs(tmpWorkPath.Value) {
|
|
log.Fatal("FORGEJO_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")
|
|
}
|
|
}
|
|
|
|
envCustomPath = getEnvFn("FORGEJO_CUSTOM")
|
|
if envCustomPath != "" {
|
|
tmpCustomPath.Set(envCustomPath)
|
|
if !filepath.IsAbs(tmpCustomPath.Value) {
|
|
log.Fatal("FORGEJO_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)
|
|
if HasInstallLock(CfgProvider) {
|
|
ClearEnvConfigKeys() // if the instance has been installed, do not pass the environment variables to sub-processes
|
|
}
|
|
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") != "" || getEnvFn("FORGEJO_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
|
|
}
|