mirror of
https://github.com/numtide/treefmt.git
synced 2024-10-26 17:30:03 +03:00
Merge pull request #309 from numtide/find-tree-root
cli: search for the tree root by default
This commit is contained in:
commit
2454542a36
@ -13,10 +13,11 @@ type Format struct {
|
|||||||
WorkingDirectory kong.ChangeDirFlag `default:"." short:"C" help:"Run as if treefmt was started in the specified working directory instead of the current working directory."`
|
WorkingDirectory kong.ChangeDirFlag `default:"." short:"C" help:"Run as if treefmt was started in the specified working directory instead of the current working directory."`
|
||||||
NoCache bool `help:"Ignore the evaluation cache entirely. Useful for CI."`
|
NoCache bool `help:"Ignore the evaluation cache entirely. Useful for CI."`
|
||||||
ClearCache bool `short:"c" help:"Reset the evaluation cache. Use in case the cache is not precise enough."`
|
ClearCache bool `short:"c" help:"Reset the evaluation cache. Use in case the cache is not precise enough."`
|
||||||
ConfigFile string `type:"existingfile" default:"./treefmt.toml" help:"The config file to use."`
|
ConfigFile string `type:"existingfile" help:"Load the config file from the given path (defaults to searching upwards for treefmt.toml)."`
|
||||||
FailOnChange bool `help:"Exit with error if any changes were made. Useful for CI."`
|
FailOnChange bool `help:"Exit with error if any changes were made. Useful for CI."`
|
||||||
Formatters []string `short:"f" help:"Specify formatters to apply. Defaults to all formatters."`
|
Formatters []string `short:"f" help:"Specify formatters to apply. Defaults to all formatters."`
|
||||||
TreeRoot string `type:"existingdir" default:"." help:"The root directory from which treefmt will start walking the filesystem."`
|
TreeRoot string `type:"existingdir" xor:"tree-root" help:"The root directory from which treefmt will start walking the filesystem (defaults to the directory containing the config file)."`
|
||||||
|
TreeRootFile string `type:"string" xor:"tree-root" help:"File to search for to find the project root (if --tree-root is not passed)."`
|
||||||
Walk walk.Type `enum:"auto,git,filesystem" default:"auto" help:"The method used to traverse the files within --tree-root. Currently supports 'auto', 'git' or 'filesystem'."`
|
Walk walk.Type `enum:"auto,git,filesystem" default:"auto" help:"The method used to traverse the files within --tree-root. Currently supports 'auto', 'git' or 'filesystem'."`
|
||||||
Verbosity int `name:"verbose" short:"v" type:"counter" default:"0" env:"LOG_LEVEL" help:"Set the verbosity of logs e.g. -vv."`
|
Verbosity int `name:"verbose" short:"v" type:"counter" default:"0" env:"LOG_LEVEL" help:"Set the verbosity of logs e.g. -vv."`
|
||||||
Version bool `name:"version" short:"V" help:"Print version."`
|
Version bool `name:"version" short:"V" help:"Print version."`
|
||||||
|
@ -69,6 +69,37 @@ func (f *Format) Run() (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// find the config file unless specified
|
||||||
|
if Cli.ConfigFile == "" {
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
Cli.ConfigFile, _, err = findUp(pwd, "treefmt.toml")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// default the tree root to the directory containing the config file
|
||||||
|
if Cli.TreeRoot == "" {
|
||||||
|
Cli.TreeRoot = filepath.Dir(Cli.ConfigFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// search the tree root using the --tree-root-file if specified
|
||||||
|
if Cli.TreeRootFile != "" {
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, Cli.TreeRoot, err = findUp(pwd, Cli.TreeRootFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("config-file=%s tree-root=%s", Cli.ConfigFile, Cli.TreeRoot)
|
||||||
|
|
||||||
// read config
|
// read config
|
||||||
cfg, err := config.ReadFile(Cli.ConfigFile, Cli.Formatters)
|
cfg, err := config.ReadFile(Cli.ConfigFile, Cli.Formatters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -384,3 +415,56 @@ func applyFormatters(ctx context.Context) func() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findUp(searchDir string, fileName string) (path string, dir string, err error) {
|
||||||
|
for _, dir := range eachDir(searchDir) {
|
||||||
|
path := filepath.Join(dir, fileName)
|
||||||
|
if fileExists(path) {
|
||||||
|
return path, dir, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", "", fmt.Errorf("could not find %s in %s", fileName, searchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func eachDir(path string) (paths []string) {
|
||||||
|
path, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
paths = []string{path}
|
||||||
|
|
||||||
|
if path == "/" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := len(path) - 1; i >= 0; i-- {
|
||||||
|
if path[i] == os.PathSeparator {
|
||||||
|
path = path[:i]
|
||||||
|
if path == "" {
|
||||||
|
path = "/"
|
||||||
|
}
|
||||||
|
paths = append(paths, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileExists(path string) bool {
|
||||||
|
// Some broken filesystems like SSHFS return file information on stat() but
|
||||||
|
// then cannot open the file. So we use os.Open.
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
// Next, check that the file is a regular file.
|
||||||
|
fi, err := f.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return fi.Mode().IsRegular()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user