github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/setting/options.go (about)

     1  // Copyright 2023 The GitBundle Inc. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // Use of this source code is governed by a MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  // Copyright 2016 The GitBundle Authors. All rights reserved.
     7  // Use of this source code is governed by a MIT-style
     8  // license that can be found in the LICENSE file.
     9  package setting
    10  
    11  import (
    12  	"fmt"
    13  	"os"
    14  	"path"
    15  
    16  	"github.com/gitbundle/modules/log"
    17  	"github.com/gitbundle/modules/util"
    18  )
    19  
    20  var directories = NewDirectorySet()
    21  
    22  // Dir returns all files from static or custom directory.
    23  func Dir(name string) ([]string, error) {
    24  	if directories.Filled(name) {
    25  		return directories.Get(name), nil
    26  	}
    27  
    28  	var result []string
    29  
    30  	customDir := path.Join(CustomPath, "options", name)
    31  
    32  	isDir, err := util.IsDir(customDir)
    33  	if err != nil {
    34  		return []string{}, fmt.Errorf("Unabe to check if custom directory %s is a directory. %v", customDir, err)
    35  	}
    36  	if isDir {
    37  		files, err := util.StatDir(customDir, true)
    38  		if err != nil {
    39  			return []string{}, fmt.Errorf("Failed to read custom directory. %v", err)
    40  		}
    41  
    42  		result = append(result, files...)
    43  	}
    44  
    45  	staticDir := path.Join(StaticRootPath, "options", name)
    46  
    47  	isDir, err = util.IsDir(staticDir)
    48  	if err != nil {
    49  		return []string{}, fmt.Errorf("Unabe to check if static directory %s is a directory. %v", staticDir, err)
    50  	}
    51  	if isDir {
    52  		files, err := util.StatDir(staticDir, true)
    53  		if err != nil {
    54  			return []string{}, fmt.Errorf("Failed to read static directory. %v", err)
    55  		}
    56  
    57  		result = append(result, files...)
    58  	}
    59  
    60  	return directories.AddAndGet(name, result), nil
    61  }
    62  
    63  // Locale reads the content of a specific locale from static or custom path.
    64  func Locale(name string) ([]byte, error) {
    65  	return fileFromDir(path.Join("locale", name))
    66  }
    67  
    68  // Readme reads the content of a specific readme from static or custom path.
    69  func Readme(name string) ([]byte, error) {
    70  	return fileFromDir(path.Join("readme", name))
    71  }
    72  
    73  // Gitignore reads the content of a specific gitignore from static or custom path.
    74  func Gitignore(name string) ([]byte, error) {
    75  	return fileFromDir(path.Join("gitignore", name))
    76  }
    77  
    78  // License reads the content of a specific license from static or custom path.
    79  func License(name string) ([]byte, error) {
    80  	return fileFromDir(path.Join("license", name))
    81  }
    82  
    83  // Labels reads the content of a specific labels from static or custom path.
    84  func Labels(name string) ([]byte, error) {
    85  	return fileFromDir(path.Join("label", name))
    86  }
    87  
    88  // fileFromDir is a helper to read files from static or custom path.
    89  func fileFromDir(name string) ([]byte, error) {
    90  	customPath := path.Join(CustomPath, "options", name)
    91  
    92  	isFile, err := util.IsFile(customPath)
    93  	if err != nil {
    94  		log.Error("Unable to check if %s is a file. Error: %v", customPath, err)
    95  	}
    96  	if isFile {
    97  		return os.ReadFile(customPath)
    98  	}
    99  
   100  	staticPath := path.Join(StaticRootPath, "options", name)
   101  
   102  	isFile, err = util.IsFile(staticPath)
   103  	if err != nil {
   104  		log.Error("Unable to check if %s is a file. Error: %v", staticPath, err)
   105  	}
   106  	if isFile {
   107  		return os.ReadFile(staticPath)
   108  	}
   109  
   110  	return []byte{}, fmt.Errorf("Asset file does not exist: %s", name)
   111  }
   112  
   113  type directorySet map[string][]string
   114  
   115  func NewDirectorySet() directorySet {
   116  	return make(directorySet)
   117  }
   118  
   119  func (s directorySet) Add(key string, value []string) {
   120  	_, ok := s[key]
   121  
   122  	if !ok {
   123  		s[key] = make([]string, 0, len(value))
   124  	}
   125  
   126  	s[key] = append(s[key], value...)
   127  }
   128  
   129  func (s directorySet) Get(key string) []string {
   130  	_, ok := s[key]
   131  
   132  	if ok {
   133  		result := []string{}
   134  		seen := map[string]string{}
   135  
   136  		for _, val := range s[key] {
   137  			if _, ok := seen[val]; !ok {
   138  				result = append(result, val)
   139  				seen[val] = val
   140  			}
   141  		}
   142  
   143  		return result
   144  	}
   145  
   146  	return []string{}
   147  }
   148  
   149  func (s directorySet) AddAndGet(key string, value []string) []string {
   150  	s.Add(key, value)
   151  	return s.Get(key)
   152  }
   153  
   154  func (s directorySet) Filled(key string) bool {
   155  	return len(s[key]) > 0
   156  }