Windows: include= and exclude= containing '/' will also match filenames that are written using '\'
And vice-versa, but it's better to use '/' for portability. Notably, standardPreferredContent contains "archive/*" and that might not match if the filename ends up coming in with the slashes the other way around.
This commit is contained in:
parent
e914cb0777
commit
6b13574827
7 changed files with 49 additions and 17 deletions
|
@ -1,15 +1,17 @@
|
|||
{-# LANGUAGE PackageImports #-}
|
||||
|
||||
{- file globbing
|
||||
-
|
||||
- Copyright 2014 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2014-2020 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- License: BSD-2-clause
|
||||
-}
|
||||
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE PackageImports #-}
|
||||
|
||||
module Utility.Glob (
|
||||
Glob,
|
||||
GlobCase(..),
|
||||
GlobFilePath(..),
|
||||
compileGlob,
|
||||
matchGlob
|
||||
) where
|
||||
|
@ -24,26 +26,42 @@ newtype Glob = Glob Regex
|
|||
|
||||
data GlobCase = CaseSensative | CaseInsensative
|
||||
|
||||
-- Is the glob being used to match filenames?
|
||||
--
|
||||
-- When matching filenames,
|
||||
-- a single path separator (eg /) in the glob will match any
|
||||
-- number of path separators in the filename.
|
||||
-- And on Windows, both / and \ are used as path separators, so compile
|
||||
-- the glob to a regexp that matches either path separator.
|
||||
newtype GlobFilePath = GlobFilePath Bool
|
||||
|
||||
{- Compiles a glob to a regex, that can be repeatedly used. -}
|
||||
compileGlob :: String -> GlobCase -> Glob
|
||||
compileGlob glob globcase = Glob $
|
||||
compileGlob :: String -> GlobCase -> GlobFilePath -> Glob
|
||||
compileGlob glob globcase globfilepath = Glob $
|
||||
case compile (defaultCompOpt {caseSensitive = casesentitive}) defaultExecOpt regex of
|
||||
Right r -> r
|
||||
Left _ -> giveup $ "failed to compile regex: " ++ regex
|
||||
where
|
||||
regex = '^' : wildToRegex glob ++ "$"
|
||||
regex = '^' : wildToRegex globfilepath glob ++ "$"
|
||||
casesentitive = case globcase of
|
||||
CaseSensative -> True
|
||||
CaseInsensative -> False
|
||||
|
||||
wildToRegex :: String -> String
|
||||
wildToRegex = concat . go
|
||||
wildToRegex :: GlobFilePath -> String -> String
|
||||
wildToRegex (GlobFilePath globfile) = concat . go
|
||||
where
|
||||
go [] = []
|
||||
go ('*':xs) = ".*" : go xs
|
||||
go ('?':xs) = "." : go xs
|
||||
go ('[':'!':xs) = "[^" : inpat xs
|
||||
go ('[':xs) = "[" : inpat xs
|
||||
#ifdef mingw32_HOST_OS
|
||||
go ('/':xs) | globfile = "[/\\]+" : go xs
|
||||
go ('\\':xs) | globfile = "[/\\]+" : go xs
|
||||
#else
|
||||
go ('/':xs) | globfile = "[/]+" : go xs
|
||||
go ('\\':xs) | globfile = "[\\]+" : go xs
|
||||
#endif
|
||||
go (x:xs)
|
||||
| isDigit x || isAlpha x = [x] : go xs
|
||||
| otherwise = esc x : go xs
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue