Skip to content

Commit

Permalink
fix(walk): match filesystem casing for entries on macOS (#33)
Browse files Browse the repository at this point in the history
* ci(travis): enable macos build

* fix(walk): ensure paths match filesystem casing
  • Loading branch information
haltcase committed Sep 27, 2018
1 parent 17675cc commit d9d1175
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 10 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
os:
- linux
- osx

language: c

env:
Expand Down
29 changes: 19 additions & 10 deletions src/glob.nim
Original file line number Diff line number Diff line change
Expand Up @@ -291,35 +291,38 @@ func makeCaseInsensitive (pattern: string): string {.used.} =

# helper to find file system items case insensitively
# on case insensitive systems this is equivalent to an existence check
# any resulting paths are guaranteed to be absolute
iterator initStack (
path: string,
kinds = {pcFile, pcLinkToFile, pcDir, pcLinkToDir},
ignoreCase = false
): GlobEntry =
template push (path: string) =
var kind: PathComponent
if path.pathType(kind) and kind in kinds: yield (path, kind)
if path.pathType(kind) and kind in kinds:
yield (path.expandFilename, kind)

let normalized =
when FileSystemCaseSensitive:
if ignoreCase: path.makeCaseInsensitive
else: path
else: path
else:
path

# using `walkPattern` even on case insensitive systems (where it can only match
# one item anyway) gets us a path that matches the casing of the actual filesystem
for realPath in walkPattern(normalized):
push realPath.unixToNativePath
for subPath in walkPattern(normalized):
push subPath

proc expandGlob (pattern: string, ignoreCase: bool): string =
proc expandGlob (pattern, root: string, ignoreCase: bool): string =
if pattern.hasMagic: return pattern

for path, _ in initStack(pattern, {pcDir, pcLinkToDir}, ignoreCase):
for path, _ in initStack(maybeJoin(root, pattern), {pcDir, pcLinkToDir}, ignoreCase):
# we can't easily check a file's existence case insensitively on case
# sensitive systems, so (when necessary) walk over a case insensitive
# version of this pattern until we find a matching directory and
# break/return immediately when we've found one
return path & "/**"
return path.toRelative(root) & "/**"

return pattern

Expand Down Expand Up @@ -448,7 +451,10 @@ iterator walkGlobKinds* (
for path, kind in walkGlobKinds("src/**/*", options = options):
doAssert kind notin {pcLinkToFile, pcLinkToDir}

let internalRoot = if root == "": getCurrentDir() else: root
let internalRoot =
if root == "": getCurrentDir()
elif root.isAbsolute: root
else: getCurrentDir() / root
var matchPattern = when pattern is Glob: pattern.pattern else: pattern
var proceed = matchPattern.hasMagic

Expand All @@ -460,7 +466,10 @@ iterator walkGlobKinds* (
)

if not proceed:
for path, kind in initStack(matchPattern, ignoreCase = IgnoreCase in options):
for path, kind in initStack(
maybeJoin(internalRoot, matchPattern),
ignoreCase = IgnoreCase in options
):
if Hidden notin options and path.isHidden: continue

case kind
Expand All @@ -479,7 +488,7 @@ iterator walkGlobKinds* (
var dir: string
when pattern is Glob:
dir = maybeJoin(internalRoot, pattern.base)
matchPattern = pattern.magic.expandGlob(IgnoreCase in options)
matchPattern = pattern.magic.expandGlob(dir, IgnoreCase in options)
else:
let stems = splitPattern(matchPattern)
dir = maybeJoin(internalRoot, stems.base)
Expand Down

0 comments on commit d9d1175

Please sign in to comment.