@@ -51,15 +51,13 @@ import Docs.Search.Types (PartId)
51
51
import Effect (Effect )
52
52
import Effect.Aff (Aff , parallel , sequential )
53
53
import Effect.Class (liftEffect )
54
- import Effect.Console (log )
55
54
import JSON (JSON )
56
55
import JSON as JSON
57
56
import Node.Encoding (Encoding (UTF8))
58
57
import Node.FS.Aff (mkdir , readFile , readTextFile , readdir , stat , writeFile , writeTextFile )
59
58
import Node.FS.Stats (isDirectory , isFile )
60
59
import Node.FS.Sync (exists )
61
60
import Node.Path as Path
62
- import Node.Process as Process
63
61
import Registry.Manifest (Manifest (..))
64
62
import Registry.Manifest as Manifest
65
63
import Registry.PackageName (PackageName )
@@ -72,15 +70,16 @@ type Config =
72
70
, generatedDocs :: String
73
71
, workspacePackages :: Set PackageName
74
72
, moduleGraph :: Graph.ModuleGraphWithPackage
73
+ , log :: String -> Aff Unit
74
+ , die :: String -> Aff Unit
75
75
}
76
76
77
77
run :: Config -> Aff Unit
78
- run cfg = do
78
+ run cfg@{ log } = do
79
79
80
80
checkDirectories cfg
81
81
82
- liftEffect do
83
- log " Building the search index..."
82
+ log " Building the search index..."
84
83
85
84
docsJsons /\ packageMetas <- sequential $
86
85
Tuple
@@ -91,13 +90,12 @@ run cfg = do
91
90
countOfPackages = Array .length packageMetas
92
91
countOfModules = Array .length docsJsons
93
92
94
- liftEffect do
95
- log $
96
- " Indexing "
97
- <> show countOfModules
98
- <> " modules from "
99
- <> show countOfPackages
100
- <> " packages..."
93
+ log $
94
+ " Indexing "
95
+ <> show countOfModules
96
+ <> " modules from "
97
+ <> show countOfPackages
98
+ <> " packages..."
101
99
102
100
let
103
101
scores = mkScores packageMetas
@@ -108,32 +106,28 @@ run cfg = do
108
106
109
107
createDirectories cfg
110
108
111
- void $ sequential do
112
- ignore <$> parallel (writeIndex cfg index)
113
- < *> parallel (writeTypeIndex typeIndex)
114
- < *> parallel (writePackageInfo packageInfo)
115
- < *> parallel (writeModuleIndex moduleIndex)
116
- < *> parallel (patchDocs cfg)
117
- < *> parallel (copyAppFile cfg)
109
+ sequential $
110
+ parallel (writeIndex cfg index)
111
+ *> parallel (writeTypeIndex typeIndex)
112
+ *> parallel (writePackageInfo packageInfo)
113
+ *> parallel (writeModuleIndex moduleIndex)
114
+ *> parallel (patchDocs cfg)
115
+ *> parallel (copyAppFile cfg)
118
116
119
117
let
120
118
countOfDefinitions = Trie .size $ unwrap index
121
119
countOfTypeDefinitions =
122
120
sum $ fromMaybe 0 <$> map Array .length <$> Map .values (unwrap typeIndex)
123
121
124
- liftEffect do
125
- log $
126
- " Added "
127
- <> show countOfDefinitions
128
- <> " definitions and "
129
- <> show countOfTypeDefinitions
130
- <> " type definitions from "
131
- <> show countOfPackages
132
- <>
133
- " packages to the search index."
134
-
135
- where
136
- ignore _ _ _ _ _ _ _ = unit
122
+ log $
123
+ " Added "
124
+ <> show countOfDefinitions
125
+ <> " definitions and "
126
+ <> show countOfTypeDefinitions
127
+ <> " type definitions from "
128
+ <> show countOfPackages
129
+ <>
130
+ " packages to the search index."
137
131
138
132
-- | Exit early if something is missing.
139
133
checkDirectories :: Config -> Aff Unit
@@ -147,23 +141,20 @@ checkDirectories cfg = do
147
141
148
142
for_ dirs \dir -> do
149
143
whenM (not <$> directoryExists dir) $
150
- liftEffect do
151
- logAndExit " Build the documentation first!"
144
+ cfg.die " Build the documentation first!"
152
145
153
146
-- | Read and decode given `docs.json` files.
154
147
decodeDocsJsons
155
- :: forall rest
156
- . { docsFiles :: Array String | rest }
148
+ :: ∀ rest
149
+ . { docsFiles :: Array String , log :: String -> Aff Unit , die :: String -> Aff Unit | rest }
157
150
-> Aff (Array DocModule )
158
- decodeDocsJsons cfg@{ docsFiles } = do
151
+ decodeDocsJsons cfg@{ docsFiles, log } = do
159
152
160
153
paths <- getPathsByGlobs docsFiles
161
154
162
155
when (Array .null paths) do
163
- liftEffect do
164
- logAndExit $
165
- " The following globs do not match any files: " <> showGlobs cfg.docsFiles <>
166
- " .\n Build the documentation first!"
156
+ cfg.die $
157
+ " The following globs do not match any files: " <> showGlobs cfg.docsFiles <> " .\n Build the documentation first!"
167
158
168
159
docsJsons <- Array .catMaybes <$> for paths \jsonFile -> do
169
160
doesExist <- fileExists jsonFile
@@ -179,38 +170,36 @@ decodeDocsJsons cfg@{ docsFiles } = do
179
170
180
171
case eiResult of
181
172
Left error -> do
182
- liftEffect $ log $
183
- " \" docs.json\" decoding failed failed for " <> jsonFile <> " : " <> error
173
+ log $ " \" docs.json\" decoding failed failed for " <> jsonFile <> " : " <> error
184
174
pure Nothing
185
175
Right result -> pure $ Just result
186
176
187
177
else do
188
- liftEffect $ do
189
- log $
190
- " File does not exist: " <> jsonFile
178
+ log $ " File does not exist: " <> jsonFile
191
179
pure Nothing
192
180
193
181
when (Array .null docsJsons) do
194
- liftEffect $ logAndExit $
182
+ cfg.die $
195
183
" Couldn't decode any of the files matched by the following globs: " <> showGlobs cfg.docsFiles
196
184
197
185
pure docsJsons
198
186
199
- decodePursJsons :: forall rest . { pursJsonFiles :: Array String | rest } -> Aff (Array Manifest )
200
- decodePursJsons { pursJsonFiles } = do
187
+ decodePursJsons
188
+ :: ∀ rest
189
+ . { pursJsonFiles :: Array String , log :: String -> Aff Unit , die :: String -> Aff Unit | rest }
190
+ -> Aff (Array Manifest )
191
+ decodePursJsons cfg@{ pursJsonFiles } = do
201
192
paths <- getPathsByGlobs pursJsonFiles
202
193
203
194
when (Array .null paths) do
204
- liftEffect do
205
- logAndExit $
206
- " The following globs do not match any files: " <> showGlobs pursJsonFiles <>
207
- " .\n Are you in a project directory?"
208
-
195
+ cfg.die $
196
+ " The following globs do not match any files: " <> showGlobs pursJsonFiles <>
197
+ " .\n Are you in a project directory?"
209
198
Array .nubBy compareNames
210
199
<$> Array .catMaybes
211
200
<$>
212
201
for paths \jsonFileName ->
213
- join <$> withExisting jsonFileName
202
+ join <$> withExisting cfg jsonFileName
214
203
\contents ->
215
204
either (logError jsonFileName) (pure <<< Just )
216
205
( JSON .parse contents >>=
@@ -224,24 +213,23 @@ decodePursJsons { pursJsonFiles } = do
224
213
(Manifest { name: name2 }) = compare name1 name2
225
214
226
215
logError fileName error = do
227
- liftEffect $ log $
228
- " \" purs.json\" decoding failed for " <> fileName <> " : " <> error
216
+ cfg.log $ " \" purs.json\" decoding failed for " <> fileName <> " : " <> error
229
217
pure Nothing
230
218
231
219
-- | Write type index parts to files.
232
220
writeTypeIndex :: TypeIndex -> Aff Unit
233
221
writeTypeIndex typeIndex =
234
222
for_ entries \(Tuple typeShape results) -> do
235
223
writeTextFile UTF8 (unwrap Config .typeIndexDirectory <> " /" <> typeShape <> " .js" )
236
- (mkHeader typeShape <> JSON .print (CJ .encode codec results))
224
+ (mkHeader typeShape <> JSON .print (CJ .encode codec $ fromMaybe [] results))
237
225
where
238
226
mkHeader typeShape =
239
227
" // This file was generated by docs-search\n "
240
228
<> " window.DocsSearchTypeIndex[\" "
241
229
<> typeShape
242
230
<> " \" ] = "
243
231
244
- codec = CJ.Common .maybe $ CJ . array SearchResult .searchResultCodec
232
+ codec = CJ .array SearchResult .searchResultCodec
245
233
246
234
entries :: Array _
247
235
entries = Map .toUnfoldableUnordered (unwrap typeIndex)
@@ -350,18 +338,18 @@ patchDocs cfg = do
350
338
-- | Create directories for two indices, or fail with a message
351
339
-- | in case the docs were not generated.
352
340
createDirectories :: Config -> Aff Unit
353
- createDirectories { generatedDocs } = do
341
+ createDirectories { generatedDocs, die } = do
354
342
let
355
343
htmlDocs = Path .concat [ generatedDocs, " html" ]
356
344
indexDir = Path .concat [ generatedDocs, " html" , " index" ]
357
345
declIndexDir = Path .concat [ generatedDocs, " html" , " index" , " declarations" ]
358
346
typeIndexDir = Path .concat [ generatedDocs, " html" , " index" , " types" ]
359
347
360
- whenM (not <$> directoryExists generatedDocs) $ liftEffect do
361
- logAndExit " Generate the documentation first!"
348
+ whenM (not <$> directoryExists generatedDocs) $
349
+ die " Generate the documentation first!"
362
350
363
- whenM (not <$> directoryExists htmlDocs) $ liftEffect do
364
- logAndExit " Generate the documentation first!"
351
+ whenM (not <$> directoryExists htmlDocs) $
352
+ die " Generate the documentation first!"
365
353
366
354
whenM (not <$> directoryExists indexDir) do
367
355
mkdir indexDir
@@ -375,13 +363,13 @@ createDirectories { generatedDocs } = do
375
363
-- | Copy the client-side application, responsible for handling user input and rendering
376
364
-- | the results, to the destination path.
377
365
copyAppFile :: Config -> Aff Unit
378
- copyAppFile { generatedDocs } = do
366
+ copyAppFile { generatedDocs, die } = do
379
367
appFile <- liftEffect getDocsSearchAppPath
380
- whenM (not <$> fileExists appFile) do
381
- liftEffect do
382
- logAndExit $
383
- " Client-side app was not found at " <> appFile <> " .\n " <>
384
- " Check your installation."
368
+ unlessM ( fileExists appFile)
369
+ $ die
370
+ $
371
+ " Client-side app was not found at " <> appFile <> " .\n " <>
372
+ " Check your installation."
385
373
buffer <- readFile appFile
386
374
writeFile (Path .concat [ generatedDocs, " html" , " docs-search-app.js" ]) buffer
387
375
@@ -399,25 +387,18 @@ fileExists path = do
399
387
false -> pure false
400
388
true -> isFile <$> stat path
401
389
402
- withExisting :: forall a . String -> (String -> Aff a ) -> Aff (Maybe a )
403
- withExisting file f = do
390
+ withExisting :: ∀ a r . { log :: String -> Aff Unit | r } -> String -> (String -> Aff a ) -> Aff (Maybe a )
391
+ withExisting cfg file f = do
404
392
doesExist <- fileExists file
405
393
406
394
if doesExist then do
407
395
contents <- readTextFile UTF8 file
408
396
res <- f contents
409
397
pure $ Just res
410
398
else do
411
- liftEffect $ do
412
- log $
413
- " File does not exist: " <> file
399
+ cfg.log $ " File does not exist: " <> file
414
400
pure Nothing
415
401
416
- logAndExit :: forall a . String -> Effect a
417
- logAndExit message = do
418
- log message
419
- Process .exit' 1
420
-
421
402
showGlobs :: Array String -> String
422
403
showGlobs = Array .intercalate " , "
423
404
0 commit comments