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