on master help sign in
Update Elm.Project.Json for Elm.Version, Data.Utf8, etc.
1e0616aEvan Czaplicki
builder/src/Elm/Project/Json.hs+67−103
@@ -22,21 +22,17 @@ module Elm.Project.Json
22
22
23import Prelude hiding (read)
23import Prelude hiding (read)
24import Control.Monad.Trans (liftIO)
24import Control.Monad.Trans (liftIO)
25−import qualified Data.ByteString as BS
26import Data.Foldable (traverse_)
25import Data.Foldable (traverse_)
27−import Data.Map (Map)
28−import Data.Text (Text)
29import qualified Data.Map as Map
26import qualified Data.Map as Map
30−import qualified Data.Text as Text
27+import qualified Data.Utf8 as Utf8
31import qualified System.Directory as Dir
28import qualified System.Directory as Dir
32import System.FilePath ((</>))
29import System.FilePath ((</>))
33
30
31+import qualified Elm.Constraint as Con
32+import qualified Elm.Licenses as Licenses
34import qualified Elm.ModuleName as ModuleName
33import qualified Elm.ModuleName as ModuleName
35import qualified Elm.Package as Pkg
34import qualified Elm.Package as Pkg
36−import Elm.Package (Name, Version)
35+import qualified Elm.Version as V
37−
38−import qualified Elm.Project.Constraint as Con
39−import qualified Elm.Project.Licenses as Licenses
40import qualified Json.Decode as D
36import qualified Json.Decode as D
41import qualified Json.Encode as E
37import qualified Json.Encode as E
42import qualified Reporting.Exit as Exit
38import qualified Reporting.Exit as Exit
@@ -59,12 +55,12 @@ data Project
59
55
60data AppInfo =
56data AppInfo =
61 AppInfo
57 AppInfo
62− { _app_elm_version :: Version
58+ { _app_elm_version :: V.Version
63 , _app_source_dirs :: [FilePath]
59 , _app_source_dirs :: [FilePath]
64− , _app_deps_direct :: Map Name Version
60+ , _app_deps_direct :: Map.Map Pkg.Name V.Version
65− , _app_deps_trans :: Map Name Version
61+ , _app_deps_trans :: Map.Map Pkg.Name V.Version
66− , _app_test_direct :: Map Name Version
62+ , _app_test_direct :: Map.Map Pkg.Name V.Version
67− , _app_test_trans :: Map Name Version
63+ , _app_test_trans :: Map.Map Pkg.Name V.Version
68 }
64 }
69
65
70
66
@@ -74,27 +70,27 @@ data AppInfo =
74
70
75data PkgInfo =
71data PkgInfo =
76 PkgInfo
72 PkgInfo
77− { _pkg_name :: Name
73+ { _pkg_name :: Pkg.Name
78− , _pkg_summary :: Text
74+ , _pkg_summary :: Utf8.String
79 , _pkg_license :: Licenses.License
75 , _pkg_license :: Licenses.License
80− , _pkg_version :: Version
76+ , _pkg_version :: V.Version
81 , _pkg_exposed :: Exposed
77 , _pkg_exposed :: Exposed
82− , _pkg_deps :: Map Name Con.Constraint
78+ , _pkg_deps :: Map.Map Pkg.Name Con.Constraint
83− , _pkg_test_deps :: Map Name Con.Constraint
79+ , _pkg_test_deps :: Map.Map Pkg.Name Con.Constraint
84 , _pkg_elm_version :: Con.Constraint
80 , _pkg_elm_version :: Con.Constraint
85 }
81 }
86
82
87
83
88data Exposed
84data Exposed
89 = ExposedList [ModuleName.Raw]
85 = ExposedList [ModuleName.Raw]
90− | ExposedDict [(Text, [ModuleName.Raw])]
86+ | ExposedDict [(Utf8.String, [ModuleName.Raw])]
91
87
92
88
93
89
94-- DEFAULTS
90-- DEFAULTS
95
91
96
92
97−defaultSummary :: Text
93+defaultSummary :: Utf8.String
98defaultSummary =
94defaultSummary =
99 "helpful summary of your project, less than 80 characters"
95 "helpful summary of your project, less than 80 characters"
100
96
@@ -117,7 +113,7 @@ isPlatformPackage project =
117 author == "elm" || author == "elm-explorations"
113 author == "elm" || author == "elm-explorations"
118
114
119
115
120−getName :: Project -> Name
116+getName :: Project -> Pkg.Name
121getName project =
117getName project =
122 case project of
118 case project of
123 App _ ->
119 App _ ->
@@ -174,32 +170,32 @@ encode project =
174 case project of
170 case project of
175 App (AppInfo elm srcDirs depsDirect depsTrans testDirect testTrans) ->
171 App (AppInfo elm srcDirs depsDirect depsTrans testDirect testTrans) ->
176 E.object
172 E.object
177− [ "type" ==> E.text "application"
173+ [ "type" ==> E.string "application"
178− , "source-directories" ==> E.list (E.text . Text.pack) srcDirs
174+ , "source-directories" ==> E.list (E.string . Utf8.fromChars) srcDirs
179− , "elm-version" ==> encodeVersion elm
175+ , "elm-version" ==> V.encode elm
180 , "dependencies" ==>
176 , "dependencies" ==>
181 E.object
177 E.object
182− [ "direct" ==> encodeDeps encodeVersion depsDirect
178+ [ "direct" ==> encodeDeps V.encode depsDirect
183− , "indirect" ==> encodeDeps encodeVersion depsTrans
179+ , "indirect" ==> encodeDeps V.encode depsTrans
184 ]
180 ]
185 , "test-dependencies" ==>
181 , "test-dependencies" ==>
186 E.object
182 E.object
187− [ "direct" ==> encodeDeps encodeVersion testDirect
183+ [ "direct" ==> encodeDeps V.encode testDirect
188− , "indirect" ==> encodeDeps encodeVersion testTrans
184+ , "indirect" ==> encodeDeps V.encode testTrans
189 ]
185 ]
190 ]
186 ]
191
187
192 Pkg (PkgInfo name summary license version exposed deps tests elm) ->
188 Pkg (PkgInfo name summary license version exposed deps tests elm) ->
193 E.object
189 E.object
194− [ "type" ==> E.text "package"
190+ [ "type" ==> E.string "package"
195− , "name" ==> E.text (Pkg.toText name)
191+ , "name" ==> E.string (Pkg.toString name)
196− , "summary" ==> E.text summary
192+ , "summary" ==> E.string summary
197 , "license" ==> Licenses.encode license
193 , "license" ==> Licenses.encode license
198− , "version" ==> E.text (Pkg.versionToText version)
194+ , "version" ==> V.encode version
199 , "exposed-modules" ==> encodeExposed exposed
195 , "exposed-modules" ==> encodeExposed exposed
200− , "elm-version" ==> encodeConstraint elm
196+ , "elm-version" ==> Con.encode elm
201− , "dependencies" ==> encodeDeps encodeConstraint deps
197+ , "dependencies" ==> encodeDeps Con.encode deps
202− , "test-dependencies" ==> encodeDeps encodeConstraint tests
198+ , "test-dependencies" ==> encodeDeps Con.encode tests
203 ]
199 ]
204
200
205
201
@@ -223,19 +219,9 @@ encodeModule name =
223 E.name name
219 E.name name
224
220
225
221
226−encodeDeps :: (a -> E.Value) -> Map Pkg.Name a -> E.Value
222+encodeDeps :: (a -> E.Value) -> Map.Map Pkg.Name a -> E.Value
227encodeDeps encodeValue deps =
223encodeDeps encodeValue deps =
228− E.dict Pkg.toText encodeValue deps
224+ E.dict Pkg.toString encodeValue deps
229−
230−
231−encodeConstraint :: Con.Constraint -> E.Value
232−encodeConstraint constraint =
233− E.text (Con.toText constraint)
234−
235−
236−encodeVersion :: Pkg.Version -> E.Value
237−encodeVersion version =
238− E.text (Pkg.versionToText version)
239
225
240
226
241
227
@@ -244,17 +230,19 @@ encodeVersion version =
244
230
245read :: FilePath -> Task.Task Project
231read :: FilePath -> Task.Task Project
246read path =
232read path =
247− do bytes <- liftIO $ BS.readFile path
233+ do result <- liftIO $ D.fromFile decoder path
248− case D.parse "project" E.badContentToDocs decoder bytes of
234+ case result of
249− Left err ->
235+ Right project ->
250− throwBadJson (E.BadJson err)
236+ case project of
237+ Pkg _ ->
238+ do return project
251
239
252− Right project@(Pkg _) ->
240+ App (AppInfo _ srcDirs _ _ _ _) ->
241+ do mapM_ doesDirectoryExist srcDirs
253− return project
242+ return project
254
243
255− Right project@(App (AppInfo _ srcDirs _ _ _ _)) ->
244+ Left err ->
256− do mapM_ doesDirectoryExist srcDirs
245+ throwBadJson (error "TODO bad json" err)
257− return project
258
246
259
247
260throwBadJson :: E.ElmJsonProblem -> Task.Task a
248throwBadJson :: E.ElmJsonProblem -> Task.Task a
@@ -280,16 +268,16 @@ type Decoder a =
280
268
281decoder :: Decoder Project
269decoder :: Decoder Project
282decoder =
270decoder =
283− do tipe <- D.field "type" D.text
271+ do tipe <- D.field "type" D.string
284 case tipe of
272 case tipe of
285 "application" ->
273 "application" ->
286− D.map App appDecoder
274+ App <$> appDecoder
287
275
288 "package" ->
276 "package" ->
289− D.map Pkg pkgDecoder
277+ Pkg <$> pkgDecoder
290
278
291 other ->
279 other ->
292− D.fail (E.BadType other)
280+ D.failure (E.BadType other)
293
281
294
282
295appDecoder :: Decoder AppInfo
283appDecoder :: Decoder AppInfo
@@ -325,73 +313,49 @@ pkgNameDecoder =
325 D.mapError E.BadPkgName Pkg.decoder
313 D.mapError E.BadPkgName Pkg.decoder
326
314
327
315
328−summaryDecoder :: Decoder Text
316+summaryDecoder :: Decoder Utf8.String
329summaryDecoder =
317summaryDecoder =
330− do summary <- D.text
318+ do summary <- D.string
331− if Text.length summary < 80
319+ if Utf8.size summary < 80
332− then D.succeed summary
320+ then return summary
333− else D.fail E.BadSummaryTooLong
321+ else D.failure E.BadSummaryTooLong
334
322
335
323
336licenseDecoder :: Decoder Licenses.License
324licenseDecoder :: Decoder Licenses.License
337licenseDecoder =
325licenseDecoder =
338− do txt <- D.text
326+ Licenses.decoder E.BadLicense
339− case Licenses.check txt of
340− Left suggestions ->
341− D.fail (E.BadLicense txt suggestions)
342−
343− Right license ->
344− D.succeed license
345
327
346
328
347−versionDecoder :: Decoder Version
329+versionDecoder :: Decoder V.Version
348versionDecoder =
330versionDecoder =
349− do txt <- D.text
350− case Pkg.versionFromText txt of
351− Just version ->
352− D.succeed version
353−
354− Nothing ->
355− D.fail (E.BadVersion txt)
331+ D.mapError E.BadVersion V.decoder
356
332
357
333
358constraintDecoder :: Decoder Con.Constraint
334constraintDecoder :: Decoder Con.Constraint
359constraintDecoder =
335constraintDecoder =
360− do txt <- D.text
336+ D.mapError E.BadConstraint Con.decoder
361− case Con.fromText txt of
362− Right constraint ->
363− D.succeed constraint
364
337
365− Left msg ->
366− D.fail (E.BadConstraint msg)
367
338
368−
369−depsDecoder :: Decoder a -> Decoder (Map Name a)
339+depsDecoder :: Decoder a -> Decoder (Map.Map Pkg.Name a)
370depsDecoder valueDecoder =
340depsDecoder valueDecoder =
371 Map.fromList <$> (
341 Map.fromList <$> (
372 traverse validateKey =<< D.pairs valueDecoder
342 traverse validateKey =<< D.pairs valueDecoder
373 )
343 )
374
344
375
345
376−validateKey :: (Text, a) -> Decoder (Name, a)
346+validateKey :: (Utf8.String, a) -> Decoder (Pkg.Name, a)
377validateKey (key, value) =
347validateKey (key, value) =
378− case Pkg.fromText key of
348+ case Pkg.fromString key of
379 Right name ->
349 Right name ->
380− D.succeed (name, value)
350+ return (name, value)
381
351
382 Left _ ->
352 Left _ ->
383− D.fail (E.BadDependencyName key)
353+ D.failure (E.BadDependencyName key)
384
354
385
355
386dirDecoder :: Decoder FilePath
356dirDecoder :: Decoder FilePath
387dirDecoder =
357dirDecoder =
388− do maybeText <- D.maybe D.text
358+ Utf8.toChars <$> D.string
389− case maybeText of
390− Nothing ->
391− D.fail E.BadDirectoryNotString
392−
393− Just txt ->
394− D.succeed (Text.unpack txt)
395
359
396
360
397
361
@@ -413,9 +377,9 @@ moduleDecoder =
413 D.mapError E.BadModuleName ModuleName.decoder
377 D.mapError E.BadModuleName ModuleName.decoder
414
378
415
379
416−checkHeader :: Text -> Decoder ()
380+checkHeader :: Utf8.String -> Decoder ()
417checkHeader header =
381checkHeader header =
418− if Text.length header < 20 then
382+ if Utf8.size header < 20 then
419− D.succeed ()
383+ return ()
420 else
384 else
421− D.fail (E.BadModuleHeaderTooLong header)
385+ D.failure (E.BadModuleHeaderTooLong header)