@@ -7,6 +7,7 @@ import System.Cmd
7import System.Directory
7import System.Directory
8import System.FilePath
8import System.FilePath
9import System.IO
9import System.IO
11import Control.Monad
12import Control.Monad
@@ -29,6 +30,7 @@ import Control.Monad
29-- Assumptions
30-- Assumptions
30-- Elm.cabal expects the generated files to end up in dist/data
31-- Elm.cabal expects the generated files to end up in dist/data
31rtsDir lbi = (buildDir lbi) </> ".." </> "data" -- git won't look in dist + cabal will clean it
32rtsDir lbi = (buildDir lbi) </> ".." </> "data" -- git won't look in dist + cabal will clean it
33+jsDir lbi = (buildDir lbi) </> ".." </> "js"
33-- The runtime is called:
35-- The runtime is called:
34rts lbi = (rtsDir lbi) </> "elm-runtime.js"
36rts lbi = (rtsDir lbi) </> "elm-runtime.js"
@@ -44,13 +46,6 @@ types lbi = (rtsDir lbi) </> "docs.json"
44-- buildDir with LocalBuildInfo points to "dist/build" (usually)
46-- buildDir with LocalBuildInfo points to "dist/build" (usually)
45elm lbi = (buildDir lbi) </> "elm" </> "elm"
47elm lbi = (buildDir lbi) </> "elm" </> "elm"
47−-- "touch" is available as a system command.
48−-- There is no portable file touch (unix-compat might work but leads to cabal library dependency
49−-- issues: see: http://hackage.haskell.org/trac/summer-of-code/ticket/1602 )
50−-- Files that need recompilation after docs.json is updated
51−-- (Would be nice if this list was in the cabal file, but can't see any way to do that)
52−docTouches = ["compiler" </> "Model" </> "LoadLibraries.hs"]
54-- Care! This appears to be based on an unstable API
49-- Care! This appears to be based on an unstable API
55-- See: http://www.haskell.org/cabal/release/cabal-latest/doc/API/Cabal/Distribution-Simple.html#2
50-- See: http://www.haskell.org/cabal/release/cabal-latest/doc/API/Cabal/Distribution-Simple.html#2
@@ -67,11 +62,17 @@ myBuild pd lbi uh bf = do
67 withExe pd (\x -> putStrLn (exeName x))
62 withExe pd (\x -> putStrLn (exeName x))
68 buildHook simpleUserHooks (filterExe elmDoc pd) (filterLBI elmDoc lbi) uh bf
63 buildHook simpleUserHooks (filterExe elmDoc pd) (filterLBI elmDoc lbi) uh bf
69 putStrLn "Custom build step started: build docs.json"
64 putStrLn "Custom build step started: build docs.json"
70− buildTypes lbi
65+ buildTypes lbi -- see note(1) below
71− forM_ docTouches (\s -> system ("touch " ++ s)) -- NB non-portable
72 putStrLn "Custom build step started: compile everything"
66 putStrLn "Custom build step started: compile everything"
73 buildHook simpleUserHooks pd lbi uh bf
67 buildHook simpleUserHooks pd lbi uh bf
69+-- note(1): We use to include docs.json directly into LoadLibraries at compile time
70+-- If docs.json is used in other (template) haskell files, they should be copied
71+-- and compiled in a separate directory (eg, dist/copiedSrc).
72+-- This is to make sure they are re-compiled on docs.json changes.
73+-- Copying is a better solution than 'touch'ing the source files
74+-- (touch is non-portable and confusing wrt RCS).
75-- In the PackageDescription, the list of stuff to build is held in library (in a Maybe)
76-- In the PackageDescription, the list of stuff to build is held in library (in a Maybe)
76-- and the executables list. We want a PackageDescription that only mentions the executable 'name'
77-- and the executables list. We want a PackageDescription that only mentions the executable 'name'
77filterExe name pd = pd {
78filterExe name pd = pd {
@@ -116,10 +117,25 @@ appendJS lbi file = do
116 appendFile (rts lbi) str
117 appendFile (rts lbi) str
118appendElm lbi file = do
119appendElm lbi file = do
119− system (elm lbi ++ " --only-js " ++ file)
120+ jsFile <- runElm lbi file
120− let jsFile = replaceExtension file ".js"
121 appendJS lbi jsFile
121 appendJS lbi jsFile
122− removeFile jsFile
122+
123+-- replace 'system' call with 'runProcess' which handles args better and allows env variable
124+-- "Elm_datadir" which is used by LoadLibraries to find docs.json
125+runElm :: LocalBuildInfo -> String -> IO FilePath
127+ rts_c <- canonicalizePath (rts lbi) -- dist/data/elm-runtime.js
128+ let js = jsDir lbi -- dist/js
129+ let j = dropFileName (js </> file) -- dist/js/libraries/
130+ createDirectoryIfMissing True j -- must do before any canonicalization
131+ out_c <- canonicalizePath js -- dist/js (root folder)
132+ elm_c <- canonicalizePath (elm lbi) -- dist/build/elm/elm
133+ rtd_c <- canonicalizePath (rtsDir lbi) -- dist/data (for docs.json)
134+ handle <- runProcess elm_c ["--only-js", "--runtime="++rts_c, "--output-directory="++out_c, file]
135+ Nothing (Just [("Elm_datadir", rtd_c)]) Nothing Nothing Nothing
136+ waitForProcess handle
137+ return $ j </> replaceExtension (takeFileName file) ".js"
124buildRuntime lbi = do
140buildRuntime lbi = do
125 createDirectoryIfMissing False (rtsDir lbi) -- dist should already exist
141 createDirectoryIfMissing False (rtsDir lbi) -- dist should already exist