@@ -7,7 +7,7 @@ import qualified Control.Exception as E
77import Data.Aeson
88import qualified Data.List as List
99import qualified Data.ByteString.Lazy as BS
10−import qualified Data.Map as Map
10+import qualified Data.HashMap.Strict as Map
1111import qualified Elm.Internal.Name as N
1212import qualified Elm.Internal.Version as V
1313
@@ -20,35 +20,54 @@ data Deps = Deps
2020 , repo :: String
2121 , exposed :: [String]
2222 , elmVersion :: V.Version
23+ , dependencies :: [(N.Name,V.Version)]
2324 } deriving Show
2425
2526instance FromJSON Deps where
2627 parseJSON (Object obj) =
27− do version <- obj .: "version"
28+ do version <- get obj "version" "your projects version number"
2829
29− summary <- obj .: "summary"
30+ summary <- get obj "summary" "a short summary of your project"
3031 when (length summary >= 80) $
3132 fail "'summary' must be less than 80 characters"
3233
33− desc <- obj .: "description"
34− license <- obj .: "license"
34+ desc <- get obj "description" "an extended description of your project \
35+ \and how to get started with it."
36+ license <- get obj "license" "license information (BSD3 is recommended)"
3537
36− repo <- obj .: "repository"
38+ repo <- get obj "repository" "a link to the project's GitHub repo"
3739 name <- case repoToName repo of
3840 Left err -> fail err
3941 Right nm -> return nm
4042
41− exposed <- obj .: "exposed-modules"
43+ exposed <- get obj "exposed-modules" "a list of modules exposed to users"
4244 when (null exposed) $
4345 fail "there are no 'exposed-modules'.\n\
44− \At least one module must be exposed for anyone to use this library!"
46+ \At least one module must be exposed \
47+ \for anyone to use this library!"
4548
46− elmVersion <- obj .: "elm-version"
49+ elmVersion <- get obj "elm-version" "the version of the Elm compiler you are using"
4750
48− return $ Deps name version summary desc license repo exposed elmVersion
51+ deps <- toDeps =<< get obj "dependencies"
52+ "a listing of your project's dependencies"
53+
54+ return $ Deps name version summary desc license repo exposed elmVersion deps
4955
5056 parseJSON _ = mzero
5157
58+toDeps deps =
59+ forM (Map.toList deps) $ \(f,v) ->
60+ case (N.fromString f, V.fromString v) of
61+ (Just name, Just version) -> return (name,version)
62+ (Nothing, _) -> fail $ N.errorMsg f
63+ (_, Nothing) -> fail $ "invalid version number " ++ v
64+
65+get obj field desc =
66+ do maybe <- obj .:? field
67+ case maybe of
68+ Nothing -> fail $ "Missing field " ++ show field ++ ", " ++ desc
69+ Just value -> return value
70+
5271repoToName :: String -> Either String N.Name
5372repoToName repo
5473 | not (end `List.isSuffixOf` repo) = Left msg
@@ -86,8 +105,5 @@ withDeps handle path =
86105 "could not find file " ++ path ++
87106 "\n You may need to create a dependency file for your project."
88107
89−dependencies :: FilePath -> ErrorT String IO (Map.Map String String)
90−dependencies _ = return Map.empty -- withDeps deps
91−
92108depsAt :: FilePath -> ErrorT String IO Deps
93109depsAt = withDeps id