on master help sign in
Get --docs flag working again
10216a8Evan Czaplicki
builder/src/Deps/Verify.hs+4−3
@@ -234,14 +234,15 @@ getIface name version info infos depIfaces =
234 then IO.readBinary (root </> "ifaces.dat")
234 then IO.readBinary (root </> "ifaces.dat")
235 else
235 else
236 do Paths.removeStuff root
236 do Paths.removeStuff root
237+ let docsPath = root </> "docs.json"
237
238
238 let summary = Summary.cheapInit root info infos depIfaces
239 let summary = Summary.cheapInit root info infos depIfaces
239 args <- Args.fromSummary summary
240 args <- Args.fromSummary summary
240 graph <- Crawl.crawl summary args
241 graph <- Crawl.crawl summary args
241− (dirty, cachedIfaces) <- Plan.plan summary graph
242+ (dirty, cachedIfaces) <- Plan.plan (Just docsPath) summary graph
242− answers <- Compile.compile (Pkg info) cachedIfaces dirty
243+ answers <- Compile.compile (Pkg info) (Just docsPath) cachedIfaces dirty
243 results <- Artifacts.ignore answers
244 results <- Artifacts.ignore answers
244− _ <- Artifacts.writeDocs (root </> "docs.json") results
245+ _ <- Artifacts.writeDocs results docsPath
245
246
246 Paths.removeStuff root
247 Paths.removeStuff root
247
248
builder/src/Elm/Project.hs+13−12
@@ -25,7 +25,6 @@ import qualified File.Crawl as Crawl
25import qualified File.Plan as Plan
25import qualified File.Plan as Plan
26import qualified Generate.Output as Output
26import qualified Generate.Output as Output
27import qualified Reporting.Task as Task
27import qualified Reporting.Task as Task
28−import qualified Stuff.Paths as Path
29
28
30
29
31
30
@@ -46,13 +45,14 @@ getRootWithReplFallback =
46-- COMPILE
45-- COMPILE
47
46
48
47
49−compile :: Output.Options -> Summary -> [FilePath] -> Task.Task ()
48+compile :: Output.Options -> Maybe FilePath -> Summary -> [FilePath] -> Task.Task ()
50−compile options summary@(Summary.Summary root project _ _ _) paths =
49+compile options docs summary@(Summary.Summary root project _ _ _) paths =
51 do args <- Args.fromPaths summary paths
50 do args <- Args.fromPaths summary paths
52 graph <- Crawl.crawl summary args
51 graph <- Crawl.crawl summary args
53− (dirty, ifaces) <- Plan.plan summary graph
52+ (dirty, ifaces) <- Plan.plan docs summary graph
54− answers <- Compile.compile project ifaces dirty
53+ answers <- Compile.compile project docs ifaces dirty
55 results <- Artifacts.write root answers
54 results <- Artifacts.write root answers
55+ _ <- traverse (Artifacts.writeDocs results) docs
56 Output.generate options summary graph
56 Output.generate options summary graph
57
57
58
58
@@ -64,9 +64,9 @@ compileForRepl :: BS.ByteString -> Maybe N.Name -> Task.Task (Maybe FilePath)
64compileForRepl source maybeName =
64compileForRepl source maybeName =
65 do summary@(Summary.Summary root project _ _ _) <- getRoot
65 do summary@(Summary.Summary root project _ _ _) <- getRoot
66 graph <- Crawl.crawlFromSource summary source
66 graph <- Crawl.crawlFromSource summary source
67− (dirty, ifaces) <- Plan.plan summary graph
67+ (dirty, ifaces) <- Plan.plan Nothing summary graph
68− answers <- Compile.compile project ifaces dirty
68+ answers <- Compile.compile project Nothing ifaces dirty
69− results <- Artifacts.write root answers
69+ _results <- Artifacts.write root answers
70 traverse (Output.generateReplFile summary graph) maybeName
70 traverse (Output.generateReplFile summary graph) maybeName
71
71
72
72
@@ -76,9 +76,10 @@ compileForRepl source maybeName =
76
76
77generateDocs :: Summary.Summary -> Task.Task Docs.Documentation
77generateDocs :: Summary.Summary -> Task.Task Docs.Documentation
78generateDocs summary@(Summary.Summary root project _ _ _) =
78generateDocs summary@(Summary.Summary root project _ _ _) =
79+ do let docsPath = root </> "docs.json"
79− do args <- Args.fromSummary summary
80+ args <- Args.fromSummary summary
80 graph <- Crawl.crawl summary args
81 graph <- Crawl.crawl summary args
81− (dirty, ifaces) <- Plan.plan summary graph
82+ (dirty, ifaces) <- Plan.plan (Just docsPath) summary graph
82− answers <- Compile.compile project ifaces dirty
83+ answers <- Compile.compile project (Just docsPath) ifaces dirty
83 results <- Artifacts.ignore answers
84 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
14 -- queries
14 -- queries
15 , appSolution
15 , appSolution
16 , isPlatformPackage
16 , isPlatformPackage
17− , isPackageRoot
18 , get
17 , get
19 , getName
18 , getName
20 , getExposed
19 , getExposed
@@ -127,21 +126,6 @@ isPlatformPackage project =
127 user == "elm-lang" || user == "elm-explorations"
126 user == "elm-lang" || user == "elm-explorations"
128
127
129
128
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−
145get :: (AppInfo -> a) -> (PkgInfo -> a) -> Project -> a
129get :: (AppInfo -> a) -> (PkgInfo -> a) -> Project -> a
146get appFunc pkgFunc project =
130get appFunc pkgFunc project =
147 case project of
131 case project of
builder/src/File/Artifacts.hs+2−2
@@ -62,8 +62,8 @@ write root answers =
62 liftIO $ traverse readMVar mvars
62 liftIO $ traverse readMVar mvars
63
63
64
64
65−writeDocs :: FilePath -> Map Module.Raw Compiler.Artifacts -> Task.Task Docs.Documentation
65+writeDocs :: Map Module.Raw Compiler.Artifacts -> FilePath -> Task.Task Docs.Documentation
66−writeDocs path results =
66+writeDocs results path =
67 let
67 let
68 getDocs (Compiler.Artifacts _ _ docs) =
68 getDocs (Compiler.Artifacts _ _ docs) =
69 docs
69 docs
builder/src/File/Compile.hs+39−6
@@ -26,8 +26,8 @@ import qualified Reporting.Task as Task
26-- COMPILE
26-- COMPILE
27
27
28
28
29−compile :: Project -> Module.Interfaces -> Dict Plan.Info -> Task.Task (Dict Answer)
29+compile :: Project -> Maybe FilePath -> Module.Interfaces -> Dict Plan.Info -> Task.Task (Dict Answer)
30−compile project ifaces modules =
30+compile project maybeDocsPath ifaces modules =
31 do Task.report (Progress.CompileStart (Map.size modules))
31 do Task.report (Progress.CompileStart (Map.size modules))
32
32
33 tell <- Task.getReporter
33 tell <- Task.getReporter
@@ -35,7 +35,7 @@ compile project ifaces modules =
35 answers <- liftIO $
35 answers <- liftIO $
36 do mvar <- newEmptyMVar
36 do mvar <- newEmptyMVar
37 iMVar <- newMVar ifaces
37 iMVar <- newMVar ifaces
38− answerMVars <- Map.traverseWithKey (compileModule tell project mvar iMVar) modules
38+ answerMVars <- Map.traverseWithKey (compileModule tell project maybeDocsPath mvar iMVar) modules
39 putMVar mvar answerMVars
39 putMVar mvar answerMVars
40 traverse readMVar answerMVars
40 traverse readMVar answerMVars
41
41
@@ -64,12 +64,13 @@ type Dict a = Map.Map Module.Raw a
64compileModule
64compileModule
65 :: (Progress.Progress -> IO ())
65 :: (Progress.Progress -> IO ())
66 -> Project
66 -> Project
67+ -> Maybe FilePath
67 -> MVar (Dict (MVar Answer))
68 -> MVar (Dict (MVar Answer))
68 -> MVar Module.Interfaces
69 -> MVar Module.Interfaces
69 -> Module.Raw
70 -> Module.Raw
70 -> Plan.Info
71 -> Plan.Info
71 -> IO (MVar Answer)
72 -> IO (MVar Answer)
72−compileModule tell project answersMVar ifacesMVar name info =
73+compileModule tell project maybeDocsPath answersMVar ifacesMVar name info =
73 do mvar <- newEmptyMVar
74 do mvar <- newEmptyMVar
74
75
75 void $ forkIO $
76 void $ forkIO $
@@ -80,10 +81,10 @@ compileModule tell project answersMVar ifacesMVar name info =
80 else
81 else
81 do tell (Progress.CompileFileStart name)
82 do tell (Progress.CompileFileStart name)
82 let pkg = Project.getName project
83 let pkg = Project.getName project
83− let isExposed = Project.isPackageRoot name project
84+ let docs = toDocsFlag name project maybeDocsPath
84 let imports = makeImports project info
85 let imports = makeImports project info
85 ifaces <- readMVar ifacesMVar
86 ifaces <- readMVar ifacesMVar
86− let context = Compiler.Context pkg isExposed imports ifaces
87+ let context = Compiler.Context pkg docs imports ifaces
87 let source = Plan._src info
88 let source = Plan._src info
88 case Compiler.compile context source of
89 case Compiler.compile context source of
89 (_warnings, Left errors) ->
90 (_warnings, Left errors) ->
@@ -103,6 +104,38 @@ compileModule tell project answersMVar ifacesMVar name info =
103
104
104
105
105
106
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+
106-- IMPORTS
139-- IMPORTS
107
140
108
141
builder/src/File/Plan.hs+18−9
@@ -35,11 +35,11 @@ import qualified Stuff.Paths
35type Dict value = Map.Map Module.Raw value
35type Dict value = Map.Map Module.Raw value
36
36
37
37
38−plan :: Summary.Summary -> Crawl.Result -> Task.Task (Dict Info, Module.Interfaces)
38+plan :: Maybe FilePath -> Summary.Summary -> Crawl.Result -> Task.Task (Dict Info, Module.Interfaces)
39−plan (Summary.Summary root project _ ifaces _) (Crawl.Graph _ locals _ foreigns _) =
39+plan docs (Summary.Summary root project _ ifaces _) (Crawl.Graph _ locals _ foreigns _) =
40 liftIO $
40 liftIO $
41 do queue <- newChan
41 do queue <- newChan
42− let env = Env queue root (Project.getName project)
42+ let env = Env queue root (Project.getName project) docs
43
43
44 mvar <- newEmptyMVar
44 mvar <- newEmptyMVar
45 statusMVars <- Map.traverseWithKey (getStatus env mvar foreigns) locals
45 statusMVars <- Map.traverseWithKey (getStatus env mvar foreigns) locals
@@ -57,6 +57,7 @@ data Env =
57 { _queue :: Chan Msg
57 { _queue :: Chan Msg
58 , _root :: FilePath
58 , _root :: FilePath
59 , _pkg :: Pkg.Name
59 , _pkg :: Pkg.Name
60+ , _docs :: Maybe FilePath
60 }
61 }
61
62
62
63
@@ -99,21 +100,29 @@ getStatus env statusMVars foreigns name (Header.Info path time src deps) =
99 info <- foldM (addDep statuses foreigns) (Info path time src [] [] []) deps
100 info <- foldM (addDep statuses foreigns) (Info path time src [] [] []) deps
100
101
101 let elmi = Stuff.Paths.elmi (_root env) name
102 let elmi = Stuff.Paths.elmi (_root env) name
103+ let docs = Stuff.Paths.moduleDocs (_root env) name
102
104
103 case _dirty info of
105 case _dirty info of
104 _ : _ ->
106 _ : _ ->
105 do remove elmi
107 do remove elmi
108+ remove docs
106 return (Just info)
109 return (Just info)
107
110
108 [] ->
111 [] ->
109− do fresh <- isFresh time elmi
112+ do freshElmi <- isFresh time elmi
110− if fresh
113+ freshDocs <-
114+ case _docs env of
115+ Nothing -> return True
116+ Just _ -> isFresh time docs
117+
118+ if freshElmi && freshDocs
111 then
119 then
112 do let canonical = Module.Canonical (_pkg env) name
120 do let canonical = Module.Canonical (_pkg env) name
113 writeChan (_queue env) (Get canonical elmi)
121 writeChan (_queue env) (Get canonical elmi)
114 return Nothing
122 return Nothing
115 else
123 else
116 do remove elmi
124 do remove elmi
125+ remove docs
117 return (Just info)
126 return (Just info)
118
127
119 return mvar
128 return mvar
@@ -145,11 +154,11 @@ addDep locals foreigns info name =
145
154
146
155
147isFresh :: Time.UTCTime -> FilePath -> IO Bool
156isFresh :: Time.UTCTime -> FilePath -> IO Bool
148−isFresh srcTime elmi =
157+isFresh srcTime cachedFile =
149 andM
158 andM
150− [ Dir.doesFileExist elmi
159+ [ Dir.doesFileExist cachedFile
151− , do elmiTime <- Dir.getModificationTime elmi
160+ , do cacheTime <- Dir.getModificationTime cachedFile
152− return (elmiTime >= srcTime)
161+ return (cacheTime >= srcTime)
153 ]
162 ]
154
163
155
164
builder/src/Stuff/Paths.hs+6
@@ -7,6 +7,7 @@ module Stuff.Paths
7 , removeStuff
7 , removeStuff
8 , elmi
8 , elmi
9 , elmo
9 , elmo
10+ , moduleDocs
10 , temp
11 , temp
11 )
12 )
12 where
13 where
@@ -79,6 +80,11 @@ elmo root name =
79 toArtifactPath root name "elmo"
80 toArtifactPath root name "elmo"
80
81
81
82
83+moduleDocs :: FilePath -> Module.Raw -> FilePath
84+moduleDocs root name =
85+ toArtifactPath root name "json"
86+
87+
82toArtifactPath :: FilePath -> Module.Raw -> String -> FilePath
88toArtifactPath :: FilePath -> Module.Raw -> String -> FilePath
83toArtifactPath root name ext =
89toArtifactPath root name ext =
84 root </> stuff </> Module.nameToHyphenPath name <.> ext
90 root </> stuff </> Module.nameToHyphenPath name <.> ext
compiler/src/Elm/Compiler.hs+3−6
@@ -2,6 +2,7 @@
2module Elm.Compiler
2module Elm.Compiler
3 ( version
3 ( version
4 , Context(..)
4 , Context(..)
5+ , Compile.DocsFlag(..)
5 , Compile.Artifacts(..)
6 , Compile.Artifacts(..)
6 , compile
7 , compile
7 , Error.Error
8 , Error.Error
@@ -47,18 +48,14 @@ version =
47data Context =
48data Context =
48 Context
49 Context
49 { _package :: Pkg.Name
50 { _package :: Pkg.Name
50− , _exposed :: Bool
51+ , _docsFlag :: Compile.DocsFlag
51 , _imports :: Map.Map M.Raw M.Canonical
52 , _imports :: Map.Map M.Raw M.Canonical
52 , _interfaces :: M.Interfaces
53 , _interfaces :: M.Interfaces
53 }
54 }
54
55
55
56
56compile :: Context -> BS.ByteString -> ([Warning.Warning], Either [Error.Error] Compile.Artifacts)
57compile :: Context -> BS.ByteString -> ([Warning.Warning], Either [Error.Error] Compile.Artifacts)
57−compile (Context pkg exposed importDict interfaces) source =
58+compile (Context pkg docsFlag importDict interfaces) source =
58− let
59− docsFlag =
60− if exposed then Compile.YesDocs else Compile.NoDocs
61− in
62 Result.run $ Compile.compile docsFlag pkg importDict interfaces source
59 Result.run $ Compile.compile docsFlag pkg importDict interfaces source
63
60
64
61
ui/terminal/src/Develop/StaticFiles/Build.hs+1−1
@@ -40,7 +40,7 @@ compile =
40 reporter <- Terminal.create
40 reporter <- Terminal.create
41 void $ Task.run reporter $
41 void $ Task.run reporter $
42 do summary <- Project.getRoot
42 do summary <- Project.getRoot
43− Project.compile options summary rootPaths
43+ Project.compile options Nothing summary rootPaths
44
44
45 result <- BS.readFile tempFileName
45 result <- BS.readFile tempFileName
46 seq (BS.length result) (Dir.removeFile tempFileName)
46 seq (BS.length result) (Dir.removeFile tempFileName)
ui/terminal/src/Main.hs+1
@@ -176,6 +176,7 @@ make =
176 |-- 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."
176 |-- 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."
177 |-- 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!"
177 |-- 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!"
178 |-- 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!"
178 |-- 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."
179 in
180 in
180 Interface "make" (Common summary) details example (zeroOrMore elmFile) makeFlags Make.run
181 Interface "make" (Common summary) details example (zeroOrMore elmFile) makeFlags Make.run
181
182
ui/terminal/src/Make.hs+21−3
@@ -3,11 +3,13 @@ module Make
3 , run
3 , run
4 , ReportType(..)
4 , ReportType(..)
5 , reportType
5 , reportType
6+ , docsFile
6 )
7 )
7 where
8 where
8
9
9
10
10import Control.Monad (void)
11import Control.Monad (void)
12+import qualified System.FilePath as FP
11
13
12import qualified Elm.Compiler.Objects as Obj
14import qualified Elm.Compiler.Objects as Obj
13import qualified Elm.Project as Project
15import qualified Elm.Project as Project
@@ -15,7 +17,7 @@ import qualified Generate.Output as Output
15import qualified Reporting.Task as Task
17import qualified Reporting.Task as Task
16import qualified Reporting.Progress.Json as Json
18import qualified Reporting.Progress.Json as Json
17import qualified Reporting.Progress.Terminal as Terminal
19import qualified Reporting.Progress.Terminal as Terminal
18−import Terminal.Args (Parser(..))
20+import Terminal.Args (Parser(..), suggestFiles)
19
21
20
22
21
23
@@ -27,11 +29,12 @@ data Flags =
27 { _debug :: Bool
29 { _debug :: Bool
28 , _output :: Maybe Output.Output
30 , _output :: Maybe Output.Output
29 , _report :: Maybe ReportType
31 , _report :: Maybe ReportType
32+ , _docs :: Maybe FilePath
30 }
33 }
31
34
32
35
33run :: [FilePath] -> Flags -> IO ()
36run :: [FilePath] -> Flags -> IO ()
34−run paths (Flags debug output report) =
37+run paths (Flags debug output report docs) =
35 let
38 let
36 mode =
39 mode =
37 if debug then Obj.Debug else Obj.Prod
40 if debug then Obj.Debug else Obj.Prod
@@ -50,7 +53,7 @@ run paths (Flags debug output report) =
50 do reporter <- makeReporter
53 do reporter <- makeReporter
51 void $ Task.run reporter $
54 void $ Task.run reporter $
52 do summary <- Project.getRoot
55 do summary <- Project.getRoot
53− Project.compile outputOptions summary paths
56+ Project.compile outputOptions docs summary paths
54
57
55
58
56
59
@@ -70,3 +73,18 @@ reportType =
70 , _suggest = \_ -> return ["json"]
73 , _suggest = \_ -> return ["json"]
71 , _examples = \_ -> return ["json"]
74 , _examples = \_ -> return ["json"]
72 }
75 }
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+ }