{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Test.Morpheus.File
( withSource,
ReadSource,
cd,
file,
readJSON,
readGQL,
FileUrl (..),
ls,
mkUrl,
isDirectory,
scanDirectories,
searchAppFiles,
)
where
import qualified Data.ByteString.Lazy.Char8 as L
import Data.ByteString.Lazy.Char8 (ByteString)
import Data.List
import qualified Data.Text.IO as T
import Relude hiding (ByteString)
import System.Directory (doesDirectoryExist, listDirectory)
class ReadSource t where
readSource :: ToString name => name -> IO t
instance ReadSource Text where
readSource = T.readFile . toString
instance ReadSource ByteString where
readSource = L.readFile . toString
withSource :: ReadSource t => (String, String) -> FileUrl -> IO t
withSource (name, format) url
| isDir url = readSource $ toString url <> "/" <> name <> "." <> format
| otherwise = readSource $ toString url <> "." <> format
readGQL :: ReadSource t => String -> FileUrl -> IO t
readGQL x = withSource (x, "gql")
readJSON :: ReadSource t => String -> FileUrl -> IO t
readJSON x = withSource (x, "json")
data FileUrl = FileUrl
{ filePath :: [FilePath],
fileName :: FilePath,
isDir :: Bool
}
deriving (Show)
instance ToString FileUrl where
toString FileUrl {..} = foldl' (\y x -> x <> "/" <> y) fileName filePath
goTo :: FileUrl -> FilePath -> Bool -> FileUrl
goTo FileUrl {fileName, filePath} name isDir =
FileUrl
{ filePath = fileName : filePath,
fileName = name,
..
}
cd :: FileUrl -> FilePath -> FileUrl
cd url name = goTo url name True
file :: FileUrl -> FilePath -> FileUrl
file url name = goTo url name False
ls :: FileUrl -> IO [FileUrl]
ls url = do
files <- listDirectory (toString url)
traverse mkFile files
where
mkFile name =
goTo url name
<$> doesDirectoryExist
(toString url <> "/" <> name)
isDirectory :: FileUrl -> IO Bool
isDirectory = doesDirectoryExist . toString
mkUrl :: FilePath -> FileUrl
mkUrl fileName =
FileUrl
{ filePath = ["test"],
fileName,
isDir = True
}
scanDirectories :: FileUrl -> IO [FileUrl]
scanDirectories = fmap (filter isDir) . ls
searchAppFiles :: FileUrl -> IO [FilePath]
searchAppFiles = fmap (nub . mapMaybe isAppFile) . ls
where
isAppFile FileUrl {fileName, isDir}
| not isDir
&& "app-" `isPrefixOf` fileName =
Just $ takeWhile (/= '.') fileName
| otherwise = Nothing