on master help sign in
Get --docs flag working again

Also resolves issue that “elm publish” may not have complete documentation by having the elm-stuff/Module-Name.json files for partially generated docs. That allows me to figure out if adding the --docs flag requires a recompile of older files.

commit10216a89bbb72dda615a2f2746e4ab81cabac2b8 authorEvan Czaplicki <evancz@users.noreply.github.com> dateThu 29 Mar 2018, 14:09 (9 years ago) parent0845251
11 files changed+108−58
builder/src/Deps/Verify.hs+4−3 builder/src/Elm/Project.hs+13−12 builder/src/Elm/Project/Json.hs−16 builder/src/File/Artifacts.hs+2−2 builder/src/File/Compile.hs+39−6 builder/src/File/Plan.hs+18−9 builder/src/Stuff/Paths.hs+6 compiler/src/Elm/Compiler.hs+3−6 ui/terminal/src/Develop/StaticFiles/Build.hs+1−1 ui/terminal/src/Main.hs+1 ui/terminal/src/Make.hs+21−3
builder/src/Deps/Verify.hs+4−3
@@ -234,14 +234,15 @@ getIface name version info infos depIfaces =
234234 then IO.readBinary (root </> "ifaces.dat")
235235 else
236236 do Paths.removeStuff root
237+ let docsPath = root </> "docs.json"
237238
238239 let summary = Summary.cheapInit root info infos depIfaces
239240 args <- Args.fromSummary summary
240241 graph <- Crawl.crawl summary args
241− (dirty, cachedIfaces) <- Plan.plan summary graph
242− answers <- Compile.compile (Pkg info) cachedIfaces dirty
242+ (dirty, cachedIfaces) <- Plan.plan (Just docsPath) summary graph
243+ answers <- Compile.compile (Pkg info) (Just docsPath) cachedIfaces dirty
243244 results <- Artifacts.ignore answers
244− _ <- Artifacts.writeDocs (root </> "docs.json") results
245+ _ <- Artifacts.writeDocs results docsPath
245246
246247 Paths.removeStuff root
247248
builder/src/Elm/Project.hs+13−12
@@ -25,7 +25,6 @@ import qualified File.Crawl as Crawl
2525import qualified File.Plan as Plan
2626import qualified Generate.Output as Output
2727import qualified Reporting.Task as Task
28−import qualified Stuff.Paths as Path
2928
3029
3130
@@ -46,13 +45,14 @@ getRootWithReplFallback =
4645-- COMPILE
4746
4847
49−compile :: Output.Options -> Summary -> [FilePath] -> Task.Task ()
50−compile options summary@(Summary.Summary root project _ _ _) paths =
48+compile :: Output.Options -> Maybe FilePath -> Summary -> [FilePath] -> Task.Task ()
49+compile options docs summary@(Summary.Summary root project _ _ _) paths =
5150 do args <- Args.fromPaths summary paths
5251 graph <- Crawl.crawl summary args
53− (dirty, ifaces) <- Plan.plan summary graph
54− answers <- Compile.compile project ifaces dirty
52+ (dirty, ifaces) <- Plan.plan docs summary graph
53+ answers <- Compile.compile project docs ifaces dirty
5554 results <- Artifacts.write root answers
55+ _ <- traverse (Artifacts.writeDocs results) docs
5656 Output.generate options summary graph
5757
5858
@@ -64,9 +64,9 @@ compileForRepl :: BS.ByteString -> Maybe N.Name -> Task.Task (Maybe FilePath)
6464compileForRepl source maybeName =
6565 do summary@(Summary.Summary root project _ _ _) <- getRoot
6666 graph <- Crawl.crawlFromSource summary source
67− (dirty, ifaces) <- Plan.plan summary graph
68− answers <- Compile.compile project ifaces dirty
69− results <- Artifacts.write root answers
67+ (dirty, ifaces) <- Plan.plan Nothing summary graph
68+ answers <- Compile.compile project Nothing ifaces dirty
69+ _results <- Artifacts.write root answers
7070 traverse (Output.generateReplFile summary graph) maybeName
7171
7272
@@ -76,9 +76,10 @@ compileForRepl source maybeName =
7676
7777generateDocs :: Summary.Summary -> Task.Task Docs.Documentation
7878generateDocs summary@(Summary.Summary root project _ _ _) =
79− do args <- Args.fromSummary summary
79+ do let docsPath = root </> "docs.json"
80+ args <- Args.fromSummary summary
8081 graph <- Crawl.crawl summary args
81− (dirty, ifaces) <- Plan.plan summary graph
82− answers <- Compile.compile project ifaces dirty
82+ (dirty, ifaces) <- Plan.plan (Just docsPath) summary graph
83+ answers <- Compile.compile project (Just docsPath) ifaces dirty
8384 results <- Artifacts.ignore answers
84− Artifacts.writeDocs (root </> Path.docs) results
85+ Artifacts.writeDocs results docsPath
builder/src/Elm/Project/Json.hs−16
@@ -14,7 +14,6 @@ module Elm.Project.Json
1414 -- queries
1515 , appSolution
1616 , isPlatformPackage
17− , isPackageRoot
1817 , get
1918 , getName
2019 , getExposed
@@ -127,21 +126,6 @@ isPlatformPackage project =
127126 user == "elm-lang" || user == "elm-explorations"
128127
129128
130−isPackageRoot :: Module.Raw -> Project -> Bool
131−isPackageRoot name project =
132− case project of
133− App _ ->
134− False
135−
136− Pkg info ->
137− case _pkg_exposed info of
138− ExposedList modules ->
139− elem name modules
140−
141− ExposedDict chunks ->
142− elem name (concatMap snd chunks)
143−
144−
145129get :: (AppInfo -> a) -> (PkgInfo -> a) -> Project -> a
146130get appFunc pkgFunc project =
147131 case project of
builder/src/File/Artifacts.hs+2−2
@@ -62,8 +62,8 @@ write root answers =
6262 liftIO $ traverse readMVar mvars
6363
6464
65−writeDocs :: FilePath -> Map Module.Raw Compiler.Artifacts -> Task.Task Docs.Documentation
66−writeDocs path results =
65+writeDocs :: Map Module.Raw Compiler.Artifacts -> FilePath -> Task.Task Docs.Documentation
66+writeDocs results path =
6767 let
6868 getDocs (Compiler.Artifacts _ _ docs) =
6969 docs
builder/src/File/Compile.hs+39−6
@@ -26,8 +26,8 @@ import qualified Reporting.Task as Task
2626-- COMPILE
2727
2828
29−compile :: Project -> Module.Interfaces -> Dict Plan.Info -> Task.Task (Dict Answer)
30−compile project ifaces modules =
29+compile :: Project -> Maybe FilePath -> Module.Interfaces -> Dict Plan.Info -> Task.Task (Dict Answer)
30+compile project maybeDocsPath ifaces modules =
3131 do Task.report (Progress.CompileStart (Map.size modules))
3232
3333 tell <- Task.getReporter
@@ -35,7 +35,7 @@ compile project ifaces modules =
3535 answers <- liftIO $
3636 do mvar <- newEmptyMVar
3737 iMVar <- newMVar ifaces
38− answerMVars <- Map.traverseWithKey (compileModule tell project mvar iMVar) modules
38+ answerMVars <- Map.traverseWithKey (compileModule tell project maybeDocsPath mvar iMVar) modules
3939 putMVar mvar answerMVars
4040 traverse readMVar answerMVars
4141
@@ -64,12 +64,13 @@ type Dict a = Map.Map Module.Raw a
6464compileModule
6565 :: (Progress.Progress -> IO ())
6666 -> Project
67+ -> Maybe FilePath
6768 -> MVar (Dict (MVar Answer))
6869 -> MVar Module.Interfaces
6970 -> Module.Raw
7071 -> Plan.Info
7172 -> IO (MVar Answer)
72−compileModule tell project answersMVar ifacesMVar name info =
73+compileModule tell project maybeDocsPath answersMVar ifacesMVar name info =
7374 do mvar <- newEmptyMVar
7475
7576 void $ forkIO $
@@ -80,10 +81,10 @@ compileModule tell project answersMVar ifacesMVar name info =
8081 else
8182 do tell (Progress.CompileFileStart name)
8283 let pkg = Project.getName project
83− let isExposed = Project.isPackageRoot name project
84+ let docs = toDocsFlag name project maybeDocsPath
8485 let imports = makeImports project info
8586 ifaces <- readMVar ifacesMVar
86− let context = Compiler.Context pkg isExposed imports ifaces
87+ let context = Compiler.Context pkg docs imports ifaces
8788 let source = Plan._src info
8889 case Compiler.compile context source of
8990 (_warnings, Left errors) ->
@@ -103,6 +104,38 @@ compileModule tell project answersMVar ifacesMVar name info =
103104
104105
105106
107+-- TO DOCS FLAG
108+
109+
110+toDocsFlag :: Module.Raw -> Project -> Maybe FilePath -> Compiler.DocsFlag
111+toDocsFlag name project maybeDocsPath =
112+ case maybeDocsPath of
113+ Nothing ->
114+ Compiler.NoDocs
115+
116+ Just _ ->
117+ case project of
118+ Project.App _ ->
119+ Compiler.NoDocs
120+
121+ Project.Pkg info ->
122+ if isExposed name (Project._pkg_exposed info) then
123+ Compiler.YesDocs
124+ else
125+ Compiler.NoDocs
126+
127+
128+isExposed :: Module.Raw -> Project.Exposed -> Bool
129+isExposed name exposed =
130+ case exposed of
131+ Project.ExposedList modules ->
132+ elem name modules
133+
134+ Project.ExposedDict chunks ->
135+ elem name (concatMap snd chunks)
136+
137+
138+
106139-- IMPORTS
107140
108141
builder/src/File/Plan.hs+18−9
@@ -35,11 +35,11 @@ import qualified Stuff.Paths
3535type Dict value = Map.Map Module.Raw value
3636
3737
38−plan :: Summary.Summary -> Crawl.Result -> Task.Task (Dict Info, Module.Interfaces)
39−plan (Summary.Summary root project _ ifaces _) (Crawl.Graph _ locals _ foreigns _) =
38+plan :: Maybe FilePath -> Summary.Summary -> Crawl.Result -> Task.Task (Dict Info, Module.Interfaces)
39+plan docs (Summary.Summary root project _ ifaces _) (Crawl.Graph _ locals _ foreigns _) =
4040 liftIO $
4141 do queue <- newChan
42− let env = Env queue root (Project.getName project)
42+ let env = Env queue root (Project.getName project) docs
4343
4444 mvar <- newEmptyMVar
4545 statusMVars <- Map.traverseWithKey (getStatus env mvar foreigns) locals
@@ -57,6 +57,7 @@ data Env =
5757 { _queue :: Chan Msg
5858 , _root :: FilePath
5959 , _pkg :: Pkg.Name
60+ , _docs :: Maybe FilePath
6061 }
6162
6263
@@ -99,21 +100,29 @@ getStatus env statusMVars foreigns name (Header.Info path time src deps) =
99100 info <- foldM (addDep statuses foreigns) (Info path time src [] [] []) deps
100101
101102 let elmi = Stuff.Paths.elmi (_root env) name
103+ let docs = Stuff.Paths.moduleDocs (_root env) name
102104
103105 case _dirty info of
104106 _ : _ ->
105107 do remove elmi
108+ remove docs
106109 return (Just info)
107110
108111 [] ->
109− do fresh <- isFresh time elmi
110− if fresh
112+ do freshElmi <- isFresh time elmi
113+ freshDocs <-
114+ case _docs env of
115+ Nothing -> return True
116+ Just _ -> isFresh time docs
117+
118+ if freshElmi && freshDocs
111119 then
112120 do let canonical = Module.Canonical (_pkg env) name
113121 writeChan (_queue env) (Get canonical elmi)
114122 return Nothing
115123 else
116124 do remove elmi
125+ remove docs
117126 return (Just info)
118127
119128 return mvar
@@ -145,11 +154,11 @@ addDep locals foreigns info name =
145154
146155
147156isFresh :: Time.UTCTime -> FilePath -> IO Bool
148−isFresh srcTime elmi =
157+isFresh srcTime cachedFile =
149158 andM
150− [ Dir.doesFileExist elmi
151− , do elmiTime <- Dir.getModificationTime elmi
152− return (elmiTime >= srcTime)
159+ [ Dir.doesFileExist cachedFile
160+ , do cacheTime <- Dir.getModificationTime cachedFile
161+ return (cacheTime >= srcTime)
153162 ]
154163
155164
builder/src/Stuff/Paths.hs+6
@@ -7,6 +7,7 @@ module Stuff.Paths
77 , removeStuff
88 , elmi
99 , elmo
10+ , moduleDocs
1011 , temp
1112 )
1213 where
@@ -79,6 +80,11 @@ elmo root name =
7980 toArtifactPath root name "elmo"
8081
8182
83+moduleDocs :: FilePath -> Module.Raw -> FilePath
84+moduleDocs root name =
85+ toArtifactPath root name "json"
86+
87+
8288toArtifactPath :: FilePath -> Module.Raw -> String -> FilePath
8389toArtifactPath root name ext =
8490 root </> stuff </> Module.nameToHyphenPath name <.> ext
compiler/src/Elm/Compiler.hs+3−6
@@ -2,6 +2,7 @@
22module Elm.Compiler
33 ( version
44 , Context(..)
5+ , Compile.DocsFlag(..)
56 , Compile.Artifacts(..)
67 , compile
78 , Error.Error
@@ -47,18 +48,14 @@ version =
4748data Context =
4849 Context
4950 { _package :: Pkg.Name
50− , _exposed :: Bool
51+ , _docsFlag :: Compile.DocsFlag
5152 , _imports :: Map.Map M.Raw M.Canonical
5253 , _interfaces :: M.Interfaces
5354 }
5455
5556
5657compile :: Context -> BS.ByteString -> ([Warning.Warning], Either [Error.Error] Compile.Artifacts)
57−compile (Context pkg exposed importDict interfaces) source =
58− let
59− docsFlag =
60− if exposed then Compile.YesDocs else Compile.NoDocs
61− in
58+compile (Context pkg docsFlag importDict interfaces) source =
6259 Result.run $ Compile.compile docsFlag pkg importDict interfaces source
6360
6461
ui/terminal/src/Develop/StaticFiles/Build.hs+1−1
@@ -40,7 +40,7 @@ compile =
4040 reporter <- Terminal.create
4141 void $ Task.run reporter $
4242 do summary <- Project.getRoot
43− Project.compile options summary rootPaths
43+ Project.compile options Nothing summary rootPaths
4444
4545 result <- BS.readFile tempFileName
4646 seq (BS.length result) (Dir.removeFile tempFileName)
ui/terminal/src/Main.hs+1
@@ -176,6 +176,7 @@ make =
176176 |-- onOff "debug" "Turn on debug mode. This allows you to (1) use functions like Debug.log and Debug.crash and (2) use the interactive debugger to rewind your programs."
177177 |-- flag "output" Output.output "Specify the name of the resulting JS file. For example --output=assets/elm.js to generate the JS at assets/elm.js or --output=/dev/null to generate no output at all!"
178178 |-- flag "report" Make.reportType "You can say --report=json to get error messages as JSON. This is only really useful if you are an editor plugin. Humans should avoid it!"
179+ |-- flag "docs" Make.docsFile "Generate a JSON file of documentation for your project. Eventually it will be possible to preview docs with `reactor` because it is quite hard to deal with these JSON files directly."
179180 in
180181 Interface "make" (Common summary) details example (zeroOrMore elmFile) makeFlags Make.run
181182
ui/terminal/src/Make.hs+21−3
@@ -3,11 +3,13 @@ module Make
33 , run
44 , ReportType(..)
55 , reportType
6+ , docsFile
67 )
78 where
89
910
1011import Control.Monad (void)
12+import qualified System.FilePath as FP
1113
1214import qualified Elm.Compiler.Objects as Obj
1315import qualified Elm.Project as Project
@@ -15,7 +17,7 @@ import qualified Generate.Output as Output
1517import qualified Reporting.Task as Task
1618import qualified Reporting.Progress.Json as Json
1719import qualified Reporting.Progress.Terminal as Terminal
18−import Terminal.Args (Parser(..))
20+import Terminal.Args (Parser(..), suggestFiles)
1921
2022
2123
@@ -27,11 +29,12 @@ data Flags =
2729 { _debug :: Bool
2830 , _output :: Maybe Output.Output
2931 , _report :: Maybe ReportType
32+ , _docs :: Maybe FilePath
3033 }
3134
3235
3336run :: [FilePath] -> Flags -> IO ()
34−run paths (Flags debug output report) =
37+run paths (Flags debug output report docs) =
3538 let
3639 mode =
3740 if debug then Obj.Debug else Obj.Prod
@@ -50,7 +53,7 @@ run paths (Flags debug output report) =
5053 do reporter <- makeReporter
5154 void $ Task.run reporter $
5255 do summary <- Project.getRoot
53− Project.compile outputOptions summary paths
56+ Project.compile outputOptions docs summary paths
5457
5558
5659
@@ -70,3 +73,18 @@ reportType =
7073 , _suggest = \_ -> return ["json"]
7174 , _examples = \_ -> return ["json"]
7275 }
76+
77+
78+
79+-- DOCS
80+
81+
82+docsFile :: Parser FilePath
83+docsFile =
84+ Parser
85+ { _singular = "json file"
86+ , _plural = "json files"
87+ , _parser = \string -> if FP.takeExtension string == ".json" then Just string else Nothing
88+ , _suggest = suggestFiles ["json"]
89+ , _examples = \_ -> return ["docs.json","documentation.json"]
90+ }