module Development.Duplo.Files where
import Control.Exception (throw)
import Control.Lens hiding (Action)
import Control.Lens.TH (makeLenses)
import Control.Monad.Except (ExceptT(..), runExceptT)
import Control.Monad.Trans.Class (lift)
import Data.List (intercalate)
import Data.Text (split, pack, unpack)
import Development.Duplo.Component (appId)
import Development.Shake hiding (readFile)
import Prelude hiding (readFile)
import System.FilePath.Posix (makeRelative, splitDirectories, joinPath)
import qualified Development.Duplo.Component as CM
import qualified Development.Duplo.Types.Builder as BD
type FileName = String
type FileContent = String
type ComponentId = String
data File = File { _filePath :: FilePath
, _fileDir :: FilePath
, _fileName :: FileName
, _componentId :: ComponentId
, _fileContent :: String
, _isRoot :: Bool
} deriving (Show)
pseudoFile = File { _filePath = ""
, _fileDir = ""
, _fileName = ""
, _componentId = ""
, _fileContent = ""
, _isRoot = False
}
makeLenses ''File
readFile :: FilePath -> FilePath -> ExceptT String Action File
readFile cwd path = do
let (fileDir, fileName) = parseFilePath path
fileContent <- lift $ readFile' path
appInfo <- liftIO CM.readManifest
let appId' = appId appInfo
let componentId = parseComponentId cwd appId' fileDir
let isRoot = componentId == appId'
return $ File path fileDir fileName componentId fileContent isRoot
parseFilePath :: FilePath -> (FilePath, FileName)
parseFilePath path = (fileDir, fileName)
where
segments = splitDirectories path
segLength = length segments
dirLength = segLength 1
fileDir = joinPath $ take dirLength segments
fileName = segments !! dirLength
parseComponentId :: FilePath -> ComponentId -> FilePath -> ComponentId
parseComponentId cwd defaultId path =
let
relPath = makeRelative cwd path
segments = splitDirectories relPath
in
case segments of
("components" : appId : xs) -> appId
_ -> defaultId