1 {-# LANGUAGE DeriveFunctor #-}
2 {-# LANGUAGE DeriveGeneric #-}
3 {-# LANGUAGE LambdaCase #-}
5 -----------------------------------------------------------------------------
8 -- Module : Distribution.Simple.Glob
9 -- Copyright : Isaac Jones, Simon Marlow 2003-2004
11 -- portions Copyright (c) 2007, Galois Inc.
13 -- Maintainer : cabal-devel@haskell.org
14 -- Portability : portable
16 -- Simple file globbing.
17 module Distribution
.Simple
.Glob
21 -- * Matching on globs
26 , matchDirFileGlobWithDie
31 , GlobSyntaxError
(..)
32 , explainGlobSyntaxError
39 import Distribution
.Compat
.Prelude
42 import Distribution
.CabalSpecVersion
(CabalSpecVersion
)
43 import Distribution
.Simple
.Errors
44 ( CabalException
(MatchDirFileGlob
, MatchDirFileGlobErrors
)
46 import Distribution
.Simple
.Glob
.Internal
47 import Distribution
.Simple
.Utils
(dieWithException
, warn
)
48 import Distribution
.Verbosity
(Verbosity
)
50 -------------------------------------------------------------------------------
54 --------------------------------------------------------------------------------
56 -- | Extract the matches from a list of 'GlobResult's.
58 -- Note: throws away the 'GlobMissingDirectory' results; chances are
59 -- that you want to check for these and error out if any are present.
62 globMatches
:: [GlobResult a
] -> [a
]
63 globMatches input
= [a | GlobMatch a
<- input
]
65 -- | This will 'die'' when the glob matches no files, or if the glob
66 -- refers to a missing directory, or if the glob fails to parse.
68 -- The 'Version' argument must be the spec version of the package
69 -- description being processed, as globs behave slightly differently
70 -- in different spec versions.
72 -- The first 'FilePath' argument is the directory that the glob is
73 -- relative to. It must be a valid directory (and hence it can't be
74 -- the empty string). The returned values will not include this
77 -- The second 'FilePath' is the glob itself.
78 matchDirFileGlob
:: Verbosity
-> CabalSpecVersion
-> FilePath -> FilePath -> IO [FilePath]
79 matchDirFileGlob v
= matchDirFileGlobWithDie v dieWithException
81 -- | Like 'matchDirFileGlob' but with customizable 'die'
84 matchDirFileGlobWithDie
86 -> (Verbosity
-> CabalException
-> IO [FilePath])
91 matchDirFileGlobWithDie verbosity rip version dir filepath
= case parseFileGlob version filepath
of
92 Left err
-> rip verbosity
$ MatchDirFileGlob
(explainGlobSyntaxError filepath err
)
94 results
<- runDirFileGlob verbosity
(Just version
) dir glob
95 let missingDirectories
=
96 [missingDir | GlobMissingDirectory missingDir
<- results
]
97 matches
= globMatches results
98 directoryMatches
= [a | GlobMatchesDirectory a
<- results
]
100 let errors
:: [String]
102 [ "filepath wildcard '"
104 ++ "' refers to the directory"
107 ++ "', which does not exist or is not a directory."
108 | missingDir
<- missingDirectories
110 ++ [ "filepath wildcard '" ++ filepath
++ "' does not match any files."
111 |
null matches
&& null directoryMatches
112 -- we don't error out on directory matches, simply warn about them and ignore.
117 [ "Ignoring directory '" ++ path
++ "'" ++ " listed in a Cabal package field which should only include files (not directories)."
118 | path
<- directoryMatches
123 unless (null warns
) $
127 else rip verbosity
$ MatchDirFileGlobErrors errors