11{-# LANGUAGE DefaultSignatures #-}
22{-# LANGUAGE DeriveDataTypeable #-}
3+ {-# LANGUAGE FlexibleInstances #-}
34{-# LANGUAGE GeneralizedNewtypeDeriving #-}
45{-# LANGUAGE OverloadedStrings #-}
56{-# LANGUAGE TemplateHaskell #-}
@@ -15,8 +16,11 @@ import Control.Monad (liftM, mzero)
1516import Control.Monad.Catch (MonadThrow , throwM )
1617import Control.Monad.Reader (MonadReader , ask , asks , MonadIO , liftIO )
1718import Control.Monad.Logger (LogLevel (.. ))
18- import Data.Aeson.Extended (ToJSON , toJSON , FromJSON , parseJSON , withText , withObject , object
19- ,(.=) , (.:?) , (.!=) , (.:) , Value (String , Object ))
19+ import Data.Aeson.Extended
20+ (ToJSON , toJSON , FromJSON , parseJSON , withText , withObject , object ,
21+ (.=) , (.:) , (..:) , (..:?) , (..!=) , Value (String ),
22+ withObjectWarnings , WarningParser , Object , jsonSubWarnings , JSONWarning ,
23+ jsonSubWarningsMT )
2024import Data.Binary (Binary )
2125import Data.ByteString (ByteString )
2226import qualified Data.ByteString.Char8 as S8
@@ -121,12 +125,12 @@ data PackageIndex = PackageIndex
121125 -- ^ Require that hashes and package size information be available for packages in this index
122126 }
123127 deriving Show
124- instance FromJSON PackageIndex where
125- parseJSON = withObject " PackageIndex" $ \ o -> do
126- name <- o .: " name"
127- prefix <- o .: " download-prefix"
128- mgit <- o .:? " git"
129- mhttp <- o .:? " http"
128+ instance FromJSON ( PackageIndex , [ JSONWarning ]) where
129+ parseJSON = withObjectWarnings " PackageIndex" $ \ o -> do
130+ name <- o .. : " name"
131+ prefix <- o .. : " download-prefix"
132+ mgit <- o .. :? " git"
133+ mhttp <- o .. :? " http"
130134 loc <-
131135 case (mgit, mhttp) of
132136 (Nothing , Nothing ) -> fail $
@@ -135,8 +139,8 @@ instance FromJSON PackageIndex where
135139 (Just git, Nothing ) -> return $ ILGit git
136140 (Nothing , Just http) -> return $ ILHttp http
137141 (Just git, Just http) -> return $ ILGitHttp git http
138- gpgVerify <- o .:? " gpg-verify" .!= False
139- reqHashes <- o .:? " require-hashes" .!= False
142+ gpgVerify <- o .. :? " gpg-verify" . .!= False
143+ reqHashes <- o .. :? " require-hashes" . .!= False
140144 return PackageIndex
141145 { indexName = name
142146 , indexLocation = loc
@@ -293,20 +297,20 @@ instance ToJSON PackageEntry where
293297 , " location" .= peLocation pe
294298 , " subdirs" .= peSubdirs pe
295299 ]
296- instance FromJSON PackageEntry where
300+ instance FromJSON ( PackageEntry , [ JSONWarning ]) where
297301 parseJSON (String t) = do
298302 loc <- parseJSON $ String t
299- return PackageEntry
300- { peExtraDepMaybe = Nothing
301- , peValidWanted = Nothing
302- , peLocation = loc
303- , peSubdirs = []
304- }
305- parseJSON v = withObject " PackageEntry" (\ o -> PackageEntry
306- <$> o .:? " extra-dep"
307- <*> o .:? " valid-wanted"
308- <*> o .: " location"
309- <*> o .:? " subdirs" .!= [] ) v
303+ return ( PackageEntry
304+ { peExtraDepMaybe = Nothing
305+ , peValidWanted = Nothing
306+ , peLocation = loc
307+ , peSubdirs = []
308+ }, [] )
309+ parseJSON v = withObjectWarnings " PackageEntry" (\ o -> PackageEntry
310+ <$> o .. :? " extra-dep"
311+ <*> o .. :? " valid-wanted"
312+ <*> o .. : " location"
313+ <*> o .. :? " subdirs" . .!= [] ) v
310314
311315data PackageLocation
312316 = PLFilePath FilePath
@@ -528,31 +532,35 @@ instance Monoid ConfigMonoid where
528532 , configMonoidImageOpts = configMonoidImageOpts l <> configMonoidImageOpts r
529533 }
530534
531- instance FromJSON ConfigMonoid where
532- parseJSON =
533- withObject " ConfigMonoid" $
534- \ obj ->
535- do configMonoidDockerOpts <- obj .:? T. pack " docker" .!= mempty
536- configMonoidConnectionCount <- obj .:? " connection-count"
537- configMonoidHideTHLoading <- obj .:? " hide-th-loading"
538- configMonoidLatestSnapshotUrl <- obj .:? " latest-snapshot-url"
539- configMonoidPackageIndices <- obj .:? " package-indices"
540- configMonoidSystemGHC <- obj .:? " system-ghc"
541- configMonoidInstallGHC <- obj .:? " install-ghc"
542- configMonoidSkipGHCCheck <- obj .:? " skip-ghc-check"
543- configMonoidSkipMsys <- obj .:? " skip-msys"
544- configMonoidRequireStackVersion <- unVersionRangeJSON <$>
545- obj .:? " require-stack-version"
546- .!= VersionRangeJSON anyVersion
547- configMonoidOS <- obj .:? " os"
548- configMonoidArch <- obj .:? " arch"
549- configMonoidJobs <- obj .:? " jobs"
550- configMonoidExtraIncludeDirs <- obj .:? " extra-include-dirs" .!= Set. empty
551- configMonoidExtraLibDirs <- obj .:? " extra-lib-dirs" .!= Set. empty
552- configMonoidConcurrentTests <- obj .:? " concurrent-tests"
553- configMonoidLocalBinPath <- obj .:? " local-bin-path"
554- configMonoidImageOpts <- obj .:? T. pack " image" .!= mempty
555- return ConfigMonoid {.. }
535+ instance FromJSON (ConfigMonoid , [JSONWarning ]) where
536+ parseJSON = withObjectWarnings " ConfigMonoid" parseConfigMonoidJSON
537+
538+ -- | Parse a partial configuration. Used both to parse both a standalone config
539+ -- file and a project file, so that a sub-parser is not required, which would interfere with
540+ -- warnings for missing fields.
541+ parseConfigMonoidJSON :: Object -> WarningParser ConfigMonoid
542+ parseConfigMonoidJSON obj = do
543+ configMonoidDockerOpts <- jsonSubWarnings (obj ..:? " docker" ..!= mempty )
544+ configMonoidConnectionCount <- obj ..:? " connection-count"
545+ configMonoidHideTHLoading <- obj ..:? " hide-th-loading"
546+ configMonoidLatestSnapshotUrl <- obj ..:? " latest-snapshot-url"
547+ configMonoidPackageIndices <- jsonSubWarningsMT (obj ..:? " package-indices" )
548+ configMonoidSystemGHC <- obj ..:? " system-ghc"
549+ configMonoidInstallGHC <- obj ..:? " install-ghc"
550+ configMonoidSkipGHCCheck <- obj ..:? " skip-ghc-check"
551+ configMonoidSkipMsys <- obj ..:? " skip-msys"
552+ configMonoidRequireStackVersion <- unVersionRangeJSON <$>
553+ obj ..:? " require-stack-version"
554+ ..!= VersionRangeJSON anyVersion
555+ configMonoidOS <- obj ..:? " os"
556+ configMonoidArch <- obj ..:? " arch"
557+ configMonoidJobs <- obj ..:? " jobs"
558+ configMonoidExtraIncludeDirs <- obj ..:? " extra-include-dirs" ..!= Set. empty
559+ configMonoidExtraLibDirs <- obj ..:? " extra-lib-dirs" ..!= Set. empty
560+ configMonoidConcurrentTests <- obj ..:? " concurrent-tests"
561+ configMonoidLocalBinPath <- obj ..:? " local-bin-path"
562+ configMonoidImageOpts <- jsonSubWarnings (obj ..:? " image" ..!= mempty )
563+ return ConfigMonoid {.. }
556564
557565-- | Newtype for non-orphan FromJSON instance.
558566newtype VersionRangeJSON = VersionRangeJSON { unVersionRangeJSON :: VersionRange }
@@ -778,18 +786,18 @@ getMinimalEnvOverride = do
778786data ProjectAndConfigMonoid
779787 = ProjectAndConfigMonoid ! Project ! ConfigMonoid
780788
781- instance FromJSON ProjectAndConfigMonoid where
782- parseJSON = withObject " Project, ConfigMonoid " $ \ o -> do
783- dirs <- o .:? " packages" .!= [packageEntryCurrDir]
784- extraDeps' <- o .:? " extra-deps" .!= []
789+ instance FromJSON ( ProjectAndConfigMonoid , [ JSONWarning ]) where
790+ parseJSON = withObjectWarnings " ProjectAndConfigMonoid " $ \ o -> do
791+ dirs <- jsonSubWarningsMT ( o .. :? " packages" ) . .!= [packageEntryCurrDir]
792+ extraDeps' <- o .. :? " extra-deps" . .!= []
785793 extraDeps <-
786794 case partitionEithers $ goDeps extraDeps' of
787795 ([] , x) -> return $ Map. fromList x
788796 (errs, _) -> fail $ unlines errs
789797
790- flags <- o .:? " flags" .!= mempty
791- resolver <- o .: " resolver"
792- config <- parseJSON $ Object o
798+ flags <- o .. :? " flags" . .!= mempty
799+ resolver <- o .. : " resolver"
800+ config <- parseConfigMonoidJSON o
793801 let project = Project
794802 { projectPackages = dirs
795803 , projectExtraDeps = extraDeps
0 commit comments