stackage/Stackage/ShakeBuild.hs
2015-02-15 23:48:31 +01:00

105 lines
3.6 KiB
Haskell

-- | Build everything with Shake.
module Stackage.ShakeBuild where
import Stackage.BuildPlan
import Stackage.PackageDescription
import Stackage.BuildConstraints
import Stackage.PerformBuild (PerformBuild(..))
import Control.Monad
import Data.List ((\\))
import qualified Data.Map.Strict as M
import Data.Text (Text)
import Development.Shake
import Distribution.Package (PackageName)
import Distribution.Text (display)
import System.Directory
import System.Environment
-- | Run the shake builder.
performBuild :: PerformBuild -> IO ()
performBuild pb = do
shakeDir <- fmap (<//> "shake/") getCurrentDirectory
withArgs
[]
(shakeArgs
shakeOptions {shakeFiles = shakeDir}
(shakePlan pb shakeDir))
-- | The complete build plan as far as Shake is concerned.
shakePlan :: PerformBuild -> FilePath -> Rules ()
shakePlan pb shakeDir = do
fetched <- target (targetForFetched shakeDir) $
fetchedTarget shakeDir pb
_ <- forM corePackages $
\name ->
let fp =
targetForPackage shakeDir name
in target fp (makeFile fp)
packageTargets <- forM normalPackages $
\(name,plan) ->
target
(targetForPackage shakeDir name)
(do need [fetched]
packageTarget shakeDir name plan)
want packageTargets
where corePackages =
M.keys $ siCorePackages $ bpSystemInfo $ pbPlan pb
normalPackages =
filter (not . (`elem` corePackages) . fst) $
M.toList $ bpPackages $ pbPlan pb
-- | Make sure all package archives have been fetched.
fetchedTarget :: FilePath -> PerformBuild -> Action ()
fetchedTarget shakeDir pb = do
() <- cmd "cabal" "fetch" "--no-dependencies" $
map
(\(name,plan) ->
display name ++
"-" ++
display (ppVersion plan))
(M.toList
(bpPackages
(pbPlan pb)))
makeFile (targetForFetched shakeDir)
-- | Build, test and generate documentation for the package.
packageTarget :: FilePath -> PackageName -> PackagePlan -> Action ()
packageTarget shakeDir name plan = do
need (map (targetForPackage shakeDir)
(M.keys (sdPackages (ppDesc plan))))
() <- cmd (Cwd shakeDir) "cabal" "unpack" nameVer
() <- cmd (Cwd pkgDir) "cabal" "configure"
() <- cmd (Cwd pkgDir) "cabal" "build"
() <- cmd (Cwd pkgDir) "cabal" "copy"
() <- cmd (Cwd pkgDir) "cabal" "register"
makeFile (targetForPackage shakeDir name)
where pkgDir =
shakeDir <//> nameVer
nameVer =
display name ++
"-" ++
display (ppVersion plan)
-- | Get the target file for confirming that all packages have been
-- pre-fetched.
targetForFetched :: FilePattern -> FilePattern
targetForFetched shakeDir =
shakeDir <//> "fetched"
-- | Get the target file for a package.
targetForPackage :: FilePattern -> PackageName -> FilePattern
targetForPackage shakeDir name =
shakeDir <//> "packages" <//> display name
-- | Declare a target, returning the target name.
target :: FilePattern -> Action () -> Rules FilePattern
target name action = do
name *> const action
return name
-- | Make a file of this name.
makeFile :: FilePath -> Action ()
makeFile fp = liftIO $ writeFile fp ""