@@ -1,147 +0,0 @@
1−{-# OPTIONS_GHC -W #-}
2−import Distribution.Simple
3−import Distribution.Simple.LocalBuildInfo
4−import Distribution.Simple.Setup
5−import Distribution.PackageDescription
6−
7−import System.Directory
8−import System.FilePath
9−import System.IO
10−import System.Process
11−
12−import qualified Data.Binary as Binary
13−import qualified Data.ByteString.Lazy as BS
14−import qualified Data.List as List
15−
16−-- OVERVIEW
17−-- --------
18−-- Add a post-build callout that compiles the standard libraries with the new
19−-- compiler before cabal copies static files to actually install things.
20−
21−assetsDir :: FilePath
22−assetsDir = "data"
23−
24−tempDir :: FilePath
25−tempDir = "temp"
26−
27−-- The runtime is called:
28−runtime :: FilePath
29−runtime = assetsDir </> "elm-runtime.js"
30−
31−-- The runtime is called:
32−docs :: FilePath
33−docs = assetsDir </> "docs.json"
34−
35−-- The interfaces for the Standard Libraries live in:
36−interfaces :: FilePath
37−interfaces = assetsDir </> "interfaces.data"
38−
39−elm :: LocalBuildInfo -> FilePath
40−elm lbi = buildDir lbi </> "elm" </> "elm"
41−
42−document :: LocalBuildInfo -> FilePath
43−document lbi = buildDir lbi </> "elm-doc" </> "elm-doc"
44−
45−-- Care! This appears to be based on an unstable API
46−-- See: http://www.haskell.org/cabal/release/cabal-latest/doc/API/Cabal/Distribution-Simple.html#2
47−
48−
49−main :: IO ()
50−main = defaultMainWithHooks simpleUserHooks { postBuild = myPostBuild }
51−
52−
53−
54−-- Post Build
55−
56−myPostBuild :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
57−myPostBuild args flags packageDescription lbi = do
58− putStrLn "Custom build step: compiling standard libraries"
59− (elmos, elmis) <- compileLibraries lbi
60− putStrLn "Custom build step: build interfaces.data"
61− buildInterfaces elmis
62− putStrLn "Custom build step: build elm-runtime.js"
63− buildRuntime elmos
64− putStrLn "Custom build step: build docs.json"
65− buildDocs
66− removeDirectoryRecursive tempDir
67− removeDirectoryRecursive ("libraries" </> "docs")
68− postBuild simpleUserHooks args flags packageDescription lbi
69−
70−
71−compileLibraries lbi = do
72− createDirectoryIfMissing True tempDir
73− createDirectoryIfMissing True assetsDir
74− out_c <- canonicalizePath tempDir -- temp (root folder)
75− elm_c <- canonicalizePath (elm lbi) -- dist/build/elm/elm
76− doc_c <- canonicalizePath (document lbi) -- dist/build/elm-doc/elm-doc
77− rtd_c <- canonicalizePath assetsDir -- data
78−
79− let make file = do
80− let args =
81− [ "--only-js"
82− , "--make"
83− , "--no-prelude"
84− , "--cache-dir=" ++ out_c
85− , "--build-dir=" ++ out_c
86− , file
87− ]
88− let arg = Just [("Elm_datadir", rtd_c)]
89− handle <- runProcess elm_c args Nothing arg Nothing Nothing Nothing
90− _exitCode <- waitForProcess handle
91− return ( out_c </> replaceExtension file "elmo"
92− , out_c </> replaceExtension file "elmi"
93− )
94−
95− setCurrentDirectory "libraries"
96− paths <- getFiles ".elm" "."
97− files <- unzip `fmap` mapM make paths
98− mapM_ (\path -> rawSystem doc_c [path]) paths
99− setCurrentDirectory ".."
100− return files
101−
102−buildInterfaces :: [FilePath] -> IO ()
103−buildInterfaces elmis = do
104− createDirectoryIfMissing True assetsDir
105− ifaceHandle <- openBinaryFile interfaces WriteMode
106− BS.hPut ifaceHandle (Binary.encode (length elmis))
107− let append file = do
108− handle <- openBinaryFile file ReadMode
109− bits <- hGetContents handle
110− length bits `seq` hPutStr ifaceHandle bits
111− hClose handle
112− mapM_ append elmis
113− hClose ifaceHandle
114−
115−buildRuntime :: [FilePath] -> IO ()
116−buildRuntime elmos = do
117− createDirectoryIfMissing True assetsDir
118− writeFile runtime
119− "'use strict';\n\
120− \var Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
121− \var ElmRuntime = {}; ElmRuntime.Render = {};\n"
122− mapM_ (appendTo runtime) =<< getFiles ".js" "libraries"
123− mapM_ (appendTo runtime) elmos
124− mapM_ (appendTo runtime) =<< getFiles ".js" "runtime"
125−
126−buildDocs :: IO ()
127−buildDocs = do
128− createDirectoryIfMissing True assetsDir
129− writeFile docs "[\n"
130− json <- getFiles ".json" ("libraries" </> "docs")
131− let appends = map (appendTo docs) json
132− addCommas = List.intersperse (appendFile docs ",\n")
133− sequence_ (addCommas appends)
134− appendFile docs "\n]"
135−
136−getFiles ext dir = do
137− contents <- map (dir </>) `fmap` getDirectoryContents dir
138− let files = filter (\f -> takeExtension f == ext) contents
139− dirs = filter (not . hasExtension) contents
140− filess <- mapM (getFiles ext) dirs
141− return (files ++ concat filess)
142−
143−appendTo :: FilePath -> FilePath -> IO ()
144−appendTo destination source = do
145− str <- readFile source
146− length str `seq` return ()
147− appendFile destination str