From 7d2ee0df9599bc61564d1ba18bb7ba9150dc5389 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 18 Jun 2015 10:48:15 -0700 Subject: [PATCH] Fix glob dependencies when initial non-wild path does not exist If the initial non-wild part of a glob path does not exist, return the last existing part of the path as a dependency to detect if the path is created later. Change-Id: Ib5a39e6830cb386deed26e017279d0aac1bc9a20 --- pathtools/glob.go | 32 ++++++++++++++++++-------- pathtools/glob_test.go | 52 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/pathtools/glob.go b/pathtools/glob.go index 239a3c7..5541643 100644 --- a/pathtools/glob.go +++ b/pathtools/glob.go @@ -39,12 +39,7 @@ func Glob(pattern string) (matches, dirs []string, err error) { // exclude patterns are equivalent to filepath.Glob, with an extension that // recursive glob (** matching zero or more complete path entries) is supported. func GlobWithExcludes(pattern string, excludes []string) (matches, dirs []string, err error) { - if !isWild(pattern) { - // If there are no wilds in the pattern, just return whether the file at the pattern - // exists or not. Uses filepath.Glob instead of manually statting to get consistent - // results. - matches, err = filepath.Glob(filepath.Clean(pattern)) - } else if filepath.Base(pattern) == "**" { + if filepath.Base(pattern) == "**" { return nil, nil, GlobLastRecursiveErr } else { matches, dirs, err = glob(pattern, false) @@ -66,10 +61,27 @@ func GlobWithExcludes(pattern string, excludes []string) (matches, dirs []string // allowing searched directories to be tracked. Also handles the recursive glob pattern, **. func glob(pattern string, hasRecursive bool) (matches, dirs []string, err error) { if !isWild(pattern) { - // If there are no wilds in the pattern, just return whether the file at the pattern - // exists or not. Uses filepath.Glob instead of manually statting to get consistent - // results. - matches, err = filepath.Glob(filepath.Clean(pattern)) + // If there are no wilds in the pattern, check whether the file exists or not. + // Uses filepath.Glob instead of manually statting to get consistent results. + pattern = filepath.Clean(pattern) + matches, err = filepath.Glob(pattern) + if err != nil { + return matches, dirs, err + } + + if len(matches) == 0 { + // Some part of the non-wild pattern didn't exist. Add the last existing directory + // as a dependency. + var matchDirs []string + for len(matchDirs) == 0 { + pattern, _ = saneSplit(pattern) + matchDirs, err = filepath.Glob(pattern) + if err != nil { + return matches, dirs, err + } + } + dirs = append(dirs, matchDirs...) + } return matches, dirs, err } diff --git a/pathtools/glob_test.go b/pathtools/glob_test.go index efd63b0..b082267 100644 --- a/pathtools/glob_test.go +++ b/pathtools/glob_test.go @@ -334,6 +334,58 @@ var globTestCases = []struct { dirs: []string{"c", "c/f", "c/g", "c/h"}, }, + // non-existant non-wild path tests + { + pattern: "d/*", + matches: nil, + dirs: []string{"."}, + }, + { + pattern: "d", + matches: nil, + dirs: []string{"."}, + }, + { + pattern: "a/d/*", + matches: nil, + dirs: []string{"a"}, + }, + { + pattern: "a/d", + matches: nil, + dirs: []string{"a"}, + }, + { + pattern: "a/a/d/*", + matches: nil, + dirs: []string{"a/a"}, + }, + { + pattern: "a/a/d", + matches: nil, + dirs: []string{"a/a"}, + }, + { + pattern: "a/d/a/*", + matches: nil, + dirs: []string{"a"}, + }, + { + pattern: "a/d/a", + matches: nil, + dirs: []string{"a"}, + }, + { + pattern: "a/d/a/*/a", + matches: nil, + dirs: []string{"a"}, + }, + { + pattern: "a/d/a/**/a", + matches: nil, + dirs: []string{"a"}, + }, + // recursive exclude error tests { pattern: "**/*",