@@ -5,14 +5,14 @@ module Stuff.Verify
55 where
66
77
8−import Prelude hiding (read)
9−import qualified Data.Map as Map
8+import Control.Monad (liftM2, liftM3, liftM4)
9+import Data.Binary
1010import Data.Map (Map)
1111
12+import qualified Elm.Compiler.Module as Module
1213import Elm.Package (Name, Version)
1314
1415import qualified Deps.Verify as Verify
15−import Elm.Project.Json (Project(..), PkgInfo(..))
1616import qualified Elm.Project.Json as Project
1717import qualified Elm.Project.Constraint as Con
1818import qualified Elm.Project.Summary as Summary
@@ -25,72 +25,99 @@ import qualified Stuff.Paths as Path
2525-- VERIFY
2626
2727
28−verify :: FilePath -> Project -> Task.Task Summary.Summary
28+verify :: FilePath -> Project.Project -> Task.Task Summary.Summary
2929verify root project =
30− do fresh <-
31− IO.andM
32− [ IO.exists Path.solution
33− , IO.exists Path.summary
34− , checkSolution project
35− ]
30+ do exists <- IO.exists Path.summary
31+ if exists
32+ then
33+ do (MiniSummary deps exposed ifaces graph) <- IO.readBinary Path.summary
34+ if isValidMiniSummary deps project
35+ then
36+ return (Summary.Summary root project exposed ifaces graph)
37+ else
38+ do IO.remove Path.summary
39+ cacheSummary root project
40+ else
41+ cacheSummary root project
42+
43+
44+cacheSummary :: FilePath -> Project.Project -> Task.Task Summary.Summary
45+cacheSummary root project =
46+ do summary@(Summary.Summary _ _ exposed ifaces graph) <- Verify.verify root project
47+ IO.writeBinary Path.summary (MiniSummary (getDeps project) exposed ifaces graph)
48+ return summary
3649
37− if fresh
38− then read root project
39− else rebuildCache root project
4050
4151
42−rebuildCache :: FilePath -> Project -> Task.Task Summary.Summary
43−rebuildCache root project =
44− do IO.remove Path.solution
45− IO.remove Path.summary
52+-- MINI SUMMARY
4653
47− (solution, summary) <- Verify.verify root project
4854
49− IO.writeBinary Path.solution solution
50− write summary
51− return summary
55+data MiniSummary =
56+ MiniSummary
57+ { _deps :: ProjectDeps
58+ , _exposed :: Summary.ExposedModules
59+ , _ifaces :: Module.Interfaces
60+ , _depsGraph :: Summary.DepsGraph
61+ }
5262
5363
64+data ProjectDeps
65+ = App (Map Name Version) (Map Name Version) (Map Name Version)
66+ | Pkg (Map Name Con.Constraint) (Map Name Con.Constraint)
5467
55−-- READ / WRITE
5668
69+getDeps :: Project.Project -> ProjectDeps
70+getDeps project =
71+ case project of
72+ Project.App (Project.AppInfo _ _ direct test trans) ->
73+ App direct test trans
5774
58−read :: FilePath -> Project -> Task.Task Summary.Summary
59−read root project =
60− do (exposed, ifaces, graph) <- IO.readBinary Path.summary
61− return (Summary.Summary root project exposed ifaces graph)
75+ Project.Pkg (Project.PkgInfo _ _ _ _ _ direct test _) ->
76+ Pkg direct test
6277
6378
64−write :: Summary.Summary -> Task.Task ()
65−write (Summary.Summary _ _ exposed ifaces graph) =
66− IO.writeBinary Path.summary ( exposed, ifaces, graph )
79+isValidMiniSummary :: ProjectDeps -> Project.Project -> Bool
80+isValidMiniSummary deps project =
81+ case deps of
82+ App cachedDirect cachedTest cachedTrans ->
83+ case project of
84+ Project.Pkg _ ->
85+ False
6786
87+ Project.App (Project.AppInfo _ _ direct test trans) ->
88+ cachedDirect == direct
89+ && cachedTest == test
90+ && cachedTrans == trans
6891
92+ Pkg cachedDirect cachedTest ->
93+ case project of
94+ Project.Pkg (Project.PkgInfo _ _ _ _ _ direct test _) ->
95+ cachedDirect == direct
96+ && cachedTest == test
6997
70−-- CHECK SOLUTION
98+ Project.App _ ->
99+ False
71100
72101
73−checkSolution :: Project -> Task.Task Bool
74−checkSolution project =
75− checkSolutionHelp project <$> IO.readBinary Path.solution
76102
103+-- BINARY
77104
78−checkSolutionHelp :: Project -> Map Name Version -> Bool
79−checkSolutionHelp project solution =
80− case project of
81− App info ->
82− solution == Project.appSolution info
83−
84− Pkg info ->
85− allGood (_pkg_test_deps info) solution
86− && allGood (_pkg_deps info) solution
87−
88−
89−allGood :: Map Name Con.Constraint -> Map Name Version -> Bool
90−allGood cons vsns =
91− let
92− bools =
93− Map.intersectionWith Con.satisfies cons vsns
94− in
95− Map.size cons == Map.size bools
96− && Map.foldr (&&) True bools
105+
106+instance Binary MiniSummary where
107+ get = liftM4 MiniSummary get get get get
108+ put (MiniSummary a b c d) = put a >> put b >> put c >> put d
109+
110+
111+
112+instance Binary ProjectDeps where
113+ put deps =
114+ case deps of
115+ App a b c -> putWord8 0 >> put a >> put b >> put c
116+ Pkg a b -> putWord8 1 >> put a >> put b
117+
118+ get =
119+ do n <- getWord8
120+ case n of
121+ 0 -> liftM3 App get get get
122+ 1 -> liftM2 Pkg get get
123+ _ -> error "binary encoding of ProjectDeps was corrupted"