github.com/zyedidia/knit@v1.1.2-0.20230901152954-f7d4e39a0e24/config.go (about)

     1  package knit
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/adrg/xdg"
     9  	"github.com/pelletier/go-toml/v2"
    10  )
    11  
    12  var ErrBuildFileNotFound = errors.New("build file not found")
    13  
    14  const defaultFile = "knitfile.def"
    15  
    16  // Returns true if 'path' exists.
    17  func exists(path string) bool {
    18  	_, err := os.Stat(path)
    19  	return err == nil
    20  }
    21  
    22  // Returns true if 'path' exists and is not a directory.
    23  func existsFile(path string) bool {
    24  	info, err := os.Stat(path)
    25  	return err == nil && !info.IsDir()
    26  }
    27  
    28  var configDirs = []string{
    29  	filepath.Join(xdg.ConfigHome, "knit"),
    30  }
    31  
    32  func init() {
    33  	for _, dir := range xdg.DataDirs {
    34  		configDirs = append(configDirs, filepath.Join(dir, "knit"))
    35  	}
    36  }
    37  func DefaultBuildFile() (string, bool) {
    38  	for _, dir := range configDirs {
    39  		if existsFile(filepath.Join(dir, defaultFile)) {
    40  			return filepath.Join(defaultFile), true
    41  		} else if existsFile(filepath.Join(dir, title(defaultFile))) {
    42  			return filepath.Join(dir, title(defaultFile)), true
    43  		}
    44  	}
    45  	return "", false
    46  }
    47  
    48  func FindBuildFile(name string) (string, string, error) {
    49  	if filepath.IsAbs(name) {
    50  		if existsFile(name) {
    51  			return name, filepath.Dir(name), nil
    52  		} else {
    53  			return "", "", errors.New("does not exist")
    54  		}
    55  	}
    56  
    57  	wd, err := os.Getwd()
    58  	if err != nil {
    59  		return "", "", err
    60  	}
    61  	path := wd
    62  	for filepath.Dir(path) != path {
    63  		if existsFile(filepath.Join(path, name)) {
    64  			p, e := filepath.Rel(wd, path)
    65  			return name, p, e
    66  		}
    67  		if existsFile(filepath.Join(path, title(name))) {
    68  			p, e := filepath.Rel(wd, path)
    69  			return title(name), p, e
    70  		}
    71  		path = filepath.Dir(path)
    72  	}
    73  	return "", "", nil
    74  }
    75  
    76  const configFile = ".knit.toml"
    77  
    78  func UserDefaults() (UserFlags, error) {
    79  	var flags UserFlags
    80  
    81  	loadFile := func(dir string) error {
    82  		configPath := filepath.Join(dir, configFile)
    83  		if exists(configPath) {
    84  			data, err := os.ReadFile(configPath)
    85  			if err != nil {
    86  				return err
    87  			}
    88  			err = toml.Unmarshal(data, &flags)
    89  			if err != nil {
    90  				return err
    91  			}
    92  		}
    93  		return nil
    94  	}
    95  
    96  	wd, err := os.Getwd()
    97  	if err != nil {
    98  		return UserFlags{}, err
    99  	}
   100  	dirs := []string{wd}
   101  	path := wd
   102  	for filepath.Dir(path) != path {
   103  		path = filepath.Dir(path)
   104  		dirs = append(dirs, path)
   105  	}
   106  	dirs = append(dirs, configDirs...)
   107  	for i := len(dirs) - 1; i >= 0; i-- {
   108  		dir := dirs[i]
   109  		err := loadFile(dir)
   110  		if err != nil {
   111  			return UserFlags{}, err
   112  		}
   113  	}
   114  	return flags, nil
   115  }