shikensu-0.2.0: src/Shikensu/Internal/Utilities.hs
{-| Internal utility functions.
-}
module Shikensu.Internal.Utilities
( cleanPath
, commonDirectory
, compilePatterns
, compileParentPath
, compilePathToRoot
, globDir
, replaceSingleDot
, stripPrefix
, takeDirName
) where
import Data.Maybe (fromMaybe)
import Flow
import Shikensu.Types (Pattern)
import System.FilePath
import qualified Data.List as List (map, stripPrefix)
import qualified System.FilePath.Glob as Glob
{-| "Clean up" a path.
> `/directory/./nested/` -> `directory/nested`
> `./` -> ``
> `.` -> ``
-}
cleanPath :: FilePath -> FilePath
cleanPath =
normalise .> dropTrailingPathSeparator .> dropDrive .> replaceSingleDot
{-| Get the common directory from a Pattern.
-}
commonDirectory :: Pattern -> FilePath
commonDirectory pattern =
(Glob.compile .> Glob.commonDirectory .> fst) pattern
{-| Compile a list of `Pattern`s to `Glob.Pattern`s.
-}
compilePatterns :: [Pattern] -> [Glob.Pattern]
compilePatterns =
List.map Glob.compile
{-| Path to parent, when there is one.
> Just "../" or Nothing
-}
compileParentPath :: FilePath -> Maybe FilePath
compileParentPath dirname =
case dirname of
"" -> Nothing
_ -> Just "../"
{-| Path to root.
Example, if `dirname` is 'example/subdir',
then this will be `../../`.
If the `dirname` is empty,
then this will be empty as well.
-}
compilePathToRoot :: FilePath -> FilePath
compilePathToRoot dirname =
if dirname == "" then
""
else
dirname
|> splitDirectories
|> fmap (\_ -> "..")
|> joinPath
|> addTrailingPathSeparator
{-| List contents of a directory using a glob pattern.
Returns a relative path, based on the given rootDirname.
-}
globDir :: FilePath -> [Glob.Pattern] -> IO [[FilePath]]
globDir rootDir patterns =
Glob.globDir patterns rootDir
|> fmap (fst)
|> fmap (List.map . List.map . makeRelative $ rootDir)
{-| If the path is a single dot, return an empty string.
Otherwise return the path.
-}
replaceSingleDot :: String -> String
replaceSingleDot path =
if path == "." then "" else path
{-| Strip prefix.
-}
stripPrefix :: String -> String -> String
stripPrefix prefix target =
fromMaybe target (List.stripPrefix prefix target)
{-| Take dirname and replace single dot.
-}
takeDirName :: FilePath -> FilePath
takeDirName =
replaceSingleDot . takeDirectory