module Bioshake( module Types
, module Implicit
, module Tags
, All(..)
, Referenced(..)
, Capture(..)
, ignoringIOErrors
, withTempDirectory
, bioshake
, out
, withAll
, withPair) where
import Bioshake.Cluster.Torque
import Bioshake.Implicit as Implicit
import Bioshake.Tags as Tags
import Bioshake.Types as Types
import qualified Control.Exception as E
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Trans.State.Strict
import Data.List
import qualified Data.Set as S
import Data.String
import Development.Shake
import Language.Haskell.TH
import System.Directory (copyFile,
removeDirectoryRecursive)
import System.IO.Temp (createTempDirectory)
class Referenced a where
getRef :: a -> FilePath
name :: a -> String
dbnsfp :: a -> FilePath
dbnsfp _ = error "dbNSFP not available"
instance Referenced a => Referenced (a :-> b) where
getRef (a :-> _) = getRef a
name (a :-> _) = name a
dbnsfp (a :-> _) = dbnsfp a
class Capture a where
getBED :: a -> FilePath
instance Capture a => Capture (a :-> b) where
getBED (a :-> _) = getBED a
data Out = Out [FilePath] deriving Show
out = Out
instance Pathable (a :-> Out) where
paths (_ :-> Out outs) = outs
instance Pathable a => Buildable (a :-> Out) where
build ((paths -> inputs) :-> Out outs) = zipWithM_ ((liftIO .) . copyFile) inputs outs
$(allTransTagsPipe ''Out)
data All a where
All :: (Functor f, Foldable f) => f a -> All a
withAll :: (Functor f, Foldable f) => f a -> All a
withAll = All
withPair :: a -> a -> All a
withPair a b = All [a, b]
instance Compilable a => Compilable (All a) where
compile (All as) = mapM_ compile as
instance Pathable a => Pathable (All a) where
paths (All ps) = nub $ concatMap paths ps
instance Referenced a => Referenced (All a) where
getRef (All as) = foldl1 (\l r -> if l == r then l else error "cannot combine mixed references") $ fmap getRef as
name (All as) = foldl1 (\l r -> if l == r then l else error "cannot combine mixed references") $ fmap name as
dbnsfp (All as) = foldl1 (\l r -> if l == r then l else error "cannot combine mixed references") $ fmap dbnsfp as
instance Capture a => Capture (All a) where
getBED (All as) = foldl1 (\l r -> if l == r then l else error "cannot combine mixed captures") $ fmap getBED as
instance Show a => Show (All a) where
show (All as) = foldl1 (\l r -> l ++ "," ++ r) $ fmap show as
$(allTransTags ''All)
bioshake :: Int
-> ShakeOptions
-> (Implicit Resource => Rules ()) -> IO ()
bioshake n opts cont = shakeArgs opts{shakeThreads = n} $ do
res <- newResource "cpus" n
cont $~ res
withTempDirectory :: FilePath
-> String
-> (FilePath -> Action b)
-> Action b
withTempDirectory targetDir template act = do
path <- liftIO $ createTempDirectory targetDir template
act path `actionFinally` (liftIO . ignoringIOErrors $ removeDirectoryRecursive path)
ignoringIOErrors :: IO () -> IO ()
ignoringIOErrors ioe = ioe `E.catch` (\e -> const (return ()) (e :: IOError))