diff options
Diffstat (limited to 'modules/options')
-rw-r--r-- | modules/options/base.go | 118 | ||||
-rw-r--r-- | modules/options/dynamic.go | 25 | ||||
-rw-r--r-- | modules/options/options.go | 45 | ||||
-rw-r--r-- | modules/options/static.go | 95 |
4 files changed, 19 insertions, 264 deletions
diff --git a/modules/options/base.go b/modules/options/base.go index 7882ed0081..6c6e3839f4 100644 --- a/modules/options/base.go +++ b/modules/options/base.go @@ -4,131 +4,39 @@ package options import ( - "fmt" - "io/fs" - "os" - "path/filepath" - - "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/assetfs" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" ) -var directories = make(directorySet) +func CustomAssets() *assetfs.Layer { + return assetfs.Local("custom", setting.CustomPath, "options") +} + +func AssetFS() *assetfs.LayeredFS { + return assetfs.Layered(CustomAssets(), BuiltinAssets()) +} // Locale reads the content of a specific locale from static/bindata or custom path. func Locale(name string) ([]byte, error) { - return fileFromOptionsDir("locale", name) + return AssetFS().ReadFile("locale", name) } // Readme reads the content of a specific readme from static/bindata or custom path. func Readme(name string) ([]byte, error) { - return fileFromOptionsDir("readme", name) + return AssetFS().ReadFile("readme", name) } // Gitignore reads the content of a gitignore locale from static/bindata or custom path. func Gitignore(name string) ([]byte, error) { - return fileFromOptionsDir("gitignore", name) + return AssetFS().ReadFile("gitignore", name) } // License reads the content of a specific license from static/bindata or custom path. func License(name string) ([]byte, error) { - return fileFromOptionsDir("license", name) + return AssetFS().ReadFile("license", name) } // Labels reads the content of a specific labels from static/bindata or custom path. func Labels(name string) ([]byte, error) { - return fileFromOptionsDir("label", name) -} - -// WalkLocales reads the content of a specific locale -func WalkLocales(callback func(path, name string, d fs.DirEntry, err error) error) error { - if IsDynamic() { - if err := walkAssetDir(filepath.Join(setting.StaticRootPath, "options", "locale"), callback); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to walk locales. Error: %w", err) - } - } - - if err := walkAssetDir(filepath.Join(setting.CustomPath, "options", "locale"), callback); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to walk locales. Error: %w", err) - } - return nil -} - -func walkAssetDir(root string, callback func(path, name string, d fs.DirEntry, err error) error) error { - if err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { - // name is the path relative to the root - name := path[len(root):] - if len(name) > 0 && name[0] == '/' { - name = name[1:] - } - if err != nil { - if os.IsNotExist(err) { - return callback(path, name, d, err) - } - return err - } - if util.CommonSkip(d.Name()) { - if d.IsDir() { - return fs.SkipDir - } - return nil - } - return callback(path, name, d, err) - }); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("unable to get files for assets in %s: %w", root, err) - } - return nil -} - -// 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 { - // This should never happen in a real system. If it happens, the user must have already been in trouble: the system is not able to resolve its own paths. - log.Fatal("Unable to get absolute path for %q: %v", s, err) - } - 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.FilePathJoinAbs(abs...)) - } - 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 path %q 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 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 - } else if !os.IsNotExist(err) { - log.Error("Unable to read file %q. Error: %v", localPath, err) - } - } - return nil, os.ErrNotExist + return AssetFS().ReadFile("label", name) } diff --git a/modules/options/dynamic.go b/modules/options/dynamic.go index 3d6261983f..085492d11c 100644 --- a/modules/options/dynamic.go +++ b/modules/options/dynamic.go @@ -6,29 +6,10 @@ package options import ( + "code.gitea.io/gitea/modules/assetfs" "code.gitea.io/gitea/modules/setting" ) -// Dir returns all files from static or custom directory. -func Dir(name string) ([]string, error) { - if directories.Filled(name) { - return directories.Get(name), nil - } - - result, err := listLocalDirIfExist([]string{setting.CustomPath, setting.StaticRootPath}, "options", name) - if err != nil { - return nil, err - } - - return directories.AddAndGet(name, result), nil -} - -// fileFromOptionsDir is a helper to read files from custom or static path. -func fileFromOptionsDir(elems ...string) ([]byte, error) { - return readLocalFile([]string{setting.CustomPath, setting.StaticRootPath}, "options", elems...) -} - -// IsDynamic will return false when using embedded data (-tags bindata) -func IsDynamic() bool { - return true +func BuiltinAssets() *assetfs.Layer { + return assetfs.Local("builtin(static)", setting.StaticRootPath, "options") } diff --git a/modules/options/options.go b/modules/options/options.go deleted file mode 100644 index 17a8fa482e..0000000000 --- a/modules/options/options.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2016 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package options - -type directorySet map[string][]string - -func (s directorySet) Add(key string, value []string) { - _, ok := s[key] - - if !ok { - s[key] = make([]string, 0, len(value)) - } - - s[key] = append(s[key], value...) -} - -func (s directorySet) Get(key string) []string { - _, ok := s[key] - - if ok { - result := []string{} - seen := map[string]string{} - - for _, val := range s[key] { - if _, ok := seen[val]; !ok { - result = append(result, val) - seen[val] = val - } - } - - return result - } - - return []string{} -} - -func (s directorySet) AddAndGet(key string, value []string) []string { - s.Add(key, value) - return s.Get(key) -} - -func (s directorySet) Filled(key string) bool { - return len(s[key]) > 0 -} diff --git a/modules/options/static.go b/modules/options/static.go index 0482dea681..72b28e990e 100644 --- a/modules/options/static.go +++ b/modules/options/static.go @@ -6,98 +6,9 @@ package options import ( - "fmt" - "io" - - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/assetfs" ) -// Dir returns all files from custom directory or bindata. -func Dir(name string) ([]string, error) { - if directories.Filled(name) { - return directories.Get(name), nil - } - - result, err := listLocalDirIfExist([]string{setting.CustomPath}, "options", name) - if err != nil { - return nil, err - } - - files, err := AssetDir(name) - if err != nil { - return []string{}, fmt.Errorf("unable to read embedded directory %q. %w", name, err) - } - - result = append(result, files...) - return directories.AddAndGet(name, result), nil -} - -func AssetDir(dirName string) ([]string, error) { - d, err := Assets.Open(dirName) - if err != nil { - return nil, err - } - defer d.Close() - - files, err := d.Readdir(-1) - if err != nil { - return nil, err - } - results := make([]string, 0, len(files)) - for _, file := range files { - results = append(results, file.Name()) - } - return results, nil -} - -// 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 := readLocalFile([]string{setting.CustomPath}, "options", elems...); err == nil { - return data, nil - } - - f, err := Assets.Open(util.PathJoinRelX(elems...)) - if err != nil { - return nil, err - } - defer f.Close() - return io.ReadAll(f) -} - -func Asset(name string) ([]byte, error) { - f, err := Assets.Open("/" + name) - if err != nil { - return nil, err - } - defer f.Close() - return io.ReadAll(f) -} - -func AssetNames() []string { - realFS := Assets.(vfsgen۰FS) - results := make([]string, 0, len(realFS)) - for k := range realFS { - results = append(results, k[1:]) - } - return results -} - -func AssetIsDir(name string) (bool, error) { - if f, err := Assets.Open("/" + name); err != nil { - return false, err - } else { - defer f.Close() - if fi, err := f.Stat(); err != nil { - return false, err - } else { - return fi.IsDir(), nil - } - } -} - -// IsDynamic will return false when using embedded data (-tags bindata) -func IsDynamic() bool { - return false +func BuiltinAssets() *assetfs.Layer { + return assetfs.Bindata("builtin(bindata)", Assets) } |