-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Haskell suite library for package management and integration with Cabal -- @package haskell-packages @version 0.3 module Distribution.HaskellSuite.Packages type Packages = [InstalledPackageInfo] -- | Get all packages that are registered in a particular database -- -- If the database doesn't exist, the behaviour is determined by -- maybeInitDB. getInstalledPackages :: IsPackageDB db => Proxy db -> PackageDB -> IO Packages -- | Try to retrieve an InstalledPackageInfo for each of -- InstalledPackageIds from a specified set of PackageDBs. -- -- May throw a PkgInfoNotFound exception. -- -- If a database doesn't exist, the behaviour is determined by -- maybeInitDB. readPackagesInfo :: IsPackageDB db => Proxy db -> [PackageDB] -> [InstalledPackageId] -> IO Packages -- | Package database class. -- -- db will typically be a newtype-wrapped path to the database -- file, although more sophisticated setups are certainly possible. -- -- Consider using StandardDB first, and implement your own -- database type if that isn't enough. 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 } dbName :: IsPackageDB db => Tagged db String readPackageDB :: IsPackageDB db => MaybeInitDB -> db -> IO Packages writePackageDB :: IsPackageDB db => db -> Packages -> IO () globalDB :: IsPackageDB db => IO (Maybe db) dbFromPath :: IsPackageDB db => FilePath -> IO db locateDB :: IsPackageDB db => PackageDB -> IO (Maybe db) userDB :: IsPackageDB db => IO db -- | A flag which tells whether the library should create an empty package -- database if it doesn't exist yet data MaybeInitDB InitDB :: MaybeInitDB Don'tInitDB :: MaybeInitDB -- | This function determines whether a package database should be -- initialized if it doesn't exist yet. -- -- The rule is this: if it is a global or a user database, then -- initialize it; otherwise, don't. -- -- Rationale: if the database was specified by the user, she could have -- made a mistake in the path, and we'd rather report it. On the other -- hand, it is our responsibility to ensure that the user and global -- databases exist. maybeInitDB :: PackageDB -> MaybeInitDB data StandardDB name StandardDB :: FilePath -> StandardDB name class IsDBName name getDBName :: IsDBName name => Tagged name String -- | Make all paths in the package info relative to the given base -- directory. makePkgInfoRelative :: FilePath -> InstalledPackageInfo -> InstalledPackageInfo -- | Make all relative paths in the package info absolute, interpreting -- them relative to the given base directory. makePkgInfoAbsolute :: FilePath -> InstalledPackageInfo -> InstalledPackageInfo -- | Apply a given function to all file paths contained in the package info mapPaths :: (FilePath -> FilePath) -> (InstalledPackageInfo -> InstalledPackageInfo) writeDB :: FilePath -> Packages -> IO () readDB :: MaybeInitDB -> FilePath -> IO Packages -- | If the path does not exist, create an empty database there. Otherwise, -- do nothing. initDB :: FilePath -> IO () data PkgDBError -- | package database could not be parsed or contains errors BadPkgDB :: FilePath -> PkgDBError -- | package db file could not be read PkgDBReadError :: FilePath -> IOException -> PkgDBError -- | attempt to register an already present package id PkgExists :: InstalledPackageId -> PkgDBError -- | attempt to register in the global db when it's not present RegisterNullDB :: PkgDBError data PkgInfoError -- | requested package id could not be found in any of the package -- databases PkgInfoNotFound :: InstalledPackageId -> PkgInfoError instance FromJSON m0 => FromJSON (InstalledPackageInfo_ m0) instance ToJSON m0 => ToJSON (InstalledPackageInfo_ m0) instance FromJSON ExposedModule instance ToJSON ExposedModule instance FromJSON OriginalModule instance ToJSON OriginalModule instance Typeable PkgDBError instance Typeable PkgInfoError instance FromJSON PackageKey instance ToJSON PackageKey instance FromJSON InstalledPackageId instance ToJSON InstalledPackageId instance FromJSON PackageIdentifier instance ToJSON PackageIdentifier instance FromJSON PackageName instance ToJSON PackageName instance FromJSON ModuleName instance ToJSON ModuleName instance FromJSON Version instance ToJSON Version instance FromJSON License instance ToJSON License instance Show PkgInfoError instance Exception PkgInfoError instance Exception PkgDBError instance Show PkgDBError instance IsDBName name => IsPackageDB (StandardDB name) module Distribution.HaskellSuite.Modules -- | A standard module monad transformer. -- -- i is the type of module info, m is the underlying -- monad. data ModuleT i m a -- | Tries to find the module in the current set of packages, then find the -- module's info file, and reads and caches its contents. -- -- Returns Nothing if the module could not be found in the current -- set of packages. If the module is found, but something else goes wrong -- (e.g. there's no info file for it), an exception is thrown. getModuleInfo :: (MonadModule m, ModName n) => n -> m (Maybe (ModuleInfo m)) -- | Run a ModuleT action. -- -- This is a simplified version of runModuleT. evalModuleT :: MonadIO m => ModuleT i m a -> Packages -> String -> (FilePath -> m i) -> m a -- | Run a ModuleT action runModuleT :: MonadIO m => ModuleT i m a -> Packages -> String -> (FilePath -> m i) -> Map ModuleName i -> m (a, Map ModuleName i) -- | This class defines the interface that is used by getModuleInfo, -- so that you can use it in monads other than ModuleT. -- -- You don't typically have to define your own instances of this class, -- but here are a couple of cases when you might: -- --
-- import qualified Distribution.HaskellSuite.Compiler as Compiler --module Distribution.HaskellSuite.Compiler -- | An abstraction over a Haskell compiler. -- -- Once you've written a Compiler.Is instance, you get -- Cabal integration for free (via Compiler.main). -- -- Consider whether Compiler.Simple suits your needs — -- then you need to write even less code. -- -- Minimal definition: DB, name, version, -- fileExtensions, compile, languages, -- languageExtensions. -- -- fileExtensions are only used for installLib, so if you -- define a custom installLib, fileExtensions won't be used -- (but you'll still get a compiler warning if you do not define it). class IsPackageDB (DB compiler) => Is compiler where type family 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 = installedPackageId 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 (installedPackageId 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 . installedPackageId } } } name :: Is compiler => compiler -> String version :: Is compiler => compiler -> Version fileExtensions :: Is compiler => compiler -> [String] compile :: Is compiler => compiler -> CompileFn languages :: Is compiler => compiler -> [Language] languageExtensions :: Is compiler => compiler -> [Extension] installLib :: Is compiler => compiler -> FilePath -> FilePath -> Maybe FilePath -> PackageIdentifier -> [ModuleName] -> IO () register :: Is compiler => compiler -> PackageDB -> InstalledPackageInfo -> IO () unregister :: Is compiler => compiler -> PackageDB -> PackageId -> IO () list :: Is compiler => compiler -> PackageDB -> IO () -- | Compilation function type CompileFn = FilePath -> Maybe Language -> [Extension] -> CpphsOptions -> PackageId -> PackageDBStack -> [InstalledPackageId] -> [FilePath] -> IO () data Simple db simple :: String -> Version -> [Language] -> [Extension] -> CompileFn -> [String] -> Simple db main :: Is c => c -> IO () customMain :: Is c => Parser (IO ()) -> c -> IO () instance IsPackageDB db => Is (Simple db) -- | This module re-exports all you need in order to read package -- databases and module info files created by compilers that use -- haskell-packages. -- -- If you are writing a compiler, i.e. a program that creates or writes -- package databases or module info files — then take a look at -- Distribution.HaskellSuite.Compiler. It provides command-line -- options handling and Cabal integration. module Distribution.HaskellSuite