haskell-packages 0.2.4.4 → 0.6.2
raw patch · 7 files changed
Files
- CHANGELOG.md +13/−0
- README.md +8/−7
- haskell-packages.cabal +8/−7
- src/Distribution/HaskellSuite/Cabal.hs +44/−43
- src/Distribution/HaskellSuite/Compiler.hs +14/−13
- src/Distribution/HaskellSuite/Modules.hs +28/−30
- src/Distribution/HaskellSuite/Packages.hs +35/−150
CHANGELOG.md view
@@ -1,6 +1,19 @@ Changes ======= +Version 0.4+-----------++Update to Cabal-1.24.+Update to aeson-0.11.0.0.++Version 0.3+-----------++Update to Cabal-1.22.++Change the format of on-disk JSON interface files.+ Version 0.2.4.4 ---------------
README.md view
@@ -10,14 +10,14 @@ If you go the hard way, this involves: -1. **Parsing command line parameters**. Sounds easy — just take a list of files to+1. **Parsing command line parameters**. Sounds easy — just take a list of files to compile. In reality you also need to handle package ids and package dbs, CPP options (`-DFOO=1`), language extension flags (`-XRankNTypes`) etc. To integrate with Cabal, you also need to tell it the list of installed packages, supported languages and extensions etc. -2. Actual **integration with Cabal** means understanding how Cabal works and+2. Actual **integration with Cabal** means understanding how Cabal works and hard-coding support for your compiler. And then getting it accepted and waiting for the next Cabal release. @@ -25,7 +25,7 @@ by Cabal. It might work, but often it won't, for various reasons. Also, GHC's command line protocol is quite complex. -3. **Package management**. You need to implement a package db mechanism, which would+3. **Package management**. You need to implement a package db mechanism, which would let you to keep track of installed packages. Then you'd have to implement a `ghc-pkg`-like tool to manage those databases, for both Cabal and your users. @@ -39,7 +39,7 @@ ## Using other compilers Some compilers produce artifacts that you may want to use. A good example is the-`hs-gen-iface` compiler from haskell-names which generates an *interface* for each+`hs-gen-iface` compiler from haskell-names which generates an _interface_ for each module — the set of all named entities (functions, types, classes) that are exported by that module. This information can be then used either by other compilers, or by tools like IDEs.@@ -65,10 +65,11 @@ where `$TOOL` may be either a full path to the compiler, or just an executable name if it's in `$PATH`. -Maintainers------------+## Maintainers -[Roman Cheplyaka](https://github.com/feuerbach) is the primary maintainer.+[David Himmelstrup](https://github.com/Lemmih) is the primary maintainer.++[Roman Cheplyaka](https://github.com/feuerbach) is the original author. [Adam Bergmark](https://github.com/bergmark) is the backup maintainer. Please get in touch with him if the primary maintainer cannot be reached.
haskell-packages.cabal view
@@ -2,19 +2,20 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: haskell-packages-version: 0.2.4.4+version: 0.6.2 synopsis: Haskell suite library for package management and integration with Cabal description: See <http://documentup.com/haskell-suite/haskell-packages> license: MIT license-file: LICENSE author: Roman Cheplyaka-maintainer: Roman Cheplyaka <roma@ro-che.info>-copyright: (c) Roman Cheplyaka 2012+maintainer: David Himmelstrup <lemmih@gmail.com>+copyright: (c) Roman Cheplyaka 2012, David Himmelstrup 2016-2018 category: Distribution homepage: http://documentup.com/haskell-suite/haskell-packages bug-reports: https://github.com/haskell-suite/haskell-packages/issues build-type: Simple cabal-version: >=1.10+tested-with: GHC == 8.2.1 extra-source-files: README.md CHANGELOG.md@@ -39,16 +40,16 @@ build-depends: base >=4.5 && < 5 , optparse-applicative >= 0.11- , aeson >= 0.6+ , binary >= 0.8 , bytestring >= 0.9- , Cabal >= 1.14 && <= 1.20.0.2+ , Cabal == 2.3.* || == 2.0.* , deepseq , directory , filepath , containers , mtl >= 2.1- , hse-cpp+ , hse-cpp >= 0.2 , transformers >= 0.3 , transformers-compat >= 0.3- , haskell-src-exts >= 1.14+ , haskell-src-exts >= 1.18 , tagged
src/Distribution/HaskellSuite/Cabal.hs view
@@ -1,40 +1,41 @@ -- | This module provides Cabal integration.-{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ScopedTypeVariables #-} module Distribution.HaskellSuite.Cabal ( main, customMain ) where -import Data.Typeable-import Data.Version-import Data.List-import Data.Monoid-import Data.Proxy-import Distribution.Simple.Compiler-import Distribution.InstalledPackageInfo- ( showInstalledPackageInfo- , parseInstalledPackageInfo )-import Distribution.ParseUtils-import Distribution.Package-import Distribution.Text-import Distribution.ModuleName hiding (main)-import Options.Applicative-import Options.Applicative.Types-import Control.Monad-import Control.Monad.Trans.Except-import Control.Exception-import Text.Printf+import Control.Exception+import Control.Monad+import Control.Monad.Trans.Except+import Data.Foldable (asum)+import Data.List+import Data.Monoid+import Data.Proxy+import Data.Typeable import qualified Distribution.HaskellSuite.Compiler as Compiler-import Distribution.HaskellSuite.Packages-import Language.Haskell.Exts.Extension-import Paths_haskell_packages as Our (version)-import System.FilePath-import System.Directory+import Distribution.HaskellSuite.Packages+import Distribution.InstalledPackageInfo (parseInstalledPackageInfo,+ showInstalledPackageInfo)+import Distribution.ModuleName hiding (main)+import Distribution.Package+import Distribution.ParseUtils+import Distribution.Simple.Compiler+import Distribution.Text+import Distribution.Version+import Language.Haskell.Exts.Extension+import Options.Applicative+import Options.Applicative.Types+import Paths_haskell_packages as Our (version)+import System.Directory+import System.FilePath+import Text.Printf -- It is actually important that we import 'defaultCpphsOptions' from -- hse-cpp and not from cpphs, because they are different. hse-cpp version -- provides the defaults more compatible with haskell-src-exts.-import Language.Haskell.Exts.Annotated.CPP+import Language.Haskell.Exts.CPP main :: forall c . Compiler.Is c@@ -50,7 +51,7 @@ where optParser =- foldr (<|>) empty+ asum [ version , compilerVersion , hspkgVersion@@ -61,7 +62,7 @@ ] versionStr = showVersion $ Compiler.version t- ourVersionStr = showVersion Our.version+ ourVersionStr = showVersion (mkVersion' Our.version) compilerVersion = flag'@@ -113,11 +114,11 @@ pkgInstallLib = command "install-library" $ flip info idm $ Compiler.installLib t <$>- (strOption (long "build-dir" <> metavar "PATH")) <*>- (strOption (long "target-dir" <> metavar "PATH")) <*>- (optional $ strOption (long "dynlib-target-dir" <> metavar "PATH")) <*>- (option (simpleParseM "package-id") (long "package-id" <> metavar "ID")) <*>- (many $ argument (simpleParseM "module") (metavar "MODULE"))+ strOption (long "build-dir" <> metavar "PATH") <*>+ strOption (long "target-dir" <> metavar "PATH") <*>+ optional (strOption (long "dynlib-target-dir" <> metavar "PATH")) <*>+ option (simpleParseM "package-id") (long "package-id" <> metavar "ID") <*>+ many (argument (simpleParseM "module") (metavar "MODULE")) pkgUpdate = command "update" $ flip info idm $@@ -126,7 +127,7 @@ doRegister d = do pi <- parseInstalledPackageInfo <$> getContents case pi of- ParseOk _ a -> Compiler.register t d a+ ParseOk _ a -> Compiler.register t d a ParseFailed e -> putStrLn $ snd $ locatedErrorMsg e pkgUnregister =@@ -146,17 +147,17 @@ compiler = (\srcDirs buildDir lang exts cppOpts pkg dbStack deps mods -> Compiler.compile t buildDir lang exts cppOpts pkg dbStack deps =<< findModules srcDirs mods) <$>- (many $ strOption (short 'i' <> metavar "PATH")) <*>+ many (strOption (short 'i' <> metavar "PATH")) <*> (strOption (long "build-dir" <> metavar "PATH") <|> pure ".") <*>- (optional $ classifyLanguage <$> strOption (short 'G' <> metavar "language")) <*>- (many $ parseExtension <$> strOption (short 'X' <> metavar "extension")) <*>+ optional (classifyLanguage <$> strOption (short 'G' <> metavar "language")) <*>+ many (parseExtension <$> strOption (short 'X' <> metavar "extension")) <*> cppOptsParser <*>- (option (simpleParseM "package name") (long "package-name" <> metavar "NAME-VERSION")) <*>+ option (simpleParseM "package name") (long "package-name" <> metavar "NAME-VERSION") <*> pkgDbStackParser <*>- (many $ InstalledPackageId <$> strOption (long "package-id")) <*>- (many $ argument str (metavar "MODULE"))+ many (mkUnitId <$> strOption (long "package-id")) <*>+ many (argument str (metavar "MODULE")) -data ModuleNotFound = ModuleNotFound String+newtype ModuleNotFound = ModuleNotFound String deriving Typeable instance Show ModuleNotFound where@@ -171,7 +172,7 @@ r <- runExceptT $ sequence_ (checkInDir <$> srcDirs <*> exts) case r of Left found -> return found- Right {} -> throwIO $ ModuleNotFound mod+ Right {} -> throwIO $ ModuleNotFound mod where exts = ["hs", "lhs"]@@ -210,7 +211,7 @@ def :: (String, String) def = case span (/= '=') str of- (_, []) -> (str, "1")+ (_, []) -> (str, "1") (sym, _:var) -> (sym, var) in Endo $ \opts -> opts { defines = def : defines opts }
src/Distribution/HaskellSuite/Compiler.hs view
@@ -22,13 +22,14 @@ ) where -import Data.Version+-- import Data.Version+import Distribution.Version import Distribution.HaskellSuite.Packages import {-# SOURCE #-} Distribution.HaskellSuite.Cabal import Distribution.Simple.Compiler import Distribution.Simple.Utils import Distribution.Verbosity-import Distribution.InstalledPackageInfo+import Distribution.InstalledPackageInfo (InstalledPackageInfo, sourcePackageId) import Distribution.Package import Distribution.Text import Distribution.ModuleName (ModuleName)@@ -36,7 +37,7 @@ import Control.Exception import Data.List import Data.Function-import Language.Haskell.Exts.Annotated.CPP+import Language.Haskell.Exts.CPP import Language.Haskell.Exts.Extension -- | Compilation function@@ -47,7 +48,7 @@ -> CpphsOptions -- ^ CPP options -> PackageId -- ^ name and version of the package being compiled -> PackageDBStack -- ^ package db stack to use- -> [InstalledPackageId] -- ^ dependencies+ -> [UnitId] -- ^ dependencies -> [FilePath] -- ^ list of files to compile -> IO () @@ -95,7 +96,7 @@ -> IO () installLib t buildDir targetDir _dynlibTargetDir _pkg mods = -- see https://github.com/haskell-suite/haskell-packages/pull/17- forM_ (fileExtensions t) $ \ext -> do+ forM_ (fileExtensions t) $ \ext -> findModuleFiles [buildDir] [ext] mods >>= installOrdinaryFiles normal targetDir @@ -113,7 +114,7 @@ Nothing -> throwIO RegisterNullDB Just db -> do pkgs <- readPackageDB (maybeInitDB dbspec) db- let pkgid = installedPackageId pkg+ let pkgid = installedUnitId pkg writePackageDB db $ pkg : removePackage pkgid pkgs -- | Unregister the package@@ -126,8 +127,8 @@ let pkgCriterion = -- if the version is not specified, treat it as a wildcard- (case pkgVersion $ packageId pkg of- Version [] _ ->+ (case versionNumbers $ pkgVersion $ packageId pkg of+ [] -> ((==) `on` pkgName) pkg _ -> (==) pkg)@@ -145,11 +146,11 @@ if null packagesRemoved then- putStrLn $ "No packages removed"+ putStrLn "No packages removed" else do putStrLn "Packages removed:" forM_ packagesRemoved $ \p ->- putStrLn $ " " ++ display (installedPackageId p)+ putStrLn $ " " ++ display (installedUnitId p) writePackageDB db packagesLeft @@ -165,10 +166,10 @@ Just db -> do pkgs <- readPackageDB (maybeInitDB dbspec) db - forM_ pkgs $ putStrLn . display . installedPackageId+ forM_ pkgs $ putStrLn . display . installedUnitId -removePackage :: InstalledPackageId -> Packages -> Packages-removePackage pkgid = filter ((pkgid /=) . installedPackageId)+removePackage :: UnitId -> Packages -> Packages+removePackage pkgid = filter ((pkgid /=) . installedUnitId) data Simple db = Simple { stName :: String
src/Distribution/HaskellSuite/Modules.hs view
@@ -1,8 +1,10 @@-{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies,- FlexibleInstances, TypeSynonymInstances,- DeriveDataTypeable, StandaloneDeriving,- MultiParamTypeClasses, UndecidableInstances,- ScopedTypeVariables #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-} module Distribution.HaskellSuite.Modules ( -- * Module monad@@ -28,21 +30,20 @@ , ModName(..) , convertModuleName ) where-import Distribution.HaskellSuite.Packages-import Distribution.Simple.Utils-import Distribution.InstalledPackageInfo-import Distribution.Text-import Distribution.ModuleName-import Control.Applicative-import Control.Monad-import Control.Monad.State-import Control.Monad.Cont-import Control.Monad.Error-import Control.Monad.Reader-import Control.Monad.Writer-import Data.List-import qualified Data.Map as Map-import System.FilePath+import Control.Monad+import Control.Monad.Cont+import Control.Monad.Except+import Control.Monad.Reader+import Control.Monad.State+import Control.Monad.Writer+import Data.List+import qualified Data.Map as Map+import Distribution.HaskellSuite.Packages+import Distribution.InstalledPackageInfo+import Distribution.ModuleName+import Distribution.Simple.Utils+import Distribution.Text+import System.FilePath -- | This class defines the interface that is used by 'getModuleInfo', so -- that you can use it in monads other than 'ModuleT'.@@ -102,18 +103,21 @@ return $ Just i findModule'sPackage :: ModName n => Packages -> n -> Maybe InstalledPackageInfo-findModule'sPackage pkgs m = find ((convertModuleName m `elem`) . exposedModules) pkgs+findModule'sPackage pkgs m =+ find+ ((convertModuleName m `elem`) . map exposedName . exposedModules)+ pkgs -- | A standard module monad transformer. -- -- @i@ is the type of module info, @m@ is the underlying monad. newtype ModuleT i m a = ModuleT { unModuleT ::- (StateT (Map.Map ModuleName i)+ StateT (Map.Map ModuleName i) (ReaderT (Packages, [FilePath] -> ModuleName -> m i) m)- a)+ a }- deriving (Functor, Applicative, Monad)+ deriving (Functor, Applicative, Monad, MonadWriter w, MonadError e, MonadCont) instance MonadTrans (ModuleT i) where lift = ModuleT . lift . lift@@ -146,12 +150,6 @@ get = lift get put = lift . put state = lift . state--deriving instance MonadWriter w m => MonadWriter w (ModuleT i m)--deriving instance MonadError e m => MonadError e (ModuleT i m)--deriving instance MonadCont m => MonadCont (ModuleT i m) -- | Run a 'ModuleT' action runModuleT
src/Distribution/HaskellSuite/Packages.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable,- TemplateHaskell, ScopedTypeVariables, OverloadedStrings #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Distribution.HaskellSuite.Packages (@@ -56,31 +57,25 @@ ) where -import Data.Aeson-import Data.Aeson.Types-import Control.Applicative-import qualified Data.ByteString as BS-import qualified Data.ByteString.Lazy as LBS-import Control.Exception as E-import Control.Monad-import Data.Typeable-import Data.Tagged-import Data.Proxy-import qualified Data.Map as Map-import Text.Printf+import Control.Exception as E+import Control.Monad+import Data.Binary+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as LBS+import qualified Data.Map as Map+import Data.Tagged+import Data.Typeable import qualified Distribution.InstalledPackageInfo as Info-import Distribution.Package-import Distribution.Text-import System.FilePath-import System.Directory+import Distribution.Package+import Distribution.Text+import System.Directory+import System.FilePath+import Text.Printf -- The following imports are needed only for JSON instances-import Data.Version (Version(..))-import Distribution.Simple.Compiler (PackageDB(..))-import Distribution.License (License(..))-import Distribution.ModuleName(ModuleName)-import Distribution.Simple.Utils-import Distribution.Verbosity+import Distribution.Simple.Compiler (PackageDB (..))+import Distribution.Simple.Utils+import Distribution.Verbosity -------------- -- Querying --@@ -106,7 +101,7 @@ (mbDb :: Maybe db) -- | Try to retrieve an 'InstalledPackageInfo' for each of--- 'InstalledPackageId's from a specified set of 'PackageDB's.+-- 'UnitId's from a specified set of 'PackageDB's. -- -- May throw a 'PkgInfoNotFound' exception. --@@ -114,13 +109,13 @@ -- 'maybeInitDB'. readPackagesInfo :: IsPackageDB db- => Proxy db -> [PackageDB] -> [InstalledPackageId] -> IO Packages+ => Proxy db -> [PackageDB] -> [UnitId] -> IO Packages readPackagesInfo proxyDb dbs pkgIds = do allPkgInfos <- concat <$> mapM (getInstalledPackages proxyDb) dbs let pkgMap = Map.fromList- [ (Info.installedPackageId pkgInfo, pkgInfo)+ [ (Info.installedUnitId pkgInfo, pkgInfo) | pkgInfo <- allPkgInfos ] forM pkgIds $ \pkgId ->@@ -166,8 +161,8 @@ -- | Convert a package db specification to a db object locateDB :: PackageDB -> IO (Maybe db)- locateDB GlobalPackageDB = globalDB- locateDB UserPackageDB = Just <$> userDB+ locateDB GlobalPackageDB = globalDB+ locateDB UserPackageDB = Just <$> userDB locateDB (SpecificPackageDB p) = Just <$> dbFromPath p -- | The user database@@ -192,8 +187,8 @@ -- hand, it is our responsibility to ensure that the user and global -- databases exist. maybeInitDB :: PackageDB -> MaybeInitDB-maybeInitDB GlobalPackageDB = InitDB-maybeInitDB UserPackageDB = InitDB+maybeInitDB GlobalPackageDB = InitDB+maybeInitDB UserPackageDB = InitDB maybeInitDB SpecificPackageDB {} = Don'tInitDB ----------------@@ -203,7 +198,7 @@ class IsDBName name where getDBName :: Tagged name String -data StandardDB name = StandardDB FilePath+newtype StandardDB name = StandardDB FilePath instance IsDBName name => IsPackageDB (StandardDB name) where dbName = retag (getDBName :: Tagged name String)@@ -221,8 +216,7 @@ -- | Make all paths in the package info relative to the given base -- directory. makePkgInfoRelative :: FilePath -> Info.InstalledPackageInfo -> Info.InstalledPackageInfo-makePkgInfoRelative base info =- mapPaths (makeRelative base) info+makePkgInfoRelative base = mapPaths (makeRelative base) -- | Make all relative paths in the package info absolute, interpreting -- them relative to the given base directory.@@ -260,7 +254,9 @@ cts <- LBS.fromChunks . return <$> BS.readFile path `E.catch` \e -> throwIO $ PkgDBReadError path e- maybe (throwIO $ BadPkgDB path) return $ decode' cts+ case decodeOrFail cts of+ Left{} -> throwIO $ BadPkgDB path+ Right (_rest, _offset, values) -> pure values where maybeDoInitDB@@ -289,7 +285,7 @@ data PkgDBError = BadPkgDB FilePath -- ^ package database could not be parsed or contains errors | PkgDBReadError FilePath IOException -- ^ package db file could not be read- | PkgExists InstalledPackageId -- ^ attempt to register an already present package id+ | PkgExists UnitId -- ^ attempt to register an already present package id | RegisterNullDB -- ^ attempt to register in the global db when it's not present deriving (Typeable) instance Show PkgDBError where@@ -300,126 +296,15 @@ errPrefix path (show e) show (PkgExists pkgid) = printf "%s: package %s is already in the database" errPrefix (display pkgid)- show (RegisterNullDB) =+ show RegisterNullDB = printf "%s: attempt to register in a null global db" errPrefix instance Exception PkgDBError -data PkgInfoError- = PkgInfoNotFound InstalledPackageId+newtype PkgInfoError+ = PkgInfoNotFound UnitId -- ^ requested package id could not be found in any of the package databases deriving Typeable instance Exception PkgInfoError instance Show PkgInfoError where show (PkgInfoNotFound pkgid) = printf "%s: package not found: %s" errPrefix (display pkgid)-------------------------- Aeson instances --------------------------stdToJSON :: Text a => a -> Value-stdToJSON = toJSON . display-stdFromJSON :: Text a => Value -> Parser a-stdFromJSON = maybe mzero return . simpleParse <=< parseJSON--instance ToJSON License where- toJSON = stdToJSON-instance FromJSON License where- parseJSON = stdFromJSON--instance ToJSON Version where- toJSON = stdToJSON-instance FromJSON Version where- parseJSON = stdFromJSON--instance ToJSON ModuleName where- toJSON = stdToJSON-instance FromJSON ModuleName where- parseJSON = stdFromJSON--instance ToJSON PackageName where- toJSON = stdToJSON-instance FromJSON PackageName where- parseJSON = stdFromJSON--instance ToJSON PackageIdentifier where- toJSON = stdToJSON-instance FromJSON PackageIdentifier where- parseJSON = stdFromJSON--instance ToJSON InstalledPackageId where- toJSON = stdToJSON-instance FromJSON InstalledPackageId where- parseJSON = stdFromJSON--instance ToJSON a => ToJSON (Info.InstalledPackageInfo_ a) where- toJSON i = object- [ "id" .= Info.installedPackageId i- , "name" .= Info.sourcePackageId i- , "license" .= Info.license i- , "copyright" .= Info.copyright i- , "maintainer" .= Info.maintainer i- , "author" .= Info.author i- , "stability" .= Info.stability i- , "homepage" .= Info.homepage i- , "package-url" .= Info.pkgUrl i- , "synopsis" .= Info.synopsis i- , "description" .= Info.description i- , "category" .= Info.category i- , "exposed" .= Info.exposed i- , "exposed-modules" .= Info.exposedModules i- , "hidden-modules" .= Info.hiddenModules i- , "trusted" .= Info.trusted i- , "import-dirs" .= Info.importDirs i- , "library-dirs" .= Info.libraryDirs i- , "hs-libraries" .= Info.hsLibraries i- , "extra-libraries" .= Info.extraLibraries i- , "extra-ghci-libraries" .= Info.extraGHCiLibraries i- , "include-dirs" .= Info.includeDirs i- , "includes" .= Info.includes i- , "depends" .= Info.depends i- , "hugs-options" .= Info.hugsOptions i- , "cc-options" .= Info.ccOptions i- , "ld-options" .= Info.ldOptions i- , "framework-dirs" .= Info.frameworkDirs i- , "frameworks" .= Info.frameworks i- , "haddock-interfaces" .= Info.haddockInterfaces i- , "haddock-html" .= Info.haddockHTMLs i- ]---- FIXME this will break silently if the order of fields changes in the--- future-instance FromJSON a => FromJSON (Info.InstalledPackageInfo_ a) where- parseJSON (Object v) = Info.InstalledPackageInfo <$>- v .: "id" <*>- v .: "name" <*>- v .: "license" <*>- v .: "copyright" <*>- v .: "maintainer" <*>- v .: "author" <*>- v .: "stability" <*>- v .: "homepage" <*>- v .: "package-url" <*>- v .: "synopsis" <*>- v .: "description" <*>- v .: "category" <*>- v .: "exposed" <*>- v .: "exposed-modules" <*>- v .: "hidden-modules" <*>- v .: "trusted" <*>- v .: "import-dirs" <*>- v .: "library-dirs" <*>- v .: "hs-libraries" <*>- v .: "extra-libraries" <*>- v .: "extra-ghci-libraries" <*>- v .: "include-dirs" <*>- v .: "includes" <*>- v .: "depends" <*>- v .: "hugs-options" <*>- v .: "cc-options" <*>- v .: "ld-options" <*>- v .: "framework-dirs" <*>- v .: "frameworks" <*>- v .: "haddock-interfaces" <*>- v .: "haddock-html"- parseJSON _ = mzero