Skip to content

Commit

Permalink
Adjust representation of file glob roots
Browse files Browse the repository at this point in the history
Previously we represented unix and windows roots/drives explicitly but
this isn't necessary and it makes it inconvenient to use portable
functions like FilePath.takeDrive (which returns "/" on unix or things
like "c:\\" on windows). So instead we just use a FilePath as the root.
  • Loading branch information
dcoutts committed Apr 17, 2016
1 parent 1223a39 commit 2e17ea2
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 27 deletions.
27 changes: 10 additions & 17 deletions cabal-install/Distribution/Client/Glob.hs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ data GlobPiece = WildCard

data FilePathRoot
= FilePathRelative
| FilePathUnixRoot
| FilePathWinDrive Char
| FilePathRoot FilePath -- ^ e.g. @"/"@, @"c:\"@ or result of 'takeDrive'
| FilePathHomeDir
deriving (Eq, Show, Generic)

Expand All @@ -76,9 +75,8 @@ instance Binary GlobPiece
isTrivialFilePathGlob :: FilePathGlob -> Maybe FilePath
isTrivialFilePathGlob (FilePathGlob root pathglob) =
case root of
FilePathRelative -> go [] pathglob
FilePathUnixRoot -> go ["/"] pathglob
FilePathWinDrive drive -> go [drive:":"] pathglob
FilePathRelative -> go [] pathglob
FilePathRoot root' -> go [root'] pathglob
FilePathHomeDir -> Nothing
where
go paths (GlobDir [Literal path] globs) = go (path:paths) globs
Expand All @@ -95,10 +93,9 @@ isTrivialFilePathGlob (FilePathGlob root pathglob) =
getFilePathRootDirectory :: FilePathRoot
-> FilePath -- ^ root for relative paths
-> IO FilePath
getFilePathRootDirectory FilePathRelative root = return root
getFilePathRootDirectory FilePathUnixRoot _ = return "/"
getFilePathRootDirectory (FilePathWinDrive drive) _ = return (drive:":")
getFilePathRootDirectory FilePathHomeDir _ = getHomeDirectory
getFilePathRootDirectory FilePathRelative root = return root
getFilePathRootDirectory (FilePathRoot root) _ = return root
getFilePathRootDirectory FilePathHomeDir _ = getHomeDirectory


------------------------------------------------------------------------------
Expand Down Expand Up @@ -180,21 +177,17 @@ instance Text FilePathGlob where

instance Text FilePathRoot where
disp FilePathRelative = Disp.empty
disp FilePathUnixRoot = Disp.char '/'
disp (FilePathWinDrive c) = Disp.char c
Disp.<> Disp.char ':'
Disp.<> Disp.char '\\'
disp FilePathHomeDir = Disp.char '~'
Disp.<> Disp.char '/'
disp (FilePathRoot root) = Disp.text root
disp FilePathHomeDir = Disp.char '~' Disp.<> Disp.char '/'

parse =
( (Parse.char '/' >> return FilePathUnixRoot)
( (Parse.char '/' >> return (FilePathRoot "/"))
+++ (Parse.char '~' >> Parse.char '/' >> return FilePathHomeDir)
+++ (do drive <- Parse.satisfy (\c -> (c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z'))
_ <- Parse.char ':'
_ <- Parse.char '/' +++ Parse.char '\\'
return (FilePathWinDrive (toUpper drive)))
return (FilePathRoot (toUpper drive : ":\\")))
)
<++ return FilePathRelative

Expand Down
21 changes: 11 additions & 10 deletions cabal-install/tests/UnitTests/Distribution/Client/Glob.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ prop_roundtrip_printparse pathglob =
testParseCases :: Assertion
testParseCases = do

FilePathGlob FilePathUnixRoot GlobDirTrailing <- testparse "/"
FilePathGlob (FilePathRoot "/") GlobDirTrailing <- testparse "/"
FilePathGlob FilePathHomeDir GlobDirTrailing <- testparse "~/"

FilePathGlob (FilePathWinDrive 'A') GlobDirTrailing <- testparse "A:/"
FilePathGlob (FilePathWinDrive 'Z') GlobDirTrailing <- testparse "z:/"
FilePathGlob (FilePathWinDrive 'C') GlobDirTrailing <- testparse "C:\\"
FilePathGlob (FilePathRoot "A:\\") GlobDirTrailing <- testparse "A:/"
FilePathGlob (FilePathRoot "Z:\\") GlobDirTrailing <- testparse "z:/"
FilePathGlob (FilePathRoot "C:\\") GlobDirTrailing <- testparse "C:\\"
FilePathGlob FilePathRelative (GlobFile [Literal "_:"]) <- testparse "_:"

FilePathGlob FilePathRelative
Expand All @@ -68,7 +68,7 @@ testParseCases = do
(GlobDir [Literal "foo"]
(GlobDir [Literal "bar"] GlobDirTrailing)) <- testparse "foo/bar/"

FilePathGlob FilePathUnixRoot
FilePathGlob (FilePathRoot "/")
(GlobDir [Literal "foo"]
(GlobDir [Literal "bar"] GlobDirTrailing)) <- testparse "/foo/bar/"

Expand Down Expand Up @@ -134,16 +134,17 @@ instance Arbitrary FilePathRoot where
arbitrary =
frequency
[ (3, pure FilePathRelative)
, (1, pure FilePathUnixRoot)
, (1, pure (FilePathRoot unixroot))
, (1, FilePathRoot <$> windrive)
, (1, pure FilePathHomeDir)
, (1, FilePathWinDrive <$> choose ('A', 'Z'))
]
where
unixroot = "/"
windrive = do d <- choose ('A', 'Z'); return (d : ":\\")

shrink FilePathRelative = []
shrink FilePathUnixRoot = [FilePathRelative]
shrink (FilePathRoot _) = [FilePathRelative]
shrink FilePathHomeDir = [FilePathRelative]
shrink (FilePathWinDrive d) = FilePathRelative
: [ FilePathWinDrive d' | d' <- shrink d ]


instance Arbitrary FilePathGlobRel where
Expand Down

0 comments on commit 2e17ea2

Please sign in to comment.