haskell-packages 0.5 → 0.6
raw patch · 6 files changed
+116/−166 lines, 6 filesdep +binarydep −aesondep ~CabalPVP ok
version bump matches the API change (PVP)
Dependencies added: binary
Dependencies removed: aeson
Dependency ranges changed: Cabal
API changes (from Hackage documentation)
- Distribution.HaskellSuite.Packages: data PkgInfoError
- Distribution.HaskellSuite.Packages: data StandardDB name
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.InstalledPackageInfo.ExposedModule
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.InstalledPackageInfo.InstalledPackageInfo
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.InstalledPackageInfo.OriginalModule
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.License.License
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.ModuleName.ModuleName
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.Package.AbiHash
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.Package.PackageIdentifier
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.Package.PackageName
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.FromJSON.FromJSON Distribution.Package.UnitId
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.InstalledPackageInfo.ExposedModule
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.InstalledPackageInfo.InstalledPackageInfo
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.InstalledPackageInfo.OriginalModule
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.License.License
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.ModuleName.ModuleName
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.Package.AbiHash
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.Package.PackageIdentifier
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.Package.PackageName
- Distribution.HaskellSuite.Packages: instance Data.Aeson.Types.ToJSON.ToJSON Distribution.Package.UnitId
+ Distribution.HaskellSuite.Packages: newtype PkgInfoError
+ Distribution.HaskellSuite.Packages: newtype StandardDB name
- Distribution.HaskellSuite.Compiler: class IsPackageDB (DB compiler) => Is compiler where type DB compiler installLib t buildDir targetDir _dynlibTargetDir _pkg mods = forM_ (fileExtensions t) $ \ ext -> do { findModuleFiles [buildDir] [ext] mods >>= installOrdinaryFiles normal targetDir } register _tool dbspec pkg = do { mbDb <- locateDB dbspec; case mbDb :: Maybe (DB compiler) of { Nothing -> throwIO RegisterNullDB Just db -> do { pkgs <- readPackageDB (maybeInitDB dbspec) db; let pkgid = installedUnitId pkg; writePackageDB db $ pkg : removePackage pkgid pkgs } } } unregister _tool dbspec pkg = do { let pkgCriterion = (case pkgVersion $ packageId pkg of { Version [] _ -> ((==) `on` pkgName) pkg _ -> (==) pkg }) . sourcePackageId; mbDb <- locateDB dbspec; case mbDb :: Maybe (DB compiler) of { Nothing -> throwIO RegisterNullDB Just db -> do { pkgs <- readPackageDB (maybeInitDB dbspec) db; let (packagesRemoved, packagesLeft) = partition pkgCriterion pkgs; if null packagesRemoved then putStrLn $ "No packages removed" else do { putStrLn "Packages removed:"; forM_ packagesRemoved $ \ p -> putStrLn $ " " ++ display (installedUnitId p) }; writePackageDB db packagesLeft } } } list _tool dbspec = do { mbDb <- locateDB dbspec; case mbDb :: Maybe (DB compiler) of { Nothing -> return () Just db -> do { pkgs <- readPackageDB (maybeInitDB dbspec) db; forM_ pkgs $ putStrLn . display . installedUnitId } } } where {
+ Distribution.HaskellSuite.Compiler: class IsPackageDB (DB compiler) => Is compiler where {
- Distribution.HaskellSuite.Compiler: customMain :: Is c => Parser (IO ()) -> c -> IO ()
+ Distribution.HaskellSuite.Compiler: customMain :: Is c => Parser IO () -> c -> IO ()
- Distribution.HaskellSuite.Modules: class Monad m => MonadModule m where type ModuleInfo m where {
+ Distribution.HaskellSuite.Modules: class Monad m => MonadModule m where {
- Distribution.HaskellSuite.Packages: class IsPackageDB db where locateDB GlobalPackageDB = globalDB locateDB UserPackageDB = Just <$> userDB locateDB (SpecificPackageDB p) = Just <$> dbFromPath p userDB = do { let name = untag (dbName :: Tagged db String); path <- (</>) <$> haskellPackagesDir <*> pure (name <.> "db"); dbFromPath path }
+ Distribution.HaskellSuite.Packages: class IsPackageDB db
Files
- README.md +8/−7
- haskell-packages.cabal +6/−5
- src/Distribution/HaskellSuite/Cabal.hs +44/−43
- src/Distribution/HaskellSuite/Compiler.hs +6/−5
- src/Distribution/HaskellSuite/Modules.hs +24/−29
- src/Distribution/HaskellSuite/Packages.hs +28/−77
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.5+version: 0.6 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,9 +40,9 @@ build-depends: base >=4.5 && < 5 , optparse-applicative >= 0.11- , aeson >= 0.11+ , binary >= 0.8 , bytestring >= 0.9- , Cabal == 1.24.*+ , Cabal == 2.0.* , deepseq , directory , filepath
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.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 $ mkUnitId <$> 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,7 +22,8 @@ ) where -import Data.Version+-- import Data.Version+import Distribution.Version import Distribution.HaskellSuite.Packages import {-# SOURCE #-} Distribution.HaskellSuite.Cabal import Distribution.Simple.Compiler@@ -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 @@ -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,7 +146,7 @@ if null packagesRemoved then- putStrLn $ "No packages removed"+ putStrLn "No packages removed" else do putStrLn "Packages removed:" forM_ packagesRemoved $ \p ->
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'.@@ -112,11 +113,11 @@ -- @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@@ -149,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.TH-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 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 --@@ -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,7 @@ cts <- LBS.fromChunks . return <$> BS.readFile path `E.catch` \e -> throwIO $ PkgDBReadError path e- maybe (throwIO $ BadPkgDB path) return $ decode' cts+ maybe (throwIO $ BadPkgDB path) return $ decode cts where maybeDoInitDB@@ -300,11 +294,11 @@ 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+newtype PkgInfoError = PkgInfoNotFound UnitId -- ^ requested package id could not be found in any of the package databases deriving Typeable@@ -312,46 +306,3 @@ 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 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 UnitId where- toJSON = stdToJSON-instance FromJSON UnitId where- parseJSON = stdFromJSON--instance ToJSON AbiHash where- toJSON = stdToJSON-instance FromJSON AbiHash where- parseJSON = stdFromJSON--deriveJSON defaultOptions ''Info.OriginalModule-deriveJSON defaultOptions ''Info.ExposedModule-deriveJSON defaultOptions ''Info.InstalledPackageInfo