From 86974ffd34605da4e1f352a2bc9d5743302aa441 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 21 Mar 2023 14:45:25 +0800 Subject: [PATCH] tolerate the legacy relative path behavior --- modules/options/base.go | 60 +++++++++++++++++++++++--------------- modules/options/dynamic.go | 19 +++--------- modules/options/static.go | 19 +++--------- 3 files changed, 44 insertions(+), 54 deletions(-) diff --git a/modules/options/base.go b/modules/options/base.go index 47c4e406e5f57..3f808ceb093c8 100644 --- a/modules/options/base.go +++ b/modules/options/base.go @@ -14,6 +14,8 @@ import ( "code.gitea.io/gitea/modules/util" ) +var directories = make(directorySet) + // Locale reads the content of a specific locale from static/bindata or custom path. func Locale(name string) ([]byte, error) { return fileFromOptionsDir("locale", name) @@ -79,37 +81,47 @@ func walkAssetDir(root string, callback func(path, name string, d fs.DirEntry, e return nil } -func statDirIfExist(dir string) ([]string, error) { - isDir, err := util.IsDir(dir) +// mustLocalPathAbs coverts a path to absolute path +// FIXME: the old behavior (StaticRootPath might not be absolute), not ideal, just keep the same as before +func mustLocalPathAbs(s string) string { + abs, err := filepath.Abs(s) if err != nil { - return nil, fmt.Errorf("unable to check if static directory %s is a directory. %w", dir, err) + log.Fatal("Unable to get absolute path for %q: %v", s, err) } - if !isDir { - return nil, nil + return abs +} + +func joinLocalPaths(baseDirs []string, subDir string, elems ...string) (paths []string) { + abs := make([]string, len(elems)+2) + abs[1] = subDir + copy(abs[2:], elems) + for _, baseDir := range baseDirs { + abs[0] = mustLocalPathAbs(baseDir) + paths = append(paths, util.SafeFilePathAbs(abs...)) } - files, err := util.StatDir(dir, true) - if err != nil { - return nil, fmt.Errorf("unable to read directory %q. %w", dir, err) + return paths +} + +func listLocalDirIfExist(baseDirs []string, subDir string, elems ...string) (files []string, err error) { + for _, localPath := range joinLocalPaths(baseDirs, subDir, elems...) { + isDir, err := util.IsDir(localPath) + if err != nil { + return nil, fmt.Errorf("unable to check if static directory %s is a directory. %w", localPath, err) + } else if !isDir { + continue + } + + dirFiles, err := util.StatDir(localPath, true) + if err != nil { + return nil, fmt.Errorf("unable to read directory %q. %w", localPath, err) + } + files = append(files, dirFiles...) } return files, nil } -func readFileFromLocal(base []string, sub string, elems ...string) ([]byte, error) { - localPathElems := make([]string, len(elems)+2) // path[0] will be used for the custom path prefix - localPathElems[1] = sub - copy(localPathElems[2:], elems) - - for _, dir := range base { - if !filepath.IsAbs(dir) { - // FIXME: the old behavior (CustomPath or StaticRootPath might not be absolute), not ideal, just keep the same as before - var err error - dir, err = filepath.Abs(dir) - if err != nil { - return nil, fmt.Errorf("unable to get absolute path for %q. %w", dir, err) - } - } - localPathElems[0] = dir - localPath := util.SafeFilePathAbs(localPathElems...) +func readLocalFile(baseDirs []string, subDir string, elems ...string) ([]byte, error) { + for _, localPath := range joinLocalPaths(baseDirs, subDir, elems...) { data, err := os.ReadFile(localPath) if err == nil { return data, nil diff --git a/modules/options/dynamic.go b/modules/options/dynamic.go index e643e4a92f332..3d6261983f2de 100644 --- a/modules/options/dynamic.go +++ b/modules/options/dynamic.go @@ -7,28 +7,17 @@ package options import ( "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" ) -var directories = make(directorySet) - // Dir returns all files from static or custom directory. func Dir(name string) ([]string, error) { if directories.Filled(name) { return directories.Get(name), nil } - var result []string - - for _, dir := range []string{ - util.SafeFilePathAbs(setting.CustomPath, "options", name), // custom dir - util.SafeFilePathAbs(setting.StaticRootPath, "options", name), // static dir - } { - files, err := statDirIfExist(dir) - if err != nil { - return nil, err - } - result = append(result, files...) + result, err := listLocalDirIfExist([]string{setting.CustomPath, setting.StaticRootPath}, "options", name) + if err != nil { + return nil, err } return directories.AddAndGet(name, result), nil @@ -36,7 +25,7 @@ func Dir(name string) ([]string, error) { // fileFromOptionsDir is a helper to read files from custom or static path. func fileFromOptionsDir(elems ...string) ([]byte, error) { - return readFileFromLocal([]string{setting.CustomPath, setting.StaticRootPath}, "options", elems...) + return readLocalFile([]string{setting.CustomPath, setting.StaticRootPath}, "options", elems...) } // IsDynamic will return false when using embedded data (-tags bindata) diff --git a/modules/options/static.go b/modules/options/static.go index 72a2569843c70..359e2dd2605af 100644 --- a/modules/options/static.go +++ b/modules/options/static.go @@ -8,31 +8,20 @@ package options import ( "fmt" "io" - "path/filepath" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" ) -var directories = make(directorySet) - // Dir returns all files from custom directory or bindata. func Dir(name string) ([]string, error) { if directories.Filled(name) { return directories.Get(name), nil } - var result []string - - for _, dir := range []string{ - filepath.Join(setting.CustomPath, "options", name), // custom dir - // no static dir - } { - files, err := statDirIfExist(dir) - if err != nil { - return nil, err - } - result = append(result, files...) + result, err := listLocalDirIfExist([]string{setting.CustomPath}, "options", name) + if err != nil { + return nil, err } files, err := AssetDir(name) @@ -65,7 +54,7 @@ func AssetDir(dirName string) ([]string, error) { // fileFromOptionsDir is a helper to read files from custom path or bindata. func fileFromOptionsDir(elems ...string) ([]byte, error) { // only try custom dir, no static dir - if data, err := readFileFromLocal([]string{setting.CustomPath}, "options", elems...); err == nil { + if data, err := readLocalFile([]string{setting.CustomPath}, "options", elems...); err == nil { return data, nil }