Skip to content

Commit

Permalink
fix recursive files walker
Browse files Browse the repository at this point in the history
  • Loading branch information
Tofel committed Jan 9, 2024
1 parent 0b92ff1 commit 6dbbc61
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 58 deletions.
2 changes: 1 addition & 1 deletion config/examples/testconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func GetConfig(configurationName string, product string) (TestConfig, error) {

for _, fileName := range fileNames {
logger.Debug().Msgf("Looking for config file %s", fileName)
filePath, err := osutil.FindFile(fileName, osutil.DEFAULT_STOP_FILE_NAME)
filePath, err := osutil.FindFile(fileName, osutil.DEFAULT_STOP_FILE_NAME, 2)

if err != nil && errors.Is(err, os.ErrNotExist) {
logger.Debug().Msgf("Config file %s not found", fileName)
Expand Down
95 changes: 38 additions & 57 deletions utils/osutil/osutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package osutil
import (
"bufio"
"context"
"errors"
"fmt"
"io"
"io/fs"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -97,97 +99,76 @@ func GetAbsoluteFolderPath(folder string) (string, error) {
return filepath.Join(wd, folder), nil
}

const DEFAULT_STOP_FILE_NAME = ".root_dir"
const (
DEFAULT_STOP_FILE_NAME = ".root_dir"
ErrStopFileNotFoundWithinLimit = "stop file not found within limit"
)

func FindFile(filename, stopFile string) (string, error) {
currentDir, err := os.Getwd()
// FindFile looks for given file in the current directory and its parent directories first by locating
// top level parent folder where the search should begin (defined by stopFile, which cannot be located
// further "up" than limit parent folders) and then by searching from there for the file all subdirectories
func FindFile(filename, stopFile string, limit int) (string, error) {
workingDir, err := os.Getwd()
if err != nil {
return "", err
}

rootDirPath, err := findFileRecursivelyWithLimit(currentDir, stopFile, "", 2)
rootDirPath, err := findTopParentFolderWithLimit(workingDir, stopFile, limit)
if err != nil {
return "", err
}

configFilePath, err := findFileRecursively(rootDirPath, filename, "")
configFilePath, err := findFileInSubfolders(rootDirPath, filename)
if err != nil {
return "", err
}

return configFilePath, nil
}

func findFileRecursively(startDir, targetFileName, stopFileName string) (string, error) {
var filePath string
func findTopParentFolderWithLimit(startDir, stopFileName string, limit int) (string, error) {
currentDir := startDir

err := filepath.Walk(startDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
for level := 0; level < limit; level++ {
stopFilePath := filepath.Join(currentDir, stopFileName)
if _, err := os.Stat(stopFilePath); err == nil {
return currentDir, nil
}

// Check if the file has the specified name
if info.IsDir() {
return nil // Skip directories
}

if info.Name() == targetFileName {
// Read the content of the file
filePath = path
if err != nil {
return err
}
parentDir := filepath.Dir(currentDir)
if parentDir == currentDir {
break
}

return nil
})

if err != nil {
return "", err
currentDir = parentDir
}

if filePath == "" {
return "", os.ErrNotExist // File not found
}

return filePath, nil
return "", errors.New(ErrStopFileNotFoundWithinLimit)
}

func findFileRecursivelyWithLimit(startDir, targetFileName, stopFileName string, limit int) (string, error) {
func findFileInSubfolders(startDir, targetFileName string) (string, error) {
var filePath string
parentLevel := 0

for parentLevel <= limit {
err := filepath.Walk(startDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

// Check if the file has the specified name
if !info.IsDir() && info.Name() == targetFileName {
// Set the filePath when the target file is found
filePath = path
}

return nil
})
ErrFileFound := "file found"

err := filepath.WalkDir(startDir, func(path string, info fs.DirEntry, err error) error {
if err != nil {
return "", err
return err
}

if filePath != "" {
break // Exit the loop if ".root_dir" is found
if !info.IsDir() && info.Name() == targetFileName {
filePath = path
return errors.New(ErrFileFound)
}

// Move to the parent directory
startDir = filepath.Dir(startDir)
parentLevel++
return nil
})

if err != nil && err.Error() != ErrFileFound {
return "", err
}

if filePath == "" {
return "", os.ErrNotExist // File not found
return "", os.ErrNotExist
}

return filepath.Dir(filePath), nil
return filePath, nil
}

0 comments on commit 6dbbc61

Please sign in to comment.