From 7f47a61986d055046e0f743a1a7fa4a4bd93a223 Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Thu, 30 Jun 2022 11:00:58 +0200 Subject: [PATCH] Allow globs in filenames for locators Signed-off-by: Evan Lezar --- internal/lookup/executable.go | 15 ++++++++------- internal/lookup/file.go | 29 ++++++++++++++++++----------- internal/lookup/symlinks.go | 17 +++++++++-------- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/internal/lookup/executable.go b/internal/lookup/executable.go index 615d608c..2bfe04ea 100644 --- a/internal/lookup/executable.go +++ b/internal/lookup/executable.go @@ -49,18 +49,19 @@ func NewExecutableLocator(logger *log.Logger, root string) Locator { var _ Locator = (*executable)(nil) -// Locate finds executable files in the path. If a relative or absolute path is specified, the prefix paths are not considered. -func (p executable) Locate(filename string) ([]string, error) { +// Locate finds executable files with the specified pattern in the path. +// If a relative or absolute path is specified, the prefix paths are not considered. +func (p executable) Locate(pattern string) ([]string, error) { // For absolute paths we ensure that it is executable - if strings.Contains(filename, "/") { - err := assertExecutable(filename) + if strings.Contains(pattern, "/") { + err := assertExecutable(pattern) if err != nil { - return nil, fmt.Errorf("absolute path %v is not an executable file: %v", filename, err) + return nil, fmt.Errorf("absolute path %v is not an executable file: %v", pattern, err) } - return []string{filename}, nil + return []string{pattern}, nil } - return p.file.Locate(filename) + return p.file.Locate(pattern) } // assertExecutable checks whether the specified path is an execuable file. diff --git a/internal/lookup/file.go b/internal/lookup/file.go index c9008f93..ab52d03d 100644 --- a/internal/lookup/file.go +++ b/internal/lookup/file.go @@ -50,22 +50,29 @@ func newFileLocator(logger *log.Logger, root string) file { var _ Locator = (*file)(nil) -// Locate attempts to find the specified file. All prefixes are searched and any matching -// candidates are returned. If no matches are found, an error is returned. -func (p file) Locate(filename string) ([]string, error) { +// Locate attempts to find files with names matching the specified pattern. +// All prefixes are searched and any matching candidates are returned. If no matches are found, an error is returned. +func (p file) Locate(pattern string) ([]string, error) { var filenames []string for _, prefix := range p.prefixes { - candidate := filepath.Join(prefix, filename) - p.logger.Debugf("Checking candidate '%v'", candidate) - err := p.filter(candidate) + pathPattern := filepath.Join(prefix, pattern) + candidates, err := filepath.Glob(pathPattern) if err != nil { - p.logger.Debugf("Candidate '%v' does not meet requirements: %v", candidate, err) - continue + p.logger.Debugf("Checking pattern '%v' failed: %v", pathPattern, err) + } + + for _, candidate := range candidates { + p.logger.Debugf("Checking candidate '%v'", candidate) + err := p.filter(candidate) + if err != nil { + p.logger.Debugf("Candidate '%v' does not meet requirements: %v", candidate, err) + continue + } + filenames = append(filenames, candidate) } - filenames = append(filenames, candidate) } - if len(filename) == 0 { - return nil, fmt.Errorf("file %v not found", filename) + if len(filenames) == 0 { + return nil, fmt.Errorf("pattern %v not found", pattern) } return filenames, nil } diff --git a/internal/lookup/symlinks.go b/internal/lookup/symlinks.go index 19684e49..43e37123 100644 --- a/internal/lookup/symlinks.go +++ b/internal/lookup/symlinks.go @@ -52,10 +52,10 @@ func NewSymlinkLocator(logger *logrus.Logger, root string) Locator { return &l } -// Locate finds the specified file at the specified root. If the file is a symlink, the link is followed and all candidates -// to the final target are returned. -func (p symlinkChain) Locate(filename string) ([]string, error) { - candidates, err := p.file.Locate(filename) +// Locate finds the specified pattern at the specified root. +// If the file is a symlink, the link is followed and all candidates to the final target are returned. +func (p symlinkChain) Locate(pattern string) ([]string, error) { + candidates, err := p.file.Locate(pattern) if err != nil { return nil, err } @@ -104,14 +104,15 @@ func (p symlinkChain) Locate(filename string) ([]string, error) { return filenames, nil } -// Locate finds the specified file at the specified root. If the file is a symlink, the link is resolved and the target returned. -func (p symlink) Locate(filename string) ([]string, error) { - candidates, err := p.file.Locate(filename) +// Locate finds the specified pattern at the specified root. +// If the file is a symlink, the link is resolved and the target returned. +func (p symlink) Locate(pattern string) ([]string, error) { + candidates, err := p.file.Locate(pattern) if err != nil { return nil, err } if len(candidates) != 1 { - return nil, fmt.Errorf("failed to uniquely resolve symlink %v: %v", filename, candidates) + return nil, fmt.Errorf("failed to uniquely resolve symlink %v: %v", pattern, candidates) } target, err := filepath.EvalSymlinks(candidates[0])