module Drasil.Meta.Analysis.DirectoryController (createFolder, createFile, finder, getDirectories,
DrasilPack, FileName, FolderName, File(..), Folder(..)) where
import Data.List ((\\), isInfixOf, isPrefixOf, isSuffixOf, partition, sort)
import System.Directory (doesDirectoryExist, listDirectory,
setCurrentDirectory)
import System.FilePath (joinPath)
type FilterPrefix = String
type DrasilPack = String
type FileName = FilePath
type FolderName = FilePath
data File = File { File -> DrasilPack
fileDrasilPack :: DrasilPack
, File -> DrasilPack
fileName :: FileName
, File -> DrasilPack
filePath :: FilePath
} deriving (Int -> File -> ShowS
[File] -> ShowS
File -> DrasilPack
(Int -> File -> ShowS)
-> (File -> DrasilPack) -> ([File] -> ShowS) -> Show File
forall a.
(Int -> a -> ShowS)
-> (a -> DrasilPack) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> File -> ShowS
showsPrec :: Int -> File -> ShowS
$cshow :: File -> DrasilPack
show :: File -> DrasilPack
$cshowList :: [File] -> ShowS
showList :: [File] -> ShowS
Show)
data Folder = Folder { Folder -> DrasilPack
folderDrasilPack :: DrasilPack
, Folder -> DrasilPack
folderName :: FolderName
, Folder -> DrasilPack
folderPath :: FilePath
} deriving (Int -> Folder -> ShowS
[Folder] -> ShowS
Folder -> DrasilPack
(Int -> Folder -> ShowS)
-> (Folder -> DrasilPack) -> ([Folder] -> ShowS) -> Show Folder
forall a.
(Int -> a -> ShowS)
-> (a -> DrasilPack) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Folder -> ShowS
showsPrec :: Int -> Folder -> ShowS
$cshow :: Folder -> DrasilPack
show :: Folder -> DrasilPack
$cshowList :: [Folder] -> ShowS
showList :: [Folder] -> ShowS
Show)
createFolder :: FilePath -> DrasilPack -> FolderName -> Folder
createFolder :: DrasilPack -> DrasilPack -> DrasilPack -> Folder
createFolder DrasilPack
dp DrasilPack
drpk DrasilPack
fn = Folder {folderDrasilPack :: DrasilPack
folderDrasilPack=DrasilPack
drpk,folderName :: DrasilPack
folderName=DrasilPack
fn,folderPath :: DrasilPack
folderPath=DrasilPack
dp}
createFile :: FilePath -> DrasilPack -> FileName -> File
createFile :: DrasilPack -> DrasilPack -> DrasilPack -> File
createFile DrasilPack
fp DrasilPack
drpk DrasilPack
fn = File {fileDrasilPack :: DrasilPack
fileDrasilPack=DrasilPack
drpk,fileName :: DrasilPack
fileName=DrasilPack
fn,filePath :: DrasilPack
filePath=DrasilPack
fp}
iterator :: Folder -> IO ([Folder],[File])
iterator :: Folder -> IO ([Folder], [File])
iterator Folder
folder = do
DrasilPack -> IO ()
setCurrentDirectory (Folder -> DrasilPack
folderPath Folder
folder)
[DrasilPack]
rawContents <- DrasilPack -> IO [DrasilPack]
listDirectory (Folder -> DrasilPack
folderName Folder
folder)
let bakedContents :: ([Folder], [File])
bakedContents = ([Folder]
folders,[File]
files)
folders :: [Folder]
folders = (DrasilPack -> Folder) -> [DrasilPack] -> [Folder]
forall a b. (a -> b) -> [a] -> [b]
map (DrasilPack -> DrasilPack -> DrasilPack -> Folder
createFolder DrasilPack
workingDirectory DrasilPack
currentDrasilPack) [DrasilPack]
folderNames
files :: [File]
files = (DrasilPack -> File) -> [DrasilPack] -> [File]
forall a b. (a -> b) -> [a] -> [b]
map (DrasilPack -> DrasilPack -> DrasilPack -> File
createFile DrasilPack
workingDirectory DrasilPack
currentDrasilPack) [DrasilPack]
fileNames
folderNames :: [DrasilPack]
folderNames = [DrasilPack] -> [DrasilPack]
forall a. Ord a => [a] -> [a]
sort ([DrasilPack] -> [DrasilPack]) -> [DrasilPack] -> [DrasilPack]
forall a b. (a -> b) -> a -> b
$ [DrasilPack]
rawContents [DrasilPack] -> [DrasilPack] -> [DrasilPack]
forall a. Eq a => [a] -> [a] -> [a]
\\ (DrasilPack -> Bool) -> [DrasilPack] -> [DrasilPack]
forall a. (a -> Bool) -> [a] -> [a]
filter (DrasilPack -> DrasilPack -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isInfixOf DrasilPack
".") [DrasilPack]
rawContents
fileNames :: [DrasilPack]
fileNames = [DrasilPack] -> [DrasilPack]
forall a. Ord a => [a] -> [a]
sort ([DrasilPack] -> [DrasilPack]) -> [DrasilPack] -> [DrasilPack]
forall a b. (a -> b) -> a -> b
$ (DrasilPack -> Bool) -> [DrasilPack] -> [DrasilPack]
forall a. (a -> Bool) -> [a] -> [a]
filter (DrasilPack -> DrasilPack -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isSuffixOf DrasilPack
".hs") [DrasilPack]
rawContents
workingDirectory :: DrasilPack
workingDirectory = Folder -> DrasilPack
getFolderPath Folder
folder
currentDrasilPack :: DrasilPack
currentDrasilPack = Folder -> DrasilPack
folderDrasilPack Folder
folder
([Folder], [File]) -> IO ([Folder], [File])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Folder], [File])
bakedContents
finder :: Folder -> IO [File]
finder :: Folder -> IO [File]
finder Folder
folder = do
([Folder], [File])
rawData <- Folder -> IO ([Folder], [File])
iterator Folder
folder
let rawFolders :: [Folder]
rawFolders = ([Folder], [File]) -> [Folder]
forall a b. (a, b) -> a
fst ([Folder], [File])
rawData
[Folder]
folders <- [Folder] -> IO [Folder]
verifyDirectories [Folder]
rawFolders
[[File]]
rawFiles <- (Folder -> IO [File]) -> [Folder] -> IO [[File]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Folder -> IO [File]
finder [Folder]
folders
let bakedFiles :: [File]
bakedFiles = [[File]] -> [File]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[File]]
rawFiles
let files :: [File]
files
| [Folder] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Folder]
folders = ([Folder], [File]) -> [File]
forall a b. (a, b) -> b
snd ([Folder], [File])
rawData
| Bool
otherwise = [File]
bakedFiles [File] -> [File] -> [File]
forall a. [a] -> [a] -> [a]
++ ([Folder], [File]) -> [File]
forall a b. (a, b) -> b
snd ([Folder], [File])
rawData
[File] -> IO [File]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [File]
files
getDirectories :: FilePath -> FilterPrefix -> IO [Folder]
getDirectories :: DrasilPack -> DrasilPack -> IO [Folder]
getDirectories DrasilPack
directoryPath DrasilPack
filterPrefix = do
[DrasilPack]
allPaths <- DrasilPack -> IO [DrasilPack]
listDirectory DrasilPack
directoryPath
let rawPackages :: [DrasilPack]
rawPackages = [DrasilPack] -> [DrasilPack]
forall a. Ord a => [a] -> [a]
sort ([DrasilPack] -> [DrasilPack]) -> [DrasilPack] -> [DrasilPack]
forall a b. (a -> b) -> a -> b
$ (DrasilPack -> Bool) -> [DrasilPack] -> [DrasilPack]
forall a. (a -> Bool) -> [a] -> [a]
filter (DrasilPack -> DrasilPack -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf DrasilPack
filterPrefix) [DrasilPack]
allPaths
packageNames :: [DrasilPack]
packageNames = ShowS -> [DrasilPack] -> [DrasilPack]
forall a b. (a -> b) -> [a] -> [b]
map (DrasilPack -> ShowS
forall a. Eq a => [a] -> [a] -> [a]
\\DrasilPack
"drasil-") [DrasilPack]
rawPackages
directories :: [Folder]
directories = (DrasilPack -> DrasilPack -> Folder)
-> [DrasilPack] -> [DrasilPack] -> [Folder]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (DrasilPack -> DrasilPack -> DrasilPack -> Folder
createFolder DrasilPack
directoryPath) [DrasilPack]
packageNames [DrasilPack]
rawPackages
[Folder] -> IO [Folder]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [Folder]
directories
verifyDirectories :: [Folder] -> IO [Folder]
verifyDirectories :: [Folder] -> IO [Folder]
verifyDirectories [Folder]
rawFolders = do
let rawDirectories :: [DrasilPack]
rawDirectories = (Folder -> DrasilPack) -> [Folder] -> [DrasilPack]
forall a b. (a -> b) -> [a] -> [b]
map Folder -> DrasilPack
getFolderPath [Folder]
rawFolders
[Bool]
boolFolders <- (DrasilPack -> IO Bool) -> [DrasilPack] -> IO [Bool]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM DrasilPack -> IO Bool
doesDirectoryExist [DrasilPack]
rawDirectories
let verifiedDirectories :: [Folder]
verifiedDirectories = ([Folder], [Folder]) -> [Folder]
forall a b. (a, b) -> b
snd (([Folder], [Folder]) -> [Folder])
-> ([Folder], [Folder]) -> [Folder]
forall a b. (a -> b) -> a -> b
$ (Folder -> Bool) -> [Folder] -> ([Folder], [Folder])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Folder -> Bool
nullFolder ((Bool -> Folder -> Folder) -> [Bool] -> [Folder] -> [Folder]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Bool -> Folder -> Folder
fBool [Bool]
boolFolders [Folder]
rawFolders)
[Folder] -> IO [Folder]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [Folder]
verifiedDirectories
fBool :: Bool -> Folder -> Folder
fBool :: Bool -> Folder -> Folder
fBool Bool
b Folder
f = if Bool
b then Folder
f else DrasilPack -> DrasilPack -> DrasilPack -> Folder
createFolder DrasilPack
"" DrasilPack
"" DrasilPack
""
nullFolder :: Folder -> Bool
nullFolder :: Folder -> Bool
nullFolder Folder
folder = Bool
empty where
empty :: Bool
empty = (DrasilPack -> Bool) -> [DrasilPack] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all DrasilPack -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Folder -> DrasilPack
folderName Folder
folder,Folder -> DrasilPack
folderPath Folder
folder,Folder -> DrasilPack
folderDrasilPack Folder
folder]
getFolderPath :: Folder -> FilePath
getFolderPath :: Folder -> DrasilPack
getFolderPath Folder
folder = [DrasilPack] -> DrasilPack
joinPath [Folder -> DrasilPack
folderPath Folder
folder, Folder -> DrasilPack
folderName Folder
folder]