shaker-0.4: src/Shaker/Type.hs
-- | Aggregate all types and data used through shaker
module Shaker.Type
where
import DynFlags hiding (OneShot)
import qualified Data.Map as M
import Control.Monad.Reader
import System.Time(ClockTime)
import Control.Concurrent.MVar
import Control.Concurrent
-- | Environnement containing the project configuration.
-- It is generated at startup and won't change
type Shaker = ReaderT ShakerInput
type ShakerR = Reader ShakerInput
type ThreadIdList = MVar [ThreadId]
type Token = MVar Int
-- | Environnement for the project compilation
-- This environnement can change depending on the compile
-- action called
type CompileM = Reader CompileInput
-- | Duration define the life span of an action
data Duration =
OneShot -- ^Execute the action and give back control
| Continuous-- ^Execute the action when a source file modification is done until it is stopped
deriving (Show,Eq)
-- | Action represents the differents action with arguments
data Action =
Action ShakerAction
| ActionWithArg ShakerAction String
deriving (Show,Eq,Ord)
-- | The input mvar is used to push the parsed command
type Input = MVar (Maybe Command)
data InputState = InputState {
input :: Input,
token :: Token -- ^ Token is used to manage the token between action executor and command-line listener
}
-- | ShakerAction represents the differents actions realisable by shaker
data ShakerAction =
Compile -- ^ Compile sources with ghc
| FullCompile -- ^ Compile all hs sources with ghc
| TestFramework -- ^ Execute both quickcheck and hunit using test framework
| IntelligentTestFramework -- ^ Execute both quickcheck and hunit using test framework on recompiled modules
| InvalidAction -- ^ Display an error when invalid action is inputed
| Help -- ^ Display the help
| Execute -- ^ Execute a command
| Empty -- ^ Nothing to execute
| Quit -- ^ Exit shaker
| Clean -- ^ Delete generated
deriving (Show,Eq,Ord)
-- | Command agregate a duration with an action
data Command = Command Duration [Action]
deriving (Show,Eq)
-- | Represents the global configuration of the system
data ShakerInput = ShakerInput {
compileInputs :: [CompileInput]
,listenerInput :: ListenerInput
,pluginMap :: PluginMap
,commandMap :: CommandMap
,argument :: Maybe String
,modifiedInfoFiles :: [FileInfo]
,threadData :: ThreadData
,inputState :: InputState
}
data ThreadData = ThreadData {
-- processToken :: Token
listenToken :: Token
,quitToken :: Token
,threadIdListenList :: ThreadIdList
,threadIdQuitList :: ThreadIdList
}
getListenThreadList :: ShakerInput -> ThreadIdList
getListenThreadList = threadIdListenList . threadData
-- | Configuration flags to pass to the ghc compiler
data CompileInput = CompileInput{
cfSourceDirs :: [String] -- ^ Source directory of haskell files
,cfDescription :: String -- ^ Desctipition of the compile input (executable or library if comming from cabal)
,cfCompileTarget :: String -- ^ Destination of .o and .hi files
,cfDynFlags :: (DynFlags->DynFlags) -- ^ A transform fonction wich will takes the DynFlags of the current ghc session and change some values
,cfCommandLineFlags :: [String] -- ^ The command line to pass options to pass to the ghc compiler
,cfTargetFiles :: [String] -- ^ List of files or list of modules to compile
}
instance Show CompileInput
where show (CompileInput src desc _ _ commandLine target) =
concat ["CompileInput |source : ",show src," |desc : ",desc," |cmdLine : ",show commandLine," |targetfiles : ", show target]
-- | Configuration of the continuous listener
data ListenerInput = ListenerInput {
fileListenInfo :: [FileListenInfo] -- ^ The files to listen
,delay :: Int -- ^ Delay beetween 2 check in microsecond
}
-- | Represents directory to listen
data FileListenInfo = FileListenInfo{
dir :: FilePath -- ^ location of the listened directory
,ignore :: [String] -- ^ ignore patterns
,include :: [String] -- ^include patterns
}
deriving (Show,Eq)
-- |Agregate a FilePath with its modification time
data FileInfo = FileInfo {
fileInfoFilePath :: FilePath
,fileInfoClockTime:: ClockTime
}
deriving (Show,Eq)
-- | Represents the mapping beetween an action and the function to execute
type PluginMap = M.Map ShakerAction Plugin
-- | Represents the mapping between the command-line input and the action
type CommandMap = M.Map String ShakerAction
-- | Represents an action of shaker
type Plugin = Shaker IO()
-- * Default data
-- | Default compilation argument.
-- Wall is activated by default
defaultCompileInput :: CompileInput
defaultCompileInput = CompileInput {
cfSourceDirs= ["src/","testsuite/tests/"]
,cfDescription = "Default Compilation"
,cfCompileTarget = "target"
,cfDynFlags = defaultCompileFlags
,cfCommandLineFlags = ["-Wall"]
,cfTargetFiles = []
}
-- | default dynamics flags
-- the sources are expected to be in src as described in <http://www.haskell.org/haskellwiki/structure_of_a_haskell_project>
-- the result of compilation (.o and .hi) are placed in the target/ directory
-- there is no main linkage by default to allow faster compilation feedback
defaultCompileFlags :: (DynFlags -> DynFlags)
defaultCompileFlags = \a-> a {
verbosity = 1
,ghcLink = NoLink
}
-- | The default Listener configuration
-- Listened sources are all haskell sources in src/ and testsuite/
-- The default delay is 2 sec
defaultListenerInput :: ListenerInput
defaultListenerInput = ListenerInput {
fileListenInfo= [FileListenInfo "src/" [] defaultHaskellPatterns, FileListenInfo "testsuite/" [] defaultHaskellPatterns ]
,delay = 2000000
}
-- | Default haskell file pattern : *.hs
defaultHaskellPatterns :: [String]
defaultHaskellPatterns = [".*\\.hs$", ".*\\.lhs"]
-- | Default exclude pattern : Setup.hs
defaultExclude :: [String]
defaultExclude = [".*Setup\\.hs$"]
exitCommand :: Command
exitCommand = Command OneShot [Action Quit]
emptyCommand :: Command
emptyCommand = Command OneShot [Action Empty]