arion-0.1.0.8: src/Arion/Types.hs
module Arion.Types (
Command(..),
FileContent,
SourceTestMap,
SourceFile(..),
TestFile(..),
FileType(..),
toSourceFile,
toTestFile,
typeOf
) where
import Data.List (isInfixOf)
import Data.List.Split (splitOn)
import Data.Map (Map)
import Data.Maybe (mapMaybe)
import Text.Regex.Posix (getAllTextMatches, (=~))
data Command = RunHaskell { sourceFolder :: String, testFolder :: String, commandString :: String } |
Echo String
deriving (Eq,Ord)
instance Show Command where
show (RunHaskell sourceFolder testFolder commandString) = "cabal exec runhaskell -- -i" ++ sourceFolder ++ " -i" ++ testFolder ++ " " ++ commandString
show (Echo stringToEcho) = "echo " ++ stringToEcho
type FileContent = String
type SourceTestMap = Map FilePath [TestFile]
data SourceFile = SourceFile {
sourceFilePath :: String,
moduleName :: String,
importedModules :: [String]
} deriving (Eq, Ord, Show)
data TestFile = TestFile {
testFilePath :: String,
imports :: [String]
} deriving (Eq, Ord, Show)
data FileType = Source | Test
typeOf :: String -> FileType
typeOf filePath
| isInfixOf "Spec" filePath == True = Test
| otherwise = Source
toSourceFile :: FilePath -> FileContent -> SourceFile
toSourceFile filePath content = let theModuleName = getModuleName content
theImportedModules = getImports content
in SourceFile {
sourceFilePath = filePath,
moduleName = theModuleName,
importedModules = theImportedModules
}
toTestFile :: FilePath -> FileContent -> TestFile
toTestFile filePath content = let importLines = getImports content
in TestFile {
testFilePath = filePath,
imports = importLines
}
getImports :: FileContent -> [String]
getImports fileContent = let importLines = getAllTextMatches $ fileContent =~ "^import .*" :: [String]
imports = mapMaybe (getSecond . filter (not . (`elem` ["","qualified"])) . splitOn " ") importLines
in imports
getSecond (_:x:_) = Just x
getSecond _ = Nothing
-- this is just wrong - we can't always find a module in a file.
-- need to rework to propagate Maybe up through toSourceFile etc.
getModuleName :: FileContent -> String
getModuleName fileContent = let moduleLine = fileContent =~ "(module\\s+.*\\s+.*)" :: String
(_:moduleName:_)= splitOn " " moduleLine
in moduleName