a classic game implemented using Happstack+Fay+Acid-State

root / Setup.hs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{-# LANGUAGE ViewPatterns #-}
import Control.Monad.Trans
import Data.List

import Distribution.Simple
import Distribution.Verbosity
import Distribution.ModuleName (ModuleName,toFilePath)
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program
import Distribution.Simple.PreProcess
import Distribution.Simple.Setup
import Distribution.PackageDescription
import Control.Monad
import System.FilePath
import System.Directory
import Data.Default
import Data.Maybe
import Fay
import Fay.Types
import Fay.Compiler.Config

main :: IO ()
main =
    defaultMainWithHooks simpleUserHooks { hookedPrograms      = [hsx2hsProgram]
                                         , hookedPreProcessors = [("hsx", ppHsx2hs)]
                                         , preBuild            = note
                                         , postBuild           = buildFay
                                         }

note :: Args -> BuildFlags -> IO HookedBuildInfo
note _ _ = do
  putStrLn "Building the server ..."
  return emptyHookedBuildInfo

hsx2hsProgram :: Program
hsx2hsProgram =
    simpleProgram  "hsx2hs"

ppHsx2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor
ppHsx2hs _bi lbi = PreProcessor
    { platformIndependent = True
    , runPreProcessor =
        mkSimplePreProcessor $ \inFile outFile verbosity ->
            do putStrLn (inFile ++ " has been preprocessed to " ++ outFile)
               rawSystemProgramConf verbosity hsx2hsProgram (withPrograms lbi) [inFile, outFile]
    }

buildFay :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
buildFay args bfs pkgdesc localBuildInfo = do
  putStrLn $ "Building the client ..."
  case library pkgdesc of
    Nothing -> error "Need a library in the Cabal file!"
    Just library ->
      forM_ (exposedModules library) $ \(moduleNameToPath -> path) -> do
        let depends = (map (\(Dependency (PackageName n) _) -> n) $ targetBuildDepends (libBuildInfo library))
        forM_ ((buildDir localBuildInfo) : hsSourceDirs (libBuildInfo library)) $ \dir -> do -- FIXME: this should do something smarter if the module is found in more than one directory
          let candidate = dir </> path
              PackageName name = pkgName (package pkgdesc)
              outdir = "data/js" -- FIXME: would should probably write this out to the builddir. See the Setup.lhs for alex to see how to add generated files to data-files. May also require changes to cabal-debian
              out = outdir </> name ++ ".js"
              candidateHS  = addExtension candidate ".hs"
          createDirectoryIfMissing True outdir
          putStrLn $ "checking for " ++ candidateHS
          exists <- doesFileExist candidateHS
          when exists $ do
            putStrLn $ "Compiling " ++ candidateHS ++ " to " ++ out ++ " ..."
            compileFromTo (config depends dir) candidateHS (Just out)
            putStrLn "Finished!"
  where moduleNameToPath md = toFilePath md
        config depends dir =
             addConfigPackages depends $
              addConfigDirectoryIncludePaths ["."] $
                def { configFlattenApps       = True
                    , configExportBuiltins    = True
                    , configPackageConf       = Nothing -- Just "cabal-dev/packages-7.4.1.conf"
                    , configPrettyPrint       = False
                    , configTypecheck         = False
                    }