git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Change psci to use the common Make support

Change psci to uses the make code from Language.PureScript.Make. It overrides the progress function to filter out the $PSCI modules, but all other make actions are shared.

commitf7147d29dc997bf9e9219288a4f337822c7f4e3a authorJohn Lenz <lenz@math.uic.edu> dateThu 9 Jul 2015, 17:04 (11 years ago) parent5720107
3 files changed+23−134
psci/Make.hs−127 psci/PSCi.hs+23−6 purescript.cabal−1
psci/Make.hsdeleted−127
@@ -1,127 +0,0 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Make
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−--
13−-----------------------------------------------------------------------------
14−
15−{-# LANGUAGE DataKinds #-}
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17−{-# LANGUAGE TupleSections #-}
18−
19−module Make where
20−
21−import Data.List (isPrefixOf)
22−import Data.Maybe (fromMaybe)
23−import Data.Time.Clock
24−import Data.Traversable (traverse)
25−import qualified Data.Map as M
26−
27−import Control.Applicative
28−import Control.Monad
29−import Control.Monad.Error.Class (MonadError(..))
30−import Control.Monad.IO.Class (MonadIO, liftIO)
31−import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
32−import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
33−import Control.Monad.Writer (MonadWriter, WriterT, runWriterT, tell)
34−
35−import System.Directory (getModificationTime, doesFileExist)
36−import System.FilePath ((</>), pathSeparator)
37−import System.IO.Error (tryIOError)
38−
39−import qualified Language.PureScript as P
40−import qualified Language.PureScript.CodeGen.JS as J
41−import qualified Language.PureScript.CoreFn as CF
42−
43−import IO (mkdirp)
44−
45−options :: P.Options
46−options = P.Options False False Nothing False False False Nothing
47−
48−modulesDir :: FilePath
49−modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
50−
51−newtype Make a = Make { unMake :: ReaderT P.Options (WriterT P.MultipleErrors (ExceptT P.MultipleErrors IO)) a }
52− deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadWriter P.MultipleErrors, MonadReader P.Options)
53−
54−runMake :: Make a -> IO (Either P.MultipleErrors a)
55−runMake = runExceptT . fmap fst . runWriterT . flip runReaderT options . unMake
56−
57−makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
58−makeIO f io = do
59− e <- liftIO $ tryIOError io
60− either (throwError . P.singleError . f) return e
61−
62−-- Traverse (Either e) instance (base 4.7)
63−traverseEither :: Applicative f => (a -> f b) -> Either e a -> f (Either e b)
64−traverseEither _ (Left x) = pure (Left x)
65−traverseEither f (Right y) = Right <$> f y
66−
67−buildMakeActions :: M.Map P.ModuleName (Either P.RebuildPolicy String)
68− -> M.Map P.ModuleName P.ForeignJS
69− -> P.MakeActions Make
70−buildMakeActions filePathMap foreigns =
71− P.MakeActions getInputTimestamp getOutputTimestamp readExterns codegen progress
72− where
73−
74− getInputTimestamp :: P.ModuleName -> Make (Either P.RebuildPolicy (Maybe UTCTime))
75− getInputTimestamp mn = do
76− let path = fromMaybe (error "Module has no filename in 'make'") $ M.lookup mn filePathMap
77− traverseEither getTimestamp path
78−
79− getOutputTimestamp :: P.ModuleName -> Make (Maybe UTCTime)
80− getOutputTimestamp mn = do
81− let filePath = P.runModuleName mn
82− jsFile = modulesDir </> filePath </> "index.js"
83− externsFile = modulesDir </> filePath </> "externs.purs"
84− min <$> getTimestamp jsFile <*> getTimestamp externsFile
85−
86− readExterns :: P.ModuleName -> Make (FilePath, String)
87− readExterns mn = do
88− let path = modulesDir </> P.runModuleName mn </> "externs.purs"
89− (path, ) <$> readTextFile path
90−
91− codegen :: CF.Module CF.Ann -> P.Environment -> P.SupplyVar -> P.Externs -> Make ()
92− codegen m _ nextVar exts = do
93− let mn = CF.moduleName m
94− foreignInclude <- case CF.moduleName m `M.lookup` foreigns of
95− Just path
96− | not $ requiresForeign m -> do tell $ P.errorMessage $ P.UnnecessaryFFIModule mn path
97− return Nothing
98− | otherwise -> return $ Just $ J.JSApp (J.JSVar "require") [J.JSStringLiteral "./foreign"]
99− Nothing | requiresForeign m -> throwError . P.errorMessage $ P.MissingFFIModule mn
100− | otherwise -> return Nothing
101− pjs <- P.evalSupplyT nextVar $ P.prettyPrintJS <$> J.moduleToJs m foreignInclude
102− let filePath = P.runModuleName $ CF.moduleName m
103− jsFile = modulesDir </> filePath </> "index.js"
104− externsFile = modulesDir </> filePath </> "externs.purs"
105− foreignFile = modulesDir </> filePath </> "foreign.js"
106− writeTextFile jsFile pjs
107− maybe (return ()) (writeTextFile foreignFile) $ CF.moduleName m `M.lookup` foreigns
108− writeTextFile externsFile exts
109−
110− requiresForeign :: CF.Module a -> Bool
111− requiresForeign = not . null . CF.moduleForeign
112−
113− getTimestamp :: FilePath -> Make (Maybe UTCTime)
114− getTimestamp path = makeIO (const (P.SimpleErrorWrapper $ P.CannotGetFileInfo path)) $ do
115− exists <- doesFileExist path
116− traverse (const $ getModificationTime path) $ guard exists
117−
118− readTextFile :: FilePath -> Make String
119− readTextFile path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ readFile path
120−
121− writeTextFile :: FilePath -> String -> Make ()
122− writeTextFile path text = makeIO (const (P.SimpleErrorWrapper $ P.CannotWriteFile path)) $ do
123− mkdirp path
124− writeFile path text
125−
126− progress :: String -> Make ()
127− progress s = unless ("Compiling $PSCI" `isPrefixOf` s) $ liftIO . putStrLn $ s
psci/PSCi.hs+23−6
@@ -21,7 +21,7 @@
2121module PSCi where
2222
2323import Data.Foldable (traverse_)
24−import Data.List (intercalate, nub, sort)
24+import Data.List (intercalate, nub, sort, isPrefixOf)
2525import Data.Traversable (traverse)
2626import Data.Tuple (swap)
2727import Data.Version (showVersion)
@@ -30,10 +30,12 @@ import qualified Data.Map as M
3030import Control.Applicative
3131import Control.Arrow (first)
3232import Control.Monad
33+import Control.Monad.Error.Class (MonadError(..))
3334import Control.Monad.Trans.Class
3435import Control.Monad.Trans.Except (runExceptT)
3536import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
3637import Control.Monad.Trans.State.Strict
38+import Control.Monad.IO.Class (liftIO)
3739import Control.Monad.Writer (runWriter)
3840import qualified Control.Monad.Trans.State.Lazy as L
3941
@@ -45,6 +47,7 @@ import System.Exit
4547import System.FilePath (pathSeparator, (</>), isPathSeparator)
4648import System.FilePath.Glob (glob)
4749import System.Process (readProcessWithExitCode)
50+import System.IO.Error (tryIOError)
4851
4952import qualified Language.PureScript as P
5053import qualified Language.PureScript.Names as N
@@ -53,7 +56,6 @@ import qualified Paths_purescript as Paths
5356import qualified Directive as D
5457import Completion (completion)
5558import IO (mkdirp)
56−import Make
5759import Parser (parseCommand)
5860import Types
5961
@@ -240,10 +242,25 @@ importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ
240242indexFile :: FilePath
241243indexFile = ".psci_modules" ++ pathSeparator : "index.js"
242244
243−make :: PSCiState -> [(Either P.RebuildPolicy FilePath, P.Module)] -> Make P.Environment
244−make PSCiState{..} ms =
245− let filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
246− in P.make (buildMakeActions filePathMap (M.map snd psciForeignFiles)) (psciLoadedModules ++ ms)
245+modulesDir :: FilePath
246+modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
247+
248+-- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the
249+-- options and ignores the warning messages.
250+runMake :: P.Make a -> IO (Either P.MultipleErrors a)
251+runMake mk = fmap (fmap fst) $ P.runMake (P.Options False False Nothing False False False Nothing) mk
252+
253+makeIO :: (IOError -> P.ErrorMessage) -> IO a -> P.Make a
254+makeIO f io = do
255+ e <- liftIO $ tryIOError io
256+ either (throwError . P.singleError . f) return e
257+
258+make :: PSCiState -> [(Either P.RebuildPolicy FilePath, P.Module)] -> P.Make P.Environment
259+make PSCiState{..} ms = P.make actions' (psciLoadedModules ++ ms)
260+ where
261+ filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
262+ actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
263+ actions' = actions { P.progress = \s -> unless ("Compiling $PSCI" `isPrefixOf` s) $ liftIO . putStrLn $ s }
247264
248265-- |
249266-- Takes a value declaration and evaluates it with the current state.
purescript.cabal−1
@@ -172,7 +172,6 @@ executable psci
172172 Directive
173173 Completion
174174 PSCi
175− Make
176175 IO
177176 ghc-options: -Wall -O2
178177