packages feed

stack 0.0.3 → 0.1.0.0

raw patch · 50 files changed

+4722/−1110 lines, 50 filesdep +file-embeddep +unix-compatdep +word8dep ~asyncdep ~basedep ~bytestringnew-uploader

Dependencies added: file-embed, unix-compat, word8

Dependency ranges changed: async, base, bytestring, conduit, conduit-extra, containers, directory, filepath, process, resourcet, temporary, text, transformers

Files

ChangeLog.md view
@@ -1,4 +1,15 @@-## Unreleased+## 0.1.0.0++* Fall back to cabal dependency solver when a snapshot can't be found+* Basic implementation of `stack new` [#137](https://github.com/commercialhaskell/stack/issues/137)+* `stack solver` command [#364](https://github.com/commercialhaskell/stack/issues/364)+* `stack path` command [#95](https://github.com/commercialhaskell/stack/issues/95)+* Haddocks [#143](https://github.com/commercialhaskell/stack/issues/143):+    * Build for dependencies+    * Use relative links+    * Generate module contents and index for all packages in project++## 0.0.3  * `--prefetch` [#297](https://github.com/commercialhaskell/stack/issues/297) * `upload` command ported from stackage-upload [#225](https://github.com/commercialhaskell/stack/issues/225)
README.md view
@@ -27,18 +27,22 @@  #### How to use -Go into a Haskell project directory and run `stack build`. This will-do the following:+Go into a Haskell project directory and run `stack build`. If everything is+already configured, this will: -* Automatically create a stack configuration file in the current-  directory.-* Figure out what Stackage release (LTS or nightly) is appropriate-  for the dependencies.-* Download and install GHC. * Download the package index. * Download and install all necessary dependencies for the project. * Build and install the project. +You may be prompted to run some of the following along the way:++* `stack new` to create a brand new project.+* `stack init` to create a stack configuration file for an existing project.+  stack will figure out what Stackage release (LTS or nightly) is appropriate+  for the dependencies.+* `stack setup` to download and install the correct GHC version. (For+  information on installation paths, please use the `stack path` command.)+ Run `stack` for a complete list of commands.  #### Architecture@@ -52,8 +56,7 @@   please see   [the FAQ](https://github.com/commercialhaskell/stack/wiki/FAQ). * For general questions, comments, feedback and support please write-  to-  [the Commercial Haskell mailing list](https://groups.google.com/d/forum/commercialhaskell).+  to [the stack mailing list](https://groups.google.com/d/forum/haskell-stack). * For bugs, issues, or requests please   [open an issue](https://github.com/commercialhaskell/stack/issues/new). 
+ new-template/LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Your name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ new-template/Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ new-template/app/Main.hs view
@@ -0,0 +1,6 @@+module Main where++import Lib++main :: IO ()+main = someFunc
+ new-template/new-template.cabal view
@@ -0,0 +1,41 @@+name:                new-template+version:             0.1.0.0+synopsis:            Initial project template from stack+description:         Please see README.md+homepage:            http://github.com/name/project+license:             BSD3+license-file:        LICENSE+author:              Your name here+maintainer:          your.address@example.com+-- copyright:           +category:            Web+build-type:          Simple+-- extra-source-files:  +cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Lib+  build-depends:       base >= 4.7 && < 5+  default-language:    Haskell2010++executable new-template-exe+  hs-source-dirs:      app+  main-is:             Main.hs+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  build-depends:       base+                     , new-template+  default-language:    Haskell2010++test-suite new-template-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , new-template+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/name/project
+ new-template/src/Lib.hs view
@@ -0,0 +1,6 @@+module Lib+    ( someFunc+    ) where++someFunc :: IO ()+someFunc = putStrLn "someFunc"
+ new-template/test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"
src/Data/Aeson/Extended.hs view
@@ -15,9 +15,9 @@ import Data.Monoid ((<>))  (.:) :: FromJSON a => Object -> Text -> Parser a-(.:) o p = modifyFailure (("failed to parse field " <> unpack p <> ": ") <>) (o A..: p)+(.:) o p = modifyFailure (("failed to parse field '" <> unpack p <> "': ") <>) (o A..: p) {-# INLINE (.:) #-}  (.:?) :: FromJSON a => Object -> Text -> Parser (Maybe a)-(.:?) o p = modifyFailure (("failed to parse field " <> unpack p <> ": ") <>) (o A..:? p)+(.:?) o p = modifyFailure (("failed to parse field '" <> unpack p <> "': ") <>) (o A..:? p) {-# INLINE (.:?) #-}
+ src/Data/Attoparsec/Args.hs view
@@ -0,0 +1,30 @@+-- | Parsing argument-like things.++module Data.Attoparsec.Args (EscapingMode(..), argsParser) where++import           Control.Applicative+import           Data.Attoparsec.Text ((<?>))+import qualified Data.Attoparsec.Text as P+import           Data.Attoparsec.Types (Parser)+import           Data.Text (Text)++-- | Mode for parsing escape characters.+data EscapingMode+    = Escaping+    | NoEscaping+    deriving (Show,Eq,Enum)++-- | A basic argument parser. It supports space-separated text, and+-- string quotation with identity escaping: \x -> x.+argsParser :: EscapingMode -> Parser Text [String]+argsParser mode = many (P.skipSpace *> (quoted <|> unquoted)) <*+                  P.skipSpace <* (P.endOfInput <?> "unterminated string")+  where+    unquoted = P.many1 naked+    quoted = P.char '"' *> string <* P.char '"'+    string = many (case mode of+                     Escaping -> escaped <|> nonquote+                     NoEscaping -> nonquote)+    escaped = P.char '\\' *> P.anyChar+    nonquote = P.satisfy (not . (=='"'))+    naked = P.satisfy (not . flip elem ("\" " :: String))
src/Data/Binary/VersionTagged.hs view
@@ -1,46 +1,48 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} -- | Tag a Binary instance with the stack version number to ensure we're -- reading a compatible format. module Data.Binary.VersionTagged     ( taggedDecodeOrLoad     , taggedEncodeFile+    , BinarySchema (..)     ) where  import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Binary (Binary (..), encodeFile, decodeFileOrFail, putWord8, getWord8) import Control.Exception.Enclosed (tryIO)-import qualified Paths_stack-import Stack.Types.Version (Version, fromCabalVersion) import System.FilePath (takeDirectory) import System.Directory (createDirectoryIfMissing) import qualified Data.ByteString as S import Data.ByteString (ByteString) import Control.Monad (forM_, when)--tag :: Version-tag = fromCabalVersion Paths_stack.version+import Data.Proxy  magic :: ByteString-magic = "STACK"+magic = "stack" +-- | A @Binary@ instance that also has a schema version+class Binary a => BinarySchema a where+    binarySchema :: Proxy a -> Int+ newtype WithTag a = WithTag a-instance Binary a => Binary (WithTag a) where+instance forall a. BinarySchema a => Binary (WithTag a) where     get = do         forM_ (S.unpack magic) $ \w -> do             w' <- getWord8             when (w /= w')                 $ fail "Mismatched magic string, forcing a recompute"         tag' <- get-        if tag == tag'+        if binarySchema (Proxy :: Proxy a) == tag'             then fmap WithTag get             else fail "Mismatched tags, forcing a recompute"     put (WithTag x) = do         mapM_ putWord8 $ S.unpack magic-        put tag+        put (binarySchema (Proxy :: Proxy a))         put x  -- | Write to the given file, with a version tag.-taggedEncodeFile :: (Binary a, MonadIO m)+taggedEncodeFile :: (BinarySchema a, MonadIO m)                  => FilePath                  -> a                  -> m ()@@ -51,7 +53,7 @@ -- | Read from the given file. If the read fails, run the given action and -- write that back to the file. Always starts the file off with the version -- tag.-taggedDecodeOrLoad :: (Binary a, MonadIO m)+taggedDecodeOrLoad :: (BinarySchema a, MonadIO m)                    => FilePath                    -> m a                    -> m a
src/Network/HTTP/Download/Verified.hs view
@@ -72,29 +72,35 @@ -- | An exception regarding verification of a download. data VerifiedDownloadException     = WrongContentLength+          Request           Int -- expected           ByteString -- actual (as listed in the header)     | WrongStreamLength+          Request           Int -- expected           Int -- actual     | WrongDigest+          Request           String -- algorithm           CheckHexDigest -- expected           String -- actual (shown)   deriving (Typeable) instance Show VerifiedDownloadException where-    show (WrongContentLength expected actual) =+    show (WrongContentLength req expected actual) =         "Download expectation failure: ContentLength header\n"         ++ "Expected: " ++ show expected ++ "\n"-        ++ "Actual:   " ++ displayByteString actual-    show (WrongStreamLength expected actual) =+        ++ "Actual:   " ++ displayByteString actual ++ "\n"+        ++ "For: " ++ show (getUri req)+    show (WrongStreamLength req expected actual) =         "Download expectation failure: download size\n"         ++ "Expected: " ++ show expected ++ "\n"-        ++ "Actual:   " ++ show actual-    show (WrongDigest algo expected actual) =+        ++ "Actual:   " ++ show actual ++ "\n"+        ++ "For: " ++ show (getUri req)+    show (WrongDigest req algo expected actual) =         "Download expectation failure: content hash (" ++ algo ++  ")\n"         ++ "Expected: " ++ displayCheckHexDigest expected ++ "\n"-        ++ "Actual:   " ++ actual+        ++ "Actual:   " ++ actual ++ "\n"+        ++ "For: " ++ show (getUri req)  instance Exception VerifiedDownloadException @@ -125,9 +131,10 @@ -- -- Throws WrongDigest (VerifiedDownloadException) sinkCheckHash :: MonadThrow m-    => HashCheck+    => Request+    -> HashCheck     -> Consumer ByteString m ()-sinkCheckHash HashCheck{..} = do+sinkCheckHash req HashCheck{..} = do     digest <- sinkHashUsing hashCheckAlgorithm     let actualDigestString = show digest     let actualDigestHexByteString = digestToHexByteString digest@@ -142,23 +149,24 @@             || b == actualDigestHexByteString      when (not passedCheck) $-        throwM $ WrongDigest (show hashCheckAlgorithm) hashCheckHexDigest actualDigestString+        throwM $ WrongDigest req (show hashCheckAlgorithm) hashCheckHexDigest actualDigestString  assertLengthSink :: MonadThrow m-    => LengthCheck+    => Request+    -> LengthCheck     -> ZipSink ByteString m ()-assertLengthSink expectedStreamLength = ZipSink $ do+assertLengthSink req expectedStreamLength = ZipSink $ do   Sum actualStreamLength <- CL.foldMap (Sum . ByteString.length)   when (actualStreamLength /= expectedStreamLength) $-    throwM $ WrongStreamLength expectedStreamLength actualStreamLength+    throwM $ WrongStreamLength req expectedStreamLength actualStreamLength  -- | A more explicitly type-guided sinkHash. sinkHashUsing :: (Monad m, HashAlgorithm a) => a -> Consumer ByteString m (Digest a) sinkHashUsing _ = sinkHash  -- | Turns a list of hash checks into a ZipSink that checks all of them.-hashChecksToZipSink :: MonadThrow m => [HashCheck] -> ZipSink ByteString m ()-hashChecksToZipSink = traverse_ (ZipSink . sinkCheckHash)+hashChecksToZipSink :: MonadThrow m => Request -> [HashCheck] -> ZipSink ByteString m ()+hashChecksToZipSink req = traverse_ (ZipSink . sinkCheckHash req)  -- | Copied and extended version of Network.HTTP.Download.download. --@@ -215,7 +223,7 @@      checkExpectations = bracket (openFile fp ReadMode) hClose $ \h -> do         whenJust drLengthCheck $ checkFileSizeExpectations h-        sourceHandle h $$ getZipSink (hashChecksToZipSink drHashChecks)+        sourceHandle h $$ getZipSink (hashChecksToZipSink drRequest drHashChecks)      -- doesn't move the handle     checkFileSizeExpectations h expectedFileSize = do@@ -231,7 +239,7 @@             Just lengthBS -> do               let lengthStr = displayByteString lengthBS               when (lengthStr /= show expectedContentLength) $-                throwM $ WrongContentLength expectedContentLength lengthBS+                throwM $ WrongContentLength drRequest expectedContentLength lengthBS             _ -> return ()      go h res = do@@ -250,7 +258,7 @@         responseBody res             $= maybe (awaitForever yield) CB.isolate drLengthCheck             $$ getZipSink-                ( hashChecksToZipSink hashChecks-                  *> maybe (pure ()) assertLengthSink drLengthCheck+                ( hashChecksToZipSink drRequest hashChecks+                  *> maybe (pure ()) (assertLengthSink drRequest) drLengthCheck                   *> ZipSink (sinkHandle h)                   *> ZipSink progressSink)
src/Options/Applicative/Args.hs view
@@ -5,15 +5,11 @@ module Options.Applicative.Args     (argsArgument     ,argsOption-    ,parseArgsFromString-    ,argsParser)+    ,parseArgsFromString)     where -import           Control.Applicative-import           Data.Attoparsec.Text ((<?>))+import           Data.Attoparsec.Args import qualified Data.Attoparsec.Text as P-import           Data.Attoparsec.Types (Parser)-import           Data.Text (Text) import qualified Data.Text as T import qualified Options.Applicative as O @@ -33,17 +29,4 @@  -- | Parse from a string. parseArgsFromString :: String -> Either String [String]-parseArgsFromString = P.parseOnly argsParser . T.pack---- | A basic argument parser. It supports space-separated text, and--- string quotation with identity escaping: \x -> x.-argsParser :: Parser Text [String]-argsParser = many (P.skipSpace *> (quoted <|> unquoted)) <*-             P.skipSpace <* (P.endOfInput <?> "unterminated string")-  where-    unquoted = P.many1 naked-    quoted = P.char '"' *> string <* P.char '"'-    string = many (escaped <|> nonquote)-    escaped = P.char '\\' *> P.anyChar-    nonquote = P.satisfy (not . (=='"'))-    naked = P.satisfy (not . flip elem ("\" " :: String))+parseArgsFromString = P.parseOnly (argsParser Escaping) . T.pack
src/Options/Applicative/Builder/Extra.hs view
@@ -2,8 +2,10 @@  module Options.Applicative.Builder.Extra   (boolFlags+  ,boolFlagsNoDefault   ,maybeBoolFlags   ,enableDisableFlags+  ,enableDisableFlagsNoDefault   ,extraHelpOption   ,execExtraHelp)   where@@ -17,6 +19,10 @@ boolFlags :: Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool boolFlags defaultValue = enableDisableFlags defaultValue True False +-- | Enable/disable flags for a @Bool@, without a default case (to allow chaining @<|>@s).+boolFlagsNoDefault :: String -> String -> Mod FlagFields Bool -> Parser Bool+boolFlagsNoDefault = enableDisableFlagsNoDefault True False+ -- | Enable/disable flags for a @(Maybe Bool)@. maybeBoolFlags :: String -> String -> Mod FlagFields (Maybe Bool) -> Parser (Maybe Bool) maybeBoolFlags = enableDisableFlags Nothing (Just True) (Just False)@@ -24,6 +30,12 @@ -- | Enable/disable flags for any type. enableDisableFlags :: a -> a -> a -> String -> String -> Mod FlagFields a -> Parser a enableDisableFlags defaultValue enabledValue disabledValue name helpSuffix mods =+  enableDisableFlagsNoDefault enabledValue disabledValue name helpSuffix mods <|>+  pure defaultValue++-- | Enable/disable flags for any type, without a default (to allow chaining @<|>@s)+enableDisableFlagsNoDefault :: a -> a -> String -> String -> Mod FlagFields a -> Parser a+enableDisableFlagsNoDefault enabledValue disabledValue name helpSuffix mods =   flag' enabledValue         (long name <>          help ("Enable " ++ helpSuffix) <>@@ -41,8 +53,7 @@         (internal <>          long ("disable-" ++ name) <>          help ("Disable " ++ helpSuffix) <>-         mods) <|>-  pure defaultValue+         mods)  -- | Show an extra help option (e.g. @--docker-help@ shows help for all @--docker*@ args). -- To actually show have that help appear, use 'execExtraHelp' before executing the main parser.
src/Path/IO.hs view
@@ -14,7 +14,8 @@   ,removeTree   ,removeTreeIfExists   ,fileExists-  ,dirExists)+  ,dirExists+  ,copyDirectoryRecursive)   where  import           Control.Exception hiding (catch)@@ -150,3 +151,24 @@ dirExists :: MonadIO m => Path b Dir -> m Bool dirExists =     liftIO . doesFileExist . toFilePath++-- | Copy a directory recursively.  This just uses 'copyFile', so it is not smart about symbolic+-- links or other special files.+copyDirectoryRecursive :: (MonadIO m,MonadThrow m)+                       => Path Abs Dir -- ^ Source directory+                       -> Path Abs Dir -- ^ Destination directory+                       -> m ()+copyDirectoryRecursive srcDir destDir =+    do liftIO (createDirectoryIfMissing False (toFilePath destDir))+       (srcSubDirs,srcFiles) <- listDirectory srcDir+       forM_ srcFiles+             (\srcFile ->+                case stripDir srcDir srcFile of+                  Nothing -> return ()+                  Just relFile -> liftIO (copyFile (toFilePath srcFile)+                                                   (toFilePath (destDir </> relFile))))+       forM_ srcSubDirs+             (\srcSubDir ->+                case stripDir srcDir srcSubDir of+                  Nothing -> return ()+                  Just relSubDir -> copyDirectoryRecursive srcSubDir (destDir </> relSubDir))
src/Stack/Build.hs view
@@ -31,6 +31,7 @@ import           Prelude hiding (FilePath, writeFile) import           Stack.Build.ConstructPlan import           Stack.Build.Execute+import           Stack.Build.Haddock import           Stack.Build.Installed import           Stack.Build.Source import           Stack.Build.Types@@ -41,12 +42,6 @@ import           Stack.Types import           Stack.Types.Internal -{- EKB TODO: doc generation for stack-doc-server-#ifndef mingw32_HOST_OS-import           System.Posix.Files (createSymbolicLink,removeLink)-#endif---}- type M env m = (MonadIO m,MonadReader env m,HasHttpManager env,HasBuildConfig env,MonadLogger m,MonadBaseControl IO m,MonadCatch m,MonadMask m,HasLogLevel env,HasEnvConfig env,HasTerminal env)  -- | Build@@ -55,7 +50,12 @@     menv <- getMinimalEnvOverride      (mbp, locals, extraToBuild, sourceMap) <- loadSourceMap bopts-    (installedMap, locallyRegistered) <- getInstalled menv profiling sourceMap+    (installedMap, locallyRegistered) <-+        getInstalled menv+                     GetInstalledOpts+                         { getInstalledProfiling = profiling+                         , getInstalledHaddock   = shouldHaddockDeps bopts }+                     sourceMap      baseConfigOpts <- mkBaseConfigOpts bopts     plan <- withLoadPackage menv $ \loadPackage ->@@ -66,12 +66,12 @@      if boptsDryrun bopts         then printPlan (boptsFinalAction bopts) plan-        else executePlan menv bopts baseConfigOpts locals plan+        else executePlan menv bopts baseConfigOpts locals sourceMap plan   where     profiling = boptsLibProfile bopts || boptsExeProfile bopts  -- | Get the @BaseConfigOpts@ necessary for constructing configure options-mkBaseConfigOpts :: (MonadIO m, MonadReader env m, HasBuildConfig env, MonadThrow m)+mkBaseConfigOpts :: (MonadIO m, MonadReader env m, HasEnvConfig env, MonadThrow m)                  => BuildOpts -> m BaseConfigOpts mkBaseConfigOpts bopts = do     snapDBPath <- packageDatabaseDeps@@ -92,20 +92,20 @@                 -> ((PackageName -> Version -> Map FlagName Bool -> IO Package) -> m a)                 -> m a withLoadPackage menv inner = do-    bconfig <- asks getBuildConfig+    econfig <- asks getEnvConfig     withCabalLoader menv $ \cabalLoader ->         inner $ \name version flags -> do             bs <- cabalLoader $ PackageIdentifier name version -- TODO automatically update index the first time this fails-            readPackageBS (depPackageConfig bconfig flags) bs+            readPackageBS (depPackageConfig econfig flags) bs   where     -- | Package config to be used for dependencies-    depPackageConfig :: BuildConfig -> Map FlagName Bool -> PackageConfig-    depPackageConfig bconfig flags = PackageConfig+    depPackageConfig :: EnvConfig -> Map FlagName Bool -> PackageConfig+    depPackageConfig econfig flags = PackageConfig         { packageConfigEnableTests = False         , packageConfigEnableBenchmarks = False         , packageConfigFlags = flags-        , packageConfigGhcVersion = bcGhcVersion bconfig-        , packageConfigPlatform = configPlatform (getConfig bconfig)+        , packageConfigGhcVersion = envConfigGhcVersion econfig+        , packageConfigPlatform = configPlatform (getConfig econfig)         }  -- | Reset the build (remove Shake database and .gen files).@@ -115,196 +115,3 @@     forM_         (Map.keys (bcPackages bconfig))         (distDirFromDir >=> removeTreeIfExists)--------------------------------------------------------------- DEAD CODE BELOW HERE-------------------------------------------------------------{- EKB TODO: doc generation for stack-doc-server-            (boptsFinalAction bopts == DoHaddock)-            (buildDocIndex-                 (wanted pwd)-                 docLoc-                 packages-                 mgr-                 logLevel)-                                  -}--{- EKB TODO: doc generation for stack-doc-server--- | Build the haddock documentation index and contents.-buildDocIndex :: (Package -> Wanted)-              -> Path Abs Dir-              -> Set Package-              -> Manager-              -> LogLevel-              -> Rules ()-buildDocIndex wanted docLoc packages mgr logLevel =-  do runHaddock "--gen-contents" $(mkRelFile "index.html")-     runHaddock "--gen-index" $(mkRelFile "doc-index.html")-     combineHoogle-  where-    runWithLogging = runStackLoggingT mgr logLevel-    runHaddock genOpt destFilename =-      do let destPath = toFilePath (docLoc </> destFilename)-         want [destPath]-         destPath %> \_ ->-           runWithLogging-               (do needDeps-                   ifcOpts <- liftIO (fmap concat (mapM toInterfaceOpt (S.toList packages)))-                   runIn docLoc-                         "haddock"-                         mempty-                         (genOpt:ifcOpts)-                         Nothing)-    toInterfaceOpt package =-      do let pv = joinPkgVer (packageName package,packageVersion package)-             srcPath = (toFilePath docLoc) ++ "/" ++-                       pv ++ "/" ++-                       packageNameString (packageName package) ++ "." ++-                       haddockExtension-         exists <- doesFileExist srcPath-         return (if exists-                    then ["-i"-                         ,"../" ++-                          pv ++-                          "," ++-                          srcPath]-                     else [])-    combineHoogle =-      do let destHoogleDbLoc = hoogleDatabaseFile docLoc-             destPath = toFilePath destHoogleDbLoc-         want [destPath]-         destPath %> \_ ->-           runWithLogging-               (do needDeps-                   srcHoogleDbs <- liftIO (fmap concat (mapM toSrcHoogleDb (S.toList packages)))-                   callProcess-                        "hoogle"-                        ("combine" :-                         "-o" :-                         toFilePath destHoogleDbLoc :-                         srcHoogleDbs))-    toSrcHoogleDb package =-      do let srcPath = toFilePath docLoc ++ "/" ++-                       joinPkgVer (packageName package,packageVersion package) ++ "/" ++-                       packageNameString (packageName package) ++ "." ++-                       hoogleDbExtension-         exists <- doesFileExist srcPath-         return (if exists-                    then [srcPath]-                    else [])-    needDeps =-      need (concatMap (\package -> if wanted package == Wanted-                                    then let dir = packageDir package-                                         in [toFilePath (builtFileFromDir dir)]-                                    else [])-                      (S.toList packages))--#ifndef mingw32_HOST_OS--- | Remove existing links docs for package from @~/.shake/doc@.-removeDocLinks :: Path Abs Dir -> Package -> IO ()-removeDocLinks docLoc package =-  do createDirectoryIfMissing True-                              (toFilePath docLoc)-     userDocLs <--       fmap (map (toFilePath docLoc ++))-            (getDirectoryContents (toFilePath docLoc))-     forM_ userDocLs $-       \docPath ->-         do isDir <- doesDirectoryExist docPath-            when isDir-                 (case breakPkgVer (FilePath.takeFileName docPath) of-                    Just (p,_) ->-                      when (p == packageName package)-                           (removeLink docPath)-                    Nothing -> return ())---- | Add link for package to @~/.shake/doc@.-createDocLinks :: Path Abs Dir -> Package -> IO ()-createDocLinks docLoc package =-  do let pkgVer =-           joinPkgVer (packageName package,(packageVersion package))-     pkgVerLoc <- liftIO (parseRelDir pkgVer)-     let pkgDestDocLoc = docLoc </> pkgVerLoc-         pkgDestDocPath =-           FilePath.dropTrailingPathSeparator (toFilePath pkgDestDocLoc)-         cabalDocLoc = parent docLoc </>-                       $(mkRelDir "share/doc/")-     haddockLocs <--       do cabalDocExists <- doesDirectoryExist (toFilePath cabalDocLoc)-          if cabalDocExists-             then findFiles cabalDocLoc-                            (\fileLoc ->-                               FilePath.takeExtensions (toFilePath fileLoc) ==-                               "." ++ haddockExtension &&-                               dirname (parent fileLoc) ==-                               $(mkRelDir "html/") &&-                               toFilePath (dirname (parent (parent fileLoc))) ==-                               (pkgVer ++ "/"))-                            (\dirLoc ->-                               not (isHiddenDir dirLoc) &&-                               dirname (parent (parent dirLoc)) /=-                               $(mkRelDir "html/"))-             else return []-     case haddockLocs of-       [haddockLoc] ->-         case stripDir (parent docLoc)-                          haddockLoc of-           Just relHaddockPath ->-             do let srcRelPathCollapsed =-                      FilePath.takeDirectory (FilePath.dropTrailingPathSeparator (toFilePath relHaddockPath))-                    {-srcRelPath = "../" ++ srcRelPathCollapsed-}-                createSymbolicLink (FilePath.dropTrailingPathSeparator srcRelPathCollapsed)-                                   pkgDestDocPath-           Nothing -> return ()-       _ -> return ()-#endif /* not defined(mingw32_HOST_OS) */---- | Get @-i@ arguments for haddock for dependencies.-haddockInterfaceOpts :: Path Abs Dir -> Package -> Set Package -> IO [String]-haddockInterfaceOpts userDocLoc package packages =-  do mglobalDocLoc <- getGlobalDocPath-     globalPkgVers <--       case mglobalDocLoc of-         Nothing -> return M.empty-         Just globalDocLoc -> getDocPackages globalDocLoc-     let toInterfaceOpt pn =-           case find (\dpi -> packageName dpi == pn) (S.toList packages) of-             Nothing ->-               return (case (M.lookup pn globalPkgVers,mglobalDocLoc) of-                         (Just (v:_),Just globalDocLoc) ->-                           ["-i"-                           ,"../" ++ joinPkgVer (pn,v) ++-                            "," ++-                            toFilePath globalDocLoc ++ "/" ++-                            joinPkgVer (pn,v) ++ "/" ++-                            packageNameString pn ++ "." ++-                            haddockExtension]-                         _ -> [])-             Just dpi ->-               do let destPath = (toFilePath userDocLoc ++ "/" ++-                                 joinPkgVer (pn,packageVersion dpi) ++ "/" ++-                                 packageNameString pn ++ "." ++-                                 haddockExtension)-                  exists <- doesFileExist destPath-                  return (if exists-                             then ["-i"-                                  ,"../" ++-                                   joinPkgVer (pn,packageVersion dpi) ++-                                   "," ++-                                   destPath]-                             else [])-     --TODO: use not only direct dependencies, but dependencies of dependencies etc.-     --(e.g. redis-fp doesn't include @text@ in its dependencies which means the 'Text'-     --datatype isn't linked in its haddocks)-     fmap concat (mapM toInterfaceOpt (S.toList (packageAllDeps package)))------------------------------------------------------------------------------------- Paths--{- EKB TODO: doc generation for stack-doc-server--- | Returns true for paths whose last directory component begins with ".".-isHiddenDir :: Path b Dir -> Bool-isHiddenDir = isPrefixOf "." . toFilePath . dirname-        -}---}
src/Stack/Build/Cache.hs view
@@ -46,22 +46,22 @@ import           System.IO.Error (isDoesNotExistError)  -- | Directory containing files to mark an executable as installed-exeInstalledDir :: (MonadReader env m, HasBuildConfig env, MonadThrow m)-                => Location -> m (Path Abs Dir)+exeInstalledDir :: (MonadReader env m, HasEnvConfig env, MonadThrow m)+                => InstallLocation -> m (Path Abs Dir) exeInstalledDir Snap = (</> $(mkRelDir "installed-packages")) `liftM` installationRootDeps exeInstalledDir Local = (</> $(mkRelDir "installed-packages")) `liftM` installationRootLocal  -- | Get all of the installed executables-getInstalledExes :: (MonadReader env m, HasBuildConfig env, MonadIO m, MonadThrow m)-                 => Location -> m [PackageIdentifier]+getInstalledExes :: (MonadReader env m, HasEnvConfig env, MonadIO m, MonadThrow m)+                 => InstallLocation -> m [PackageIdentifier] getInstalledExes loc = do     dir <- exeInstalledDir loc     files <- liftIO $ handleIO (const $ return []) $ getDirectoryContents $ toFilePath dir     return $ mapMaybe parsePackageIdentifierFromString files  -- | Mark the given executable as installed-markExeInstalled :: (MonadReader env m, HasBuildConfig env, MonadIO m, MonadThrow m)-                 => Location -> PackageIdentifier -> m ()+markExeInstalled :: (MonadReader env m, HasEnvConfig env, MonadIO m, MonadThrow m)+                 => InstallLocation -> PackageIdentifier -> m () markExeInstalled loc ident = do     dir <- exeInstalledDir loc     liftIO $ createDirectoryIfMissing True $ toFilePath dir@@ -162,7 +162,7 @@              (toFilePath fp)              (Binary.encode content)) -flagCacheFile :: (MonadIO m, MonadThrow m, MonadReader env m, HasBuildConfig env)+flagCacheFile :: (MonadIO m, MonadThrow m, MonadReader env m, HasEnvConfig env)               => Installed               -> m (Path Abs File) flagCacheFile installed = do@@ -174,7 +174,7 @@     return $ dir </> rel  -- | Loads the flag cache for the given installed extra-deps-tryGetFlagCache :: (MonadIO m, MonadThrow m, MonadReader env m, HasBuildConfig env)+tryGetFlagCache :: (MonadIO m, MonadThrow m, MonadReader env m, HasEnvConfig env)                 => Installed                 -> m (Maybe ConfigCache) tryGetFlagCache gid = do@@ -184,7 +184,7 @@         Right (Right x) -> return $ Just x         _ -> return Nothing -writeFlagCache :: (MonadIO m, MonadReader env m, HasBuildConfig env, MonadThrow m)+writeFlagCache :: (MonadIO m, MonadReader env m, HasEnvConfig env, MonadThrow m)                => Installed                -> ConfigCache                -> m ()
src/Stack/Build/ConstructPlan.hs view
@@ -33,6 +33,7 @@ import           Network.HTTP.Client.Conduit (HasHttpManager) import           Prelude hiding (FilePath, pi, writeFile) import           Stack.Build.Cache+import           Stack.Build.Haddock import           Stack.Build.Installed import           Stack.Build.Source import           Stack.Build.Types@@ -43,12 +44,12 @@ import           Stack.Types  data PackageInfo-    = PIOnlyInstalled Version Location Installed+    = PIOnlyInstalled Version InstallLocation Installed     | PIOnlySource PackageSource     | PIBoth PackageSource Installed  combineSourceInstalled :: PackageSource-                       -> (Version, Location, Installed)+                       -> (Version, InstallLocation, Installed)                        -> PackageInfo combineSourceInstalled ps (version, location, installed) =     assert (piiVersion ps == version) $@@ -68,13 +69,13 @@  data AddDepRes     = ADRToInstall Task-    | ADRFound Version Installed+    | ADRFound InstallLocation Version Installed     deriving Show  type M = RWST     Ctx     ( Map PackageName (Either ConstructPlanException Task) -- finals-    , Map Text Location -- executable to be installed, and location where the binary is placed+    , Map Text InstallLocation -- executable to be installed, and location where the binary is placed     )     (Map PackageName (Either ConstructPlanException AddDepRes))     IO@@ -85,20 +86,23 @@     , loadPackage    :: !(PackageName -> Version -> Map FlagName Bool -> IO Package)     , combinedMap    :: !CombinedMap     , toolToPackages :: !(Dependency -> Map PackageName VersionRange)-    , ctxBuildConfig :: !BuildConfig+    , ctxEnvConfig   :: !EnvConfig     , callStack      :: ![PackageName]     , extraToBuild   :: !(Set PackageName)     , latestVersions :: !(Map PackageName Version)+    , wanted         :: !(Set PackageName)     }  instance HasStackRoot Ctx instance HasPlatform Ctx instance HasConfig Ctx instance HasBuildConfig Ctx where-    getBuildConfig = ctxBuildConfig+    getBuildConfig = getBuildConfig . getEnvConfig+instance HasEnvConfig Ctx where+    getEnvConfig = ctxEnvConfig  constructPlan :: forall env m.-                 (MonadCatch m, MonadReader env m, HasBuildConfig env, MonadIO m, MonadLogger m, MonadBaseControl IO m, HasHttpManager env)+                 (MonadCatch m, MonadReader env m, HasEnvConfig env, MonadIO m, MonadLogger m, MonadBaseControl IO m, HasHttpManager env)               => MiniBuildPlan               -> BaseConfigOpts               -> [LocalPackage]@@ -113,7 +117,7 @@     caches <- getPackageCaches menv     let latest = Map.fromListWith max $ map toTuple $ Map.keys caches -    bconfig <- asks getBuildConfig+    econfig <- asks getEnvConfig     let onWanted =             case boptsFinalAction $ bcoBuildOpts baseConfigOpts0 of                 DoNothing -> void . addDep . packageName . lpPackage@@ -121,7 +125,7 @@     let inner = do             mapM_ onWanted $ filter lpWanted locals             mapM_ addDep $ Set.toList extraToBuild0-    ((), m, (efinals, installExes)) <- liftIO $ runRWST inner (ctx bconfig latest) M.empty+    ((), m, (efinals, installExes)) <- liftIO $ runRWST inner (ctx econfig latest) M.empty     let toEither (_, Left e)  = Left e         toEither (k, Right v) = Right (k, v)         (errlibs, adrs) = partitionEithers $ map toEither $ M.toList m@@ -129,7 +133,7 @@         errs = errlibs ++ errfinals     if null errs         then do-            let toTask (_, ADRFound _ _) = Nothing+            let toTask (_, ADRFound _ _ _) = Nothing                 toTask (name, ADRToInstall task) = Just (name, task)                 tasks = M.fromList $ mapMaybe toTask adrs                 maybeStripLocals@@ -145,9 +149,9 @@                         then installExes                         else Map.empty                 }-        else throwM $ ConstructPlanExceptions errs (bcStackYaml bconfig)+        else throwM $ ConstructPlanExceptions errs (bcStackYaml $ getBuildConfig econfig)   where-    ctx bconfig latest = Ctx+    ctx econfig latest = Ctx         { mbp = mbp0         , baseConfigOpts = baseConfigOpts0         , loadPackage = loadPackage0@@ -155,10 +159,11 @@         , toolToPackages = \ (Dependency name _) ->           maybe Map.empty (Map.fromSet (\_ -> anyVersion)) $           Map.lookup (S8.pack . packageNameString . fromCabalPackageName $ name) toolMap-        , ctxBuildConfig = bconfig+        , ctxEnvConfig = econfig         , callStack = []         , extraToBuild = extraToBuild0         , latestVersions = latest+        , wanted = wantedLocalPackages locals         }     toolMap = getToolMap mbp0 @@ -181,7 +186,7 @@     depsRes <- addPackageDeps package     res <- case depsRes of         Left e -> return $ Left e-        Right (missing, present) -> do+        Right (missing, present, _minLoc) -> do             ctx <- ask             return $ Right Task                 { taskProvides = PackageIdentifier@@ -190,12 +195,12 @@                 , taskConfigOpts = TaskConfigOpts missing $ \missing' ->                     let allDeps = Set.union present missing'                      in configureOpts-                            (getConfig ctx)+                            (getEnvConfig ctx)                             (baseConfigOpts ctx)                             allDeps                             True -- wanted                             Local-                            (packageFlags package)+                            package                 , taskPresent = present                 , taskType = TTLocal lp                 }@@ -231,16 +236,16 @@         Nothing -> return $ Left $ UnknownPackage name         Just (PIOnlyInstalled version loc installed) -> do             tellExecutablesUpstream name version loc Map.empty -- slightly hacky, no flags since they likely won't affect executable names-            return $ Right $ ADRFound version installed+            return $ Right $ ADRFound loc version installed         Just (PIOnlySource ps) -> do             tellExecutables name ps             installPackage name ps         Just (PIBoth ps installed) -> do             tellExecutables name ps-            needInstall <- checkNeedInstall name ps installed+            needInstall <- checkNeedInstall name ps installed (wanted ctx)             if needInstall                 then installPackage name ps-                else return $ Right $ ADRFound (piiVersion ps) installed+                else return $ Right $ ADRFound (piiLocation ps) (piiVersion ps) installed  tellExecutables :: PackageName -> PackageSource -> M () -- TODO merge this with addFinal above? tellExecutables _ (PSLocal lp)@@ -249,14 +254,14 @@ tellExecutables name (PSUpstream version loc flags) = do     tellExecutablesUpstream name version loc flags -tellExecutablesUpstream :: PackageName -> Version -> Location -> Map FlagName Bool -> M ()+tellExecutablesUpstream :: PackageName -> Version -> InstallLocation -> Map FlagName Bool -> M () tellExecutablesUpstream name version loc flags = do     ctx <- ask     when (name `Set.member` extraToBuild ctx) $ do         p <- liftIO $ loadPackage ctx name version flags         tellExecutablesPackage loc p -tellExecutablesPackage :: Location -> Package -> M ()+tellExecutablesPackage :: InstallLocation -> Package -> M () tellExecutablesPackage loc p =     tell (Map.empty, m)   where@@ -272,38 +277,41 @@     depsRes <- addPackageDeps package     case depsRes of         Left e -> return $ Left e-        Right (missing, present) -> do+        Right (missing, present, minLoc) -> do             return $ Right $ ADRToInstall Task                 { taskProvides = PackageIdentifier                     (packageName package)                     (packageVersion package)                 , taskConfigOpts = TaskConfigOpts missing $ \missing' ->                     let allDeps = Set.union present missing'+                        destLoc = piiLocation ps <> minLoc                      in configureOpts-                            (getConfig ctx)+                            (getEnvConfig ctx)                             (baseConfigOpts ctx)                             allDeps                             (psWanted ps)-                            (piiLocation ps)-                            (packageFlags package)+                            -- An assertion to check for a recurrence of+                            -- https://github.com/commercialhaskell/stack/issues/345+                            (assert (destLoc == piiLocation ps) destLoc)+                            package                 , taskPresent = present                 , taskType =                     case ps of                         PSLocal lp -> TTLocal lp-                        PSUpstream _ loc _ -> TTUpstream package loc+                        PSUpstream _ loc _ -> TTUpstream package $ loc <> minLoc                 } -checkNeedInstall :: PackageName -> PackageSource -> Installed -> M Bool-checkNeedInstall name ps installed = assert (piiLocation ps == Local) $ do+checkNeedInstall :: PackageName -> PackageSource -> Installed -> Set PackageName -> M Bool+checkNeedInstall name ps installed wanted = assert (piiLocation ps == Local) $ do     package <- psPackage name ps     depsRes <- addPackageDeps package     case depsRes of         Left _e -> return True -- installPackage will find the error again-        Right (missing, present)-            | Set.null missing -> checkDirtiness ps installed package present+        Right (missing, present, _loc)+            | Set.null missing -> checkDirtiness ps installed package present wanted             | otherwise -> return True -addPackageDeps :: Package -> M (Either ConstructPlanException (Set PackageIdentifier, Set GhcPkgId))+addPackageDeps :: Package -> M (Either ConstructPlanException (Set PackageIdentifier, Set GhcPkgId, InstallLocation)) addPackageDeps package = do     ctx <- ask     deps' <- packageDepsWithTools package@@ -320,11 +328,11 @@             Right adr | not $ adrVersion adr `withinRange` range ->                 return $ Left (depname, (range, DependencyMismatch $ adrVersion adr))             Right (ADRToInstall task) -> return $ Right-                (Set.singleton $ taskProvides task, Set.empty)-            Right (ADRFound _ (Executable _)) -> return $ Right-                (Set.empty, Set.empty)-            Right (ADRFound _ (Library gid)) -> return $ Right-                (Set.empty, Set.singleton gid)+                (Set.singleton $ taskProvides task, Set.empty, taskLocation task)+            Right (ADRFound loc _ (Executable _)) -> return $ Right+                (Set.empty, Set.empty, loc)+            Right (ADRFound loc _ (Library gid)) -> return $ Right+                (Set.empty, Set.singleton gid, loc)     case partitionEithers deps of         ([], pairs) -> return $ Right $ mconcat pairs         (errs, _) -> return $ Left $ DependencyPlanFailures@@ -334,34 +342,41 @@             (Map.fromList errs)   where     adrVersion (ADRToInstall task) = packageIdentifierVersion $ taskProvides task-    adrVersion (ADRFound v _) = v+    adrVersion (ADRFound _ v _) = v  checkDirtiness :: PackageSource                -> Installed                -> Package                -> Set GhcPkgId+               -> Set PackageName                -> M Bool-checkDirtiness ps installed package present = do+checkDirtiness ps installed package present wanted = do     ctx <- ask+    moldOpts <- tryGetFlagCache installed     let configOpts = configureOpts-            (getConfig ctx)+            (getEnvConfig ctx)             (baseConfigOpts ctx)             present             (psWanted ps)             (piiLocation ps) -- should be Local always-            (packageFlags package)-        configCache = ConfigCache+            package+        buildOpts = bcoBuildOpts (baseConfigOpts ctx)+        wantConfigCache = ConfigCache             { configCacheOpts = map encodeUtf8 configOpts             , configCacheDeps = present             , configCacheComponents =                 case ps of                     PSLocal lp -> Set.map encodeUtf8 $ lpComponents lp                     PSUpstream _ _ _ -> Set.empty+            , configCacheHaddock =+                shouldHaddockPackage buildOpts wanted (packageName package) ||+                -- Disabling haddocks when old config had haddocks doesn't make dirty.+                maybe False configCacheHaddock moldOpts             }-    moldOpts <- tryGetFlagCache installed     case moldOpts of         Nothing -> return True-        Just oldOpts -> return $ oldOpts /= configCache || psDirty ps+        Just oldOpts -> return $ oldOpts /= wantConfigCache ||+                                 psDirty ps  psDirty :: PackageSource -> Bool psDirty (PSLocal lp) = lpDirtyFiles lp@@ -400,3 +415,10 @@             TTLocal _ -> False             TTUpstream _ Local -> False             TTUpstream _ Snap -> True++taskLocation :: Task -> InstallLocation+taskLocation =+    go . taskType+  where+    go (TTLocal _) = Local+    go (TTUpstream _ loc) = loc
− src/Stack/Build/Doc.hs
@@ -1,89 +0,0 @@-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-}---- | Utilities for built documentation, shared between @stack@ and @stack-doc-server@.-module Stack.Build.Doc where--import           Control.Monad-import           Data.List-import           Data.Map.Strict (Map)-import qualified Data.Map.Strict as M-import           Data.Maybe-import qualified Data.Text as T-import           Path-import           Stack.Types-import           Stack.Constants-import           System.Directory-import           System.Environment (lookupEnv)-import           System.FilePath (takeFileName)---- | Get all packages included in documentation from directory.-getDocPackages :: Path Abs Dir -> IO (Map PackageName [Version])-getDocPackages loc =-  do ls <- fmap (map (toFilePath loc ++)) (getDirectoryContents (toFilePath loc))-     mdirs <- forM ls (\e -> do isDir <- doesDirectoryExist e-                                return $ if isDir then (Just e) else Nothing)-     let sorted = -- Sort by package name ascending, version descending-                  sortBy (\(pa,va) (pb,vb) ->-                            case compare pa pb of-                              EQ -> compare vb va-                              o -> o)-                         (mapMaybe breakPkgVer (catMaybes mdirs))-     return (M.fromAscListWith (++) (map (\(k,v) -> (k,[v])) sorted))---- | Split a documentation directory name into package name and version.-breakPkgVer :: FilePath -> Maybe (PackageName,Version)-breakPkgVer pkgPath =-  case T.breakOnEnd "-"-                    (T.pack (takeFileName pkgPath)) of-    ("",_) -> Nothing-    (pkgD,verT) ->-      let pkgstr = T.dropEnd 1 pkgD-      in case parseVersionFromString (T.unpack verT) of-           Just v-             | Just pkg <--                parsePackageNameFromString (T.unpack pkgstr) ->-               Just (pkg,v)-           _ -> Nothing---- | Construct a documentation directory name from package name and version.-joinPkgVer :: (PackageName,Version) -> FilePath-joinPkgVer (pkg,ver) = (packageNameString pkg ++ "-" ++ versionString ver)----EKB TODO: doc generation for stack-doc-server--- | Get location of user-generated documentation if it exists.-getExistingUserDocPath :: Config -> IO (Maybe (Path Abs Dir))-getExistingUserDocPath config = do-    let docPath = userDocsDir config-    docExists <- doesDirectoryExist (toFilePath docPath)-    if docExists-        then return (Just docPath)-        else return Nothing----EKB TODO: doc generation for stack-doc-server--- | Get location of global package docs.-getGlobalDocPath :: IO (Maybe (Path Abs Dir))-getGlobalDocPath = do-    --EKB TODO: move this location into Config-    maybeRootEnv <- lookupEnv "STACK_DOC_ROOT"-    case maybeRootEnv of-        Nothing -> return Nothing-        Just rootEnv -> do-            pkgDocPath <- parseAbsDir rootEnv-            pkgDocExists <- doesDirectoryExist (toFilePath pkgDocPath)-            return (if pkgDocExists then Just pkgDocPath else Nothing)----EKB TODO: doc generation for stack-doc-server--- | Get location of GHC docs.-getGhcDocPath :: IO (Maybe (Path Abs Dir))-getGhcDocPath = do-    maybeGhcPathS <- findExecutable "ghc"-    case maybeGhcPathS of-        Nothing -> return Nothing-        Just ghcPathS -> do-            ghcPath <- parseAbsFile ghcPathS-            let ghcDocPath = parent (parent ghcPath) </> $(mkRelDir "share/doc/ghc/html/")-            ghcDocExists <- doesDirectoryExist (toFilePath ghcDocPath)-            return (if ghcDocExists then Just ghcDocPath else Nothing)
src/Stack/Build/Execute.hs view
@@ -33,9 +33,9 @@ import           Data.Function import           Data.List import           Data.Map.Strict                (Map)-import qualified Data.Map.Strict                as M import qualified Data.Map.Strict                as Map import           Data.Maybe+import           Data.Set                       (Set) import qualified Data.Set                       as Set import           Data.Streaming.Process         hiding (callProcess, env) import qualified Data.Streaming.Process         as Process@@ -50,7 +50,9 @@ import           Path.IO import           Prelude                        hiding (FilePath, writeFile) import           Stack.Build.Cache+import           Stack.Build.Haddock import           Stack.Build.Installed+import           Stack.Build.Source import           Stack.Build.Types import           Stack.Fetch                    as Fetch import           Stack.GhcPkg@@ -68,7 +70,7 @@ import           System.IO.Temp                 (withSystemTempDirectory) import           System.Process.Internals       (createProcess_) import           System.Process.Read-import           System.Process.Log (showProcessArgDebug)+import           System.Process.Log             (showProcessArgDebug)  type M env m = (MonadIO m,MonadReader env m,HasHttpManager env,HasBuildConfig env,MonadLogger m,MonadBaseControl IO m,MonadCatch m,MonadMask m,HasLogLevel env,HasEnvConfig env,HasTerminal env) @@ -115,7 +117,6 @@                 DoNothing -> Nothing                 DoBenchmarks -> Just "benchmark"                 DoTests -> Just "test"-                DoHaddock -> Just "haddock"     case mfinalLabel of         Nothing -> return ()         Just finalLabel -> do@@ -174,6 +175,10 @@     , eeSetupHs        :: !(Path Abs File)     , eeCabalPkgVer    :: !Version     , eeTotalWanted    :: !Int+    , eeWanted         :: !(Set PackageName)+    , eeLocals         :: ![LocalPackage]+    , eeSourceMap      :: !SourceMap+    , eeGlobalDB       :: !(Path Abs Dir)     }  -- | Perform the actual plan@@ -182,17 +187,19 @@             -> BuildOpts             -> BaseConfigOpts             -> [LocalPackage]+            -> SourceMap             -> Plan             -> m ()-executePlan menv bopts baseConfigOpts locals plan = do+executePlan menv bopts baseConfigOpts locals sourceMap plan = do     withSystemTempDirectory stackProgName $ \tmpdir -> do         tmpdir' <- parseAbsDir tmpdir         configLock <- newMVar ()         installLock <- newMVar ()-        idMap <- liftIO $ newTVarIO M.empty+        idMap <- liftIO $ newTVarIO Map.empty         let setupHs = tmpdir' </> $(mkRelFile "Setup.hs")         liftIO $ writeFile (toFilePath setupHs) "import Distribution.Simple\nmain = defaultMain"         cabalPkgVer <- asks (envConfigCabalVersion . getEnvConfig)+        globalDB <- getGlobalDB menv         executePlan' plan ExecuteEnv             { eeEnvOverride = menv             , eeBuildOpts = bopts@@ -208,6 +215,10 @@             , eeSetupHs = setupHs             , eeCabalPkgVer = cabalPkgVer             , eeTotalWanted = length $ filter lpWanted locals+            , eeWanted = wantedLocalPackages locals+            , eeLocals = locals+            , eeSourceMap = sourceMap+            , eeGlobalDB = globalDB             }      unless (Map.null $ planInstallExes plan) $ do@@ -287,7 +298,7 @@              => Plan              -> ExecuteEnv              -> m ()-executePlan' plan ee = do+executePlan' plan ee@ExecuteEnv {..} = do     case Set.toList $ planUnregisterLocal plan of         [] -> return ()         ids -> do@@ -297,7 +308,7 @@                     [ T.pack $ ghcPkgIdString id'                     , ": unregistering"                     ]-                unregisterGhcPkgId (eeEnvOverride ee) localDB id'+                unregisterGhcPkgId eeEnvOverride localDB id'      -- Yes, we're explicitly discarding result values, which in general would     -- be bad. monad-unlift does this all properly at the type system level,@@ -330,6 +341,8 @@             then loop 0             else return ()     unless (null errs) $ throwM $ ExecutionFailure errs+    when (boptsHaddock eeBuildOpts && not (null actions))+        (generateHaddockIndex eeEnvOverride eeBaseConfigOpts eeLocals)  toActions :: M env m           => (m () -> IO ())@@ -372,7 +385,6 @@             DoNothing -> Nothing             DoTests -> Just (singleTest, checkTest)             DoBenchmarks -> Just (singleBench, checkBench)-            DoHaddock -> Just (singleHaddock, const True)      checkTest task =         case taskType task of@@ -419,6 +431,8 @@                 case taskType of                     TTLocal lp -> Set.map encodeUtf8 $ lpComponents lp                     TTUpstream _ _ -> Set.empty+            , configCacheHaddock =+                shouldHaddockPackage eeBuildOpts eeWanted (packageIdentifierName taskProvides)             }      let needConfig = mOldConfigCache /= Just newConfigCache@@ -448,7 +462,7 @@ withSingleContext ActionContext {..} ExecuteEnv {..} task@Task {..} inner0 =     withPackage $ \package cabalfp pkgDir ->     withLogFile package $ \mlogFile ->-    withCabal pkgDir mlogFile $ \cabal ->+    withCabal package pkgDir mlogFile $ \cabal ->     inner0 package cabalfp pkgDir cabal announce console mlogFile   where     announce x = $logInfo $ T.concat@@ -472,7 +486,7 @@             TTUpstream package _ -> do                 mdist <- liftM Just distRelativeDir                 m <- unpackPackageIdents eeEnvOverride eeTempDir mdist $ Set.singleton taskProvides-                case M.toList m of+                case Map.toList m of                     [(ident, dir)]                         | ident == taskProvides -> do                             let name = packageIdentifierName taskProvides@@ -492,7 +506,7 @@                 (liftIO . hClose)                 $ \h -> inner (Just (logPath, h)) -    withCabal pkgDir mlogFile inner = do+    withCabal package pkgDir mlogFile inner = do         config <- asks getConfig         menv <- liftIO $ configEnvOverride config EnvSettings             { esIncludeLocals = taskLocation task == Local@@ -500,7 +514,13 @@             }         exeName <- liftIO $ join $ findExecutable menv "runhaskell"         distRelativeDir' <- distRelativeDir-        msetuphs <- liftIO $ getSetupHs pkgDir+        msetuphs <-+            -- Avoid broken Setup.hs files causing problems for simple build+            -- types, see:+            -- https://github.com/commercialhaskell/stack/issues/370+            if packageSimpleType package+                then return Nothing+                else liftIO $ getSetupHs pkgDir         let setuphs = fromMaybe eeSetupHs msetuphs         inner $ \stripTHLoading args -> do             let fullArgs =@@ -542,20 +562,16 @@                                 Just (_, h) -> UseHandle h                     , std_err =                         case mlogFile of-                            Nothing -> Inherit+                            Nothing -> CreatePipe                             Just (_, h) -> UseHandle h                     }             $logProcessRun (toFilePath exeName) fullArgs              -- Use createProcess_ to avoid the log file being closed afterwards-            (Just inH, moutH, Nothing, ph) <- liftIO $ createProcess_ "singleBuild" cp+            (Just inH, moutH, merrH, ph) <- liftIO $ createProcess_ "singleBuild" cp             liftIO $ hClose inH-            case moutH of-                Just outH ->-                    case mlogFile of-                      Just{} -> return ()-                      Nothing -> printBuildOutput stripTHLoading outH-                Nothing -> return ()+            maybePrintBuildOutput stripTHLoading LevelInfo mlogFile moutH+            maybePrintBuildOutput stripTHLoading LevelWarn mlogFile merrH             ec <- liftIO $ waitForProcess ph             case ec of                 ExitSuccess -> return ()@@ -574,6 +590,14 @@                         (fmap fst mlogFile)                         bs +    maybePrintBuildOutput stripTHLoading level mlogFile mh =+        case mh of+            Just h ->+                case mlogFile of+                  Just{} -> return ()+                  Nothing -> printBuildOutput stripTHLoading level h+            Nothing -> return ()+ singleBuild :: M env m             => ActionContext             -> ExecuteEnv@@ -593,6 +617,16 @@             TTLocal lp -> "build" : map T.unpack (Set.toList $ lpComponents lp)             TTUpstream _ _ -> ["build"] +    let doHaddock = shouldHaddockPackage eeBuildOpts eeWanted (packageName package) &&+                    -- Works around haddock failing on bytestring-builder since it has no modules+                    -- when bytestring is new enough.+                    packageHasExposedModules package+    when doHaddock $ do+        announce "haddock"+        hscolourExists <- doesExecutableExist eeEnvOverride "hscolour"+        cabal False (concat [["haddock", "--html", "--hoogle", "--html-location=../$pkg-$version/"]+                            ,["--hyperlink-source" | hscolourExists]])+     withMVar eeInstallLock $ \() -> do         announce "install"         cabal False ["install"]@@ -616,6 +650,13 @@     writeFlagCache mpkgid' cache     liftIO $ atomically $ modifyTVar eeGhcPkgIds $ Map.insert taskProvides mpkgid' +    when (doHaddock && shouldHaddockDeps eeBuildOpts) $+        copyDepHaddocks+            eeEnvOverride+            (pkgDbs ++ [eeGlobalDB])+            (PackageIdentifier (packageName package) (packageVersion package))+            Set.empty+ singleTest :: M env m            => ActionContext            -> ExecuteEnv@@ -681,8 +722,8 @@                     liftIO $ hClose inH                     ec <- liftIO $ waitForProcess ph                     return $ case ec of-                        ExitSuccess -> M.empty-                        _ -> M.singleton testName $ Just ec+                        ExitSuccess -> Map.empty+                        _ -> Map.singleton testName $ Just ec                 else do                     $logError $ T.concat                         [ "Test suite "@@ -720,70 +761,15 @@         announce "benchmarks"         cabal False ["bench"] -singleHaddock :: M env m-              => ActionContext-              -> ExecuteEnv-              -> Task-              -> m ()-singleHaddock ac ee task =-    withSingleContext ac ee task $ \_package _cabalfp _pkgDir cabal announce _console _mlogFile -> do-        announce "haddock"-        hscolourExists <- doesExecutableExist (eeEnvOverride ee) "hscolour"-              {- EKB TODO: doc generation for stack-doc-server- #ifndef mingw32_HOST_OS-              liftIO (removeDocLinks docLoc package)- #endif-              ifcOpts <- liftIO (haddockInterfaceOpts docLoc package packages)-              -}-        cabal False (concat [["haddock", "--html"]-                            ,["--hyperlink-source" | hscolourExists]])-              {- EKB TODO: doc generation for stack-doc-server-                         ,"--hoogle"-                         ,"--html-location=../$pkg-$version/"-                         ,"--haddock-options=" ++ intercalate " " ifcOpts ]-              haddockLocs <--                liftIO (findFiles (packageDocDir package)-                                  (\loc -> FilePath.takeExtensions (toFilePath loc) ==-                                           "." ++ haddockExtension)-                                  (not . isHiddenDir))-              forM_ haddockLocs $ \haddockLoc ->-                do let hoogleTxtPath = FilePath.replaceExtension (toFilePath haddockLoc) "txt"-                       hoogleDbPath = FilePath.replaceExtension hoogleTxtPath hoogleDbExtension-                   hoogleExists <- liftIO (doesFileExist hoogleTxtPath)-                   when hoogleExists-                        (callProcess-                             "hoogle"-                             ["convert"-                             ,"--haddock"-                             ,hoogleTxtPath-                             ,hoogleDbPath])-                        -}-                 {- EKB TODO: doc generation for stack-doc-server-             #ifndef mingw32_HOST_OS-                 case setupAction of-                   DoHaddock -> liftIO (createDocLinks docLoc package)-                   _ -> return ()-             #endif-- -- | Package's documentation directory.- packageDocDir :: (MonadThrow m, MonadReader env m, HasPlatform env)-               => PackageIdentifier -- ^ Cabal version-               -> Package-               -> m (Path Abs Dir)- packageDocDir cabalPkgVer package' = do-   dist <- distDirFromDir cabalPkgVer (packageDir package')-   return (dist </> $(mkRelDir "doc/"))-                 --}- -- | Grab all output from the given @Handle@ and print it to stdout, stripping -- Template Haskell "Loading package" lines. Does work in a separate thread. printBuildOutput :: (MonadIO m, MonadBaseControl IO m, MonadLogger m)-                 => Bool -> Handle -> m ()-printBuildOutput excludeTHLoading outH = void $ fork $+                 => Bool -> LogLevel -> Handle -> m ()+printBuildOutput excludeTHLoading level outH = void $ fork $          CB.sourceHandle outH     $$ CB.lines     =$ CL.filter (not . isTHLoading)-    =$ CL.mapM_ ($logInfo . T.decodeUtf8)+    =$ CL.mapM_ (logOtherN level . T.decodeUtf8)   where     -- | Is this line a Template Haskell "Loading package" line     -- ByteString@@ -793,7 +779,7 @@         "Loading package " `S8.isPrefixOf` bs &&         ("done." `S8.isSuffixOf` bs || "done.\r" `S8.isSuffixOf` bs) -taskLocation :: Task -> Location+taskLocation :: Task -> InstallLocation taskLocation task =     case taskType task of         TTLocal _ -> Local
+ src/Stack/Build/Haddock.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE RecordWildCards       #-}+{-# LANGUAGE TemplateHaskell       #-}++-- | Generate haddocks+module Stack.Build.Haddock+    ( copyDepHaddocks+    , generateHaddockIndex+    , shouldHaddockPackage+    , shouldHaddockDeps+    ) where++import           Control.Monad+import           Control.Monad.Catch            (MonadCatch)+import           Control.Monad.IO.Class+import           Control.Monad.Logger+import           Control.Monad.Trans.Resource+import           Control.Monad.Writer+import           Data.Function+import           Data.List+import           Data.Maybe+import           Data.Set                       (Set)+import qualified Data.Set                       as Set+import qualified Data.Text                      as T+import           Path+import           Path.IO+import           Prelude                        hiding (FilePath, writeFile)+import           Stack.Build.Types+import           Stack.GhcPkg+import           Stack.Package+import           Stack.Types+import           System.Directory               hiding (findExecutable,+                                                 findFiles)+import qualified System.FilePath                as FP+import           System.Process.Read++-- | Determine whether we should haddock for a package.+shouldHaddockPackage :: BuildOpts -> Set PackageName -> PackageName -> Bool+shouldHaddockPackage bopts wanted name =+    if Set.member name wanted+        then boptsHaddock bopts+        else shouldHaddockDeps bopts++-- | Determine whether to build haddocks for dependencies.+shouldHaddockDeps :: BuildOpts -> Bool+shouldHaddockDeps bopts = fromMaybe (boptsHaddock bopts) (boptsHaddockDeps bopts)++-- | Copy dependencies' haddocks to documentation directory.  This way, relative @../$pkg-$ver@+-- links work and it's easy to upload docs to a web server or otherwise view them in a+-- non-local-filesystem context. We copy instead of symlink for two reasons: (1) symlinks aren't+-- reliably supported on Windows, and (2) the filesystem containing dependencies' docs may not be+-- available where viewing the docs (e.g. if building in a Docker container).+copyDepHaddocks :: (MonadIO m, MonadLogger m, MonadThrow m, MonadCatch m, MonadBaseControl IO m)+                => EnvOverride+                -> [Path Abs Dir]+                -> PackageIdentifier+                -> Set (Path Abs Dir)+                -> m ()+copyDepHaddocks envOverride pkgDbs pkgId extraDestDirs = do+    mpkgHtmlDir <- findGhcPkgHaddockHtml envOverride pkgDbs pkgId+    case mpkgHtmlDir of+        Nothing -> return ()+        Just pkgHtmlDir -> do+            depGhcIds <- findGhcPkgDepends envOverride pkgDbs pkgId+            forM_ (map ghcPkgIdPackageIdentifier depGhcIds) $+                copyDepWhenNeeded pkgHtmlDir+  where+    copyDepWhenNeeded pkgHtmlDir depId = do+        mDepOrigDir <- findGhcPkgHaddockHtml envOverride pkgDbs depId+        case mDepOrigDir of+            Nothing -> return ()+            Just depOrigDir ->+                copyWhenNeeded (Set.insert (parent pkgHtmlDir) extraDestDirs)+                               depId depOrigDir+    copyWhenNeeded destDirs depId depOrigDir = do+        depRelDir <- parseRelDir (packageIdentifierString depId)+        copied <- forM (Set.toList destDirs) $ \destDir -> do+            let depCopyDir = destDir </> depRelDir+            if depCopyDir == depOrigDir+                then return False+                else do+                    needCopy <- getNeedCopy depOrigDir depCopyDir+                    when needCopy $ doCopy depOrigDir depCopyDir+                    return needCopy+        when (or copied) $+            copyDepHaddocks envOverride pkgDbs depId destDirs+    getNeedCopy depOrigDir depCopyDir = do+        let depOrigIndex = haddockIndexFile depOrigDir+            depCopyIndex = haddockIndexFile depCopyDir+        depOrigExists <- fileExists depOrigIndex+        depCopyExists <- fileExists depCopyIndex+        case (depOrigExists, depCopyExists) of+            (False, _) -> return False+            (True, False) -> return True+            (True, True) -> do+                copyMod <- liftIO $ getModificationTime (toFilePath depCopyIndex)+                origMod <- liftIO $ getModificationTime (toFilePath depOrigIndex)+                return (copyMod <= origMod)+    doCopy depOrigDir depCopyDir = do+        depCopyDirExists <- dirExists depCopyDir+        liftIO $ do+            when depCopyDirExists $+                removeDirectoryRecursive (toFilePath depCopyDir)+            createDirectoryIfMissing True (toFilePath depCopyDir)+        copyDirectoryRecursive depOrigDir depCopyDir++-- | Generate Haddock index and contents for local packages.+generateHaddockIndex :: (MonadIO m, MonadCatch m, MonadThrow m, MonadLogger m, MonadBaseControl IO m)+                     => EnvOverride+                     -> BaseConfigOpts+                     -> [LocalPackage]+                     -> m ()+generateHaddockIndex envOverride bco locals = do+    $logInfo ("Generating Haddock index in\n" <>+              T.pack (toFilePath (haddockIndexFile docDir)))+    interfaceArgs <- mapM (\LocalPackage {lpPackage = Package {..}} ->+                              toInterfaceOpt (PackageIdentifier packageName packageVersion))+                          locals+    readProcessNull+        (Just docDir)+        envOverride+        "haddock"+        (["--gen-contents", "--gen-index"] ++ concat interfaceArgs)+  where+    docDir = bcoLocalInstallRoot bco </> docdirSuffix+    toInterfaceOpt pid@(PackageIdentifier name _) = do+        interfaceRelFile <- parseRelFile (packageIdentifierString pid FP.</>+                                          packageNameString name FP.<.>+                                          "haddock")+        interfaceExists <- fileExists (docDir </> interfaceRelFile)+        return $ if interfaceExists+            then [ "-i"+                 , concat+                     [ packageIdentifierString pid+                     , ","+                     , toFilePath interfaceRelFile ] ]+            else []++haddockIndexFile :: Path Abs Dir -> Path Abs File+haddockIndexFile docDir = docDir </> $(mkRelFile "index.html")
src/Stack/Build/Installed.hs view
@@ -6,6 +6,7 @@ module Stack.Build.Installed     ( InstalledMap     , Installed (..)+    , GetInstalledOpts (..)     , getInstalled     ) where @@ -19,6 +20,7 @@ import           Data.Conduit import qualified Data.Conduit.List            as CL import           Data.Function+import qualified Data.HashSet                 as HashSet import           Data.List import           Data.Map.Strict              (Map) import qualified Data.Map.Strict              as M@@ -31,49 +33,58 @@ import           Prelude                      hiding (FilePath, writeFile) import           Stack.Build.Cache import           Stack.Build.Types+import           Stack.Constants import           Stack.GhcPkg import           Stack.PackageDump import           Stack.Types import           Stack.Types.Internal -type M env m = (MonadIO m,MonadReader env m,HasHttpManager env,HasBuildConfig env,MonadLogger m,MonadBaseControl IO m,MonadCatch m,MonadMask m,HasLogLevel env)+type M env m = (MonadIO m,MonadReader env m,HasHttpManager env,HasEnvConfig env,MonadLogger m,MonadBaseControl IO m,MonadCatch m,MonadMask m,HasLogLevel env)  data LoadHelper = LoadHelper     { lhId   :: !GhcPkgId     , lhDeps :: ![GhcPkgId]-    , lhPair :: !(PackageName, (Version, Location, Installed)) -- TODO Version is now redundant and can be gleaned from Installed+    , lhPair :: !(PackageName, (Version, InstallLocation, Installed)) -- TODO Version is now redundant and can be gleaned from Installed     }     deriving Show -type InstalledMap = Map PackageName (Version, Location, Installed) -- TODO Version is now redundant and can be gleaned from Installed+type InstalledMap = Map PackageName (Version, InstallLocation, Installed) -- TODO Version is now redundant and can be gleaned from Installed +-- | Options for 'getInstalled'.+data GetInstalledOpts = GetInstalledOpts+    { getInstalledProfiling :: !Bool+      -- ^ Require profiling libraries?+    , getInstalledHaddock   :: !Bool+      -- ^ Require haddocks?+    }+ -- | Returns the new InstalledMap and all of the locally registered packages. getInstalled :: (M env m, PackageInstallInfo pii)              => EnvOverride-             -> Bool -- ^ profiling?+             -> GetInstalledOpts              -> Map PackageName pii -- ^ does not contain any installed information              -> m (InstalledMap, Set GhcPkgId)-getInstalled menv profiling sourceMap = do+getInstalled menv opts sourceMap = do     snapDBPath <- packageDatabaseDeps     localDBPath <- packageDatabaseLocal      bconfig <- asks getBuildConfig -    mpcache <--        if profiling-            then liftM Just $ loadProfilingCache $ configProfilingCache bconfig+    mcache <-+        if getInstalledProfiling opts || getInstalledHaddock opts+            then liftM Just $ loadInstalledCache $ configInstalledCache bconfig             else return Nothing -    let loadDatabase' = loadDatabase menv mpcache sourceMap+    let loadDatabase' = loadDatabase menv opts mcache sourceMap     (installedLibs', localInstalled) <-         loadDatabase' Nothing [] >>=         loadDatabase' (Just (Snap, snapDBPath)) . fst >>=         loadDatabase' (Just (Local, localDBPath)) . fst     let installedLibs = M.fromList $ map lhPair installedLibs' -    case mpcache of+    case mcache of         Nothing -> return ()-        Just pcache -> saveProfilingCache (configProfilingCache bconfig) pcache+        Just pcache -> saveInstalledCache (configInstalledCache bconfig) pcache      -- Add in the executables that are installed, making sure to only trust a     -- listed installation under the right circumstances (see below)@@ -84,22 +95,9 @@                 Nothing -> m                 Just pii                     -- Not the version we want, ignore it-                    | version /= piiVersion pii -> Map.empty-                    | otherwise -> case pii of-                        {- FIXME revisit this logic-                        -- Never mark locals as installed, instead do dirty-                        -- checking-                        PSLocal _ -> Map.empty--                        -- FIXME start recording build flags for installed-                        -- executables, and only count as installed if it-                        -- matches--                        PSUpstream loc' _flags | loc == loc' -> Map.empty-                        -}+                    | version /= piiVersion pii || loc /= piiLocation pii -> Map.empty -                        -- Passed all the tests, mark this as installed!-                        _ -> m+                    | otherwise -> m           where             m = Map.singleton name (version, loc, Executable $ PackageIdentifier name version)     exesSnap <- getInstalledExes Snap@@ -119,12 +117,13 @@ -- location needed by the SourceMap loadDatabase :: (M env m, PackageInstallInfo pii)              => EnvOverride-             -> Maybe ProfilingCache -- ^ if Just, profiling is required+             -> GetInstalledOpts+             -> Maybe InstalledCache -- ^ if Just, profiling or haddock is required              -> Map PackageName pii -- ^ to determine which installed things we should include-             -> Maybe (Location, Path Abs Dir) -- ^ package database, Nothing for global+             -> Maybe (InstallLocation, Path Abs Dir) -- ^ package database, Nothing for global              -> [LoadHelper] -- ^ from parent databases              -> m ([LoadHelper], Set GhcPkgId)-loadDatabase menv mpcache sourceMap mdb lhs0 = do+loadDatabase menv opts mcache sourceMap mdb lhs0 = do     (lhs1, gids) <- ghcPkgDump menv (fmap snd mdb)                   $ conduitDumpPackage =$ sink     let lhs = pruneDeps@@ -135,14 +134,21 @@             (lhs0 ++ lhs1)     return (map (\lh -> lh { lhDeps = [] }) $ Map.elems lhs, Set.fromList gids)   where-    conduitCache =-        case mpcache of-            Just pcache -> addProfiling pcache+    conduitProfilingCache =+        case mcache of+            Just cache | getInstalledProfiling opts -> addProfiling cache             -- Just an optimization to avoid calculating the profiling             -- values when they aren't necessary-            Nothing -> CL.map (\dp -> dp { dpProfiling = False })-    sinkDP = conduitCache-          =$ CL.mapMaybe (isAllowed mpcache sourceMap (fmap fst mdb))+            _ -> CL.map (\dp -> dp { dpProfiling = False })+    conduitHaddockCache =+        case mcache of+            Just cache | getInstalledHaddock opts -> addHaddock cache+            -- Just an optimization to avoid calculating the haddock+            -- values when they aren't necessary+            _ -> CL.map (\dp -> dp { dpHaddock = False })+    sinkDP = conduitProfilingCache+          =$ conduitHaddockCache+          =$ CL.mapMaybe (isAllowed opts mcache sourceMap (fmap fst mdb))           =$ CL.consume     sinkGIDs = CL.map dpGhcPkgId =$ CL.consume     sink = getZipSink $ (,)@@ -153,17 +159,29 @@ -- on the package selections made by the user. This does not perform any -- dirtiness or flag change checks. isAllowed :: PackageInstallInfo pii-          => Maybe ProfilingCache+          => GetInstalledOpts+          -> Maybe InstalledCache           -> Map PackageName pii-          -> Maybe Location-          -> DumpPackage Bool+          -> Maybe InstallLocation+          -> DumpPackage Bool Bool           -> Maybe LoadHelper-isAllowed mpcache sourceMap mloc dp+isAllowed opts mcache sourceMap mloc dp     -- Check that it can do profiling if necessary-    | isJust mpcache && not (dpProfiling dp) = Nothing+    | getInstalledProfiling opts && isJust mcache && not (dpProfiling dp) = Nothing+    -- Check that it has haddocks if necessary+    | getInstalledHaddock opts && isJust mcache && not (dpHaddock dp) = Nothing     | toInclude = Just LoadHelper         { lhId = gid-        , lhDeps = dpDepends dp+        , lhDeps =+            -- We always want to consider the wired in packages as having all+            -- of their dependencies installed, since we have no ability to+            -- reinstall them. This is especially important for using different+            -- minor versions of GHC, where the dependencies of wired-in+            -- packages may change slightly and therefore not match the+            -- snapshot.+            if name `HashSet.member` wiredInPackages+                then []+                else dpDepends dp         , lhPair = (name, (version, fromMaybe Snap mloc, Library gid))         }     | otherwise = Nothing
src/Stack/Build/Source.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE OverloadedStrings     #-} {-# LANGUAGE TemplateHaskell       #-} {-# LANGUAGE TupleSections         #-}+{-# LANGUAGE ScopedTypeVariables   #-} -- Load information on package sources module Stack.Build.Source     ( loadSourceMap@@ -22,6 +23,7 @@ import           Data.Either import qualified Data.Foldable                as F import           Data.Function+import qualified Data.HashSet                 as HashSet import           Data.List import qualified Data.Map                     as Map import           Data.Map.Strict              (Map)@@ -44,9 +46,14 @@ import           System.Directory             hiding (findExecutable, findFiles)  type SourceMap = Map PackageName PackageSource++-- | Where the package's source is located: local directory or package index data PackageSource     = PSLocal LocalPackage-    | PSUpstream Version Location (Map FlagName Bool)+    | PSUpstream Version InstallLocation (Map FlagName Bool)+    -- ^ Upstream packages could be installed in either local or snapshot+    -- databases; this is what 'InstallLocation' specifies.+    deriving Show instance PackageInstallInfo PackageSource where     piiVersion (PSLocal lp) = packageVersion $ lpPackage lp     piiVersion (PSUpstream v _ _) = v@@ -66,8 +73,7 @@     mbp0 <- case bcResolver bconfig of         ResolverSnapshot snapName -> do             $logDebug $ "Checking resolver: " <> renderSnapName snapName-            mbp <- loadMiniBuildPlan snapName-            return mbp+            loadMiniBuildPlan snapName         ResolverGhc ghc -> return MiniBuildPlan             { mbpGhcVersion = fromMajorVersion ghc             , mbpPackages = Map.empty@@ -78,7 +84,12 @@     let latestVersion = Map.fromList $ map toTuple $ Map.keys caches     (locals, extraNames, extraIdents) <- loadLocals bopts latestVersion -    let nonLocalTargets = extraNames <> Set.map packageIdentifierName extraIdents+    let+        -- loadLocals returns PackageName (foo) and PackageIdentifier (bar-1.2.3) targets separately;+        -- here we combine them into nonLocalTargets. This is one of the+        -- return values of this function.+        nonLocalTargets :: Set PackageName+        nonLocalTargets = extraNames <> Set.map packageIdentifierName extraIdents          -- Extend extra-deps to encompass targets requested on the command line         -- that are not in the snapshot.@@ -111,7 +122,7 @@             , extraDeps3             , flip fmap (mbpPackages mbp) $ \mpi ->                 (PSUpstream (mpiVersion mpi) Snap (mpiFlags mpi))-            ] `Map.difference` Map.fromList (map (, ()) wiredInPackages)+            ] `Map.difference` Map.fromList (map (, ()) (HashSet.toList wiredInPackages))      let unknown = Set.difference nonLocalTargets $ Map.keysSet sourceMap     unless (Set.null unknown) $ do@@ -128,8 +139,24 @@      return (mbp, locals, nonLocalTargets, sourceMap) --- | Returns locals and extra target packages-loadLocals :: (MonadReader env m, HasBuildConfig env, MonadIO m, MonadLogger m, MonadThrow m, MonadCatch m,HasEnvConfig env)+-- | 'loadLocals' combines two pieces of information:+--+-- 1. Targets, i.e. arguments passed to stack such as @foo@ and @bar@ in the @stack foo bar@ invocation+--+-- 2. Local packages listed in @stack.yaml@+--+-- It returns:+--+-- 1. For every local package, a 'LocalPackage' structure+--+-- 2. If a target does not correspond to a local package but is a valid+-- 'PackageName' or 'PackageIdentifier', it is returned as such.+--+-- NOTE: as the function is written right now, it may "drop" targets if+-- they correspond to existing directories not listed in stack.yaml. This+-- may be a bug.+loadLocals :: forall m env .+              (MonadReader env m, HasBuildConfig env, MonadIO m, MonadLogger m, MonadThrow m, MonadCatch m,HasEnvConfig env)            => BuildOpts            -> Map PackageName Version            -> m ([LocalPackage], Set PackageName, Set PackageIdentifier)@@ -138,12 +165,18 @@         case boptsTargets bopts of             [] -> ["."]             x -> x++    -- Group targets by their kind     (dirs, names, idents) <-         case partitionEithers targets of             ([], targets') -> return $ partitionTargetSpecs targets'             (bad, _) -> throwM $ Couldn'tParseTargets bad +    econfig <- asks getEnvConfig     bconfig <- asks getBuildConfig+    -- Iterate over local packages declared in stack.yaml and turn them+    -- into LocalPackage structures. The targets affect whether these+    -- packages will be marked as wanted.     lps <- forM (Map.toList $ bcPackages bconfig) $ \(dir, validWanted) -> do         cabalfp <- getCabalFileName dir         name <- parsePackageNameFromFilePath cabalfp@@ -152,7 +185,7 @@                 { packageConfigEnableTests = False                 , packageConfigEnableBenchmarks = False                 , packageConfigFlags = localFlags (boptsFlags bopts) bconfig name-                , packageConfigGhcVersion = bcGhcVersion bconfig+                , packageConfigGhcVersion = envConfigGhcVersion econfig                 , packageConfigPlatform = configPlatform $ getConfig bconfig                 }             configFinal = config@@ -183,6 +216,11 @@      return (lps, unknown, idents)   where+    -- Attempt to parse a TargetSpec based on its textual form and on+    -- whether it is a name of an existing directory.+    --+    -- If a TargetSpec is not recognized, return it verbatim as Left.+    parseTarget :: Text -> m (Either Text TargetSpec)     parseTarget t = do         let s = T.unpack t         isDir <- liftIO $ doesDirectoryExist s
src/Stack/Build/Types.hs view
@@ -11,7 +11,7 @@  module Stack.Build.Types     (StackBuildException(..)-    ,Location(..)+    ,InstallLocation(..)     ,ModTime     ,modTime     ,Installed(..)@@ -27,7 +27,8 @@     ,ConfigCache(..)     ,ConstructPlanException(..)     ,configureOpts-    ,BadDependency(..))+    ,BadDependency(..)+    ,wantedLocalPackages)     where  import           Control.DeepSeq@@ -54,12 +55,12 @@ import           Distribution.System (Arch) import           Distribution.Text (display) import           GHC.Generics-import           Path (Path, Abs, File, Dir, mkRelDir, toFilePath, (</>))-import           Prelude hiding (FilePath)+import           Path (Path, Abs, File, Dir, mkRelDir, toFilePath, parseRelDir, (</>))+import           Prelude import           Stack.Package import           Stack.Types import           System.Exit (ExitCode)-import           System.FilePath (pathSeparator)+import           System.FilePath (dropTrailingPathSeparator, pathSeparator)  ---------------------------------------------- -- Exceptions@@ -163,6 +164,7 @@                     , "-"                     , versionString version                     ]) (Map.toList extras)+                    ++ ["", "You may also want to try the 'stack solver' command"]                 )          where              exceptions' = removeDuplicates exceptions@@ -263,6 +265,10 @@             ,boptsLibProfile :: !Bool             ,boptsExeProfile :: !Bool             ,boptsEnableOptimizations :: !(Maybe Bool)+            ,boptsHaddock :: !Bool+            -- ^ Build haddocks?+            ,boptsHaddockDeps :: !(Maybe Bool)+            -- ^ Build haddocks for dependencies?             ,boptsFinalAction :: !FinalAction             ,boptsDryrun :: !Bool             ,boptsGhcOptions :: ![Text]@@ -283,7 +289,6 @@ data FinalAction   = DoTests   | DoBenchmarks-  | DoHaddock   | DoNothing   deriving (Eq,Bounded,Enum,Show) @@ -293,14 +298,19 @@     deriving (Show,Typeable,Eq,Hashable,Binary,NFData)  -- | A location to install a package into, either snapshot or local-data Location = Snap | Local+data InstallLocation = Snap | Local     deriving (Show, Eq)+instance Monoid InstallLocation where+    mempty = Snap+    mappend Local _ = Local+    mappend _ Local = Local+    mappend Snap Snap = Snap  -- | Datatype which tells how which version of a package to install and where -- to install it into class PackageInstallInfo a where     piiVersion :: a -> Version-    piiLocation :: a -> Location+    piiLocation :: a -> InstallLocation  -- | Information on a locally available package of source code data LocalPackage = LocalPackage@@ -328,6 +338,8 @@       -- ^ The components to be built. It's a bit of a hack to include this in       -- here, as it's not a configure option (just a build option), but this       -- is a convenient way to force compilation when the components change.+    , configCacheHaddock :: !Bool+      -- ^ Are haddocks to be built?     }     deriving (Generic,Eq,Show) instance Binary ConfigCache@@ -359,7 +371,7 @@ -- | The type of a task, either building local code or something from the -- package index (upstream) data TaskType = TTLocal LocalPackage-              | TTUpstream Package Location+              | TTUpstream Package InstallLocation     deriving Show  -- | A complete plan of what needs to be built and how to do it@@ -368,7 +380,7 @@     , planFinals :: !(Map PackageName Task)     -- ^ Final actions to be taken (test, benchmark, etc)     , planUnregisterLocal :: !(Set GhcPkgId)-    , planInstallExes :: !(Map Text Location)+    , planInstallExes :: !(Map Text InstallLocation)     -- ^ Executables that should be installed after successful building     }     deriving Show@@ -383,24 +395,25 @@     }  -- | Render a @BaseConfigOpts@ to an actual list of options-configureOpts :: Config+configureOpts :: EnvConfig               -> BaseConfigOpts               -> Set GhcPkgId -- ^ dependencies               -> Bool -- ^ wanted?-              -> Location-              -> Map FlagName Bool+              -> InstallLocation+              -> Package               -> [Text]-configureOpts config bco deps wanted loc flags = map T.pack $ concat+configureOpts econfig bco deps wanted loc package = map T.pack $ concat     [ ["--user", "--package-db=clear", "--package-db=global"]     , map (("--package-db=" ++) . toFilePath) $ case loc of         Snap -> [bcoSnapDB bco]         Local -> [bcoSnapDB bco, bcoLocalDB bco]     , depOptions     , [ "--libdir=" ++ toFilePathNoTrailingSlash (installRoot </> $(mkRelDir "lib"))-      , "--bindir=" ++ toFilePathNoTrailingSlash  (installRoot </> bindirSuffix)-      , "--datadir=" ++ toFilePathNoTrailingSlash  (installRoot </> $(mkRelDir "share"))-      , "--docdir=" ++ toFilePathNoTrailingSlash  (installRoot </> $(mkRelDir "doc"))-      ]+      , "--bindir=" ++ toFilePathNoTrailingSlash (installRoot </> bindirSuffix)+      , "--datadir=" ++ toFilePathNoTrailingSlash (installRoot </> $(mkRelDir "share"))+      , "--docdir=" ++ toFilePathNoTrailingSlash docDir+      , "--htmldir=" ++ toFilePathNoTrailingSlash docDir+      , "--haddockdir=" ++ toFilePathNoTrailingSlash docDir]     , ["--enable-library-profiling" | boptsLibProfile bopts || boptsExeProfile bopts]     , ["--enable-executable-profiling" | boptsExeProfile bopts]     , map (\(name,enabled) ->@@ -409,7 +422,7 @@                            then ""                            else "-") <>                        flagNameString name)-                    (Map.toList flags)+                    (Map.toList (packageFlags package))     -- FIXME Chris: where does this come from now? , ["--ghc-options=-O2" | gconfigOptimize gconfig]     , if wanted         then concatMap (\x -> ["--ghc-options", T.unpack x]) (boptsGhcOptions bopts)@@ -418,31 +431,37 @@     , map (("--extra-lib-dirs=" ++) . T.unpack) (Set.toList (configExtraLibDirs config))     ]   where+    config = getConfig econfig     bopts = bcoBuildOpts bco-    toFilePathNoTrailingSlash =-        loop . toFilePath-      where-        loop [] = []-        loop [c]-            | c == pathSeparator = []-            | otherwise = [c]-        loop (c:cs) = c : loop cs+    toFilePathNoTrailingSlash = dropTrailingPathSeparator . toFilePath+    docDir =+        case pkgVerDir of+            Nothing -> installRoot </> docdirSuffix+            Just dir -> installRoot </> docdirSuffix </> dir     installRoot =         case loc of             Snap -> bcoSnapInstallRoot bco             Local -> bcoLocalInstallRoot bco+    pkgVerDir =+        parseRelDir (packageIdentifierString (PackageIdentifier (packageName package)+                                                                (packageVersion package)) +++                     [pathSeparator])      depOptions = map toDepOption $ Set.toList deps+      where+        toDepOption =+            if envConfigCabalVersion econfig >= $(mkVersion "1.22")+                then toDepOption1_22+                else toDepOption1_18 -    {- TODO does this work with some versions of Cabal?-    toDepOption gid = T.pack $ concat+    toDepOption1_22 gid = concat         [ "--dependency="         , packageNameString $ packageIdentifierName $ ghcPkgIdPackageIdentifier gid         , "="         , ghcPkgIdString gid         ]-    -}-    toDepOption gid = concat++    toDepOption1_18 gid = concat         [ "--constraint="         , packageNameString name         , "=="@@ -450,6 +469,10 @@         ]       where         PackageIdentifier name version = ghcPkgIdPackageIdentifier gid++-- | Get set of wanted package names from locals.+wantedLocalPackages :: [LocalPackage] -> Set PackageName+wantedLocalPackages = Set.fromList . map (packageName . lpPackage) . filter lpWanted  -- | Used for storage and comparison. newtype ModTime = ModTime (Integer,Rational)
src/Stack/BuildPlan.hs view
@@ -194,36 +194,65 @@ toMiniBuildPlan :: (MonadIO m, MonadLogger m, MonadReader env m, HasHttpManager env, MonadThrow m, HasConfig env, MonadBaseControl IO m, MonadCatch m)                 => BuildPlan -> m MiniBuildPlan toMiniBuildPlan bp = do-    extras <- addDeps ghcVersion $ fmap goPP $ bpPackages bp-    return MiniBuildPlan+    $logInfo "Caching build plan"++    -- Determine the dependencies of all of the packages in the build plan. We+    -- handle core packages specially, because some of them will not be in the+    -- package index. For those, we allow missing packages to exist, and then+    -- remove those from the list of dependencies, since there's no way we'll+    -- ever reinstall them anyway.+    (cores, missingCores) <- addDeps True ghcVersion+        $ fmap (, Map.empty) (siCorePackages $ bpSystemInfo bp)++    (extras, missing) <- addDeps False ghcVersion $ fmap goPP $ bpPackages bp++    assert (Set.null missing) $ return MiniBuildPlan         { mbpGhcVersion = ghcVersion-        , mbpPackages = Map.union cores extras+        , mbpPackages = Map.unions+            [ fmap (removeMissingDeps (Map.keysSet cores)) cores+            , extras+            , Map.fromList $ map goCore $ Set.toList missingCores+            ]         }   where     ghcVersion = siGhcVersion $ bpSystemInfo bp-    cores = fmap (\v -> MiniPackageInfo-                { mpiVersion = v+    goCore (PackageIdentifier name version) = (name, MiniPackageInfo+                { mpiVersion = version                 , mpiFlags = Map.empty                 , mpiPackageDeps = Set.empty                 , mpiToolDeps = Set.empty                 , mpiExes = Set.empty                 , mpiHasLibrary = True-                }) $ siCorePackages $ bpSystemInfo bp+                })      goPP pp =         ( ppVersion pp         , pcFlagOverrides $ ppConstraints pp         ) +    removeMissingDeps cores mpi = mpi+        { mpiPackageDeps = Set.intersection cores (mpiPackageDeps mpi)+        }+ -- | Add in the resolved dependencies from the package index addDeps :: (MonadIO m, MonadLogger m, MonadReader env m, HasHttpManager env, MonadThrow m, HasConfig env, MonadBaseControl IO m, MonadCatch m)-        => Version -- ^ GHC version+        => Bool -- ^ allow missing+        -> Version -- ^ GHC version         -> Map PackageName (Version, Map FlagName Bool)-        -> m (Map PackageName MiniPackageInfo)-addDeps ghcVersion toCalc = do+        -> m (Map PackageName MiniPackageInfo, Set PackageIdentifier)+addDeps allowMissing ghcVersion toCalc = do     menv <- getMinimalEnvOverride     platform <- asks $ configPlatform . getConfig-    resolvedMap <- resolvePackages menv (Map.keysSet idents0) Set.empty+    (resolvedMap, missingIdents) <-+        if allowMissing+            then do+                (missingNames, missingIdents, m) <-+                    resolvePackagesAllowMissing menv (Map.keysSet idents0) Set.empty+                assert (Set.null missingNames)+                    $ return (m, missingIdents)+            else do+                m <- resolvePackages menv (Map.keysSet idents0) Set.empty+                return (m, Set.empty)     let byIndex = Map.fromListWith (++) $ flip map (Map.toList resolvedMap)             $ \(ident, rp) ->                 (indexName $ rpIndex rp,@@ -256,7 +285,7 @@                     (buildable . libBuildInfo)                     (library pd)                 })-    return $ Map.fromList $ concat res+    return (Map.fromList $ concat res, missingIdents)   where     idents0 = Map.fromList         $ map (\(n, (v, f)) -> (PackageIdentifier n v, Left f))
src/Stack/Config.hs view
@@ -39,7 +39,6 @@ import           Data.Aeson.Extended import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString.Lazy as L-import           Data.Either (partitionEithers) import qualified Data.IntMap as IntMap import qualified Data.Map as Map import           Data.Maybe@@ -83,46 +82,6 @@                 Just lts -> lts     return (ResolverSnapshot snap) -data ProjectAndConfigMonoid-  = ProjectAndConfigMonoid !Project !ConfigMonoid--instance FromJSON ProjectAndConfigMonoid where-    parseJSON = withObject "Project, ConfigMonoid" $ \o -> do-        dirs <- o .:? "packages" .!= [packageEntryCurrDir]-        extraDeps' <- o .:? "extra-deps" .!= []-        extraDeps <--            case partitionEithers $ goDeps extraDeps' of-                ([], x) -> return $ Map.fromList x-                (errs, _) -> fail $ unlines errs--        flags <- o .:? "flags" .!= mempty-        resolver <- o .: "resolver"-        config <- parseJSON $ Object o-        let project = Project-                { projectPackages = dirs-                , projectExtraDeps = extraDeps-                , projectFlags = flags-                , projectResolver = resolver-                }-        return $ ProjectAndConfigMonoid project config-      where-        goDeps =-            map toSingle . Map.toList . Map.unionsWith S.union . map toMap-          where-            toMap i = Map.singleton-                (packageIdentifierName i)-                (S.singleton (packageIdentifierVersion i))--        toSingle (k, s) =-            case S.toList s of-                [x] -> Right (k, x)-                xs -> Left $ concat-                    [ "Multiple versions for package "-                    , packageNameString k-                    , ": "-                    , unwords $ map versionString xs-                    ]- -- | Note that this will be @Nothing@ on Windows, which is by design. defaultStackGlobalConfig :: Maybe (Path Abs File) defaultStackGlobalConfig = parseAbsFile "/etc/stack/config"@@ -287,14 +246,6 @@         , lcProjectRoot     = fmap (\(_, fp, _) -> parent fp) mproject         } --- | A PackageEntry for the current directory, used as a default-packageEntryCurrDir :: PackageEntry-packageEntryCurrDir = PackageEntry-    { peValidWanted = True-    , peLocation = PLFilePath "."-    , peSubdirs = []-    }- -- | Load the build configuration, adds build-specific values to config loaded by @loadConfig@. -- values. loadBuildConfig :: (MonadLogger m, MonadIO m, MonadCatch m, MonadReader env m, HasHttpManager env, MonadBaseControl IO m)@@ -368,7 +319,7 @@     return BuildConfig         { bcConfig = config         , bcResolver = projectResolver project-        , bcGhcVersion = ghcVersion+        , bcGhcVersionExpected = ghcVersion         , bcPackages = packages         , bcExtraDeps = projectExtraDeps project         , bcRoot = root@@ -497,7 +448,7 @@ loadYaml :: (FromJSON a,MonadIO m) => Path Abs File -> m a loadYaml path =     liftIO $ Yaml.decodeFileEither (toFilePath path)-         >>= either throwM return+         >>= either (throwM . ParseConfigFileException path) return  -- | Get the location of the project config file, if it exists. getProjectConfig :: (MonadIO m, MonadThrow m, MonadLogger m)
src/Stack/Constants.hs view
@@ -30,7 +30,8 @@ import           Control.Monad.Catch (MonadThrow) import           Control.Monad.Reader -import           Data.Maybe (fromMaybe)+import           Data.HashSet (HashSet)+import qualified Data.HashSet as HashSet import           Data.Text (Text) import qualified Data.Text as T import           Path as FL@@ -195,8 +196,9 @@ stackRootEnvVar = "STACK_ROOT"  -- See https://downloads.haskell.org/~ghc/7.10.1/docs/html/libraries/ghc/src/Module.html#integerPackageKey-wiredInPackages :: [PackageName]-wiredInPackages = fromMaybe (error "Parse error in wiredInPackages") mparsed+wiredInPackages :: HashSet PackageName+wiredInPackages =+    maybe (error "Parse error in wiredInPackages") HashSet.fromList mparsed   where     mparsed = sequence $ map parsePackageName       [ "ghc-prim"
src/Stack/Docker.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, MultiWayIf, NamedFieldPuns,+{-# LANGUAGE CPP, ConstraintKinds, DeriveDataTypeable, FlexibleContexts, MultiWayIf, NamedFieldPuns,              OverloadedStrings, RankNTypes, RecordWildCards, TemplateHaskell, TupleSections #-}  -- | Run commands in Docker containers@@ -22,9 +22,10 @@ import           Control.Applicative import           Control.Exception.Lifted import           Control.Monad-import           Control.Monad.Catch (MonadThrow, throwM, MonadCatch)+import           Control.Monad.Catch (MonadThrow,throwM,MonadCatch) import           Control.Monad.IO.Class (MonadIO,liftIO) import           Control.Monad.Logger (MonadLogger,logError,logInfo,logWarn)+import           Control.Monad.Reader (MonadReader,asks) import           Control.Monad.Writer (execWriter,runWriter,tell) import           Control.Monad.Trans.Control (MonadBaseControl) import           Data.Aeson.Extended (FromJSON(..),(.:),(.:?),(.!=),eitherDecode)@@ -49,12 +50,13 @@ import           Path.IO (getWorkingDir,listDirectory) import           Stack.Constants (projectDockerSandboxDir,stackProgName,stackDotYaml,stackRootEnvVar) import           Stack.Types+import           Stack.Types.Internal import           Stack.Docker.GlobalDB import           System.Directory (createDirectoryIfMissing,removeDirectoryRecursive,removeFile) import           System.Directory (doesDirectoryExist) import           System.Environment (lookupEnv,getProgName,getArgs,getExecutablePath) import           System.Exit (ExitCode(ExitSuccess),exitWith)-import           System.FilePath (takeBaseName,isPathSeparator)+import           System.FilePath (dropTrailingPathSeparator,takeBaseName) import           System.Info (arch,os) import           System.IO (stderr,stdin,stdout,hIsTerminalDevice) import qualified System.Process as Proc@@ -70,10 +72,12 @@ -- | If Docker is enabled, re-runs the currently running OS command in a Docker container. -- Otherwise, runs the inner action. rerunWithOptionalContainer-    :: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)-    => Config -> Maybe (Path Abs Dir) -> IO () -> m ()-rerunWithOptionalContainer config mprojectRoot =-  rerunCmdWithOptionalContainer config mprojectRoot getCmdArgs+    :: M env m+    => Maybe (Path Abs Dir)+    -> IO ()+    -> m ()+rerunWithOptionalContainer mprojectRoot =+  rerunCmdWithOptionalContainer mprojectRoot getCmdArgs   where     getCmdArgs =       do args <- getArgs@@ -82,41 +86,41 @@                      let mountPath = concat ["/opt/host/bin/",takeBaseName exePath]                      return (mountPath                             ,args-                            ,config{configDocker=docker{dockerMount=Mount exePath mountPath :-                                                                    dockerMount docker}})+                            ,\c -> c{configDocker=(configDocker c)+                                                  {dockerMount=Mount exePath mountPath :+                                                               dockerMount (configDocker c)}})              else do progName <- getProgName-                     return (takeBaseName progName,args,config)-    docker = configDocker config+                     return (takeBaseName progName,args,id)  -- | If Docker is enabled, re-runs the OS command returned by the second argument in a -- Docker container.  Otherwise, runs the inner action. rerunCmdWithOptionalContainer-    :: (MonadLogger m,MonadIO m,MonadThrow m,MonadBaseControl IO m, MonadCatch m)-    => Config-    -> Maybe (Path Abs Dir)-    -> IO (FilePath,[String],Config)+    :: M env m+    => Maybe (Path Abs Dir)+    -> IO (FilePath,[String],Config -> Config)     -> IO ()     -> m ()-rerunCmdWithOptionalContainer config mprojectRoot getCmdArgs inner =-  do inContainer <- getInContainer+rerunCmdWithOptionalContainer mprojectRoot getCmdArgs inner =+  do config <- asks getConfig+     inContainer <- getInContainer      if inContainer || not (dockerEnable (configDocker config))         then liftIO inner-        else do (cmd_,args,config') <- liftIO getCmdArgs-                runContainerAndExit config' mprojectRoot cmd_ args [] (return ())+        else do (cmd_,args,modConfig) <- liftIO getCmdArgs+                runContainerAndExit modConfig mprojectRoot cmd_ args [] (return ())  -- | If Docker is enabled, re-runs the OS command returned by the second argument in a -- Docker container.  Otherwise, runs the inner action. rerunCmdWithRequiredContainer-    :: (MonadLogger m,MonadIO m,MonadThrow m,MonadBaseControl IO m, MonadCatch m)-    => Config-    -> Maybe (Path Abs Dir)-    -> IO (FilePath,[String],Config)+    :: M env m+    => Maybe (Path Abs Dir)+    -> IO (FilePath,[String],Config -> Config)     -> m ()-rerunCmdWithRequiredContainer config mprojectRoot getCmdArgs =-  do when (not (dockerEnable (configDocker config)))+rerunCmdWithRequiredContainer mprojectRoot getCmdArgs =+  do config <- asks getConfig+     when (not (dockerEnable (configDocker config)))           (throwM DockerMustBeEnabledException)-     (cmd_,args,config') <- liftIO getCmdArgs-     runContainerAndExit config' mprojectRoot cmd_ args [] (return ())+     (cmd_,args,modConfig) <- liftIO getCmdArgs+     runContainerAndExit modConfig mprojectRoot cmd_ args [] (return ())  -- | Error if running in a container. preventInContainer :: (MonadIO m,MonadThrow m) => m () -> m ()@@ -135,21 +139,23 @@        Just _ -> return True  -- | Run a command in a new Docker container, then exit the process.-runContainerAndExit :: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)-                    => Config+runContainerAndExit :: M env m+                    => (Config -> Config)                     -> Maybe (Path Abs Dir)                     -> FilePath                     -> [String]                     -> [(String, String)]                     -> IO ()                     -> m ()-runContainerAndExit config+runContainerAndExit modConfig                     mprojectRoot                     cmnd                     args                     envVars                     successPostAction =-  do envOverride <- getEnvOverride (configPlatform config)+  do config <- fmap modConfig (asks getConfig)+     let docker = configDocker config+     envOverride <- getEnvOverride (configPlatform config)      checkDockerVersion envOverride      uidOut <- readProcessStdout Nothing envOverride "id" ["-u"]      gidOut <- readProcessStdout Nothing envOverride "id" ["-g"]@@ -157,10 +163,10 @@        liftIO ((,,) <$> lookupEnv "DOCKER_HOST"                     <*> lookupEnv "DOCKER_CERT_PATH"                     <*> lookupEnv "DOCKER_TLS_VERIFY")-     (isStdinTerminal,isStdoutTerminal,isStderrTerminal) <--       liftIO ((,,) <$> hIsTerminalDevice stdin-                    <*> hIsTerminalDevice stdout-                    <*> hIsTerminalDevice stderr)+     isStdoutTerminal <- asks getTerminal+     (isStdinTerminal,isStderrTerminal) <-+       liftIO ((,) <$> hIsTerminalDevice stdin+                   <*> hIsTerminalDevice stderr)      pwd <- getWorkingDir      when (maybe False (isPrefixOf "tcp://") dockerHost &&            maybe False (isInfixOf "boot2docker") dockerCertPath)@@ -206,7 +212,8 @@          execDockerProcess =            do mapM_ (createDirectoryIfMissing True)                     (concat [[toFilePath sandboxHomeDir-                             ,toFilePath sandboxSandboxDir] +++                             ,toFilePath sandboxSandboxDir+                             ,toFilePath stackRoot] ++                              map toFilePath sandboxSubdirs])               execProcessAndExit                 envOverride@@ -215,16 +222,18 @@                   [["run"                    ,"--net=host"                    ,"-e",inContainerEnvVar ++ "=1"-                   ,"-e",stackRootEnvVar ++ "=" ++ trimTrailingPathSep stackRoot+                   ,"-e",stackRootEnvVar ++ "=" ++ toFPNoTrailingSep stackRoot                    ,"-e","WORK_UID=" ++ uid                    ,"-e","WORK_GID=" ++ gid-                   ,"-e","WORK_WD=" ++ trimTrailingPathSep pwd-                   ,"-e","WORK_HOME=" ++ trimTrailingPathSep sandboxRepoDir-                   ,"-e","WORK_ROOT=" ++ trimTrailingPathSep projectRoot-                   ,"-v",trimTrailingPathSep stackRoot ++ ":" ++ trimTrailingPathSep stackRoot-                   ,"-v",trimTrailingPathSep projectRoot ++ ":" ++ trimTrailingPathSep projectRoot-                   ,"-v",trimTrailingPathSep sandboxSandboxDir ++ ":" ++ trimTrailingPathSep sandboxDir-                   ,"-v",trimTrailingPathSep sandboxHomeDir ++ ":" ++ trimTrailingPathSep sandboxRepoDir]+                   ,"-e","WORK_WD=" ++ toFPNoTrailingSep pwd+                   ,"-e","WORK_HOME=" ++ toFPNoTrailingSep sandboxRepoDir+                   ,"-e","WORK_ROOT=" ++ toFPNoTrailingSep projectRoot+                   ,"-v",toFPNoTrailingSep stackRoot ++ ":" ++ toFPNoTrailingSep stackRoot+                   ,"-v",toFPNoTrailingSep projectRoot ++ ":" ++ toFPNoTrailingSep projectRoot+                   ,"-v",toFPNoTrailingSep sandboxSandboxDir ++ ":" ++ toFPNoTrailingSep sandboxDir+                   ,"-v",toFPNoTrailingSep sandboxHomeDir ++ ":" ++ toFPNoTrailingSep sandboxRepoDir+                   ,"-v",toFPNoTrailingSep stackRoot ++ ":" +++                         toFPNoTrailingSep (sandboxRepoDir </> $(mkRelDir ("." ++ stackProgName ++ "/")))]                   ,if oldImage                      then ["-e",sandboxIDEnvVar ++ "=" ++ sandboxID                           ,"--entrypoint=/root/entrypoint.sh"]@@ -269,16 +278,16 @@         Just ('=':val) -> Just val         _ -> Nothing     mountArg (Mount host container) = ["-v",host ++ ":" ++ container]-    sandboxSubdirArg subdir = ["-v",trimTrailingPathSep subdir++ ":" ++ trimTrailingPathSep subdir]-    trimTrailingPathSep = dropWhileEnd isPathSeparator . toFilePath+    sandboxSubdirArg subdir = ["-v",toFPNoTrailingSep subdir++ ":" ++ toFPNoTrailingSep subdir]+    toFPNoTrailingSep = dropTrailingPathSeparator . toFilePath     projectRoot = fromMaybeProjectRoot mprojectRoot-    docker = configDocker config  -- | Clean-up old docker images and containers.-cleanup :: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)-        => Config -> CleanupOpts -> m ()-cleanup config opts =-  do envOverride <- getEnvOverride (configPlatform config)+cleanup :: M env m+        => CleanupOpts -> m ()+cleanup opts =+  do config <- asks getConfig+     envOverride <- getEnvOverride (configPlatform config)      checkDockerVersion envOverride      let runDocker = readDockerProcess envOverride      imagesOut <- runDocker ["images","--no-trunc","-f","dangling=false"]@@ -526,13 +535,13 @@        Left e -> throwM e  -- | Pull latest version of configured Docker image from registry.-pull :: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)-     => Config -> m ()-pull config =-  do envOverride <- getEnvOverride (configPlatform config)+pull :: M env m => m ()+pull =+  do config <- asks getConfig+     let docker = configDocker config+     envOverride <- getEnvOverride (configPlatform config)      checkDockerVersion envOverride      pullImage envOverride docker (dockerImage docker)-  where docker = configDocker config  -- | Pull Docker image from registry. pullImage :: (MonadLogger m,MonadIO m,MonadThrow m)@@ -945,3 +954,6 @@     "Cannot find 'docker' in PATH.  Is Docker installed?"   show (InvalidDatabasePathException ex) =     concat ["Invalid database path: ",show ex]++type M env m = (MonadIO m,MonadReader env m,MonadLogger m,MonadBaseControl IO m,MonadCatch m+               ,HasConfig env,HasTerminal env)
src/Stack/Exec.hs view
@@ -13,6 +13,7 @@  import           Path import           Stack.Types+import           System.Directory (doesFileExist) import           System.Exit import qualified System.Process as P import           System.Process.Read@@ -28,12 +29,16 @@                                 { esIncludeLocals = True                                 , esIncludeGhcPackagePath = True                                 })-    cmd' <- join $ System.Process.Read.findExecutable menv cmd-    let cp = (P.proc (toFilePath cmd') args)+    exists <- liftIO $ doesFileExist cmd+    cmd' <-+        if exists+            then return cmd+            else liftM toFilePath $ join $ System.Process.Read.findExecutable menv cmd+    let cp = (P.proc cmd' args)             { P.env = envHelper menv             , P.delegate_ctlc = True             }-    $logProcessRun (toFilePath cmd') args+    $logProcessRun cmd' args     (Nothing, Nothing, Nothing, ph) <- liftIO (P.createProcess cp)     ec <- liftIO (P.waitForProcess ph)     liftIO (exitWith ec)
src/Stack/Fetch.hs view
@@ -16,6 +16,7 @@     , unpackPackageIdents     , fetchPackages     , resolvePackages+    , resolvePackagesAllowMissing     , ResolvedPackage (..)     , withCabalFiles     , withCabalLoader@@ -188,21 +189,32 @@         Right x -> return x   where     go = do-        caches <- getPackageCaches menv-        let versions = Map.fromListWith max $ map toTuple $ Map.keys caches-            (missing, idents1) = partitionEithers $ map-                (\name -> maybe (Left name ) (Right . PackageIdentifier name)-                    (Map.lookup name versions))-                (Set.toList names0)-        return $ if null missing-            then goIdents caches $ idents0 <> Set.fromList idents1-            else Left $ UnknownPackageNames $ Set.fromList missing--    goIdents caches idents =-        case partitionEithers $ map (goIdent caches) $ Set.toList idents of-            ([], resolved) -> Right $ Map.fromList resolved-            (missing, _) -> Left $ UnknownPackageIdentifiers $ Set.fromList missing+        (missingNames, missingIdents, idents) <- resolvePackagesAllowMissing menv idents0 names0+        return $+            case () of+                ()+                    | not $ Set.null missingNames -> Left $ UnknownPackageNames missingNames+                    | not $ Set.null missingIdents -> Left $ UnknownPackageIdentifiers missingIdents+                    | otherwise -> Right idents +resolvePackagesAllowMissing+    :: (MonadIO m, MonadReader env m, HasHttpManager env, HasConfig env, MonadLogger m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)+    => EnvOverride+    -> Set PackageIdentifier+    -> Set PackageName+    -> m (Set PackageName, Set PackageIdentifier, Map PackageIdentifier ResolvedPackage)+resolvePackagesAllowMissing menv idents0 names0 = do+    caches <- getPackageCaches menv+    let versions = Map.fromListWith max $ map toTuple $ Map.keys caches+        (missingNames, idents1) = partitionEithers $ map+            (\name -> maybe (Left name ) (Right . PackageIdentifier name)+                (Map.lookup name versions))+            (Set.toList names0)+        (missingIdents, resolved) = partitionEithers $ map (goIdent caches)+                                  $ Set.toList+                                  $ idents0 <> Set.fromList idents1+    return (Set.fromList missingNames, Set.fromList missingIdents, Map.fromList resolved)+  where     goIdent caches ident =         case Map.lookup ident caches of             Nothing -> Left ident
src/Stack/GhcPkg.hs view
@@ -14,7 +14,9 @@   ,envHelper   ,createDatabase   ,unregisterGhcPkgId-  ,getCabalPkgVer)+  ,getCabalPkgVer+  ,findGhcPkgHaddockHtml+  ,findGhcPkgDepends)   where  import           Control.Monad@@ -26,6 +28,7 @@ import           Data.Either import           Data.List import           Data.Maybe+import           Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T import           Path (Path, Abs, Dir, toFilePath, parent, parseAbsDir)@@ -34,6 +37,7 @@ import           Stack.Constants import           Stack.Types import           System.Directory (createDirectoryIfMissing, doesDirectoryExist, canonicalizePath)+import           System.FilePath (normalise) import           System.Process.Read  -- | Get the global package database@@ -90,6 +94,28 @@           "--no-user-package-db"         : map (\x -> ("--package-db=" ++ toFilePath x)) pkgDbs +-- | Get the value of a field of the package.+findGhcPkgField+    :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadCatch m, MonadThrow m)+    => EnvOverride+    -> [Path Abs Dir] -- ^ package databases+    -> Text+    -> Text+    -> m (Maybe Text)+findGhcPkgField menv pkgDbs name field = do+    result <-+        ghcPkg+            menv+            pkgDbs+            ["field", "--simple-output", T.unpack name, T.unpack field]+    return $+        case result of+            Left{} -> Nothing+            Right lbs ->+                fmap (stripCR . T.decodeUtf8) $ listToMaybe $ S8.lines lbs+  where+    stripCR t = fromMaybe t (T.stripSuffix "\r" t)+ -- | Get the id of the package e.g. @foo-0.0.0-9c293923c0685761dcff6f8c3ad8f8ec@. findGhcPkgId :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadCatch m, MonadThrow m)              => EnvOverride@@ -97,29 +123,35 @@              -> PackageName              -> m (Maybe GhcPkgId) findGhcPkgId menv pkgDbs name = do-    result <--        ghcPkg menv pkgDbs ["describe", packageNameString name]-    case result of-        Left{} ->-            return Nothing-        Right lbs -> do-            let mpid =-                    fmap-                        T.encodeUtf8-                        (listToMaybe-                             (mapMaybe-                                  (fmap stripCR .-                                   T.stripPrefix "id: ")-                                  (map T.decodeUtf8 (S8.lines lbs))))-            case mpid of-                Just !pid ->-                    return (parseGhcPkgId pid)-                _ ->-                    return Nothing-  where-    stripCR t =-        fromMaybe t (T.stripSuffix "\r" t)+    mpid <- findGhcPkgField menv pkgDbs (packageNameText name) "id"+    case mpid of+        Just !pid -> return (parseGhcPkgId (T.encodeUtf8 pid))+        _ -> return Nothing +-- | Get the Haddock HTML documentation path of the package.+findGhcPkgHaddockHtml :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadCatch m, MonadThrow m)+                      => EnvOverride+                      -> [Path Abs Dir] -- ^ package databases+                      -> PackageIdentifier+                      -> m (Maybe (Path Abs Dir))+findGhcPkgHaddockHtml menv pkgDbs pkgId = do+    mpath <- findGhcPkgField menv pkgDbs (packageIdentifierText pkgId) "haddock-html"+    case mpath of+        Just !path -> return $ parseAbsDir $ normalise $ T.unpack path+        _ -> return Nothing++-- | Get the dependencies of the package.+findGhcPkgDepends :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadCatch m, MonadThrow m)+                  => EnvOverride+                  -> [Path Abs Dir] -- ^ package databases+                  -> PackageIdentifier+                  -> m [GhcPkgId]+findGhcPkgDepends menv pkgDbs pkgId = do+    mdeps <- findGhcPkgField menv pkgDbs (packageIdentifierText pkgId) "depends"+    case mdeps of+        Just !deps -> return (mapMaybe (parseGhcPkgId . T.encodeUtf8) (T.words deps))+        _ -> return []+ unregisterGhcPkgId :: (MonadIO m, MonadLogger m, MonadThrow m, MonadCatch m, MonadBaseControl IO m)                     => EnvOverride                     -> Path Abs Dir -- ^ package database@@ -137,11 +169,10 @@ -- | Get the version of Cabal from the global package database. getCabalPkgVer :: (MonadThrow m, MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadCatch m)                => EnvOverride -> m Version-getCabalPkgVer menv = do-    db <- getGlobalDB menv -- FIXME shouldn't be necessary, just tell ghc-pkg to look in the global DB+getCabalPkgVer menv =     findGhcPkgId         menv-        [db]+        [] -- global DB         cabalPackageName >>=         maybe             (throwM $ Couldn'tFindPkgId cabalPackageName)
src/Stack/Init.hs view
@@ -11,10 +11,9 @@     ) where  import           Control.Exception               (assert)-import           Control.Exception.Enclosed      (handleIO)+import           Control.Exception.Enclosed      (handleIO, catchAny) import           Control.Monad                   (liftM, when)-import           Control.Monad.Catch             (MonadCatch, SomeException,-                                                  catch, throwM)+import           Control.Monad.Catch             (MonadMask, throwM) import           Control.Monad.IO.Class import           Control.Monad.Logger import           Control.Monad.Reader            (MonadReader)@@ -40,6 +39,7 @@ import           Stack.BuildPlan import           Stack.Constants import           Stack.Package+import           Stack.Solver import           Stack.Types import           System.Directory                (getDirectoryContents) @@ -60,11 +60,10 @@     ]  -- | Generate stack.yaml-initProject :: (MonadIO m, MonadCatch m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)-            => Maybe Resolver -- ^ force this resolver to be used-            -> InitOpts+initProject :: (MonadIO m, MonadMask m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)+            => InitOpts             -> m ()-initProject mresolver initOpts = do+initProject initOpts = do     currDir <- getWorkingDir     let dest = currDir </> stackDotYaml         dest' = toFilePath dest@@ -80,10 +79,10 @@     when (null cabalfps) $ error "In order to init, you should have an existing .cabal file. Please try \"stack new\" instead"     gpds <- mapM readPackageUnresolved cabalfps -    (r, flags) <- getDefaultResolver gpds mresolver initOpts+    (r, flags, extraDeps) <- getDefaultResolver cabalfps gpds initOpts     let p = Project             { projectPackages = pkgs-            , projectExtraDeps = Map.empty+            , projectExtraDeps = extraDeps             , projectFlags = flags             , projectResolver = r             }@@ -102,10 +101,10 @@     liftIO $ Yaml.encodeFile dest' p     $logInfo $ "Wrote project config to: " <> T.pack dest' -getSnapshots' :: (MonadIO m, MonadCatch m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)-              => m Snapshots+getSnapshots' :: (MonadIO m, MonadMask m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)+              => m (Maybe Snapshots) getSnapshots' =-    getSnapshots `catch` \e -> do+    liftM Just getSnapshots `catchAny` \e -> do         $logError $             "Unable to download snapshot list, and therefore could " <>             "not generate a stack.yaml file automatically"@@ -119,42 +118,50 @@         $logError ""         $logError "    https://github.com/commercialhaskell/stack/wiki/stack.yaml"         $logError ""-        throwM (e :: SomeException)+        $logError $ "Exception was: " <> T.pack (show e)+        return Nothing  -- | Get the default resolver value-getDefaultResolver :: (MonadIO m, MonadCatch m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)-                   => [C.GenericPackageDescription] -- ^ cabal files-                   -> Maybe Resolver -- ^ resolver override+getDefaultResolver :: (MonadIO m, MonadMask m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)+                   => [Path Abs File] -- ^ cabal files+                   -> [C.GenericPackageDescription] -- ^ cabal descriptions                    -> InitOpts-                   -> m (Resolver, Map PackageName (Map FlagName Bool))-getDefaultResolver gpds mresolver initOpts = do-    names <--        case mresolver of-            Nothing -> do-                snapshots <- getSnapshots'-                getRecommendedSnapshots snapshots initOpts-            Just resolver ->-                return $-                    case resolver of-                        ResolverSnapshot name -> [name]-                        ResolverGhc _ -> []-    mpair <- findBuildPlan gpds names-    case mpair of-        Just (snap, flags) ->-            return (ResolverSnapshot snap, flags)-        Nothing ->-            case mresolver of-                Nothing ->-                    case ioFallback initOpts of-                        Nothing -> throwM $ NoMatchingSnapshot names-                        Just resolver -> return (resolver, Map.empty)-                Just resolver -> return (resolver, Map.empty)+                   -> m (Resolver, Map PackageName (Map FlagName Bool), Map PackageName Version)+getDefaultResolver cabalfps gpds initOpts = do+    case ioMethod initOpts of+        MethodSnapshot snapPref -> do+            msnapshots <- getSnapshots'+            names <-+                case msnapshots of+                    Nothing -> return []+                    Just snapshots -> getRecommendedSnapshots snapshots snapPref+            mpair <- findBuildPlan gpds names+            case mpair of+                Just (snap, flags) ->+                    return (ResolverSnapshot snap, flags, Map.empty)+                Nothing -> throwM $ NoMatchingSnapshot names+        MethodResolver resolver -> do+            mpair <-+                case resolver of+                    ResolverSnapshot name -> findBuildPlan gpds [name]+                    ResolverGhc _ -> return Nothing+            case mpair of+                Just (snap, flags) ->+                    return (ResolverSnapshot snap, flags, Map.empty)+                Nothing -> return (resolver, Map.empty, Map.empty)+        MethodSolver -> do+            (ghcVersion, extraDeps) <- cabalSolver (map parent cabalfps) []+            return+                ( ResolverGhc ghcVersion+                , Map.filter (not . Map.null) $ fmap snd extraDeps+                , fmap fst extraDeps+                ) -getRecommendedSnapshots :: (MonadIO m, MonadCatch m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)+getRecommendedSnapshots :: (MonadIO m, MonadMask m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m)                         => Snapshots-                        -> InitOpts+                        -> SnapPref                         -> m [SnapName]-getRecommendedSnapshots snapshots initOpts = do+getRecommendedSnapshots snapshots pref = do     -- Get the most recent LTS and Nightly in the snapshots directory and     -- prefer them over anything else, since odds are high that something     -- already exists for them.@@ -179,25 +186,35 @@         namesLTS = filter isLTS names         namesNightly = filter isNightly names -    case ioPref initOpts of+    case pref of         PrefNone -> return names         PrefLTS -> return $ namesLTS ++ namesNightly         PrefNightly -> return $ namesNightly ++ namesLTS  data InitOpts = InitOpts-    { ioPref     :: !SnapPref+    { ioMethod :: !Method     -- ^ Preferred snapshots-    , ioFallback :: !(Maybe Resolver)     }  data SnapPref = PrefNone | PrefLTS | PrefNightly +-- | Method of initializing+data Method = MethodSnapshot SnapPref | MethodResolver Resolver | MethodSolver+ initOptsParser :: Parser InitOpts-initOptsParser = InitOpts-    <$> pref-    <*> optional fallback+initOptsParser =+    InitOpts <$> method   where-    pref =+    method = solver+         <|> (MethodResolver <$> resolver)+         <|> (MethodSnapshot <$> snapPref)++    solver =+        flag' MethodSolver+            (long "solver" <>+             help "Use a dependency solver to determine dependencies")++    snapPref =         flag' PrefLTS             (long "prefer-lts" <>              help "Prefer LTS snapshots over Nightly snapshots") <|>@@ -206,10 +223,10 @@              help "Prefer Nightly snapshots over LTS snapshots") <|>         pure PrefNone -    fallback = option readResolver-        (long "fallback" <>+    resolver = option readResolver+        (long "resolver" <>          metavar "RESOLVER" <>-         help "Fallback resolver if none of the tested snapshots work")+         help "Use the given resolver, even if not all dependencies are met")  readResolver :: ReadM Resolver readResolver = do
src/Stack/New.hs view
@@ -1,8 +1,42 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-} module Stack.New     ( newProject     ) where -import Control.Monad.IO.Class+import           Control.Monad          (filterM, forM_, unless)+import           Control.Monad.IO.Class (MonadIO, liftIO)+import           Control.Monad.Logger   (MonadLogger, logInfo)+import           Data.ByteString        (ByteString)+import qualified Data.ByteString        as S+import           Data.FileEmbed         (embedDir)+import           Data.Map               (Map)+import qualified Data.Map               as Map+import qualified Data.Text              as T+import           System.Directory       (createDirectoryIfMissing,+                                         doesFileExist)+import           System.FilePath        (takeDirectory) -newProject :: MonadIO m => m ()-newProject = error "new command not yet implemented, check out https://github.com/commercialhaskell/stack/issues/137 for status and to get involved"+newProject :: (MonadIO m, MonadLogger m)+           => m ()+newProject = do+    $logInfo "NOTE: Currently stack new functionality is very rudimentary"+    $logInfo "There are plans to make this feature more useful in the future"+    $logInfo "For more information, see: https://github.com/commercialhaskell/stack/issues/137"+    $logInfo "For now, we'll just be generating a basic project structure in your current directory"++    exist <- filterM (liftIO . doesFileExist) (Map.keys files)+    unless (null exist) $+        error $ unlines+            $ "The following files already exist, refusing to overwrite:"+            : map ("- " ++) exist++    $logInfo ""+    forM_ (Map.toList files) $ \(fp, bs) -> do+        $logInfo $ T.pack $ "Writing: " ++ fp+        liftIO $ do+            createDirectoryIfMissing True $ takeDirectory fp+            S.writeFile fp bs++files :: Map FilePath ByteString+files = Map.fromList $(embedDir "new-template")
src/Stack/Package.hs view
@@ -120,7 +120,9 @@           ,packageTests :: !(Set Text)                    -- ^ names of test suites           ,packageBenchmarks :: !(Set Text)               -- ^ names of benchmarks           ,packageExes :: !(Set Text)                     -- ^ names of executables-          ,packageOpts :: !GetPackageOpts              -- ^ Args to pass to GHC.+          ,packageOpts :: !GetPackageOpts                 -- ^ Args to pass to GHC.+          ,packageHasExposedModules :: !Bool              -- ^ Does the package have exposed modules?+          ,packageSimpleType :: !Bool                     -- ^ Does the package of build-type: Simple           }  deriving (Show,Typeable) @@ -243,6 +245,8 @@     , packageExes = S.fromList $ [ T.pack (exeName b) | b <- executables pkg, buildable (buildInfo b)]     , packageOpts = GetPackageOpts $ \cabalfp ->         generatePkgDescOpts cabalfp pkg+    , packageHasExposedModules = maybe False (not . null . exposedModules) (library pkg)+    , packageSimpleType = buildType (packageDescription gpkg) == Just Simple     }    where
src/Stack/PackageDump.hs view
@@ -1,9 +1,11 @@ {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-} module Stack.PackageDump     ( Line     , eachSection@@ -11,22 +13,28 @@     , DumpPackage (..)     , conduitDumpPackage     , ghcPkgDump-    , ProfilingCache-    , newProfilingCache-    , loadProfilingCache-    , saveProfilingCache+    , InstalledCache+    , InstalledCacheEntry (..)+    , newInstalledCache+    , loadInstalledCache+    , saveInstalledCache     , addProfiling+    , addHaddock     , sinkMatching     , pruneDeps     ) where  import           Control.Applicative+import           Control.Exception.Enclosed (tryIO) import           Control.Monad (when, liftM) import           Control.Monad.Catch import           Control.Monad.IO.Class import           Control.Monad.Logger (MonadLogger) import           Control.Monad.Trans.Control-import           Data.Binary.VersionTagged (taggedDecodeOrLoad, taggedEncodeFile)+import           Data.Attoparsec.Args+import           Data.Attoparsec.Text as P+import           Data.Binary (Binary)+import           Data.Binary.VersionTagged (taggedDecodeOrLoad, taggedEncodeFile, BinarySchema (..)) import           Data.ByteString (ByteString) import qualified Data.ByteString as S import qualified Data.ByteString.Char8 as S8@@ -40,17 +48,31 @@ import qualified Data.Map as Map import           Data.Maybe (catMaybes) import qualified Data.Set as Set+import qualified Data.Text.Encoding as T import           Data.Typeable (Typeable)+import           GHC.Generics (Generic) import           Path import           Prelude -- Fix AMP warning import           Stack.GhcPkg import           Stack.Types-import           System.Directory (createDirectoryIfMissing, getDirectoryContents)+import           System.Directory (createDirectoryIfMissing, getDirectoryContents, doesFileExist) import           System.Process.Read --- | Cached information on whether a package has profiling libraries-newtype ProfilingCache = ProfilingCache (IORef (Map GhcPkgId Bool))+-- | Cached information on whether package have profiling libraries and haddocks.+newtype InstalledCache = InstalledCache (IORef InstalledCacheInner)+newtype InstalledCacheInner = InstalledCacheInner (Map GhcPkgId InstalledCacheEntry)+    deriving Binary+instance BinarySchema InstalledCacheInner where+    -- Don't forget to update this if you change the datatype in any way!+    binarySchema _ = 1 +-- | Cached information on whether a package has profiling libraries and haddocks.+data InstalledCacheEntry = InstalledCacheEntry+    { installedCacheProfiling :: !Bool+    , installedCacheHaddock :: !Bool }+    deriving (Eq, Generic)+instance Binary InstalledCacheEntry+ -- | Call ghc-pkg dump with appropriate flags and stream to the given @Sink@, for a single database ghcPkgDump     :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadCatch m, MonadThrow m)@@ -70,20 +92,20 @@         , ["dump", "--expand-pkgroot"]         ] --- | Create a new, empty @ProfilingCache@-newProfilingCache :: MonadIO m => m ProfilingCache-newProfilingCache = liftIO $ ProfilingCache <$> newIORef Map.empty+-- | Create a new, empty @InstalledCache@+newInstalledCache :: MonadIO m => m InstalledCache+newInstalledCache = liftIO $ InstalledCache <$> newIORef (InstalledCacheInner Map.empty) --- | Load a @ProfilingCache@ from disk, swallowing any errors and returning an+-- | Load a @InstalledCache@ from disk, swallowing any errors and returning an -- empty cache.-loadProfilingCache :: MonadIO m => Path Abs File -> m ProfilingCache-loadProfilingCache path = do-    m <- taggedDecodeOrLoad (toFilePath path) (return Map.empty)-    liftIO $ fmap ProfilingCache $ newIORef m+loadInstalledCache :: MonadIO m => Path Abs File -> m InstalledCache+loadInstalledCache path = do+    m <- taggedDecodeOrLoad (toFilePath path) (return $ InstalledCacheInner Map.empty)+    liftIO $ fmap InstalledCache $ newIORef m --- | Save a @ProfilingCache@ to disk-saveProfilingCache :: MonadIO m => Path Abs File -> ProfilingCache -> m ()-saveProfilingCache path (ProfilingCache ref) = liftIO $ do+-- | Save a @InstalledCache@ to disk+saveInstalledCache :: MonadIO m => Path Abs File -> InstalledCache -> m ()+saveInstalledCache path (InstalledCache ref) = liftIO $ do     createDirectoryIfMissing True $ toFilePath $ parent path     readIORef ref >>= taggedEncodeFile (toFilePath path) @@ -131,10 +153,15 @@ -- Packages not mentioned in the provided @Map@ are allowed to be present too. sinkMatching :: Monad m              => Bool -- ^ require profiling?+             -> Bool -- ^ require haddock?              -> Map PackageName Version -- ^ allowed versions-             -> Consumer (DumpPackage Bool) m (Map PackageName (DumpPackage Bool))-sinkMatching reqProfiling allowed = do-    dps <- CL.filter (\dp -> isAllowed (dpGhcPkgId dp) && (not reqProfiling || dpProfiling dp))+             -> Consumer (DumpPackage Bool Bool)+                         m+                         (Map PackageName (DumpPackage Bool Bool))+sinkMatching reqProfiling reqHaddock allowed = do+    dps <- CL.filter (\dp -> isAllowed (dpGhcPkgId dp) &&+                             (not reqProfiling || dpProfiling dp) &&+                             (not reqHaddock || dpHaddock dp))        =$= CL.consume     return $ pruneDeps         (packageIdentifierName . ghcPkgIdPackageIdentifier)@@ -152,25 +179,26 @@  -- | Add profiling information to the stream of @DumpPackage@s addProfiling :: MonadIO m-             => ProfilingCache-             -> Conduit (DumpPackage a) m (DumpPackage Bool)-addProfiling (ProfilingCache ref) =+             => InstalledCache+             -> Conduit (DumpPackage a b) m (DumpPackage Bool b)+addProfiling (InstalledCache ref) =     CL.mapM go   where     go dp = liftIO $ do-        m <- readIORef ref+        InstalledCacheInner m <- readIORef ref         let gid = dpGhcPkgId dp         p <- case Map.lookup gid m of-            Just p -> return p+            Just installed -> return (installedCacheProfiling installed)             Nothing | null (dpLibraries dp) -> return True             Nothing -> do                 let loop [] = return False                     loop (dir:dirs) = do-                        contents <- getDirectoryContents $ S8.unpack dir+                        econtents <- tryIO $ getDirectoryContents dir+                        let contents = either (const []) id econtents                         if or [isProfiling content lib                               | content <- contents                               , lib <- dpLibraries dp-                              ]+                              ] && not (null contents)                             then return True                             else loop dirs                 loop $ dpLibDirs dp@@ -184,19 +212,45 @@   where     prefix = S.concat ["lib", lib, "_p"] +-- | Add haddock information to the stream of @DumpPackage@s+addHaddock :: MonadIO m+           => InstalledCache+           -> Conduit (DumpPackage a b) m (DumpPackage a Bool)+addHaddock (InstalledCache ref) =+    CL.mapM go+  where+    go dp = liftIO $ do+        InstalledCacheInner m <- readIORef ref+        let gid = dpGhcPkgId dp+        h <- case Map.lookup gid m of+            Just installed -> return (installedCacheHaddock installed)+            Nothing | null (dpLibraries dp) -> return True+            Nothing -> do+                let loop [] = return False+                    loop (ifc:ifcs) = do+                        exists <- doesFileExist (S8.unpack ifc)+                        if exists+                            then return True+                            else loop ifcs+                loop $ dpHaddockInterfaces dp+        return dp { dpHaddock = h }+ -- | Dump information for a single package-data DumpPackage profiling = DumpPackage+data DumpPackage profiling haddock = DumpPackage     { dpGhcPkgId :: !GhcPkgId-    , dpLibDirs :: ![ByteString]+    , dpLibDirs :: ![FilePath]     , dpLibraries :: ![ByteString]     , dpDepends :: ![GhcPkgId]+    , dpHaddockInterfaces :: ![ByteString]     , dpProfiling :: !profiling+    , dpHaddock :: !haddock     }     deriving (Show, Eq, Ord)  data PackageDumpException     = MissingSingleField ByteString (Map ByteString [Line])     | MismatchedId PackageName Version GhcPkgId+    | Couldn'tParseField ByteString [Line]     deriving Typeable instance Exception PackageDumpException instance Show PackageDumpException where@@ -211,10 +265,12 @@     show (MismatchedId name version gid) =         "Invalid id/name/version in ghc-pkg dump output: " ++         show (name, version, gid)+    show (Couldn'tParseField name ls) =+        "Couldn't parse the field " ++ show name ++ " from lines: " ++ show ls  -- | Convert a stream of bytes into a stream of @DumpPackage@s conduitDumpPackage :: MonadThrow m-                   => Conduit ByteString m (DumpPackage ())+                   => Conduit ByteString m (DumpPackage () ()) conduitDumpPackage = (=$= CL.catMaybes) $ eachSection $ do     pairs <- eachPair (\k -> (k, ) <$> CL.consume) =$= CL.consume     let m = Map.fromList pairs@@ -251,16 +307,25 @@                 $ throwM $ MismatchedId name version ghcPkgId              -- if a package has no modules, these won't exist-            let libDirs = parseM "library-dirs"+            let libDirKey = "library-dirs"+                libDirs = parseM libDirKey                 libraries = parseM "hs-libraries"+                haddockInterfaces = parseM "haddock-interfaces"             depends <- mapM parseDepend $ parseM "depends" +            libDirPaths <-+                case mapM (P.parseOnly (argsParser NoEscaping) . T.decodeUtf8) libDirs of+                    Left{} -> throwM (Couldn'tParseField libDirKey libDirs)+                    Right dirs -> return (concat dirs)+             return $ Just DumpPackage                 { dpGhcPkgId = ghcPkgId-                , dpLibDirs = libDirs+                , dpLibDirs = libDirPaths                 , dpLibraries = S8.words $ S8.unwords libraries                 , dpDepends = catMaybes (depends :: [Maybe GhcPkgId])+                , dpHaddockInterfaces = S8.words $ S8.unwords haddockInterfaces                 , dpProfiling = ()+                , dpHaddock = ()                 }  stripPrefixBS :: ByteString -> ByteString -> Maybe ByteString
src/Stack/PackageIndex.hs view
@@ -23,7 +23,6 @@     ) where  import qualified Codec.Archive.Tar as Tar-import           Control.Applicative import           Control.Exception (Exception) import           Control.Exception.Enclosed (tryIO) import           Control.Monad (unless, when, liftM, mzero)@@ -36,17 +35,21 @@  import           Data.Aeson.Extended import qualified Data.Binary as Binary-import           Data.Binary.VersionTagged (taggedDecodeOrLoad)+import           Data.Binary.VersionTagged (taggedDecodeOrLoad, BinarySchema (..)) import           Data.ByteString (ByteString)+import qualified Data.Word8 as Word8+import qualified Data.ByteString as S+import qualified Data.ByteString.Unsafe as SU+import qualified Data.ByteString.Char8 as S8 import qualified Data.ByteString.Lazy as L-import           Data.Conduit (($$), (=$), yield, Producer, ZipSink (..))+import           Data.Conduit (($$), (=$)) import           Data.Conduit.Binary                   (sinkHandle,                                                         sourceHandle)-import qualified Data.Conduit.List as CL import           Data.Conduit.Zlib (ungzip)+import           Data.Foldable (forM_) import           Data.Int (Int64) import           Data.Map (Map)-import qualified Data.Map as Map+import qualified Data.Map.Strict as Map import           Data.Monoid import           Data.Text (Text) import qualified Data.Text as T@@ -78,18 +81,6 @@                                                         withBinaryFile) import           System.Process.Read (readInNull, EnvOverride, doesExecutableExist) --- | A cabal file with name and version parsed from the filepath, and the--- package description itself ready to be parsed. It's left in unparsed form--- for efficiency.-data UnparsedCabalFile = UnparsedCabalFile-    { ucfName    :: PackageName-    , ucfVersion :: Version-    , ucfOffset  :: !Int64-    -- ^ Byte offset into the 00-index.tar file for the entry contents-    , ucfSize    :: !Int64-    -- ^ Size of the entry contents, in bytes-    }- data PackageCache = PackageCache     { pcOffset :: !Int64     -- ^ offset in bytes into the 00-index.tar file for the .cabal file contents@@ -100,65 +91,97 @@     deriving Generic instance Binary.Binary PackageCache --- | Stream all of the cabal files from the 00-index tar file.-withSourcePackageIndex+newtype PackageCacheMap = PackageCacheMap (Map PackageIdentifier PackageCache)+    deriving Binary.Binary+instance BinarySchema PackageCacheMap where+    -- Don't forget to update this if you change the datatype in any way!+    binarySchema _ = 1+-- | Populate the package index caches and return them.+populateCache     :: (MonadIO m, MonadThrow m, MonadReader env m, HasConfig env, HasHttpManager env, MonadLogger m, MonadBaseControl IO m, MonadCatch m)     => EnvOverride     -> PackageIndex-    -> (Producer m (Either UnparsedCabalFile (PackageIdentifier, L.ByteString)) -> m a)-    -> m a-withSourcePackageIndex menv index cont = do+    -> m (Map PackageIdentifier PackageCache)+populateCache menv index = do+    $logSticky "Populating index cache ..."     requireIndex menv index     -- This uses full on lazy I/O instead of ResourceT to provide some     -- protections. Caveat emptor-    cont $ do-        path <- configPackageIndex (indexName index)-        lbs <- liftIO $ L.readFile $ Path.toFilePath path-        loop 0 (Tar.read lbs)+    path <- configPackageIndex (indexName index)+    lbs <- liftIO $ L.readFile $ Path.toFilePath path+    pis <- loop 0 Map.empty (Tar.read lbs)++    when (indexRequireHashes index) $ forM_ (Map.toList pis) $ \(ident, pc) ->+        case pcDownload pc of+            Just _ -> return ()+            Nothing -> throwM $ MissingRequiredHashes (indexName index) ident++    $logStickyDone "Populated index cache."++    return pis   where-    loop blockNo (Tar.Next e es) = do-        goE blockNo e-        loop blockNo' es-      where-        blockNo' = blockNo + entrySizeInBlocks e-    loop _ Tar.Done = return ()-    loop _ (Tar.Fail e) = throwM e+    loop !blockNo !m (Tar.Next e es) =+        loop (blockNo + entrySizeInBlocks e) (goE blockNo m e) es+    loop _ m Tar.Done = return m+    loop _ _ (Tar.Fail e) = throwM e -    goE blockNo e-        | Just front <- T.stripSuffix ".cabal" $ T.pack $ Tar.entryPath e-        , Tar.NormalFile _ size <- Tar.entryContent e = do-            PackageIdentifier name version <- parseNameVersion front-            yield $ Left UnparsedCabalFile-                { ucfName = name-                , ucfVersion = version-                , ucfOffset = (blockNo + 1) * 512-                , ucfSize = size+    goE blockNo m e =+        case Tar.entryContent e of+            Tar.NormalFile lbs size ->+                case parseNameVersion $ Tar.entryPath e of+                    Just (ident, ".cabal") -> addCabal ident size+                    Just (ident, ".json") -> addJSON ident lbs+                    _ -> m+            _ -> m+      where+        addCabal ident size = Map.insertWith+            (\_ pcOld -> pcNew { pcDownload = pcDownload pcOld })+            ident+            pcNew+            m+          where+            pcNew = PackageCache+                { pcOffset = (blockNo + 1) * 512+                , pcSize = size+                , pcDownload = Nothing                 }-        | Just front <- T.stripSuffix ".json" $ T.pack $ Tar.entryPath e-        , Tar.NormalFile lbs _size <- Tar.entryContent e = do-            ident <- parseNameVersion front-            yield $ Right (ident, lbs)-        | otherwise = return ()+        addJSON ident lbs =+            case decode lbs of+                Nothing -> m+                Just pd -> Map.insertWith+                    (\_ pc -> pc { pcDownload = Just pd })+                    ident+                    PackageCache+                        { pcOffset = 0+                        , pcSize = 0+                        , pcDownload = Just pd+                        }+                    m +    breakSlash x+        | S.null z = Nothing+        | otherwise = Just (y, SU.unsafeTail z)+      where+        (y, z) = S.break (== Word8._slash) x+     parseNameVersion t1 = do-        let (p', t2) = T.break (== '/') $ T.replace "\\" "/" t1-        p <- parsePackageNameFromString $ T.unpack p'-        t3 <- maybe (throwM $ InvalidCabalPath t1 "no slash") return-            $ T.stripPrefix "/" t2-        let (v', t4) = T.break (== '/') t3-        v <- parseVersionFromString $ T.unpack v'-        when (t4 /= T.cons '/' p') $ throwM $ InvalidCabalPath t1 $ "Expected at end: " <> p'-        return $ PackageIdentifier p v+        (p', t3) <- breakSlash+                  $ S.map (\c -> if c == Word8._backslash then Word8._slash else c)+                  $ S8.pack t1+        p <- parsePackageName p'+        (v', t5) <- breakSlash t3+        v <- parseVersion v'+        let (t6, suffix) = S.break (== Word8._period) t5+        if t6 == p'+            then return (PackageIdentifier p v, suffix)+            else Nothing  data PackageIndexException-  = InvalidCabalPath Text Text-  | GitNotAvailable IndexName+  = GitNotAvailable IndexName   | MissingRequiredHashes IndexName PackageIdentifier   deriving Typeable instance Exception PackageIndexException instance Show PackageIndexException where-    show (InvalidCabalPath x y) =-        "Invalid cabal path " ++ T.unpack x ++ ": " ++ T.unpack y     show (GitNotAvailable name) = concat         [ "Package index "         , T.unpack $ indexNameText name@@ -355,48 +378,9 @@     config <- askConfig     liftM mconcat $ forM (configPackageIndices config) $ \index -> do         fp <- liftM toFilePath $ configPackageIndexCache (indexName index)-        pis' <- taggedDecodeOrLoad fp $ populateCache menv index+        PackageCacheMap pis' <- taggedDecodeOrLoad fp $ liftM PackageCacheMap $ populateCache menv index          return (fmap (index,) pis')---- | Populate the package index caches and return them.-populateCache :: (MonadIO m, MonadThrow m, MonadReader env m, HasConfig env, MonadLogger m, HasHttpManager env, MonadBaseControl IO m, MonadCatch m)-              => EnvOverride-              -> PackageIndex-              -> m (Map PackageIdentifier PackageCache)-populateCache menv index = do-    $logSticky "Populating index cache ..."-    let toIdent (Left ucf) = Just-            ( PackageIdentifier (ucfName ucf) (ucfVersion ucf)-            , PackageCache-                { pcOffset = ucfOffset ucf-                , pcSize = ucfSize ucf-                , pcDownload = Nothing-                }-            )-        toIdent (Right _) = Nothing--        parseDownload (Left _) = Nothing-        parseDownload (Right (ident, lbs)) = do-            case decode lbs of-                Nothing -> Nothing-                Just pd -> Just (ident, pd)--    withSourcePackageIndex menv index $ \source -> do-        (pis, pds) <- source $$ getZipSink ((,)-            <$> ZipSink (CL.mapMaybe toIdent =$ CL.consume)-            <*> ZipSink (Map.fromList <$> (CL.mapMaybe parseDownload =$ CL.consume)))--        pis' <- liftM Map.fromList $ forM pis $ \(ident, pc) ->-            case Map.lookup ident pds of-                Just d -> return (ident, pc { pcDownload = Just d })-                Nothing-                    | indexRequireHashes index -> throwM $ MissingRequiredHashes (indexName index) ident-                    | otherwise -> return (ident, pc)--        $logStickyDone "Populated index cache."--        return pis'  --------------- Lifted from cabal-install, Distribution.Client.Tar: -- | Return the number of blocks in an entry.
− src/Stack/Path.hs
@@ -1,61 +0,0 @@-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE DeriveDataTypeable #-}---- | Implementation of the "path" subcommand-module Stack.Path-  ( pathString-  , PathArg(..)-  , pathGhc-  , pathLog-  , pathPackageDb-  ) where--import Control.Monad.Catch-import Control.Monad.Reader-import qualified Data.List as List-import Data.Typeable (Typeable)-import Path-import System.FilePath--import Stack.Types--data PathArg-  = PathGhc-  | PathLog-  | PathPackageDb-  deriving (Show, Eq, Ord)--data NotYetImplemented = NotYetImplemented String-  deriving (Show, Typeable)-instance Exception NotYetImplemented---- | Finds the selected PathArg and displays it as a String.-pathString :: (MonadReader env m, HasBuildConfig env, MonadThrow m)-  => PathArg -> m String-pathString PathGhc = liftM show pathGhc-pathString PathLog = liftM show pathLog-pathString PathPackageDb = liftM process pathPackageDb where-  -- Turns the list of package-db directories into a String-  -- suitable for consumption by GHC_PACKAGE_PATH.-  process :: [Path Abs Dir] -> String-  process = List.intercalate [searchPathSeparator] . map show---- | The path to the ghc--- that will be used for the current project.-pathGhc :: (MonadReader env m, HasBuildConfig env, MonadThrow m)-  => m (Path Abs File)-pathGhc = throwM $ NotYetImplemented "Stack.Path.pathGhc https://github.com/fpco/stack/issues/95"---- (Note: it's not actually as simple as just one log dir.)--- | The path to the log file directory--- that will be used for the current project.-pathLog :: (MonadReader env m, HasBuildConfig env, MonadThrow m)-  => m (Path Abs Dir)-pathLog = throwM $ NotYetImplemented "Stack.Path.pathLog https://github.com/fpco/stack/issues/95"---- | The list of package-db directories--- that will be used for the current project.--- The earlier databases in the list take precedence over the later ones.-pathPackageDb :: (MonadReader env m, HasBuildConfig env, MonadThrow m)-  => m [Path Abs Dir]-pathPackageDb = throwM $ NotYetImplemented "Stack.Path.pathPackageDb https://github.com/fpco/stack/issues/95"
src/Stack/Repl.hs view
@@ -29,8 +29,10 @@ repl :: (HasConfig r, HasBuildConfig r, HasEnvConfig r, MonadReader r m, MonadIO m, MonadThrow m, MonadLogger m, MonadCatch m)      => [Text] -- ^ Targets.      -> [String] -- ^ GHC options.+     -> FilePath      -> m ()-repl targets opts = do+repl targets opts ghciPath = do+    econfig <- asks getEnvConfig     bconfig <- asks getBuildConfig     pwd <- getWorkingDir     pkgOpts <-@@ -44,7 +46,7 @@                         { packageConfigEnableTests = True                         , packageConfigEnableBenchmarks = True                         , packageConfigFlags = localFlags mempty bconfig name-                        , packageConfigGhcVersion = bcGhcVersion bconfig+                        , packageConfigGhcVersion = envConfigGhcVersion econfig                         , packageConfigPlatform = configPlatform                               (getConfig bconfig)                         }@@ -64,9 +66,11 @@              ", "              (map packageNameText (map fst pkgOpts)))     exec-        "ghc"+        ghciPath         ("--interactive" :-         filter (not . badForGhci) (concat (map snd pkgOpts)) <>+         filter+             (not . badForGhci)+             (concat (map snd pkgOpts)) <>          opts)   where     wanted pwd cabalfp pkg =@@ -82,4 +86,6 @@             isParentOf                 (parent cabalfp)                 pwd-    badForGhci = isPrefixOf "-O"+    badForGhci x =+        isPrefixOf "-O" x ||+        elem x (words "-debug -threaded -ticky")
src/Stack/Setup.hs view
@@ -50,7 +50,8 @@ import           Prelude -- Fix AMP warning import           Safe (readMay) import           Stack.Build.Types-import           Stack.GhcPkg (getGlobalDB)+import           Stack.GhcPkg (getCabalPkgVer, getGlobalDB)+import           Stack.Solver (getGhcVersion) import           Stack.Types import           Stack.Types.StackT import           System.Directory (doesDirectoryExist, createDirectoryIfMissing)@@ -108,14 +109,14 @@  -- | Modify the environment variables (like PATH) appropriately, possibly doing installation too setupEnv :: (MonadIO m, MonadMask m, MonadLogger m, MonadReader env m, HasBuildConfig env, HasHttpManager env, MonadBaseControl IO m)-         => m BuildConfig+         => m EnvConfig setupEnv = do     bconfig <- asks getBuildConfig     let platform = getPlatform bconfig         sopts = SetupOpts             { soptsInstallIfMissing = configInstallGHC $ bcConfig bconfig             , soptsUseSystem = configSystemGHC $ bcConfig bconfig-            , soptsExpected = bcGhcVersion bconfig+            , soptsExpected = bcGhcVersionExpected bconfig             , soptsStackYaml = Just $ bcStackYaml bconfig             , soptsForceReinstall = False             , soptsSanityCheck = False@@ -141,16 +142,25 @@              $ Map.delete "HASKELL_PACKAGE_SANDBOXES"                env0 +    menv1 <- mkEnvOverride platform env1+    ghcVer <- getGhcVersion menv1+    cabalVer <- getCabalPkgVer menv1+    let envConfig0 = EnvConfig+            { envConfigBuildConfig = bconfig+            , envConfigCabalVersion = cabalVer+            , envConfigGhcVersion = ghcVer+            }+     -- extra installation bin directories-    mkDirs <- runReaderT extraBinDirs bconfig+    mkDirs <- runReaderT extraBinDirs envConfig0     let mpath = Map.lookup "PATH" env1         mkDirs' = map toFilePath . mkDirs         depsPath = augmentPath (mkDirs' False) mpath         localsPath = augmentPath (mkDirs' True) mpath -    deps <- runReaderT packageDatabaseDeps bconfig+    deps <- runReaderT packageDatabaseDeps envConfig0     depsExists <- liftIO $ doesDirectoryExist $ toFilePath deps-    localdb <- runReaderT packageDatabaseLocal bconfig+    localdb <- runReaderT packageDatabaseLocal envConfig0     localdbExists <- liftIO $ doesDirectoryExist $ toFilePath localdb     globalDB <- mkEnvOverride platform env1 >>= getGlobalDB     let mkGPP locals = T.pack $ intercalate [searchPathSeparator] $ concat@@ -189,7 +199,13 @@                         (Map.insert es eo m', ())                     return eo -    return bconfig { bcConfig = (bcConfig bconfig) { configEnvOverride = getEnvOverride' } }+    return EnvConfig+        { envConfigBuildConfig = bconfig+            { bcConfig = (bcConfig bconfig) { configEnvOverride = getEnvOverride' }+            }+        , envConfigCabalVersion = cabalVer+        , envConfigGhcVersion = ghcVer+        }  -- | Augment the PATH environment variable with the given extra paths augmentPath :: [FilePath] -> Maybe Text -> Text
+ src/Stack/Solver.hs view
@@ -0,0 +1,192 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE TemplateHaskell       #-}+module Stack.Solver+    ( cabalSolver+    , getGhcVersion+    , solveExtraDeps+    ) where++import           Control.Exception.Enclosed  (tryIO)+import           Control.Monad.Catch+import           Control.Monad.IO.Class+import           Control.Monad.Logger+import           Control.Monad.Reader+import           Control.Monad.Trans.Control+import           Data.Aeson                  (object, (.=), toJSON)+import qualified Data.ByteString             as S+import qualified Data.ByteString.Char8       as S8+import           Data.Either+import qualified Data.HashMap.Strict         as HashMap+import           Data.Map                    (Map)+import qualified Data.Map                    as Map+import           Data.Text                   (Text)+import qualified Data.Text                   as T+import           Data.Text.Encoding          (decodeUtf8, encodeUtf8)+import qualified Data.Yaml                   as Yaml+import           Network.HTTP.Client.Conduit (HasHttpManager)+import           Path+import           Stack.BuildPlan+import           Stack.Types+import           System.Directory            (copyFile,+                                              createDirectoryIfMissing,+                                              getTemporaryDirectory)+import qualified System.FilePath             as FP+import           System.IO.Temp+import           System.Process.Read++cabalSolver :: (MonadIO m, MonadLogger m, MonadMask m, MonadBaseControl IO m, MonadReader env m, HasConfig env)+            => [Path Abs Dir] -- ^ cabal files+            -> [String] -- ^ additional arguments, usually constraints+            -> m (MajorVersion, Map PackageName (Version, Map FlagName Bool))+cabalSolver cabalfps cabalArgs = withSystemTempDirectory "cabal-solver" $ \dir -> do+    configLines <- getCabalConfig dir+    let configFile = dir FP.</> "cabal.config"+    liftIO $ S.writeFile configFile $ encodeUtf8 $ T.unlines configLines++    menv <- getMinimalEnvOverride+    ghcMajorVersion <- getGhcMajorVersion menv++    -- Run from a temporary directory to avoid cabal getting confused by any+    -- sandbox files, see:+    -- https://github.com/commercialhaskell/stack/issues/356+    --+    -- In theory we could use --ignore-sandbox, but not all versions of cabal+    -- support it.+    tmpdir <- liftIO getTemporaryDirectory >>= parseAbsDir++    let args = ("--config-file=" ++ configFile)+             : "install"+             : "-v"+             : "--dry-run"+             : "--only-dependencies"+             : "--reorder-goals"+             : "--max-backjumps=-1"+             : "--package-db=clear"+             : "--package-db=global"+             : cabalArgs +++               (map toFilePath cabalfps)++    $logInfo "Asking cabal to calculate a build plan, please wait"++    bs <- readProcessStdout (Just tmpdir) menv "cabal" args+    let ls = drop 1+           $ dropWhile (not . T.isPrefixOf "In order, ")+           $ T.lines+           $ decodeUtf8 bs+        (errs, pairs) = partitionEithers $ map parseLine ls+    if null errs+        then return (ghcMajorVersion, Map.fromList pairs)+        else error $ "Could not parse cabal-install output: " ++ show errs+  where+    parseLine t0 = maybe (Left t0) Right $ do+        -- get rid of (new package) and (latest: ...) bits+        ident':flags' <- Just $ T.words $ T.takeWhile (/= '(') t0+        PackageIdentifier name version <-+            parsePackageIdentifierFromString $ T.unpack ident'+        flags <- mapM parseFlag flags'+        Just (name, (version, Map.fromList flags))+    parseFlag t0 = do+        flag <- parseFlagNameFromString $ T.unpack t1+        return (flag, enabled)+      where+        (t1, enabled) =+            case T.stripPrefix "-" t0 of+                Nothing ->+                    case T.stripPrefix "+" t0 of+                        Nothing -> (t0, True)+                        Just x -> (x, True)+                Just x -> (x, False)++getGhcVersion :: (MonadLogger m, MonadCatch m, MonadBaseControl IO m, MonadIO m)+              => EnvOverride -> m Version+getGhcVersion menv = do+    bs <- readProcessStdout Nothing menv "ghc" ["--numeric-version"]+    parseVersion $ S8.takeWhile isValid bs+  where+    isValid c = c == '.' || ('0' <= c && c <= '9')++getGhcMajorVersion :: (MonadLogger m, MonadCatch m, MonadBaseControl IO m, MonadIO m)+                   => EnvOverride -> m MajorVersion+getGhcMajorVersion menv = do+    version <- getGhcVersion menv+    return $ getMajorVersion version++getCabalConfig :: (MonadReader env m, HasConfig env, MonadIO m, MonadThrow m)+               => FilePath -- ^ temp dir+               -> m [Text]+getCabalConfig dir = do+    indices <- asks $ configPackageIndices . getConfig+    remotes <- mapM goIndex indices+    let cache = T.pack $ "remote-repo-cache: " ++ dir+    return $ cache : remotes+  where+    goIndex index = do+        src <- configPackageIndex $ indexName index+        let dstdir = dir FP.</> T.unpack (indexNameText $ indexName index)+            dst = dstdir FP.</> "00-index.tar"+        liftIO $ void $ tryIO $ do+            createDirectoryIfMissing True dstdir+            copyFile (toFilePath src) dst+        return $ T.concat+            [ "remote-repo: "+            , indexNameText $ indexName index+            , ":http://0.0.0.0/fake-url"+            ]++-- | Determine missing extra-deps+solveExtraDeps :: (MonadReader env m, HasEnvConfig env, MonadIO m, MonadMask m, MonadLogger m, MonadBaseControl IO m, HasHttpManager env)+               => Bool -- ^ modify stack.yaml?+               -> m ()+solveExtraDeps modStackYaml = do+    $logInfo "This command is not guaranteed to give you a perfect build plan"+    $logInfo "It's possible that even with the changes generated below, you will still need to do some manual tweaking"+    bconfig <- asks getBuildConfig+    snapshot <-+        case bcResolver bconfig of+            ResolverSnapshot snapName -> liftM mbpPackages $ loadMiniBuildPlan snapName+            ResolverGhc _ -> return Map.empty++    let packages = Map.union+            (bcExtraDeps bconfig)+            (fmap mpiVersion snapshot)+        constraints = map+            (\(k, v) -> concat+                [ "--constraint="+                , packageNameString k+                , "=="+                , versionString v+                ])+            (Map.toList packages)++    (_ghc, extraDeps) <- cabalSolver+        (Map.keys $ bcPackages bconfig)+        constraints++    let newDeps = extraDeps `Map.difference` packages+        newFlags = Map.filter (not . Map.null) $ fmap snd newDeps++    if Map.null newDeps+        then $logInfo "No needed changes found"+        else do+            let o = object+                    $ ("extra-deps" .= (map fromTuple $ Map.toList $ fmap fst newDeps))+                    : (if Map.null newFlags+                        then []+                        else ["flags" .= newFlags])+            mapM_ $logInfo $ T.lines $ decodeUtf8 $ Yaml.encode o++    when modStackYaml $ do+        let fp = toFilePath $ bcStackYaml bconfig+        obj <- liftIO (Yaml.decodeFileEither fp) >>= either throwM return+        ProjectAndConfigMonoid project _ <- liftIO (Yaml.decodeFileEither fp) >>= either throwM return+        let obj' =+                HashMap.insert "extra-deps"+                    (toJSON $ map fromTuple $ Map.toList+                            $ Map.union (projectExtraDeps project) (fmap fst newDeps))+              $ HashMap.insert ("flags" :: Text)+                    (toJSON $ Map.union (projectFlags project) newFlags)+                obj+        liftIO $ Yaml.encodeFile fp obj'+        $logInfo $ T.pack $ "Updated " ++ fp
src/Stack/Types/BuildPlan.hs view
@@ -32,6 +32,7 @@                                                   object, withObject, withText,                                                   (.!=), (.:), (.:?), (.=)) import           Data.Binary                     as Binary (Binary)+import           Data.Binary.VersionTagged       (BinarySchema (..)) import           Data.ByteString                 (ByteString) import qualified Data.ByteString.Char8           as S8 import           Data.Hashable                   (Hashable)@@ -364,6 +365,9 @@     }     deriving (Generic, Show, Eq) instance Binary.Binary MiniBuildPlan+instance BinarySchema MiniBuildPlan where+    -- Don't forget to update this if you change the datatype in any way!+    binarySchema _ = 1  -- | Information on a single package for the 'MiniBuildPlan'. data MiniPackageInfo = MiniPackageInfo
src/Stack/Types/Config.hs view
@@ -15,10 +15,11 @@ import           Control.Monad.Catch (MonadThrow, throwM) import           Control.Monad.Reader (MonadReader, ask, asks, MonadIO, liftIO) import           Data.Aeson.Extended (ToJSON, toJSON, FromJSON, parseJSON, withText, withObject, object-                            ,(.=), (.:?), (.!=), (.:), Value (String))+                            ,(.=), (.:?), (.!=), (.:), Value (String, Object)) import           Data.Binary (Binary) import           Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as S8+import           Data.Either (partitionEithers) import           Data.Hashable (Hashable) import           Data.Map (Map) import qualified Data.Map as Map@@ -29,6 +30,7 @@ import qualified Data.Text as T import           Data.Text.Encoding (encodeUtf8, decodeUtf8) import           Data.Typeable+import           Data.Yaml (ParseException) import           Distribution.System (Platform) import qualified Distribution.Text import           Distribution.Version (anyVersion, intersectVersionRanges)@@ -167,9 +169,8 @@     , bcResolver   :: !Resolver       -- ^ How we resolve which dependencies to install given a set of       -- packages.-    , bcGhcVersion :: !Version-      -- ^ Version of GHC we'll be using for this build, @Nothing@ if no-      -- preference+    , bcGhcVersionExpected :: !Version+      -- ^ Version of GHC we expected for this build     , bcPackages   :: !(Map (Path Abs Dir) Bool)       -- ^ Local packages identified by a path, Bool indicates whether it is       -- allowed to be wanted (see 'peValidWanted')@@ -192,13 +193,14 @@ -- | Configuration after the environment has been setup. data EnvConfig = EnvConfig     {envConfigBuildConfig :: !BuildConfig-    ,envConfigCabalVersion :: !Version}+    ,envConfigCabalVersion :: !Version+    ,envConfigGhcVersion :: !Version} instance HasBuildConfig EnvConfig where     getBuildConfig = envConfigBuildConfig instance HasConfig EnvConfig instance HasPlatform EnvConfig instance HasStackRoot EnvConfig-class HasEnvConfig r where+class HasBuildConfig r => HasEnvConfig r where     getEnvConfig :: r -> EnvConfig instance HasEnvConfig EnvConfig where     getEnvConfig = id@@ -465,13 +467,21 @@                              (Distribution.Text.simpleParse (T.unpack s)))  data ConfigException-  = ParseResolverException Text+  = ParseConfigFileException (Path Abs File) ParseException+  | ParseResolverException Text   | NoProjectConfigFound (Path Abs Dir) (Maybe Text)   | UnexpectedTarballContents [Path Abs Dir] [Path Abs File]   | BadStackVersionException VersionRange   | NoMatchingSnapshot [SnapName]   deriving Typeable instance Show ConfigException where+    show (ParseConfigFileException configFile exception) = concat+        [ "Could not parse '"+        , toFilePath configFile+        , "':\n"+        , show exception+        , "\nSee https://github.com/commercialhaskell/stack/wiki/stack.yaml."+        ]     show (ParseResolverException t) = concat         [ "Invalid resolver value: "         , T.unpack t@@ -509,8 +519,8 @@             names         , "\nYou'll then need to add some extra-deps. See:\n\n"         , "    https://github.com/commercialhaskell/stack/wiki/stack.yaml#extra-deps"-        , "\n\nNote that this will be improved in the future, see:\n\n"-        , "    https://github.com/commercialhaskell/stack/issues/116"+        , "\n\nYou can also try falling back to a dependency solver with:\n\n"+        , "    stack init --solver"         ] instance Exception ConfigException @@ -559,9 +569,9 @@     bc <- asks getBuildConfig     return (bcRoot bc </> workDirRel) --- | File containing the profiling cache, see "Stack.PackageDump"-configProfilingCache :: (HasBuildConfig env, MonadReader env m) => m (Path Abs File)-configProfilingCache = liftM (</> $(mkRelFile "profiling-cache.bin")) configProjectWorkDir+-- | File containing the installed cache, see "Stack.PackageDump"+configInstalledCache :: (HasBuildConfig env, MonadReader env m) => m (Path Abs File)+configInstalledCache = liftM (</> $(mkRelFile "installed-cache.bin")) configProjectWorkDir  -- | Relative directory for the platform identifier platformRelDir :: (MonadReader env m, HasPlatform env, MonadThrow m) => m (Path Rel Dir)@@ -583,37 +593,39 @@     return $ configStackRoot config </> $(mkRelDir "snapshots") </> platform  -- | Installation root for dependencies-installationRootDeps :: (MonadThrow m, MonadReader env m, HasBuildConfig env) => m (Path Abs Dir)+installationRootDeps :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => m (Path Abs Dir) installationRootDeps = do     snapshots <- snapshotsDir     bc <- asks getBuildConfig+    ec <- asks getEnvConfig     name <- parseRelDir $ T.unpack $ renderResolver $ bcResolver bc-    ghc <- parseRelDir $ versionString $ bcGhcVersion bc+    ghc <- parseRelDir $ versionString $ envConfigGhcVersion ec     return $ snapshots </> name </> ghc  -- | Installation root for locals-installationRootLocal :: (MonadThrow m, MonadReader env m, HasBuildConfig env) => m (Path Abs Dir)+installationRootLocal :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => m (Path Abs Dir) installationRootLocal = do     bc <- asks getBuildConfig+    ec <- asks getEnvConfig     name <- parseRelDir $ T.unpack $ renderResolver $ bcResolver bc-    ghc <- parseRelDir $ versionString $ bcGhcVersion bc+    ghc <- parseRelDir $ versionString $ envConfigGhcVersion ec     platform <- platformRelDir     return $ configProjectWorkDir bc </> $(mkRelDir "install") </> platform </> name </> ghc  -- | Package database for installing dependencies into-packageDatabaseDeps :: (MonadThrow m, MonadReader env m, HasBuildConfig env) => m (Path Abs Dir)+packageDatabaseDeps :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => m (Path Abs Dir) packageDatabaseDeps = do     root <- installationRootDeps     return $ root </> $(mkRelDir "pkgdb")  -- | Package database for installing local packages into-packageDatabaseLocal :: (MonadThrow m, MonadReader env m, HasBuildConfig env) => m (Path Abs Dir)+packageDatabaseLocal :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => m (Path Abs Dir) packageDatabaseLocal = do     root <- installationRootLocal     return $ root </> $(mkRelDir "pkgdb")  -- | Directory for holding flag cache information-flagCacheLocal :: (MonadThrow m, MonadReader env m, HasBuildConfig env) => m (Path Abs Dir)+flagCacheLocal :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => m (Path Abs Dir) flagCacheLocal = do     root <- installationRootLocal     return $ root </> $(mkRelDir "flag-cache")@@ -633,10 +645,14 @@ bindirSuffix :: Path Rel Dir bindirSuffix = $(mkRelDir "bin") +-- | Suffix applied to an installation root to get the doc dir+docdirSuffix :: Path Rel Dir+docdirSuffix = $(mkRelDir "doc")+ -- | Get the extra bin directories (for the PATH). Puts more local first -- -- Bool indicates whether or not to include the locals-extraBinDirs :: (MonadThrow m, MonadReader env m, HasBuildConfig env)+extraBinDirs :: (MonadThrow m, MonadReader env m, HasEnvConfig env)              => m (Bool -> [Path Abs Dir]) extraBinDirs = do     deps <- installationRootDeps@@ -654,3 +670,51 @@                     { esIncludeLocals = False                     , esIncludeGhcPackagePath = False                     }++data ProjectAndConfigMonoid+  = ProjectAndConfigMonoid !Project !ConfigMonoid++instance FromJSON ProjectAndConfigMonoid where+    parseJSON = withObject "Project, ConfigMonoid" $ \o -> do+        dirs <- o .:? "packages" .!= [packageEntryCurrDir]+        extraDeps' <- o .:? "extra-deps" .!= []+        extraDeps <-+            case partitionEithers $ goDeps extraDeps' of+                ([], x) -> return $ Map.fromList x+                (errs, _) -> fail $ unlines errs++        flags <- o .:? "flags" .!= mempty+        resolver <- o .: "resolver"+        config <- parseJSON $ Object o+        let project = Project+                { projectPackages = dirs+                , projectExtraDeps = extraDeps+                , projectFlags = flags+                , projectResolver = resolver+                }+        return $ ProjectAndConfigMonoid project config+      where+        goDeps =+            map toSingle . Map.toList . Map.unionsWith Set.union . map toMap+          where+            toMap i = Map.singleton+                (packageIdentifierName i)+                (Set.singleton (packageIdentifierVersion i))++        toSingle (k, s) =+            case Set.toList s of+                [x] -> Right (k, x)+                xs -> Left $ concat+                    [ "Multiple versions for package "+                    , packageNameString k+                    , ": "+                    , unwords $ map versionString xs+                    ]++-- | A PackageEntry for the current directory, used as a default+packageEntryCurrDir :: PackageEntry+packageEntryCurrDir = PackageEntry+    { peValidWanted = True+    , peLocation = PLFilePath "."+    , peSubdirs = []+    }
src/System/Process/Read.hs view
@@ -14,7 +14,7 @@   ,tryProcessStdout   ,sinkProcessStdout   ,readProcess-  ,EnvOverride+  ,EnvOverride(..)   ,unEnvOverride   ,mkEnvOverride   ,envHelper
src/main/Main.hs view
@@ -10,10 +10,10 @@ module Main where  import           Control.Exception-import           Control.Monad (join, when)-import           Control.Monad.IO.Class (liftIO)+import           Control.Monad+import           Control.Monad.IO.Class import           Control.Monad.Logger-import           Control.Monad.Reader (asks, runReaderT)+import           Control.Monad.Reader (ask,asks) import           Data.Char (toLower) import           Data.List import qualified Data.List as List@@ -21,18 +21,21 @@ import qualified Data.Map as Map import           Data.Maybe import           Data.Monoid+import qualified Data.Set as Set import           Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.IO as T+import           Data.Traversable import           Network.HTTP.Client import           Network.HTTP.Client.Conduit (getHttpManager) import           Options.Applicative.Args import           Options.Applicative.Builder.Extra import           Options.Applicative.Simple import           Options.Applicative.Types (readerAsk)-import           Path (toFilePath)+import           Path import qualified Paths_stack as Meta import           Plugins+import           Prelude hiding (pi) import           Stack.Build import           Stack.Build.Types import           Stack.Config@@ -40,21 +43,21 @@ import qualified Stack.Docker as Docker import           Stack.Exec import           Stack.Fetch-import           Stack.GhcPkg (getCabalPkgVer) import           Stack.Init import           Stack.New import qualified Stack.PackageIndex-import           Stack.Path import           Stack.Repl import           Stack.Setup+import           Stack.Solver (solveExtraDeps) import           Stack.Types+import           Stack.Types.Internal import           Stack.Types.StackT import qualified Stack.Upload as Upload import           System.Environment (getArgs, getProgName) import           System.Exit import           System.FilePath (searchPathSeparator) import           System.IO (stderr)-import qualified System.Process.Read+import           System.Process.Read  -- | Commandline dispatcher. main :: IO ()@@ -68,44 +71,62 @@                    dockerHelpOptName                    (Docker.dockerOptsParser True)                    ("Only showing --" ++ Docker.dockerCmdName ++ "* options.")+     let versionString' = $(simpleVersion Meta.version)      (level,run) <-        simpleOptions-         $(simpleVersion Meta.version)+         versionString'          "stack - The Haskell Tool Stack"          ""          (extraHelpOption progName (Docker.dockerCmdName ++ "*") dockerHelpOptName <*> globalOpts)          (do addCommand "build"                         "Build the project(s) in this directory/configuration"                         (buildCmd DoNothing)-                        buildOpts+                        (buildOpts False)              addCommand "install"                         "Build executables and install to a user path"                         installCmd-                        buildOpts+                        (buildOpts False)              addCommand "test"                         "Build and test the project(s) in this directory/configuration"                         (buildCmd DoTests)-                        buildOpts+                        (buildOpts False)              addCommand "bench"                         "Build and benchmark the project(s) in this directory/configuration"                         (buildCmd DoBenchmarks)-                        buildOpts+                        (buildOpts False)              addCommand "haddock"                         "Generate haddocks for the project(s) in this directory/configuration"-                        (buildCmd DoHaddock)-                        buildOpts+                        (buildCmd DoNothing)+                        (buildOpts True)              addCommand "new"                         "Create a brand new project"-                        (\_ _ -> newProject)-                        (pure ())+                        newCmd+                        initOptsParser              addCommand "init"                         "Initialize a stack project based on one or more cabal packages"                         initCmd                         initOptsParser+             addCommand "solver"+                        "Use a dependency solver to try and determine missing extra-deps"+                        solverCmd+                        solverOptsParser              addCommand "setup"                         "Get the appropriate ghc for your project"                         setupCmd                         setupParser+             addCommand "path"+                        "Print out handy path information"+                        pathCmd+                        (fmap+                             catMaybes+                             (sequenceA+                                  (map+                                      (\(desc,name,_) ->+                                           flag Nothing+                                                (Just name)+                                                (long (T.unpack name) <>+                                                 help desc))+                                      paths)))              addCommand "unpack"                         "Unpack one or more packages locally"                         unpackCmd@@ -133,14 +154,18 @@              addCommand "ghci"                         "Run ghci in the context of project(s)"                         replCmd-                        ((,) <$>+                        ((,,) <$>                          fmap (map T.pack)                               (many (strArgument                                        (metavar "TARGET" <>                                         help "If none specified, use all packages defined in current directory"))) <*>                          many (strOption (long "ghc-options" <>                                           metavar "OPTION" <>-                                          help "Additional options passed to GHCi")))+                                          help "Additional options passed to GHCi")) <*>+                         fmap (fromMaybe "ghc")+                              (optional (strOption (long "with-ghc" <>+                                                    metavar "GHC" <>+                                                    help "Use this command for the GHC to run"))))              addCommand "runghc"                         "Run runghc"                         execCmd@@ -152,21 +177,6 @@                         cleanCmd                         (pure ())              addSubCommands-               "path"-               "Print path information for certain things"-               (do addCommand "ghc"-                              "Print path to the ghc executable in use"-                              pathCmd-                              (pure PathGhc)-                   addCommand "log"-                              "Print path to the log directory in use"-                              pathCmd-                              (pure PathLog)-                   addCommand "package-db"-                              "Print the package databases in use"-                              pathCmd-                              (pure PathPackageDb))-             addSubCommands                Docker.dockerCmdName                "Subcommands specific to Docker use"                (do addCommand Docker.dockerPullCmdName@@ -189,6 +199,7 @@                                    <*> many (strArgument (metavar "ARGS"))))              )              -- commandsFromPlugins plugins pluginShouldHaveRun) https://github.com/commercialhaskell/stack/issues/322+     when (globalLogLevel level == LevelDebug) $ putStrLn versionString'      run level `catch` \e -> do         -- This special handler stops "stack: " from being printed before the         -- exception@@ -200,14 +211,6 @@   where     dockerHelpOptName = Docker.dockerCmdName ++ "-help" --pathCmd :: PathArg -> GlobalOpts -> IO ()-pathCmd pathArg go@GlobalOpts{..} = do-  (manager,lc) <- loadConfigWithOpts go-  buildConfig <- runStackLoggingT manager globalLogLevel globalTerminal-    (lcLoadBuildConfig lc globalResolver ExecStrategy)-  runStackT manager globalLogLevel buildConfig globalTerminal (pathString pathArg) >>= putStrLn- -- Try to run a plugin tryRunPlugin :: Plugins -> IO () tryRunPlugin plugins = do@@ -231,7 +234,116 @@ pluginShouldHaveRun _plugin _globalOpts = do   fail "Plugin should have run" +-- | Print out useful path information in a human-readable format (and+-- support others later).+pathCmd :: [Text] -> GlobalOpts -> IO ()+pathCmd keys go =+    withBuildConfig+        go+        ExecStrategy+        (do env <- ask+            let cfg = envConfig env+                bc = envConfigBuildConfig cfg+            menv <- getMinimalEnvOverride+            snap <- packageDatabaseDeps+            local <- packageDatabaseLocal+            snaproot <- installationRootDeps+            localroot <- installationRootLocal+            distDir <- distRelativeDir+            forM_+                (filter+                     (\(_,key,_) ->+                           null keys || elem key keys)+                     paths)+                (\(_,key,path) ->+                      $logInfo+                          (key <> ": " <>+                           path+                               (PathInfo+                                    bc+                                    menv+                                    snap+                                    local+                                    snaproot+                                    localroot+                                    distDir)))) +-- | Passed to all the path printers as a source of info.+data PathInfo = PathInfo+    {piBuildConfig :: BuildConfig+    ,piEnvOverride :: EnvOverride+    ,piSnapDb :: Path Abs Dir+    ,piLocalDb :: Path Abs Dir+    ,piSnapRoot :: Path Abs Dir+    ,piLocalRoot :: Path Abs Dir+    ,piDistDir :: Path Rel Dir+    }++-- | The paths of interest to a user. The first tuple string is used+-- for a description that the optparse flag uses, and the second+-- string as a machine-readable key and also for @--foo@ flags. The user+-- can choose a specific path to list like @--global-stack-root@. But+-- really it's mainly for the documentation aspect.+--+-- When printing output we generate @PathInfo@ and pass it to the+-- function to generate an appropriate string.+paths :: [(String, Text, PathInfo -> Text)]+paths =+    [ ( "Global stack root directory"+      , "global-stack-root"+      , \pi ->+             T.pack (toFilePath (configStackRoot (bcConfig (piBuildConfig pi)))))+    , ( "Project root (derived from stack.yaml file)"+      , "project-root"+      , \pi ->+             T.pack (toFilePath (bcRoot (piBuildConfig pi))))+    , ( "Configuration location (where the stack.yaml file is)"+      , "config-location"+      , \pi ->+             T.pack (toFilePath (bcStackYaml (piBuildConfig pi))))+    , ( "PATH environment variable"+      , "bin-path"+      , \pi ->+             T.pack (intercalate ":" (eoPath (piEnvOverride pi))))+    , ( "Installed GHCs (unpacked and archives)"+      , "ghc-paths"+      , \pi ->+             T.pack (toFilePath (configLocalPrograms (bcConfig (piBuildConfig pi)))))+    , ( "Local bin path where stack installs executables"+      , "local-bin-path"+      , \pi ->+             T.pack (toFilePath (configLocalBin (bcConfig (piBuildConfig pi)))))+    , ( "Extra include directories"+      , "extra-include-dirs"+      , \pi ->+             T.intercalate+                 ", "+                 (Set.elems (configExtraIncludeDirs (bcConfig (piBuildConfig pi)))))+    , ( "Extra library directories"+      , "extra-library-dirs"+      , \pi ->+             T.intercalate ", " (Set.elems (configExtraLibDirs (bcConfig (piBuildConfig pi)))))+    , ( "Snapshot package database"+      , "snapshot-pkg-db"+      , \pi ->+             T.pack (toFilePath (piSnapDb pi)))+    , ( "Local project package database"+      , "local-pkg-db"+      , \pi ->+             T.pack (toFilePath (piLocalDb pi)))+    , ( "Snapshot installation root"+      , "snapshot-install-root"+      , \pi ->+             T.pack (toFilePath (piSnapRoot pi)))+    , ( "Local project installation root"+      , "local-install-root"+      , \pi ->+             T.pack (toFilePath (piLocalRoot pi)))+    , ( "Dist work directory"+      , "dist-dir"+      , \pi ->+             T.pack (toFilePath (piDistDir pi)))]+ data SetupCmdOpts = SetupCmdOpts     { scoGhcVersion :: !(Maybe Version)     , scoForceReinstall :: !Bool@@ -254,17 +366,16 @@ setupCmd :: SetupCmdOpts -> GlobalOpts -> IO () setupCmd SetupCmdOpts{..} go@GlobalOpts{..} = do   (manager,lc) <- loadConfigWithOpts go-  runStackLoggingT manager globalLogLevel globalTerminal $+  runStackT manager globalLogLevel (lcConfig lc) globalTerminal $       Docker.rerunWithOptionalContainer-          (lcConfig lc)           (lcProjectRoot lc)           (runStackLoggingT manager globalLogLevel globalTerminal $ do               (ghc, mstack) <-                   case scoGhcVersion of                       Just v -> return (v, Nothing)                       Nothing -> do-                          bc <- lcLoadBuildConfig lc globalResolver ThrowException-                          return (bcGhcVersion bc, Just $ bcStackYaml bc)+                          bc <- lcLoadBuildConfig lc globalResolver ExecStrategy+                          return (bcGhcVersionExpected bc, Just $ bcStackYaml bc)               mpaths <- runStackT manager globalLogLevel (lcConfig lc) globalTerminal $ ensureGHC SetupOpts                   { soptsInstallIfMissing = True                   , soptsUseSystem =@@ -277,8 +388,8 @@                   }               case mpaths of                   Nothing -> $logInfo "GHC on PATH would be used"-                  Just paths -> $logInfo $ "Would add the following to PATH: "-                      <> T.pack (intercalate [searchPathSeparator] paths)+                  Just ps -> $logInfo $ "Would add the following to PATH: "+                      <> T.pack (intercalate [searchPathSeparator] ps)                   )  withBuildConfig :: GlobalOpts@@ -287,21 +398,18 @@                 -> IO () withBuildConfig go@GlobalOpts{..} strat inner = do     (manager, lc) <- loadConfigWithOpts go-    runStackLoggingT manager globalLogLevel globalTerminal $-        Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $ do-            bconfig1 <- runStackLoggingT manager globalLogLevel globalTerminal $+    runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.rerunWithOptionalContainer (lcProjectRoot lc) $ do+            bconfig <- runStackLoggingT manager globalLogLevel globalTerminal $                 lcLoadBuildConfig lc globalResolver strat-            (bconfig2,cabalVer) <-+            envConfig <-                 runStackT-                    manager globalLogLevel bconfig1 globalTerminal-                    (do cfg <- setupEnv-                        menv <- runReaderT getMinimalEnvOverride cfg-                        cabalVer <- getCabalPkgVer menv-                        return (cfg,cabalVer))+                    manager globalLogLevel bconfig globalTerminal+                    setupEnv             runStackT                 manager                 globalLogLevel-                (EnvConfig bconfig2 cabalVer)+                envConfig                 globalTerminal                 inner @@ -351,8 +459,8 @@ unpackCmd :: [String] -> GlobalOpts -> IO () unpackCmd names go@GlobalOpts{..} = do     (manager,lc) <- loadConfigWithOpts go-    runStackLoggingT manager globalLogLevel globalTerminal $-        Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $+    runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.rerunWithOptionalContainer (lcProjectRoot lc) $             runStackT manager globalLogLevel (lcConfig lc) globalTerminal $ do                 menv <- getMinimalEnvOverride                 Stack.Fetch.unpackPackages menv "." names@@ -361,8 +469,8 @@ updateCmd :: () -> GlobalOpts -> IO () updateCmd () go@GlobalOpts{..} = do     (manager,lc) <- loadConfigWithOpts go-    runStackLoggingT manager globalLogLevel globalTerminal $-        Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $+    runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.rerunWithOptionalContainer (lcProjectRoot lc) $             runStackT manager globalLogLevel (lcConfig lc) globalTerminal $                 getMinimalEnvOverride >>= Stack.PackageIndex.updateAllIndices @@ -389,16 +497,16 @@     exec cmd args  -- | Run the REPL in the context of a project, with-replCmd :: ([Text], [String]) -> GlobalOpts -> IO ()-replCmd (targets,args) go@GlobalOpts{..} = withBuildConfig go ExecStrategy $ do-      repl targets args+replCmd :: ([Text], [String], FilePath) -> GlobalOpts -> IO ()+replCmd (targets,args,path) go@GlobalOpts{..} = withBuildConfig go ExecStrategy $ do+      repl targets args path  -- | Pull the current Docker image. dockerPullCmd :: () -> GlobalOpts -> IO () dockerPullCmd _ go@GlobalOpts{..} = do     (manager,lc) <- liftIO $ loadConfigWithOpts go-    runStackLoggingT manager globalLogLevel globalTerminal $ Docker.preventInContainer $-        Docker.pull (lcConfig lc)+    runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.preventInContainer Docker.pull  -- | Reset the Docker sandbox. dockerResetCmd :: Bool -> GlobalOpts -> IO ()@@ -411,24 +519,25 @@ dockerCleanupCmd :: Docker.CleanupOpts -> GlobalOpts -> IO () dockerCleanupCmd cleanupOpts go@GlobalOpts{..} = do     (manager,lc) <- liftIO $ loadConfigWithOpts go-    runStackLoggingT manager globalLogLevel globalTerminal$ Docker.preventInContainer $-        Docker.cleanup (lcConfig lc) cleanupOpts+    runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.preventInContainer $+            Docker.cleanup cleanupOpts  -- | Execute a command dockerExecCmd :: (String, [String]) -> GlobalOpts -> IO () dockerExecCmd (cmd,args) go@GlobalOpts{..} = do     (manager,lc) <- liftIO $ loadConfigWithOpts go-    runStackLoggingT manager globalLogLevel globalTerminal$ Docker.preventInContainer $-        Docker.rerunCmdWithRequiredContainer (lcConfig lc)-                                             (lcProjectRoot lc)-                                             (return (cmd,args,lcConfig lc))+    runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.preventInContainer $+            Docker.rerunCmdWithRequiredContainer (lcProjectRoot lc)+                                                 (return (cmd,args,id))  -- | Parser for build arguments.-buildOpts :: Parser BuildOpts-buildOpts =+buildOpts :: Bool -> Parser BuildOpts+buildOpts forHaddock =             BuildOpts <$> target <*> libProfiling <*> exeProfiling <*>-            optimize <*> finalAction <*> dryRun <*> ghcOpts <*> flags <*>-            installExes <*> preFetch <*> testArgs <*> onlySnapshot+            optimize <*> haddock <*> haddockDeps <*> finalAction <*> dryRun <*> ghcOpts <*>+            flags <*> installExes <*> preFetch <*> testArgs <*> onlySnapshot   where optimize =           maybeBoolFlags "optimizations" "optimizations for TARGETs and all its dependencies" idm         target =@@ -446,6 +555,16 @@                     "executable-profiling"                     "library profiling for TARGETs and all its dependencies"                     idm+        haddock =+          boolFlags forHaddock+                    "haddock"+                    "building Haddocks"+                    idm+        haddockDeps =+          maybeBoolFlags+                    "haddock-deps"+                    "building Haddocks for dependencies"+                    idm         finalAction = pure DoNothing         installExes = pure False         dryRun = flag False True (long "dry-run" <>@@ -602,7 +721,31 @@ initCmd :: InitOpts -> GlobalOpts -> IO () initCmd initOpts go@GlobalOpts{..} = do   (manager,lc) <- loadConfigWithOpts go-  runStackLoggingT manager globalLogLevel globalTerminal $-        Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $+  runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.rerunWithOptionalContainer (lcProjectRoot lc) $             runStackT manager globalLogLevel (lcConfig lc) globalTerminal $-                initProject globalResolver initOpts+                initProject initOpts++-- | Project creation+newCmd :: InitOpts -> GlobalOpts -> IO ()+newCmd initOpts go@GlobalOpts{..} = do+  (manager,lc) <- loadConfigWithOpts go+  runStackT manager globalLogLevel (lcConfig lc) globalTerminal $+        Docker.rerunWithOptionalContainer (lcProjectRoot lc) $+            runStackT manager globalLogLevel (lcConfig lc) globalTerminal $ do+                newProject+                initProject initOpts++-- | Fix up extra-deps for a project+solverCmd :: Bool -- ^ modify stack.yaml automatically?+          -> GlobalOpts+          -> IO ()+solverCmd fixStackYaml go =+    withBuildConfig go ThrowException (solveExtraDeps fixStackYaml)++-- | Parser for @solverCmd@+solverOptsParser :: Parser Bool+solverOptsParser = boolFlags False+    "modify-stack-yaml"+    "Automatically modify stack.yaml with the solver's recommendations"+    idm
src/test/Stack/PackageDumpSpec.hs view
@@ -76,7 +76,9 @@                 , dpLibDirs = ["/opt/ghc/7.8.4/lib/ghc-7.8.4/haskell2010-1.1.2.0"]                 , dpDepends = depends                 , dpLibraries = ["HShaskell2010-1.1.2.0"]+                , dpHaddockInterfaces = ["/opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskell2010-1.1.2.0/haskell2010.haddock"]                 , dpProfiling = ()+                , dpHaddock = ()                 }          it "ghc 7.10" $ do@@ -104,28 +106,61 @@             haskell2010 `shouldBe` DumpPackage                 { dpGhcPkgId = ghcPkgId                 , dpLibDirs = ["/opt/ghc/7.10.1/lib/ghc-7.10.1/ghc_EMlWrQ42XY0BNVbSrKixqY"]+                , dpHaddockInterfaces = ["/opt/ghc/7.10.1/share/doc/ghc/html/libraries/ghc-7.10.1/ghc.haddock"]                 , dpDepends = depends                 , dpLibraries = ["HSghc-7.10.1-EMlWrQ42XY0BNVbSrKixqY"]                 , dpProfiling = ()+                , dpHaddock = ()                 }+        it "ghc 7.8.4 (osx)" $ do+            hmatrix:_ <- runResourceT+                $ CB.sourceFile "test/package-dump/ghc-7.8.4-osx.txt"+               $$ conduitDumpPackage+               =$ CL.consume+            ghcPkgId <- parseGhcPkgId "hmatrix-0.16.1.5-12d5d21f26aa98774cdd8edbc343fbfe"+            depends <- mapM parseGhcPkgId+                [ "array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b"+                , "base-4.7.0.2-918c7ac27f65a87103264a9f51652d63"+                , "binary-0.7.1.0-108d06eea2ef05e517f9c1facf10f63c"+                , "bytestring-0.10.4.0-78bc8f2c724c765c78c004a84acf6cc3"+                , "deepseq-1.3.0.2-0ddc77716bd2515426e1ba39f6788a4f"+                , "random-1.1-822c19b7507b6ac1aaa4c66731e775ae"+                , "split-0.2.2-34cfb851cc3784e22bfae7a7bddda9c5"+                , "storable-complex-0.2.2-e962c368d58acc1f5b41d41edc93da72"+                , "vector-0.10.12.3-f4222db607fd5fdd7545d3e82419b307"]+            hmatrix `shouldBe` DumpPackage+                { dpGhcPkgId = ghcPkgId+                , dpLibDirs =+                      [ "/Users/alexbiehl/.stack/snapshots/x86_64-osx/lts-2.13/7.8.4/lib/x86_64-osx-ghc-7.8.4/hmatrix-0.16.1.5"+                      , "/opt/local/lib/"+                      , "/usr/local/lib/"+                      ,  "C:/Program Files/Example/"]+                , dpHaddockInterfaces = ["/Users/alexbiehl/.stack/snapshots/x86_64-osx/lts-2.13/7.8.4/doc/html/hmatrix.haddock"]+                , dpDepends = depends+                , dpLibraries = ["HShmatrix-0.16.1.5"]+                , dpProfiling = ()+                , dpHaddock = ()+                } -    it "ghcPkgDump + addProfiling" $ (id :: IO () -> IO ()) $ runNoLoggingT $ do+    it "ghcPkgDump + addProfiling + addHaddock" $ (id :: IO () -> IO ()) $ runNoLoggingT $ do         menv' <- getEnvOverride buildPlatform         menv <- mkEnvOverride buildPlatform $ Map.delete "GHC_PACKAGE_PATH" $ unEnvOverride menv'-        pcache <- newProfilingCache+        icache <- newInstalledCache         ghcPkgDump menv Nothing             $  conduitDumpPackage-            =$ addProfiling pcache+            =$ addProfiling icache+            =$ addHaddock icache             =$ CL.sinkNull      it "sinkMatching" $ do         menv' <- getEnvOverride buildPlatform         menv <- mkEnvOverride buildPlatform $ Map.delete "GHC_PACKAGE_PATH" $ unEnvOverride menv'-        pcache <- newProfilingCache+        icache <- newInstalledCache         m <- runNoLoggingT $ ghcPkgDump menv Nothing             $  conduitDumpPackage-            =$ addProfiling pcache-            =$ sinkMatching False (Map.singleton $(mkPackageName "transformers") $(mkVersion "0.0.0.0.0.0.1"))+            =$ addProfiling icache+            =$ addHaddock icache+            =$ sinkMatching False False (Map.singleton $(mkPackageName "transformers") $(mkVersion "0.0.0.0.0.0.1"))         case Map.lookup $(mkPackageName "base") m of             Nothing -> error "base not present"             Just _ -> return ()
stack.cabal view
@@ -1,5 +1,5 @@ name:                stack-version:             0.0.3+version:             0.1.0.0 synopsis:            The Haskell Tool Stack description:         Please see the README.md for usage information, and                      the wiki on Github for more details.  Also, note that@@ -13,15 +13,28 @@ category:            Development build-type:          Simple cabal-version:       >=1.10-extra-source-files:  README.md ChangeLog.md homepage:            https://github.com/commercialhaskell/stack+extra-source-files:  README.md ChangeLog.md                       -- Glob would be nice, but apparently Cabal doesn't support it:                      --     cabal: filepath wildcard 'test/package-dump/*.txt' does not match any files.                      -- Happened during cabal sdist                      test/package-dump/ghc-7.8.txt+                     test/package-dump/ghc-7.8.4-osx.txt                      test/package-dump/ghc-7.10.txt +                     new-template/src/Lib.hs+                     new-template/new-template.cabal+                     new-template/test/Spec.hs+                     new-template/app/Main.hs+                     new-template/LICENSE+                     new-template/Setup.hs++flag integration-tests+  manual: True+  default: False+  description: Run the integration test suite+ library   hs-source-dirs:    src/   ghc-options:       -Wall@@ -40,9 +53,9 @@                      Stack.Package                      Stack.PackageDump                      Stack.PackageIndex-                     Stack.Path                      Stack.Repl                      Stack.Setup+                     Stack.Solver                      Stack.Types                      Stack.Types.Internal                      Stack.Types.BuildPlan@@ -58,10 +71,10 @@                      Stack.Build.Cache                      Stack.Build.ConstructPlan                      Stack.Build.Execute+                     Stack.Build.Haddock                      Stack.Build.Installed                      Stack.Build.Source                      Stack.Build.Types-                     Stack.Build.Doc                      Stack.Upload                      System.Process.Read                      System.Process.Log@@ -78,6 +91,7 @@                      Data.Binary.VersionTagged                      Data.Set.Monad                      Data.Maybe.Extra+                     Data.Attoparsec.Args   build-depends:     Cabal >= 1.18.1.5                    , aeson >= 0.8.0.2                    , async >= 2.0.2@@ -135,6 +149,8 @@                    , yaml >= 0.8.10.1                    , zlib >= 0.5.4.2                    , deepseq+                   , file-embed+                   , word8   if !os(windows)     build-depends:   unix >= 2.7.0.1   default-language:    Haskell2010@@ -199,6 +215,34 @@                 , conduit-extra                 , resourcet                 , Cabal+  default-language:    Haskell2010++test-suite stack-integration-test+  type:           exitcode-stdio-1.0+  hs-source-dirs: test/integration+  main-is:        Spec.hs+  ghc-options:    -Wall -threaded -rtsopts -with-rtsopts=-N++  if flag(integration-tests)+    buildable: True+  else+    buildable: False++  build-depends:  base >= 4.7 && < 10+                , temporary+                , hspec+                , process+                , filepath+                , directory+                , text+                , unix-compat+                , containers+                , conduit+                , conduit-extra+                , resourcet+                , async+                , transformers+                , bytestring   default-language:    Haskell2010  source-repository head
+ test/integration/Spec.hs view
@@ -0,0 +1,134 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ScopedTypeVariables #-}++import           Control.Applicative+import           Control.Arrow+import           Control.Concurrent.Async+import           Control.Exception+import           Control.Monad+import           Control.Monad.IO.Class+import           Control.Monad.Trans.Resource+import qualified Data.ByteString.Lazy         as L+import           Data.Char+import           Data.Conduit+import           Data.Conduit.Binary          (sinkLbs)+import           Data.Conduit.Filesystem      (sourceDirectoryDeep)+import qualified Data.Conduit.List            as CL+import           Data.Conduit.Process+import           Data.List                    (isSuffixOf, stripPrefix)+import qualified Data.Map                     as Map+import           Data.Text.Encoding.Error     (lenientDecode)+import qualified Data.Text.Lazy               as TL+import qualified Data.Text.Lazy.Encoding      as TL+import           Data.Typeable+import           System.Directory+import           System.Environment+import           System.Exit+import           System.FilePath+import           System.IO.Temp+import           System.PosixCompat.Files+import           Test.Hspec++main :: IO ()+main = do+    currDir <- canonicalizePath "test/integration"++    let findExe name = do+            mexe <- findExecutable name+            case mexe of+                Nothing -> error $ name ++ " not found on PATH"+                Just exe -> return exe+    runghc <- findExe "runghc"+    stack <- findExe "stack"++    let testDir = currDir </> "tests"+    tests <- getDirectoryContents testDir >>= filterM (hasTest testDir)++    envOrig <- getEnvironment++    withSystemTempDirectory ("stack-integration-home") $ \newHome -> do+        let env' = Map.toList+                 $ Map.insert "STACK_EXE" stack+                 $ Map.insert "HOME" newHome+                 $ Map.insert "APPDATA" newHome+                 $ Map.delete "GHC_PACKAGE_PATH"+                 $ Map.fromList+                 $ map (first (map toUpper)) envOrig++        origStackRoot <- getAppUserDataDirectory "stack"++        hspec $ mapM_ (test runghc env' currDir origStackRoot newHome) tests++hasTest :: FilePath -> FilePath -> IO Bool+hasTest root dir = doesFileExist $ root </> dir </> "Main.hs"++test :: FilePath -- ^ runghc+     -> [(String, String)] -- ^ env+     -> FilePath -- ^ currdir+     -> FilePath -- ^ origStackRoot+     -> FilePath -- ^ newHome+     -> String+     -> Spec+test runghc env' currDir origStackRoot newHome name = it name $ withDir $ \dir -> do+    removeDirectoryRecursive newHome+    copyTree toCopyRoot origStackRoot (newHome </> takeFileName origStackRoot)+    let testDir = currDir </> "tests" </> name+        mainFile = testDir </> "Main.hs"+        libDir = currDir </> "lib"+        cp = (proc runghc+                [ "-clear-package-db"+                , "-global-package-db"+                , "-i" ++ libDir+                , mainFile+                ])+                { cwd = Just dir+                , env = Just env'+                }++    copyTree (const True) (testDir </> "files") dir++    (ClosedStream, outSrc, errSrc, sph) <- streamingProcess cp+    (out, err, ec) <- runConcurrently $ (,,)+        <$> Concurrently (outSrc $$ sinkLbs)+        <*> Concurrently (errSrc $$ sinkLbs)+        <*> Concurrently (waitForStreamingProcess sph)+    when (ec /= ExitSuccess) $ throwIO $ TestFailure out err ec+  where+    withDir = withSystemTempDirectory ("stack-integration-" ++ name)++data TestFailure = TestFailure L.ByteString L.ByteString ExitCode+    deriving Typeable+instance Show TestFailure where+    show (TestFailure out err ec) = concat+        [ "Exited with " ++ show ec+        , "\n\nstdout:\n"+        , toStr out+        , "\n\nstderr:\n"+        , toStr err+        ]+      where+        toStr = TL.unpack . TL.decodeUtf8With lenientDecode+instance Exception TestFailure++copyTree :: (FilePath -> Bool) -> FilePath -> FilePath -> IO ()+copyTree toCopy src dst =+    runResourceT (sourceDirectoryDeep False src $$ CL.mapM_ go)+        `catch` \(_ :: IOException) -> return ()+  where+    go srcfp = when (toCopy srcfp) $ liftIO $ do+        Just suffix <- return $ stripPrefix src srcfp+        let dstfp = dst ++ "/" ++ suffix+        createDirectoryIfMissing True $ takeDirectory dstfp+        createSymbolicLink srcfp dstfp `catch` \(_ :: IOException) ->+            copyFile srcfp dstfp -- for Windows++toCopyRoot :: FilePath -> Bool+toCopyRoot srcfp = any (`isSuffixOf` srcfp)+    -- FIXME command line parameters to control how many of these get+    -- copied, trade-off of runtime/bandwidth vs isolation of tests+    [ ".tar"+    , ".xz"+    -- , ".gz"+    , ".7z.exe"+    , "00-index.cache"+    ]
+ test/package-dump/ghc-7.10.txt view
@@ -0,0 +1,1188 @@+name: ghc+version: 7.10.1+id: ghc-7.10.1-325809317787a897b7a97d646ceaa3a3+key: ghc_EMlWrQ42XY0BNVbSrKixqY+license: BSD3+maintainer: glasgow-haskell-users@haskell.org+homepage: http://www.haskell.org/ghc/+synopsis: The GHC API+description:+    GHC's functionality can be useful for more things than just+    compiling Haskell programs. Important use cases are programs+    that analyse (and perhaps transform) Haskell code. Others+    include loading Haskell code dynamically in a GHCi-like manner.+    For this reason, a lot of GHC's functionality is made available+    through this package.+category: Development+author: The GHC Team+exposed: False+exposed-modules:+    Avail BasicTypes ConLike DataCon PatSyn Demand Debug Exception+    GhcMonad Hooks Id IdInfo Lexeme Literal Llvm Llvm.AbsSyn+    Llvm.MetaData Llvm.PpLlvm Llvm.Types LlvmCodeGen LlvmCodeGen.Base+    LlvmCodeGen.CodeGen LlvmCodeGen.Data LlvmCodeGen.Ppr+    LlvmCodeGen.Regs LlvmMangler MkId Module Name NameEnv NameSet+    OccName RdrName SrcLoc UniqSupply Unique Var VarEnv VarSet+    UnVarGraph BlockId CLabel Cmm CmmBuildInfoTables CmmPipeline+    CmmCallConv CmmCommonBlockElim CmmContFlowOpt CmmExpr CmmInfo+    CmmLex CmmLint CmmLive CmmMachOp CmmNode CmmOpt CmmParse+    CmmProcPoint CmmSink CmmType CmmUtils CmmLayoutStack MkGraph+    PprBase PprC PprCmm PprCmmDecl PprCmmExpr Bitmap CodeGen.Platform+    CodeGen.Platform.ARM CodeGen.Platform.ARM64 CodeGen.Platform.NoRegs+    CodeGen.Platform.PPC CodeGen.Platform.PPC_Darwin+    CodeGen.Platform.SPARC CodeGen.Platform.X86 CodeGen.Platform.X86_64+    CgUtils StgCmm StgCmmBind StgCmmClosure StgCmmCon StgCmmEnv+    StgCmmExpr StgCmmForeign StgCmmHeap StgCmmHpc StgCmmArgRep+    StgCmmLayout StgCmmMonad StgCmmPrim StgCmmProf StgCmmTicky+    StgCmmUtils StgCmmExtCode SMRep CoreArity CoreFVs CoreLint CorePrep+    CoreSubst CoreSyn TrieMap CoreTidy CoreUnfold CoreUtils MkCore+    PprCore Check Coverage Desugar DsArrows DsBinds DsCCall DsExpr+    DsForeign DsGRHSs DsListComp DsMonad DsUtils Match MatchCon+    MatchLit HsBinds HsDecls HsDoc HsExpr HsImpExp HsLit PlaceHolder+    HsPat HsSyn HsTypes HsUtils BinIface BuildTyCl IfaceEnv IfaceSyn+    IfaceType LoadIface MkIface TcIface FlagChecker Annotations+    BreakArray CmdLineParser CodeOutput Config Constants DriverMkDepend+    DriverPhases PipelineMonad DriverPipeline DynFlags ErrUtils Finder+    GHC GhcMake GhcPlugins DynamicLoading HeaderInfo HscMain HscStats+    HscTypes InteractiveEval InteractiveEvalTypes PackageConfig+    Packages PlatformConstants Plugins TcPluginM PprTyThing StaticFlags+    StaticPtrTable SysTools TidyPgm Ctype HaddockUtils Lexer+    OptCoercion Parser RdrHsSyn ApiAnnotation ForeignCall PrelInfo+    PrelNames PrelRules PrimOp TysPrim TysWiredIn CostCentre ProfInit+    SCCfinal RnBinds RnEnv RnExpr RnHsDoc RnNames RnPat RnSource+    RnSplice RnTypes CoreMonad CSE FloatIn FloatOut LiberateCase+    OccurAnal SAT SetLevels SimplCore SimplEnv SimplMonad SimplUtils+    Simplify SimplStg StgStats UnariseStg Rules SpecConstr Specialise+    CoreToStg StgLint StgSyn CallArity DmdAnal WorkWrap WwLib FamInst+    Inst TcAnnotations TcArrows TcBinds TcClassDcl TcDefaults TcDeriv+    TcEnv TcExpr TcForeign TcGenDeriv TcGenGenerics TcHsSyn TcHsType+    TcInstDcls TcMType TcValidity TcMatches TcPat TcPatSyn TcRnDriver+    TcRnMonad TcRnTypes TcRules TcSimplify TcErrors TcTyClsDecls+    TcTyDecls TcType TcEvidence TcUnify TcInteract TcCanonical+    TcFlatten TcSMonad TcTypeNats TcSplice Class Coercion FamInstEnv+    FunDeps InstEnv TyCon CoAxiom Kind Type TypeRep Unify Bag Binary+    BooleanFormula BufWrite Digraph Encoding FastBool FastFunctions+    FastMutInt FastString FastTypes Fingerprint FiniteMap GraphBase+    GraphColor GraphOps GraphPpr IOEnv ListSetOps Maybes MonadUtils+    OrdList Outputable Pair Panic Pretty Serialized State Stream+    StringBuffer UniqFM UniqSet Util ExtsCompat46+    Vectorise.Builtins.Base Vectorise.Builtins.Initialise+    Vectorise.Builtins Vectorise.Monad.Base Vectorise.Monad.Naming+    Vectorise.Monad.Local Vectorise.Monad.Global+    Vectorise.Monad.InstEnv Vectorise.Monad Vectorise.Utils.Base+    Vectorise.Utils.Closure Vectorise.Utils.Hoisting+    Vectorise.Utils.PADict Vectorise.Utils.Poly Vectorise.Utils+    Vectorise.Generic.Description Vectorise.Generic.PAMethods+    Vectorise.Generic.PADict Vectorise.Generic.PData Vectorise.Type.Env+    Vectorise.Type.Type Vectorise.Type.TyConDecl+    Vectorise.Type.Classify Vectorise.Convert Vectorise.Vect+    Vectorise.Var Vectorise.Env Vectorise.Exp Vectorise Hoopl.Dataflow+    Hoopl AsmCodeGen TargetReg NCGMonad Instruction Size Reg RegClass+    PIC Platform CPrim X86.Regs X86.RegInfo X86.Instr X86.Cond X86.Ppr+    X86.CodeGen PPC.Regs PPC.RegInfo PPC.Instr PPC.Cond PPC.Ppr+    PPC.CodeGen SPARC.Base SPARC.Regs SPARC.Imm SPARC.AddrMode+    SPARC.Cond SPARC.Instr SPARC.Stack SPARC.ShortcutJump SPARC.Ppr+    SPARC.CodeGen SPARC.CodeGen.Amode SPARC.CodeGen.Base+    SPARC.CodeGen.CondCode SPARC.CodeGen.Gen32 SPARC.CodeGen.Gen64+    SPARC.CodeGen.Sanity SPARC.CodeGen.Expand RegAlloc.Liveness+    RegAlloc.Graph.Main RegAlloc.Graph.Stats RegAlloc.Graph.ArchBase+    RegAlloc.Graph.ArchX86 RegAlloc.Graph.Coalesce RegAlloc.Graph.Spill+    RegAlloc.Graph.SpillClean RegAlloc.Graph.SpillCost+    RegAlloc.Graph.TrivColorable RegAlloc.Linear.Main+    RegAlloc.Linear.JoinToTargets RegAlloc.Linear.State+    RegAlloc.Linear.Stats RegAlloc.Linear.FreeRegs+    RegAlloc.Linear.StackMap RegAlloc.Linear.Base+    RegAlloc.Linear.X86.FreeRegs RegAlloc.Linear.X86_64.FreeRegs+    RegAlloc.Linear.PPC.FreeRegs RegAlloc.Linear.SPARC.FreeRegs Dwarf+    Dwarf.Types Dwarf.Constants DsMeta Convert ByteCodeAsm ByteCodeGen+    ByteCodeInstr ByteCodeItbls ByteCodeLink Debugger LibFFI Linker+    ObjLink RtClosureInspect DebuggerUtils+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/ghc_EMlWrQ42XY0BNVbSrKixqY+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/ghc_EMlWrQ42XY0BNVbSrKixqY+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/ghc-7.10.1+hs-libraries: HSghc-7.10.1-EMlWrQ42XY0BNVbSrKixqY+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/ghc_EMlWrQ42XY0BNVbSrKixqY/include+depends:+    array-0.5.1.0-e29cdbe82692341ebb7ce6e2798294f9+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    bin-package-db-0.0.0.0-708fc7d634a370b311371a5bcde40b62+    bytestring-0.10.6.0-0909f8f31271f3d75749190bf2ee35db+    containers-0.5.6.2-2114032c163425cc264e6e1169dc2f6d+    directory-1.2.2.0-b4959b472d9eee380c6b32291ade29e0+    filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+    hoopl-3.10.0.2-8c8dfc4c3140e5f7c982da224c3cb1f0+    hpc-0.6.0.2-ac9064885aa8cb08a93314222939ead4+    process-1.2.3.0-3b1e9bca6ac38225806ff7bbf3f845b1+    template-haskell-2.10.0.0-e895139a0ffff267d412e3d0191ce93b+    time-1.5.0.1-e17a9220d438435579d2914e90774246+    transformers-0.4.2.0-c1a7bb855a176fe475d7b665301cd48f+    unix-2.7.1.0-e5915eb989e568b732bc7286b0d0817f+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/ghc-7.10.1/ghc.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/ghc-7.10.1+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: haskeline+version: 0.7.2.1+id: haskeline-0.7.2.1-a646e1ddf1a755ca5b5775dcb2ef8d8b+key: haske_IlDhIe25uAn0WJY379Nu1M+license: BSD3+copyright: (c) Judah Jacobson+maintainer: Judah Jacobson <judah.jacobson@gmail.com>+stability: Experimental+homepage: http://trac.haskell.org/haskeline+synopsis: A command-line interface for user input, written in Haskell.+description:+    Haskeline provides a user interface for line input in command-line+    programs.  This library is similar in purpose to readline, but since+    it is written in Haskell it is (hopefully) more easily used in other+    Haskell programs.+    .+    Haskeline runs both on POSIX-compatible systems and on Windows.+category: User Interfaces+author: Judah Jacobson+exposed: True+exposed-modules:+    System.Console.Haskeline System.Console.Haskeline.Completion+    System.Console.Haskeline.MonadException+    System.Console.Haskeline.History System.Console.Haskeline.IO+hidden-modules: System.Console.Haskeline.Backend+                System.Console.Haskeline.Backend.WCWidth+                System.Console.Haskeline.Command+                System.Console.Haskeline.Command.Completion+                System.Console.Haskeline.Command.History+                System.Console.Haskeline.Command.KillRing+                System.Console.Haskeline.Directory System.Console.Haskeline.Emacs+                System.Console.Haskeline.InputT System.Console.Haskeline.Key+                System.Console.Haskeline.LineState System.Console.Haskeline.Monads+                System.Console.Haskeline.Prefs System.Console.Haskeline.RunCommand+                System.Console.Haskeline.Term System.Console.Haskeline.Command.Undo+                System.Console.Haskeline.Vi System.Console.Haskeline.Recover+                System.Console.Haskeline.Backend.Posix+                System.Console.Haskeline.Backend.Posix.Encoder+                System.Console.Haskeline.Backend.DumbTerm+                System.Console.Haskeline.Backend.Terminfo+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/haske_IlDhIe25uAn0WJY379Nu1M+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/haske_IlDhIe25uAn0WJY379Nu1M+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/haskeline-0.7.2.1+hs-libraries: HShaskeline-0.7.2.1-IlDhIe25uAn0WJY379Nu1M+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    bytestring-0.10.6.0-0909f8f31271f3d75749190bf2ee35db+    containers-0.5.6.2-2114032c163425cc264e6e1169dc2f6d+    directory-1.2.2.0-b4959b472d9eee380c6b32291ade29e0+    filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+    terminfo-0.4.0.1-75199801b414a3f4c9de438be2a4e967+    transformers-0.4.2.0-c1a7bb855a176fe475d7b665301cd48f+    unix-2.7.1.0-e5915eb989e568b732bc7286b0d0817f+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/haskeline-0.7.2.1/haskeline.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/haskeline-0.7.2.1+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: terminfo+version: 0.4.0.1+id: terminfo-0.4.0.1-75199801b414a3f4c9de438be2a4e967+key: termi_7qZwBlx3clR8sTBilJl253+license: BSD3+copyright: (c) Judah Jacobson+maintainer: Judah Jacobson <judah.jacobson@gmail.com>+stability: Stable+homepage: https://github.com/judah/terminfo+synopsis: Haskell bindings to the terminfo library.+description:+    This library provides an interface to the terminfo database (via bindings to the+    curses library).  <http://en.wikipedia.org/wiki/Terminfo Terminfo> allows POSIX+    systems to interact with a variety of terminals using a standard set of capabilities.+category: User Interfaces+author: Judah Jacobson+exposed: True+exposed-modules:+    System.Console.Terminfo System.Console.Terminfo.Base+    System.Console.Terminfo.Cursor System.Console.Terminfo.Color+    System.Console.Terminfo.Edit System.Console.Terminfo.Effects+    System.Console.Terminfo.Keys+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/termi_7qZwBlx3clR8sTBilJl253+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/termi_7qZwBlx3clR8sTBilJl253+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/terminfo-0.4.0.1+hs-libraries: HSterminfo-0.4.0.1-7qZwBlx3clR8sTBilJl253+extra-libraries:+    tinfo+includes:+    ncurses.h term.h+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/terminfo-0.4.0.1/terminfo.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/terminfo-0.4.0.1+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: xhtml+version: 3000.2.1+id: xhtml-3000.2.1-7de0560ea74b173b7313fc2303cc6c58+key: xhtml_0mVDYvYGgNUBWShvlDofr1+license: BSD3+copyright: Bjorn Bringert 2004-2006, Andy Gill and the Oregon+           Graduate Institute of Science and Technology, 1999-2001+maintainer: Chris Dornan <chris@chrisdornan.com>+stability: Stable+homepage: https://github.com/haskell/xhtml+synopsis: An XHTML combinator library+description:+    This package provides combinators for producing+    XHTML 1.0, including the Strict, Transitional and+    Frameset variants.+category: Web, XML, Pretty Printer+author: Bjorn Bringert+exposed: True+exposed-modules:+    Text.XHtml Text.XHtml.Frameset Text.XHtml.Strict+    Text.XHtml.Transitional Text.XHtml.Debug Text.XHtml.Table+hidden-modules: Text.XHtml.Strict.Attributes+                Text.XHtml.Strict.Elements Text.XHtml.Frameset.Attributes+                Text.XHtml.Frameset.Elements Text.XHtml.Transitional.Attributes+                Text.XHtml.Transitional.Elements Text.XHtml.BlockTable+                Text.XHtml.Extras Text.XHtml.Internals+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/xhtml_0mVDYvYGgNUBWShvlDofr1+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/xhtml_0mVDYvYGgNUBWShvlDofr1+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/xhtml-3000.2.1+hs-libraries: HSxhtml-3000.2.1-0mVDYvYGgNUBWShvlDofr1+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/xhtml-3000.2.1/xhtml.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/xhtml-3000.2.1+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: transformers+version: 0.4.2.0+id: transformers-0.4.2.0-c1a7bb855a176fe475d7b665301cd48f+key: trans_ALYlebOVzVI4kxbFX5SGhm+license: BSD3+maintainer: Ross Paterson <ross@soi.city.ac.uk>+synopsis: Concrete functor and monad transformers+description:+    A portable library of functor and monad transformers, inspired by+    the paper \"Functional Programming with Overloading and Higher-Order+    Polymorphism\", by Mark P Jones,+    in /Advanced School of Functional Programming/, 1995+    (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>).+    .+    This package contains:+    .+    * the monad transformer class (in "Control.Monad.Trans.Class")+    and IO monad class (in "Control.Monad.IO.Class")+    .+    * concrete functor and monad transformers, each with associated+    operations and functions to lift operations associated with other+    transformers.+    .+    The package can be used on its own in portable Haskell code, in+    which case operations need to be manually lifted through transformer+    stacks (see "Control.Monad.Trans.Class" for some examples).+    Alternatively, it can be used with the non-portable monad classes in+    the @mtl@ or @monads-tf@ packages, which automatically lift operations+    introduced by monad transformers through other transformers.+category: Control+author: Andy Gill, Ross Paterson+exposed: True+exposed-modules:+    Control.Applicative.Backwards Control.Applicative.Lift+    Control.Monad.IO.Class Control.Monad.Signatures+    Control.Monad.Trans.Class Control.Monad.Trans.Cont+    Control.Monad.Trans.Except Control.Monad.Trans.Error+    Control.Monad.Trans.Identity Control.Monad.Trans.List+    Control.Monad.Trans.Maybe Control.Monad.Trans.Reader+    Control.Monad.Trans.RWS Control.Monad.Trans.RWS.Lazy+    Control.Monad.Trans.RWS.Strict Control.Monad.Trans.State+    Control.Monad.Trans.State.Lazy Control.Monad.Trans.State.Strict+    Control.Monad.Trans.Writer Control.Monad.Trans.Writer.Lazy+    Control.Monad.Trans.Writer.Strict Data.Functor.Classes+    Data.Functor.Compose Data.Functor.Constant Data.Functor.Product+    Data.Functor.Reverse Data.Functor.Sum+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/trans_ALYlebOVzVI4kxbFX5SGhm+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/trans_ALYlebOVzVI4kxbFX5SGhm+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/transformers-0.4.2.0+hs-libraries: HStransformers-0.4.2.0-ALYlebOVzVI4kxbFX5SGhm+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/transformers-0.4.2.0/transformers.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/transformers-0.4.2.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: hoopl+version: 3.10.0.2+id: hoopl-3.10.0.2-8c8dfc4c3140e5f7c982da224c3cb1f0+key: hoopl_JxODiSRz1e84NbH6nnZuUk+license: BSD3+maintainer: nr@cs.tufts.edu+homepage: http://ghc.cs.tufts.edu/hoopl/+synopsis: A library to support dataflow analysis and optimization+description:+    Higher-order optimization library+    .+    See /Norman Ramsey, Joao Dias, and Simon Peyton Jones./+    <http://research.microsoft.com/en-us/um/people/simonpj/Papers/c--/hoopl-haskell10.pdf "Hoopl: A Modular, Reusable Library for Dataflow Analysis and Transformation"> /(2010)/ for more details.+category: Compilers/Interpreters+author: Norman Ramsey, Joao Dias, Simon Marlow and Simon Peyton Jones+exposed: True+exposed-modules:+    Compiler.Hoopl Compiler.Hoopl.Internals Compiler.Hoopl.Wrappers+    Compiler.Hoopl.Passes.Dominator Compiler.Hoopl.Passes.DList+hidden-modules: Compiler.Hoopl.Checkpoint+                Compiler.Hoopl.Collections Compiler.Hoopl.Combinators+                Compiler.Hoopl.Dataflow Compiler.Hoopl.Debug Compiler.Hoopl.Block+                Compiler.Hoopl.Graph Compiler.Hoopl.Label Compiler.Hoopl.MkGraph+                Compiler.Hoopl.Fuel Compiler.Hoopl.Pointed Compiler.Hoopl.Shape+                Compiler.Hoopl.Show Compiler.Hoopl.Unique Compiler.Hoopl.XUtil+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/hoopl_JxODiSRz1e84NbH6nnZuUk+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/hoopl_JxODiSRz1e84NbH6nnZuUk+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/hoopl-3.10.0.2+hs-libraries: HShoopl-3.10.0.2-JxODiSRz1e84NbH6nnZuUk+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    containers-0.5.6.2-2114032c163425cc264e6e1169dc2f6d+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/hoopl-3.10.0.2/hoopl.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/hoopl-3.10.0.2+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: bin-package-db+version: 0.0.0.0+id: bin-package-db-0.0.0.0-708fc7d634a370b311371a5bcde40b62+key: binpa_JNoexmBMuO8C771QaIy3YN+license: BSD3+maintainer: ghc-devs@haskell.org+synopsis: The GHC compiler's view of the GHC package database format+description:+    This library is shared between GHC and ghc-pkg and is used by+    GHC to read package databases.+    .+    It only deals with the subset of the package database that the+    compiler cares about: modules paths etc and not package+    metadata like description, authors etc. It is thus not a+    library interface to ghc-pkg and is *not* suitable for+    modifying GHC package databases.+    .+    The package database format and this library are constructed in+    such a way that while ghc-pkg depends on Cabal, the GHC library+    and program do not have to depend on Cabal.+exposed: True+exposed-modules:+    GHC.PackageDb+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/binpa_JNoexmBMuO8C771QaIy3YN+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/binpa_JNoexmBMuO8C771QaIy3YN+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/bin-package-db-0.0.0.0+hs-libraries: HSbin-package-db-0.0.0.0-JNoexmBMuO8C771QaIy3YN+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    binary-0.7.3.0-0f543654a1ae447e0d4d0bbfc1bb704e+    bytestring-0.10.6.0-0909f8f31271f3d75749190bf2ee35db+    directory-1.2.2.0-b4959b472d9eee380c6b32291ade29e0+    filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/bin-package-db-0.0.0.0/bin-package-db.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/bin-package-db-0.0.0.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: Cabal+version: 1.22.2.0+id: Cabal-1.22.2.0-9f7cae2e98cca225e3d159c1e1bc773c+key: Cabal_HWT8QvVfJLn2ubvobpycJY+license: BSD3+copyright: 2003-2006, Isaac Jones+           2005-2011, Duncan Coutts+maintainer: cabal-devel@haskell.org+homepage: http://www.haskell.org/cabal/+synopsis: A framework for packaging Haskell software+description:+    The Haskell Common Architecture for Building Applications and+    Libraries: a framework defining a common interface for authors to more+    easily build their Haskell applications in a portable way.+    .+    The Haskell Cabal is part of a larger infrastructure for distributing,+    organizing, and cataloging Haskell libraries and tools.+category: Distribution+author: Isaac Jones <ijones@syntaxpolice.org>+        Duncan Coutts <duncan@community.haskell.org>+exposed: True+exposed-modules:+    Distribution.Compat.CreatePipe Distribution.Compat.Environment+    Distribution.Compat.Exception Distribution.Compat.ReadP+    Distribution.Compiler Distribution.InstalledPackageInfo+    Distribution.License Distribution.Make Distribution.ModuleName+    Distribution.Package Distribution.PackageDescription+    Distribution.PackageDescription.Check+    Distribution.PackageDescription.Configuration+    Distribution.PackageDescription.Parse+    Distribution.PackageDescription.PrettyPrint+    Distribution.PackageDescription.Utils Distribution.ParseUtils+    Distribution.ReadE Distribution.Simple Distribution.Simple.Bench+    Distribution.Simple.Build Distribution.Simple.Build.Macros+    Distribution.Simple.Build.PathsModule+    Distribution.Simple.BuildPaths Distribution.Simple.BuildTarget+    Distribution.Simple.CCompiler Distribution.Simple.Command+    Distribution.Simple.Compiler Distribution.Simple.Configure+    Distribution.Simple.GHC Distribution.Simple.GHCJS+    Distribution.Simple.Haddock Distribution.Simple.HaskellSuite+    Distribution.Simple.Hpc Distribution.Simple.Install+    Distribution.Simple.InstallDirs Distribution.Simple.JHC+    Distribution.Simple.LHC Distribution.Simple.LocalBuildInfo+    Distribution.Simple.PackageIndex Distribution.Simple.PreProcess+    Distribution.Simple.PreProcess.Unlit Distribution.Simple.Program+    Distribution.Simple.Program.Ar Distribution.Simple.Program.Builtin+    Distribution.Simple.Program.Db Distribution.Simple.Program.Find+    Distribution.Simple.Program.GHC Distribution.Simple.Program.HcPkg+    Distribution.Simple.Program.Hpc Distribution.Simple.Program.Ld+    Distribution.Simple.Program.Run Distribution.Simple.Program.Script+    Distribution.Simple.Program.Strip Distribution.Simple.Program.Types+    Distribution.Simple.Register Distribution.Simple.Setup+    Distribution.Simple.SrcDist Distribution.Simple.Test+    Distribution.Simple.Test.ExeV10 Distribution.Simple.Test.LibV09+    Distribution.Simple.Test.Log Distribution.Simple.UHC+    Distribution.Simple.UserHooks Distribution.Simple.Utils+    Distribution.System Distribution.TestSuite Distribution.Text+    Distribution.Utils.NubList Distribution.Verbosity+    Distribution.Version Language.Haskell.Extension+hidden-modules: Distribution.Compat.Binary+                Distribution.Compat.CopyFile Distribution.Compat.TempFile+                Distribution.GetOpt Distribution.Simple.GHC.Internal+                Distribution.Simple.GHC.IPI641 Distribution.Simple.GHC.IPI642+                Distribution.Simple.GHC.ImplInfo Paths_Cabal+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/Cabal_HWT8QvVfJLn2ubvobpycJY+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/Cabal_HWT8QvVfJLn2ubvobpycJY+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/Cabal-1.22.2.0+hs-libraries: HSCabal-1.22.2.0-HWT8QvVfJLn2ubvobpycJY+depends:+    array-0.5.1.0-e29cdbe82692341ebb7ce6e2798294f9+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    binary-0.7.3.0-0f543654a1ae447e0d4d0bbfc1bb704e+    bytestring-0.10.6.0-0909f8f31271f3d75749190bf2ee35db+    containers-0.5.6.2-2114032c163425cc264e6e1169dc2f6d+    deepseq-1.4.1.1-c1376f846fa170f2cc2cb2e57b203339+    directory-1.2.2.0-b4959b472d9eee380c6b32291ade29e0+    filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+    pretty-1.1.2.0-0d4e1eca3b0cfcebe20b9405f7bdaca9+    process-1.2.3.0-3b1e9bca6ac38225806ff7bbf3f845b1+    time-1.5.0.1-e17a9220d438435579d2914e90774246+    unix-2.7.1.0-e5915eb989e568b732bc7286b0d0817f+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/Cabal-1.22.2.0/Cabal.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/Cabal-1.22.2.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: binary+version: 0.7.3.0+id: binary-0.7.3.0-0f543654a1ae447e0d4d0bbfc1bb704e+key: binar_EKE3c9Lmxb3DQpU0fPtru6+license: BSD3+maintainer: Lennart Kolmodin, Don Stewart <dons00@gmail.com>+stability: provisional+homepage: https://github.com/kolmodin/binary+synopsis: Binary serialisation for Haskell values using lazy ByteStrings+description:+    Efficient, pure binary serialisation using lazy ByteStrings.+    Haskell values may be encoded to and from binary formats,+    written to disk as binary, or sent over the network.+    The format used can be automatically generated, or+    you can choose to implement a custom format if needed.+    Serialisation speeds of over 1 G\/sec have been observed,+    so this library should be suitable for high performance+    scenarios.+category: Data, Parsing+author: Lennart Kolmodin <kolmodin@gmail.com>+exposed: True+exposed-modules:+    Data.Binary Data.Binary.Put Data.Binary.Get+    Data.Binary.Get.Internal Data.Binary.Builder+    Data.Binary.Builder.Internal+hidden-modules: Data.Binary.Builder.Base Data.Binary.Class+                Data.Binary.Generic+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/binar_EKE3c9Lmxb3DQpU0fPtru6+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/binar_EKE3c9Lmxb3DQpU0fPtru6+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/binary-0.7.3.0+hs-libraries: HSbinary-0.7.3.0-EKE3c9Lmxb3DQpU0fPtru6+depends:+    array-0.5.1.0-e29cdbe82692341ebb7ce6e2798294f9+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    bytestring-0.10.6.0-0909f8f31271f3d75749190bf2ee35db+    containers-0.5.6.2-2114032c163425cc264e6e1169dc2f6d+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/binary-0.7.3.0/binary.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/binary-0.7.3.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: template-haskell+version: 2.10.0.0+id: template-haskell-2.10.0.0-e895139a0ffff267d412e3d0191ce93b+key: templ_BVMCZyLwIlfGfcqqzyUAI8+license: BSD3+maintainer: libraries@haskell.org+synopsis: Support library for Template Haskell+description:+    This package provides modules containing facilities for manipulating+    Haskell source code using Template Haskell.+    .+    See <http://www.haskell.org/haskellwiki/Template_Haskell> for more+    information.+category: Template Haskell+exposed: True+exposed-modules:+    Language.Haskell.TH Language.Haskell.TH.Lib Language.Haskell.TH.Ppr+    Language.Haskell.TH.PprLib Language.Haskell.TH.Quote+    Language.Haskell.TH.Syntax+hidden-modules: Language.Haskell.TH.Lib.Map+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/templ_BVMCZyLwIlfGfcqqzyUAI8+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/templ_BVMCZyLwIlfGfcqqzyUAI8+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/template-haskell-2.10.0.0+hs-libraries: HStemplate-haskell-2.10.0.0-BVMCZyLwIlfGfcqqzyUAI8+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    pretty-1.1.2.0-0d4e1eca3b0cfcebe20b9405f7bdaca9+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/template-haskell-2.10.0.0/template-haskell.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/template-haskell-2.10.0.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: pretty+version: 1.1.2.0+id: pretty-1.1.2.0-0d4e1eca3b0cfcebe20b9405f7bdaca9+key: prett_7jIfj8VCGFf1WS0tIQ1XSZ+license: BSD3+maintainer: David Terei <code@davidterei.com>+stability: Stable+homepage: http://github.com/haskell/pretty+synopsis: Pretty-printing library+description:+    This package contains a pretty-printing library, a set of API's+    that provides a way to easily print out text in a consistent+    format of your choosing. This is useful for compilers and related+    tools.+    .+    This library was originally designed by John Hughes's and has since+    been heavily modified by Simon Peyton Jones.+category: Text+exposed: True+exposed-modules:+    Text.PrettyPrint Text.PrettyPrint.HughesPJ+    Text.PrettyPrint.HughesPJClass+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/prett_7jIfj8VCGFf1WS0tIQ1XSZ+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/prett_7jIfj8VCGFf1WS0tIQ1XSZ+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/pretty-1.1.2.0+hs-libraries: HSpretty-1.1.2.0-7jIfj8VCGFf1WS0tIQ1XSZ+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    deepseq-1.4.1.1-c1376f846fa170f2cc2cb2e57b203339+    ghc-prim-0.4.0.0-7c945cc0c41d3b7b70f3edd125671166+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/pretty-1.1.2.0/pretty.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/pretty-1.1.2.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: hpc+version: 0.6.0.2+id: hpc-0.6.0.2-ac9064885aa8cb08a93314222939ead4+key: hpc_CmUUQl5bURfBueJrdYfNs3+license: BSD3+maintainer: ghc-devs@haskell.org+synopsis: Code Coverage Library for Haskell+description:+    This package provides the code coverage library for Haskell.+    .+    See <http://www.haskell.org/haskellwiki/Haskell_program_coverage> for more+    information.+category: Control+author: Andy Gill+exposed: True+exposed-modules:+    Trace.Hpc.Util Trace.Hpc.Mix Trace.Hpc.Tix Trace.Hpc.Reflect+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/hpc_CmUUQl5bURfBueJrdYfNs3+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/hpc_CmUUQl5bURfBueJrdYfNs3+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/hpc-0.6.0.2+hs-libraries: HShpc-0.6.0.2-CmUUQl5bURfBueJrdYfNs3+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    containers-0.5.6.2-2114032c163425cc264e6e1169dc2f6d+    directory-1.2.2.0-b4959b472d9eee380c6b32291ade29e0+    filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+    time-1.5.0.1-e17a9220d438435579d2914e90774246+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/hpc-0.6.0.2/hpc.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/hpc-0.6.0.2+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: process+version: 1.2.3.0+id: process-1.2.3.0-3b1e9bca6ac38225806ff7bbf3f845b1+key: proce_0hwN3CTKynhHQqQkChnSdH+license: BSD3+maintainer: libraries@haskell.org+synopsis: Process libraries+description:+    This package contains libraries for dealing with system processes.+category: System+exposed: True+exposed-modules:+    System.Cmd System.Process System.Process.Internals+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/proce_0hwN3CTKynhHQqQkChnSdH+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/proce_0hwN3CTKynhHQqQkChnSdH+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/process-1.2.3.0+hs-libraries: HSprocess-1.2.3.0-0hwN3CTKynhHQqQkChnSdH+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/proce_0hwN3CTKynhHQqQkChnSdH/include+includes:+    runProcess.h+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    deepseq-1.4.1.1-c1376f846fa170f2cc2cb2e57b203339+    directory-1.2.2.0-b4959b472d9eee380c6b32291ade29e0+    filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+    unix-2.7.1.0-e5915eb989e568b732bc7286b0d0817f+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/process-1.2.3.0/process.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/process-1.2.3.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: directory+version: 1.2.2.0+id: directory-1.2.2.0-b4959b472d9eee380c6b32291ade29e0+key: direc_3TcTyYedch32o1zTH2MR00+license: BSD3+maintainer: libraries@haskell.org+synopsis: Platform-agnostic library for filesystem operations+description:+    This library provides a basic set of operations for manipulating files and+    directories in a portable way.+category: System+exposed: True+exposed-modules:+    System.Directory+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/direc_3TcTyYedch32o1zTH2MR00+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/direc_3TcTyYedch32o1zTH2MR00+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/directory-1.2.2.0+hs-libraries: HSdirectory-1.2.2.0-3TcTyYedch32o1zTH2MR00+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/direc_3TcTyYedch32o1zTH2MR00/include+includes:+    HsDirectory.h+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+    time-1.5.0.1-e17a9220d438435579d2914e90774246+    unix-2.7.1.0-e5915eb989e568b732bc7286b0d0817f+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/directory-1.2.2.0/directory.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/directory-1.2.2.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: unix+version: 2.7.1.0+id: unix-2.7.1.0-e5915eb989e568b732bc7286b0d0817f+key: unix_G4Yo1pNtYrk8nCq1cx8P9d+license: BSD3+maintainer: libraries@haskell.org+homepage: https://github.com/haskell/unix+synopsis: POSIX functionality+description:+    This package gives you access to the set of operating system+    services standardised by POSIX 1003.1b (or the IEEE Portable+    Operating System Interface for Computing Environments -+    IEEE Std. 1003.1).+    .+    The package is not supported under Windows (except under Cygwin).+category: System+exposed: True+exposed-modules:+    System.Posix System.Posix.ByteString System.Posix.Error+    System.Posix.Resource System.Posix.Time System.Posix.Unistd+    System.Posix.User System.Posix.Signals System.Posix.Signals.Exts+    System.Posix.Semaphore System.Posix.SharedMem+    System.Posix.ByteString.FilePath System.Posix.Directory+    System.Posix.Directory.ByteString System.Posix.DynamicLinker.Module+    System.Posix.DynamicLinker.Module.ByteString+    System.Posix.DynamicLinker.Prim+    System.Posix.DynamicLinker.ByteString System.Posix.DynamicLinker+    System.Posix.Files System.Posix.Files.ByteString System.Posix.IO+    System.Posix.IO.ByteString System.Posix.Env+    System.Posix.Env.ByteString System.Posix.Fcntl System.Posix.Process+    System.Posix.Process.Internals System.Posix.Process.ByteString+    System.Posix.Temp System.Posix.Temp.ByteString+    System.Posix.Terminal System.Posix.Terminal.ByteString+hidden-modules: System.Posix.Directory.Common+                System.Posix.DynamicLinker.Common System.Posix.Files.Common+                System.Posix.IO.Common System.Posix.Process.Common+                System.Posix.Terminal.Common+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/unix_G4Yo1pNtYrk8nCq1cx8P9d+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/unix_G4Yo1pNtYrk8nCq1cx8P9d+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/unix-2.7.1.0+hs-libraries: HSunix-2.7.1.0-G4Yo1pNtYrk8nCq1cx8P9d+extra-libraries:+    rt util dl pthread+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/unix_G4Yo1pNtYrk8nCq1cx8P9d/include+includes:+    HsUnix.h execvpe.h+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    bytestring-0.10.6.0-0909f8f31271f3d75749190bf2ee35db+    time-1.5.0.1-e17a9220d438435579d2914e90774246+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/unix-2.7.1.0/unix.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/unix-2.7.1.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: time+version: 1.5.0.1+id: time-1.5.0.1-e17a9220d438435579d2914e90774246+key: time_Hh2clZW6in4HpYHx5bLtb7+license: BSD3+maintainer: <ashley@semantic.org>+stability: stable+homepage: https://github.com/haskell/time+synopsis: A time library+description:+    A time library+category: System+author: Ashley Yakeley+exposed: True+exposed-modules:+    Data.Time.Calendar Data.Time.Calendar.MonthDay+    Data.Time.Calendar.OrdinalDate Data.Time.Calendar.WeekDate+    Data.Time.Calendar.Julian Data.Time.Calendar.Easter Data.Time.Clock+    Data.Time.Clock.POSIX Data.Time.Clock.TAI Data.Time.LocalTime+    Data.Time.Format Data.Time+hidden-modules: Data.Time.Calendar.Private Data.Time.Calendar.Days+                Data.Time.Calendar.Gregorian Data.Time.Calendar.JulianYearDay+                Data.Time.Clock.Scale Data.Time.Clock.UTC Data.Time.Clock.CTimeval+                Data.Time.Clock.UTCDiff Data.Time.LocalTime.TimeZone+                Data.Time.LocalTime.TimeOfDay Data.Time.LocalTime.LocalTime+                Data.Time.Format.Parse Data.Time.Format.Locale+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/time_Hh2clZW6in4HpYHx5bLtb7+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/time_Hh2clZW6in4HpYHx5bLtb7+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/time-1.5.0.1+hs-libraries: HStime-1.5.0.1-Hh2clZW6in4HpYHx5bLtb7+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/time_Hh2clZW6in4HpYHx5bLtb7/include+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    deepseq-1.4.1.1-c1376f846fa170f2cc2cb2e57b203339+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/time-1.5.0.1/time.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/time-1.5.0.1+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: containers+version: 0.5.6.2+id: containers-0.5.6.2-2114032c163425cc264e6e1169dc2f6d+key: conta_47ajk3tbda43DFWyeF3oHQ+license: BSD3+maintainer: fox@ucw.cz+synopsis: Assorted concrete container types+description:+    This package contains efficient general-purpose implementations+    of various basic immutable container types.  The declared cost of+    each operation is either worst-case or amortized, but remains+    valid even if structures are shared.+category: Data Structures+exposed: True+exposed-modules:+    Data.IntMap Data.IntMap.Lazy Data.IntMap.Strict Data.IntSet+    Data.Map Data.Map.Lazy Data.Map.Strict Data.Set Data.Graph+    Data.Sequence Data.Tree+hidden-modules: Data.IntMap.Base Data.IntSet.Base Data.Map.Base+                Data.Set.Base Data.Utils.BitUtil Data.Utils.StrictFold+                Data.Utils.StrictPair+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/conta_47ajk3tbda43DFWyeF3oHQ+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/conta_47ajk3tbda43DFWyeF3oHQ+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/containers-0.5.6.2+hs-libraries: HScontainers-0.5.6.2-47ajk3tbda43DFWyeF3oHQ+depends:+    array-0.5.1.0-e29cdbe82692341ebb7ce6e2798294f9+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    deepseq-1.4.1.1-c1376f846fa170f2cc2cb2e57b203339+    ghc-prim-0.4.0.0-7c945cc0c41d3b7b70f3edd125671166+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/containers-0.5.6.2/containers.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/containers-0.5.6.2+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: bytestring+version: 0.10.6.0+id: bytestring-0.10.6.0-0909f8f31271f3d75749190bf2ee35db+key: bytes_6vj5EoliHgNHISHCVCb069+license: BSD3+copyright: Copyright (c) Don Stewart          2005-2009,+           (c) Duncan Coutts        2006-2015,+           (c) David Roundy         2003-2005,+           (c) Jasper Van der Jeugt 2010,+           (c) Simon Meier          2010-2013.+maintainer: Duncan Coutts <duncan@community.haskell.org>+homepage: https://github.com/haskell/bytestring+synopsis: Fast, compact, strict and lazy byte strings with a list interface+description:+    An efficient compact, immutable byte string type (both strict and lazy)+    suitable for binary or 8-bit character data.+    .+    The 'ByteString' type represents sequences of bytes or 8-bit characters.+    It is suitable for high performance use, both in terms of large data+    quantities, or high speed requirements. The 'ByteString' functions follow+    the same style as Haskell\'s ordinary lists, so it is easy to convert code+    from using 'String' to 'ByteString'.+    .+    Two 'ByteString' variants are provided:+    .+    * Strict 'ByteString's keep the string as a single large array. This+    makes them convenient for passing data between C and Haskell.+    .+    * Lazy 'ByteString's use a lazy list of strict chunks which makes it+    suitable for I\/O streaming tasks.+    .+    The @Char8@ modules provide a character-based view of the same+    underlying 'ByteString' types. This makes it convenient to handle mixed+    binary and 8-bit character content (which is common in many file formats+    and network protocols).+    .+    The 'Builder' module provides an efficient way to build up 'ByteString's+    in an ad-hoc way by repeated concatenation. This is ideal for fast+    serialisation or pretty printing.+    .+    There is also a 'ShortByteString' type which has a lower memory overhead+    and can can be converted to or from a 'ByteString', but supports very few+    other operations. It is suitable for keeping many short strings in memory.+    .+    'ByteString's are not designed for Unicode. For Unicode strings you should+    use the 'Text' type from the @text@ package.+    .+    These modules are intended to be imported qualified, to avoid name clashes+    with "Prelude" functions, e.g.+    .+    > import qualified Data.ByteString as BS+category: Data+author: Don Stewart,+        Duncan Coutts+exposed: True+exposed-modules:+    Data.ByteString Data.ByteString.Char8 Data.ByteString.Unsafe+    Data.ByteString.Internal Data.ByteString.Lazy+    Data.ByteString.Lazy.Char8 Data.ByteString.Lazy.Internal+    Data.ByteString.Short Data.ByteString.Short.Internal+    Data.ByteString.Builder Data.ByteString.Builder.Extra+    Data.ByteString.Builder.Prim Data.ByteString.Builder.Internal+    Data.ByteString.Builder.Prim.Internal Data.ByteString.Lazy.Builder+    Data.ByteString.Lazy.Builder.Extras+    Data.ByteString.Lazy.Builder.ASCII+hidden-modules: Data.ByteString.Builder.ASCII+                Data.ByteString.Builder.Prim.Binary+                Data.ByteString.Builder.Prim.ASCII+                Data.ByteString.Builder.Prim.Internal.Floating+                Data.ByteString.Builder.Prim.Internal.UncheckedShifts+                Data.ByteString.Builder.Prim.Internal.Base16+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/bytes_6vj5EoliHgNHISHCVCb069+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/bytes_6vj5EoliHgNHISHCVCb069+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/bytestring-0.10.6.0+hs-libraries: HSbytestring-0.10.6.0-6vj5EoliHgNHISHCVCb069+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/bytes_6vj5EoliHgNHISHCVCb069/include+includes:+    fpstring.h+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+    deepseq-1.4.1.1-c1376f846fa170f2cc2cb2e57b203339+    ghc-prim-0.4.0.0-7c945cc0c41d3b7b70f3edd125671166+    integer-gmp-1.0.0.0-3c947e5fb6dca14804d9b2793c521b67+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/bytestring-0.10.6.0/bytestring.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/bytestring-0.10.6.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: deepseq+version: 1.4.1.1+id: deepseq-1.4.1.1-c1376f846fa170f2cc2cb2e57b203339+key: deeps_FpR4obOZALU1lutWnrBldi+license: BSD3+maintainer: libraries@haskell.org+synopsis: Deep evaluation of data structures+description:+    This package provides methods for fully evaluating data structures+    (\"deep evaluation\"). Deep evaluation is often used for adding+    strictness to a program, e.g. in order to force pending exceptions,+    remove space leaks, or force lazy I/O to happen. It is also useful+    in parallel programs, to ensure pending work does not migrate to the+    wrong thread.+    .+    The primary use of this package is via the 'deepseq' function, a+    \"deep\" version of 'seq'. It is implemented on top of an 'NFData'+    typeclass (\"Normal Form Data\", data structures with no unevaluated+    components) which defines strategies for fully evaluating different+    data types.+category: Control+exposed: True+exposed-modules:+    Control.DeepSeq+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/deeps_FpR4obOZALU1lutWnrBldi+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/deeps_FpR4obOZALU1lutWnrBldi+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/deepseq-1.4.1.1+hs-libraries: HSdeepseq-1.4.1.1-FpR4obOZALU1lutWnrBldi+depends:+    array-0.5.1.0-e29cdbe82692341ebb7ce6e2798294f9+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/deepseq-1.4.1.1/deepseq.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/deepseq-1.4.1.1+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: array+version: 0.5.1.0+id: array-0.5.1.0-e29cdbe82692341ebb7ce6e2798294f9+key: array_FaHmcBFfuRM8kmZLEY8D5S+license: BSD3+maintainer: libraries@haskell.org+synopsis: Mutable and immutable arrays+description:+    In addition to providing the "Data.Array" module+    <http://www.haskell.org/onlinereport/haskell2010/haskellch14.html as specified in the Haskell 2010 Language Report>,+    this package also defines the classes 'IArray' of+    immutable arrays and 'MArray' of arrays mutable within appropriate+    monads, as well as some instances of these classes.+category: Data Structures+exposed: True+exposed-modules:+    Data.Array Data.Array.Base Data.Array.IArray Data.Array.IO+    Data.Array.IO.Safe Data.Array.IO.Internals Data.Array.MArray+    Data.Array.MArray.Safe Data.Array.ST Data.Array.ST.Safe+    Data.Array.Storable Data.Array.Storable.Safe+    Data.Array.Storable.Internals Data.Array.Unboxed Data.Array.Unsafe+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/array_FaHmcBFfuRM8kmZLEY8D5S+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/array_FaHmcBFfuRM8kmZLEY8D5S+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/array-0.5.1.0+hs-libraries: HSarray-0.5.1.0-FaHmcBFfuRM8kmZLEY8D5S+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/array-0.5.1.0/array.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/array-0.5.1.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: filepath+version: 1.4.0.0+id: filepath-1.4.0.0-40d643aa87258c186441a1f8f3e13ca6+key: filep_5HhyRonfEZoDO205Wm9E4h+license: BSD3+copyright: Neil Mitchell 2005-2015+maintainer: Neil Mitchell <ndmitchell@gmail.com>+homepage: https://github.com/haskell/filepath#readme+synopsis: Library for manipulating FilePaths in a cross platform way.+description:+    This package provides functionality for manipulating @FilePath@ values, and is shipped with both <https://www.haskell.org/ghc/ GHC> and the <https://www.haskell.org/platform/ Haskell Platform>. It provides three modules:+    .+    * "System.FilePath.Posix" manipulates POSIX\/Linux style @FilePath@ values (with @\/@ as the path separator).+    .+    * "System.FilePath.Windows" manipulates Windows style @FilePath@ values (with either @\\@ or @\/@ as the path separator, and deals with drives).+    .+    * "System.FilePath" is an alias for the module appropriate to your platform.+    .+    All three modules provide the same API, and the same documentation (calling out differences in the different variants).+category: System+author: Neil Mitchell <ndmitchell@gmail.com>+exposed: True+exposed-modules:+    System.FilePath System.FilePath.Posix System.FilePath.Windows+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/filep_5HhyRonfEZoDO205Wm9E4h+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/filep_5HhyRonfEZoDO205Wm9E4h+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/filepath-1.4.0.0+hs-libraries: HSfilepath-1.4.0.0-5HhyRonfEZoDO205Wm9E4h+depends:+    base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/filepath-1.4.0.0/filepath.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/filepath-1.4.0.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: base+version: 4.8.0.0+id: base-4.8.0.0-1b689eb8d72c4d4cc88f445839c1f01a+key: base_I5BErHzyOm07EBNpKBEeUv+license: BSD3+maintainer: libraries@haskell.org+synopsis: Basic libraries+description:+    This package contains the "Prelude" and its support libraries,+    and a large collection of useful libraries ranging from data+    structures to parsing combinators and debugging utilities.+category: Prelude+exposed: True+exposed-modules:+    Control.Applicative Control.Arrow Control.Category+    Control.Concurrent Control.Concurrent.Chan Control.Concurrent.MVar+    Control.Concurrent.QSem Control.Concurrent.QSemN Control.Exception+    Control.Exception.Base Control.Monad Control.Monad.Fix+    Control.Monad.Instances Control.Monad.ST Control.Monad.ST.Lazy+    Control.Monad.ST.Lazy.Safe Control.Monad.ST.Lazy.Unsafe+    Control.Monad.ST.Safe Control.Monad.ST.Strict+    Control.Monad.ST.Unsafe Control.Monad.Zip Data.Bifunctor Data.Bits+    Data.Bool Data.Char Data.Coerce Data.Complex Data.Data Data.Dynamic+    Data.Either Data.Eq Data.Fixed Data.Foldable Data.Function+    Data.Functor Data.Functor.Identity Data.IORef Data.Int Data.Ix+    Data.List Data.Maybe Data.Monoid Data.Ord Data.Proxy Data.Ratio+    Data.STRef Data.STRef.Lazy Data.STRef.Strict Data.String+    Data.Traversable Data.Tuple Data.Type.Bool Data.Type.Coercion+    Data.Type.Equality Data.Typeable Data.Typeable.Internal Data.Unique+    Data.Version Data.Void Data.Word Debug.Trace Foreign Foreign.C+    Foreign.C.Error Foreign.C.String Foreign.C.Types Foreign.Concurrent+    Foreign.ForeignPtr Foreign.ForeignPtr.Safe+    Foreign.ForeignPtr.Unsafe Foreign.Marshal Foreign.Marshal.Alloc+    Foreign.Marshal.Array Foreign.Marshal.Error Foreign.Marshal.Pool+    Foreign.Marshal.Safe Foreign.Marshal.Unsafe Foreign.Marshal.Utils+    Foreign.Ptr Foreign.Safe Foreign.StablePtr Foreign.Storable GHC.Arr+    GHC.Base GHC.Char GHC.Conc GHC.Conc.IO GHC.Conc.Signal+    GHC.Conc.Sync GHC.ConsoleHandler GHC.Constants GHC.Desugar GHC.Enum+    GHC.Environment GHC.Err GHC.Exception GHC.Exts GHC.Fingerprint+    GHC.Fingerprint.Type GHC.Float GHC.Float.ConversionUtils+    GHC.Float.RealFracMethods GHC.Foreign GHC.ForeignPtr GHC.GHCi+    GHC.Generics GHC.IO GHC.IO.Buffer GHC.IO.BufferedIO GHC.IO.Device+    GHC.IO.Encoding GHC.IO.Encoding.CodePage GHC.IO.Encoding.Failure+    GHC.IO.Encoding.Iconv GHC.IO.Encoding.Latin1 GHC.IO.Encoding.Types+    GHC.IO.Encoding.UTF16 GHC.IO.Encoding.UTF32 GHC.IO.Encoding.UTF8+    GHC.IO.Exception GHC.IO.FD GHC.IO.Handle GHC.IO.Handle.FD+    GHC.IO.Handle.Internals GHC.IO.Handle.Text GHC.IO.Handle.Types+    GHC.IO.IOMode GHC.IOArray GHC.IORef GHC.IP GHC.Int GHC.List+    GHC.MVar GHC.Natural GHC.Num GHC.OldList GHC.PArr GHC.Pack+    GHC.Profiling GHC.Ptr GHC.Read GHC.Real GHC.RTS.Flags GHC.ST+    GHC.StaticPtr GHC.STRef GHC.Show GHC.Stable GHC.Stack GHC.Stats+    GHC.Storable GHC.TopHandler GHC.TypeLits GHC.Unicode GHC.Weak+    GHC.Word Numeric Numeric.Natural Prelude System.CPUTime+    System.Console.GetOpt System.Environment System.Exit System.IO+    System.IO.Error System.IO.Unsafe System.Info System.Mem+    System.Mem.StableName System.Mem.Weak System.Posix.Internals+    System.Posix.Types System.Timeout Text.ParserCombinators.ReadP+    Text.ParserCombinators.ReadPrec Text.Printf Text.Read Text.Read.Lex+    Text.Show Text.Show.Functions Unsafe.Coerce GHC.Event+hidden-modules: Control.Monad.ST.Imp Control.Monad.ST.Lazy.Imp+                Data.OldList Foreign.ForeignPtr.Imp+                System.Environment.ExecutablePath GHC.Event.Arr GHC.Event.Array+                GHC.Event.Clock GHC.Event.Control GHC.Event.EPoll+                GHC.Event.IntTable GHC.Event.Internal GHC.Event.KQueue+                GHC.Event.Manager GHC.Event.PSQ GHC.Event.Poll GHC.Event.Thread+                GHC.Event.TimerManager GHC.Event.Unique+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/base_I5BErHzyOm07EBNpKBEeUv+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/base_I5BErHzyOm07EBNpKBEeUv+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/base-4.8.0.0+hs-libraries: HSbase-4.8.0.0-I5BErHzyOm07EBNpKBEeUv+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/base_I5BErHzyOm07EBNpKBEeUv/include+includes:+    HsBase.h+depends:+    builtin_rts ghc-prim-0.4.0.0-7c945cc0c41d3b7b70f3edd125671166+    integer-gmp-1.0.0.0-3c947e5fb6dca14804d9b2793c521b67+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/base-4.8.0.0/base.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/base-4.8.0.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: integer-gmp+version: 1.0.0.0+id: integer-gmp-1.0.0.0-3c947e5fb6dca14804d9b2793c521b67+key: integ_2aU3IZNMF9a7mQ0OzsZ0dS+license: BSD3+maintainer: hvr@gnu.org+synopsis: Integer library based on GMP+category: Numeric, Algebra+author: Herbert Valerio Riedel+exposed: True+exposed-modules:+    GHC.Integer GHC.Integer.Logarithms GHC.Integer.Logarithms.Internals+    GHC.Integer.GMP.Internals+hidden-modules: GHC.Integer.Type+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/integ_2aU3IZNMF9a7mQ0OzsZ0dS+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/integ_2aU3IZNMF9a7mQ0OzsZ0dS+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/integer-gmp-1.0.0.0+hs-libraries: HSinteger-gmp-1.0.0.0-2aU3IZNMF9a7mQ0OzsZ0dS+extra-libraries:+    gmp+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/integ_2aU3IZNMF9a7mQ0OzsZ0dS/include+depends:+    ghc-prim-0.4.0.0-7c945cc0c41d3b7b70f3edd125671166+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/integer-gmp-1.0.0.0/integer-gmp.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/integer-gmp-1.0.0.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: ghc-prim+version: 0.4.0.0+id: ghc-prim-0.4.0.0-7c945cc0c41d3b7b70f3edd125671166+key: ghcpr_8TmvWUcS1U1IKHT0levwg3+license: BSD3+maintainer: libraries@haskell.org+synopsis: GHC primitives+description:+    GHC primitives.+category: GHC+exposed: True+exposed-modules:+    GHC.CString GHC.Classes GHC.Debug GHC.IntWord64 GHC.Magic+    GHC.PrimopWrappers GHC.Tuple GHC.Types GHC.Prim+trusted: False+import-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/ghcpr_8TmvWUcS1U1IKHT0levwg3+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/ghcpr_8TmvWUcS1U1IKHT0levwg3+data-dir: /opt/ghc/7.10.1/share/x86_64-linux-ghc-7.10.1/ghc-prim-0.4.0.0+hs-libraries: HSghc-prim-0.4.0.0-8TmvWUcS1U1IKHT0levwg3+depends:+    builtin_rts+haddock-interfaces: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/ghc-prim-0.4.0.0/ghc-prim.haddock+haddock-html: /opt/ghc/7.10.1/share/doc/ghc/html/libraries/ghc-prim-0.4.0.0+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+---+name: rts+version: 1.0+id: builtin_rts+key: rts+license: BSD3+maintainer: glasgow-haskell-users@haskell.org+exposed: True+trusted: False+library-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/rts+hs-libraries: HSrts Cffi+extra-libraries:+    m rt dl+include-dirs: /opt/ghc/7.10.1/lib/ghc-7.10.1/include+includes:+    Stg.h+ld-options: "-Wl,-u,ghczmprim_GHCziTypes_Izh_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Czh_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Fzh_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Dzh_static_info"+            "-Wl,-u,base_GHCziPtr_Ptr_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Wzh_static_info"+            "-Wl,-u,base_GHCziInt_I8zh_static_info"+            "-Wl,-u,base_GHCziInt_I16zh_static_info"+            "-Wl,-u,base_GHCziInt_I32zh_static_info"+            "-Wl,-u,base_GHCziInt_I64zh_static_info"+            "-Wl,-u,base_GHCziWord_W8zh_static_info"+            "-Wl,-u,base_GHCziWord_W16zh_static_info"+            "-Wl,-u,base_GHCziWord_W32zh_static_info"+            "-Wl,-u,base_GHCziWord_W64zh_static_info"+            "-Wl,-u,base_GHCziStable_StablePtr_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Izh_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Czh_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Fzh_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Dzh_con_info"+            "-Wl,-u,base_GHCziPtr_Ptr_con_info"+            "-Wl,-u,base_GHCziPtr_FunPtr_con_info"+            "-Wl,-u,base_GHCziStable_StablePtr_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_False_closure"+            "-Wl,-u,ghczmprim_GHCziTypes_True_closure"+            "-Wl,-u,base_GHCziPack_unpackCString_closure"+            "-Wl,-u,base_GHCziIOziException_stackOverflow_closure"+            "-Wl,-u,base_GHCziIOziException_heapOverflow_closure"+            "-Wl,-u,base_ControlziExceptionziBase_nonTermination_closure"+            "-Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnMVar_closure"+            "-Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnSTM_closure"+            "-Wl,-u,base_GHCziIOziException_allocationLimitExceeded_closure"+            "-Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure"+            "-Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure"+            "-Wl,-u,base_GHCziWeak_runFinalizzerBatch_closure"+            "-Wl,-u,base_GHCziTopHandler_flushStdHandles_closure"+            "-Wl,-u,base_GHCziTopHandler_runIO_closure"+            "-Wl,-u,base_GHCziTopHandler_runNonIO_closure"+            "-Wl,-u,base_GHCziConcziIO_ensureIOManagerIsRunning_closure"+            "-Wl,-u,base_GHCziConcziIO_ioManagerCapabilitiesChanged_closure"+            "-Wl,-u,base_GHCziConcziSync_runSparks_closure"+            "-Wl,-u,base_GHCziConcziSignal_runHandlersPtr_closure"+pkgroot: "/opt/ghc/7.10.1/lib/ghc-7.10.1"+
+ test/package-dump/ghc-7.8.4-osx.txt view
@@ -0,0 +1,67 @@+name: hmatrix+version: 0.16.1.5+id: hmatrix-0.16.1.5-12d5d21f26aa98774cdd8edbc343fbfe+license: BSD3+copyright:+maintainer: Alberto Ruiz+stability: provisional+homepage: https://github.com/albertoruiz/hmatrix+package-url:+synopsis: Numeric Linear Algebra+description: Linear algebra based on BLAS and LAPACK.+             .+             The package is organized as follows:+             .+             ["Numeric.LinearAlgebra.HMatrix"] Starting point and recommended import module for most applications.+             .+             ["Numeric.LinearAlgebra.Static"] Experimental alternative interface.+             .+             ["Numeric.LinearAlgebra.Devel"] Tools for extending the library.+             .+             (Other modules are exposed with hidden documentation for backwards compatibility.)+             .+             Code examples: <http://dis.um.es/~alberto/hmatrix/hmatrix.html>+category: Math+author: Alberto Ruiz+exposed: True+exposed-modules: Data.Packed Data.Packed.Vector Data.Packed.Matrix+                 Data.Packed.Foreign Data.Packed.ST Data.Packed.Development+                 Numeric.LinearAlgebra Numeric.LinearAlgebra.LAPACK+                 Numeric.LinearAlgebra.Algorithms Numeric.Container+                 Numeric.LinearAlgebra.Util Numeric.LinearAlgebra.Devel+                 Numeric.LinearAlgebra.Data Numeric.LinearAlgebra.HMatrix+                 Numeric.LinearAlgebra.Static+hidden-modules: Data.Packed.Internal Data.Packed.Internal.Common+                Data.Packed.Internal.Signatures Data.Packed.Internal.Vector+                Data.Packed.Internal.Matrix Data.Packed.IO Numeric.Chain+                Numeric.Vectorized Numeric.Vector Numeric.Matrix+                Data.Packed.Internal.Numeric Data.Packed.Numeric+                Numeric.LinearAlgebra.Util.Convolution+                Numeric.LinearAlgebra.Util.CG Numeric.LinearAlgebra.Random+                Numeric.Conversion Numeric.Sparse+                Numeric.LinearAlgebra.Static.Internal+trusted: False+import-dirs: /Users/alexbiehl/.stack/snapshots/x86_64-osx/lts-2.13/7.8.4/lib/x86_64-osx-ghc-7.8.4/hmatrix-0.16.1.5+library-dirs: /Users/alexbiehl/.stack/snapshots/x86_64-osx/lts-2.13/7.8.4/lib/x86_64-osx-ghc-7.8.4/hmatrix-0.16.1.5+              /opt/local/lib/ /usr/local/lib/ "C:/Program Files/Example/"+hs-libraries: HShmatrix-0.16.1.5+extra-libraries: blas lapack+extra-ghci-libraries:+include-dirs: /opt/local/include/ /usr/local/include/+includes:+depends: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-918c7ac27f65a87103264a9f51652d63+         binary-0.7.1.0-108d06eea2ef05e517f9c1facf10f63c+         bytestring-0.10.4.0-78bc8f2c724c765c78c004a84acf6cc3+         deepseq-1.3.0.2-0ddc77716bd2515426e1ba39f6788a4f+         random-1.1-822c19b7507b6ac1aaa4c66731e775ae+         split-0.2.2-34cfb851cc3784e22bfae7a7bddda9c5+         storable-complex-0.2.2-e962c368d58acc1f5b41d41edc93da72+         vector-0.10.12.3-f4222db607fd5fdd7545d3e82419b307+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks: Accelerate+haddock-interfaces: /Users/alexbiehl/.stack/snapshots/x86_64-osx/lts-2.13/7.8.4/doc/html/hmatrix.haddock+haddock-html: /Users/alexbiehl/.stack/snapshots/x86_64-osx/lts-2.13/7.8.4/doc/html
+ test/package-dump/ghc-7.8.txt view
@@ -0,0 +1,1529 @@+name: haskell2010+version: 1.1.2.0+id: haskell2010-1.1.2.0-05c8dd51009e08c6371c82972d40f55a+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage: http://www.haskell.org/onlinereport/haskell2010/+package-url:+synopsis: Compatibility with Haskell 2010+description: This package provides exactly the library modules defined by+             the <http://www.haskell.org/onlinereport/haskell2010/ Haskell 2010 standard>.+category: Haskell2010, Prelude+author:+exposed: False+exposed-modules: Prelude Control.Monad Data.Array Data.Bits+                 Data.Char Data.Complex Data.Int Data.Ix Data.List Data.Maybe+                 Data.Ratio Data.Word Foreign Foreign.C Foreign.C.Error+                 Foreign.C.String Foreign.C.Types Foreign.ForeignPtr Foreign.Marshal+                 Foreign.Marshal.Alloc Foreign.Marshal.Array Foreign.Marshal.Error+                 Foreign.Marshal.Utils Foreign.Ptr Foreign.StablePtr+                 Foreign.Storable Numeric System.Environment System.Exit System.IO+                 System.IO.Error+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/haskell2010-1.1.2.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/haskell2010-1.1.2.0+hs-libraries: HShaskell2010-1.1.2.0+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         ghc-prim-0.3.1.0-a24f9c14c632d75b683d0f93283aea37+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskell2010-1.1.2.0/haskell2010.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskell2010-1.1.2.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: haskell98+version: 2.0.0.3+id: haskell98-2.0.0.3-045e8778b656db76e2c729405eee707b+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage: http://www.haskell.org/definition/+package-url:+synopsis: Compatibility with Haskell 98+description: This package provides compatibility with the modules of Haskell+             98 and the FFI addendum, by means of wrappers around modules from+             the base package (which in many cases have additional features).+             However "Prelude", "Numeric" and "Foreign" are provided directly by+             the @base@ package.+category: Haskell98, Prelude+author:+exposed: False+exposed-modules: Prelude Array CPUTime Char Complex Directory IO Ix+                 List Locale Maybe Monad Numeric Random Ratio System Time Bits+                 CError CForeign CString CTypes ForeignPtr Int MarshalAlloc+                 MarshalArray MarshalError MarshalUtils Ptr StablePtr Storable Word+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/haskell98-2.0.0.3+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/haskell98-2.0.0.3+hs-libraries: HShaskell98-2.0.0.3+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         directory-1.2.1.0-07cd1f59e3c6cac5e3e180019c59a115+         old-locale-1.0.0.6-50b0125c49f76af85dc7aa22975cdc34+         old-time-1.1.0.2-e3f776e97c1a6ff1770b04943a7ef7c6+         process-1.2.0.0-06c3215a79834ce4886ae686a0f81122+         time-1.4.2-9b3076800c33f8382c38628f35717951+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskell98-2.0.0.3/haskell98.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskell98-2.0.0.3+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: old-time+version: 1.1.0.2+id: old-time-1.1.0.2-e3f776e97c1a6ff1770b04943a7ef7c6+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Time library+description: This package provides the old time library.+             .+             For new projects, the newer+             <http://hackage.haskell.org/package/time time library>+             is recommended.+category: System+author:+exposed: True+exposed-modules: System.Time+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/old-time-1.1.0.2+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/old-time-1.1.0.2+hs-libraries: HSold-time-1.1.0.2+extra-libraries:+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/old-time-1.1.0.2/include+includes: HsTime.h+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         old-locale-1.0.0.6-50b0125c49f76af85dc7aa22975cdc34+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/old-time-1.1.0.2/old-time.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/old-time-1.1.0.2+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: ghc+version: 7.8.4+id: ghc-7.8.4-6c4818bc66adb23509058069f781d99a+license: BSD3+copyright:+maintainer: glasgow-haskell-users@haskell.org+stability:+homepage: http://www.haskell.org/ghc/+package-url:+synopsis: The GHC API+description: GHC's functionality can be useful for more things than just+             compiling Haskell programs. Important use cases are programs+             that analyse (and perhaps transform) Haskell code. Others+             include loading Haskell code dynamically in a GHCi-like manner.+             For this reason, a lot of GHC's functionality is made available+             through this package.+category: Development+author: The GHC Team+exposed: False+exposed-modules: Avail BasicTypes ConLike DataCon PatSyn Demand+                 Exception GhcMonad Hooks Id IdInfo Literal Llvm Llvm.AbsSyn+                 Llvm.MetaData Llvm.PpLlvm Llvm.Types LlvmCodeGen LlvmCodeGen.Base+                 LlvmCodeGen.CodeGen LlvmCodeGen.Data LlvmCodeGen.Ppr+                 LlvmCodeGen.Regs LlvmMangler MkId Module Name NameEnv NameSet+                 OccName RdrName SrcLoc UniqSupply Unique Var VarEnv VarSet BlockId+                 CLabel Cmm CmmBuildInfoTables CmmPipeline CmmCallConv+                 CmmCommonBlockElim CmmContFlowOpt CmmExpr CmmInfo CmmLex CmmLint+                 CmmLive CmmMachOp CmmNode CmmOpt CmmParse CmmProcPoint+                 CmmRewriteAssignments CmmSink CmmType CmmUtils CmmLayoutStack+                 MkGraph PprBase PprC PprCmm PprCmmDecl PprCmmExpr Bitmap+                 CodeGen.Platform CodeGen.Platform.ARM CodeGen.Platform.NoRegs+                 CodeGen.Platform.PPC CodeGen.Platform.PPC_Darwin+                 CodeGen.Platform.SPARC CodeGen.Platform.X86 CodeGen.Platform.X86_64+                 CgUtils StgCmm StgCmmBind StgCmmClosure StgCmmCon StgCmmEnv+                 StgCmmExpr StgCmmForeign StgCmmHeap StgCmmHpc StgCmmArgRep+                 StgCmmLayout StgCmmMonad StgCmmPrim StgCmmProf StgCmmTicky+                 StgCmmUtils StgCmmExtCode SMRep CoreArity CoreFVs CoreLint CorePrep+                 CoreSubst CoreSyn TrieMap CoreTidy CoreUnfold CoreUtils+                 ExternalCore MkCore MkExternalCore PprCore PprExternalCore Check+                 Coverage Desugar DsArrows DsBinds DsCCall DsExpr DsForeign DsGRHSs+                 DsListComp DsMonad DsUtils Match MatchCon MatchLit HsBinds HsDecls+                 HsDoc HsExpr HsImpExp HsLit HsPat HsSyn HsTypes HsUtils BinIface+                 BuildTyCl IfaceEnv IfaceSyn IfaceType LoadIface MkIface TcIface+                 FlagChecker Annotations BreakArray CmdLineParser CodeOutput Config+                 Constants DriverMkDepend DriverPhases PipelineMonad DriverPipeline+                 DynFlags ErrUtils Finder GHC GhcMake GhcPlugins DynamicLoading+                 HeaderInfo HscMain HscStats HscTypes InteractiveEval+                 InteractiveEvalTypes PackageConfig Packages PlatformConstants+                 PprTyThing StaticFlags SysTools TidyPgm Ctype HaddockUtils LexCore+                 Lexer OptCoercion Parser ParserCore ParserCoreUtils RdrHsSyn+                 ForeignCall PrelInfo PrelNames PrelRules PrimOp TysPrim TysWiredIn+                 CostCentre ProfInit SCCfinal RnBinds RnEnv RnExpr RnHsDoc RnNames+                 RnPat RnSource RnSplice RnTypes CoreMonad CSE FloatIn FloatOut+                 LiberateCase OccurAnal SAT SetLevels SimplCore SimplEnv SimplMonad+                 SimplUtils Simplify SimplStg StgStats UnariseStg Rules SpecConstr+                 Specialise CoreToStg StgLint StgSyn DmdAnal WorkWrap WwLib FamInst+                 Inst TcAnnotations TcArrows TcBinds TcClassDcl TcDefaults TcDeriv+                 TcEnv TcExpr TcForeign TcGenDeriv TcGenGenerics TcHsSyn TcHsType+                 TcInstDcls TcMType TcValidity TcMatches TcPat TcPatSyn TcRnDriver+                 TcRnMonad TcRnTypes TcRules TcSimplify TcErrors TcTyClsDecls+                 TcTyDecls TcType TcEvidence TcUnify TcInteract TcCanonical TcSMonad+                 TcTypeNats TcSplice Class Coercion FamInstEnv FunDeps InstEnv TyCon+                 CoAxiom Kind Type TypeRep Unify Bag Binary BooleanFormula BufWrite+                 Digraph Encoding FastBool FastFunctions FastMutInt FastString+                 FastTypes Fingerprint FiniteMap GraphBase GraphColor GraphOps+                 GraphPpr IOEnv ListSetOps Maybes MonadUtils OrdList Outputable Pair+                 Panic Pretty Serialized State Stream StringBuffer UniqFM UniqSet+                 Util ExtsCompat46 Vectorise.Builtins.Base+                 Vectorise.Builtins.Initialise Vectorise.Builtins+                 Vectorise.Monad.Base Vectorise.Monad.Naming Vectorise.Monad.Local+                 Vectorise.Monad.Global Vectorise.Monad.InstEnv Vectorise.Monad+                 Vectorise.Utils.Base Vectorise.Utils.Closure+                 Vectorise.Utils.Hoisting Vectorise.Utils.PADict+                 Vectorise.Utils.Poly Vectorise.Utils Vectorise.Generic.Description+                 Vectorise.Generic.PAMethods Vectorise.Generic.PADict+                 Vectorise.Generic.PData Vectorise.Type.Env Vectorise.Type.Type+                 Vectorise.Type.TyConDecl Vectorise.Type.Classify Vectorise.Convert+                 Vectorise.Vect Vectorise.Var Vectorise.Env Vectorise.Exp Vectorise+                 Hoopl.Dataflow Hoopl AsmCodeGen TargetReg NCGMonad Instruction Size+                 Reg RegClass PIC Platform CPrim X86.Regs X86.RegInfo X86.Instr+                 X86.Cond X86.Ppr X86.CodeGen PPC.Regs PPC.RegInfo PPC.Instr+                 PPC.Cond PPC.Ppr PPC.CodeGen SPARC.Base SPARC.Regs SPARC.Imm+                 SPARC.AddrMode SPARC.Cond SPARC.Instr SPARC.Stack+                 SPARC.ShortcutJump SPARC.Ppr SPARC.CodeGen SPARC.CodeGen.Amode+                 SPARC.CodeGen.Base SPARC.CodeGen.CondCode SPARC.CodeGen.Gen32+                 SPARC.CodeGen.Gen64 SPARC.CodeGen.Sanity SPARC.CodeGen.Expand+                 RegAlloc.Liveness RegAlloc.Graph.Main RegAlloc.Graph.Stats+                 RegAlloc.Graph.ArchBase RegAlloc.Graph.ArchX86+                 RegAlloc.Graph.Coalesce RegAlloc.Graph.Spill+                 RegAlloc.Graph.SpillClean RegAlloc.Graph.SpillCost+                 RegAlloc.Graph.TrivColorable RegAlloc.Linear.Main+                 RegAlloc.Linear.JoinToTargets RegAlloc.Linear.State+                 RegAlloc.Linear.Stats RegAlloc.Linear.FreeRegs+                 RegAlloc.Linear.StackMap RegAlloc.Linear.Base+                 RegAlloc.Linear.X86.FreeRegs RegAlloc.Linear.X86_64.FreeRegs+                 RegAlloc.Linear.PPC.FreeRegs RegAlloc.Linear.SPARC.FreeRegs DsMeta+                 Convert ByteCodeAsm ByteCodeGen ByteCodeInstr ByteCodeItbls+                 ByteCodeLink Debugger LibFFI Linker ObjLink RtClosureInspect+                 DebuggerUtils+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/ghc-7.8.4+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/ghc-7.8.4+hs-libraries: HSghc-7.8.4+extra-libraries:+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/ghc-7.8.4/include+includes:+depends: Cabal-1.18.1.5-6478013104bde01737bfd67d34bbee0a+         array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         bin-package-db-0.0.0.0-0f3da03684207f2dc4dce793df1db62e+         bytestring-0.10.4.0-d6f1d17d717e8652498cab8269a0acd5+         containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+         directory-1.2.1.0-07cd1f59e3c6cac5e3e180019c59a115+         filepath-1.3.0.2-25a474a9272ae6260626ce0d70ad1cab+         hoopl-3.10.0.1-267659e4b5b51c3d2e02f2a6d6f46936+         hpc-0.6.0.1-cca17f12dab542e09c423a74a4590c5d+         process-1.2.0.0-06c3215a79834ce4886ae686a0f81122+         template-haskell-2.9.0.0-6d27c2b362b15abb1822f2f34b9ae7f9+         time-1.4.2-9b3076800c33f8382c38628f35717951+         transformers-0.3.0.0-6458c21515cab7c1cf21e53141557a1c+         unix-2.7.0.1-f8658ba9ec1c4fba8a371a8e0f42ec6c+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/ghc-7.8.4/ghc.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/ghc-7.8.4+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: haskeline+version: 0.7.1.2+id: haskeline-0.7.1.2-2dd2f2fb537352f5367ae77fe47ab211+license: BSD3+copyright: (c) Judah Jacobson+maintainer: Judah Jacobson <judah.jacobson@gmail.com>+stability: Experimental+homepage: http://trac.haskell.org/haskeline+package-url:+synopsis: A command-line interface for user input, written in Haskell.+description: Haskeline provides a user interface for line input in command-line+             programs.  This library is similar in purpose to readline, but since+             it is written in Haskell it is (hopefully) more easily used in other+             Haskell programs.+             .+             Haskeline runs both on POSIX-compatible systems and on Windows.+category: User Interfaces+author: Judah Jacobson+exposed: True+exposed-modules: System.Console.Haskeline+                 System.Console.Haskeline.Completion+                 System.Console.Haskeline.MonadException+                 System.Console.Haskeline.History System.Console.Haskeline.IO+hidden-modules: System.Console.Haskeline.Backend+                System.Console.Haskeline.Backend.WCWidth+                System.Console.Haskeline.Command+                System.Console.Haskeline.Command.Completion+                System.Console.Haskeline.Command.History+                System.Console.Haskeline.Command.KillRing+                System.Console.Haskeline.Directory System.Console.Haskeline.Emacs+                System.Console.Haskeline.InputT System.Console.Haskeline.Key+                System.Console.Haskeline.LineState System.Console.Haskeline.Monads+                System.Console.Haskeline.Prefs System.Console.Haskeline.RunCommand+                System.Console.Haskeline.Term System.Console.Haskeline.Command.Undo+                System.Console.Haskeline.Vi System.Console.Haskeline.Recover+                System.Console.Haskeline.Backend.Posix+                System.Console.Haskeline.Backend.Posix.Encoder+                System.Console.Haskeline.Backend.DumbTerm+                System.Console.Haskeline.Backend.Terminfo+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/haskeline-0.7.1.2+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/haskeline-0.7.1.2+hs-libraries: HShaskeline-0.7.1.2+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         bytestring-0.10.4.0-d6f1d17d717e8652498cab8269a0acd5+         containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+         directory-1.2.1.0-07cd1f59e3c6cac5e3e180019c59a115+         filepath-1.3.0.2-25a474a9272ae6260626ce0d70ad1cab+         terminfo-0.4.0.0-c1d02a7210b0d1bc250d87463b38b8d1+         transformers-0.3.0.0-6458c21515cab7c1cf21e53141557a1c+         unix-2.7.0.1-f8658ba9ec1c4fba8a371a8e0f42ec6c+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskeline-0.7.1.2/haskeline.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskeline-0.7.1.2+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: terminfo+version: 0.4.0.0+id: terminfo-0.4.0.0-c1d02a7210b0d1bc250d87463b38b8d1+license: BSD3+copyright: (c) Judah Jacobson+maintainer: Judah Jacobson <judah.jacobson@gmail.com>+stability: Stable+homepage: https://github.com/judah/terminfo+package-url:+synopsis: Haskell bindings to the terminfo library.+description: This library provides an interface to the terminfo database (via bindings to the+             curses library).  <http://en.wikipedia.org/wiki/Terminfo Terminfo> allows POSIX+             systems to interact with a variety of terminals using a standard set of capabilities.+category: User Interfaces+author: Judah Jacobson+exposed: True+exposed-modules: System.Console.Terminfo+                 System.Console.Terminfo.Base System.Console.Terminfo.Cursor+                 System.Console.Terminfo.Color System.Console.Terminfo.Edit+                 System.Console.Terminfo.Effects System.Console.Terminfo.Keys+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/terminfo-0.4.0.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/terminfo-0.4.0.0+hs-libraries: HSterminfo-0.4.0.0+extra-libraries: tinfo+extra-ghci-libraries:+include-dirs:+includes: ncurses.h term.h+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/terminfo-0.4.0.0/terminfo.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/terminfo-0.4.0.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: xhtml+version: 3000.2.1+id: xhtml-3000.2.1-6a3ed472b07e58fe29db22a5bc2bdb06+license: BSD3+copyright: Bjorn Bringert 2004-2006, Andy Gill and the Oregon+           Graduate Institute of Science and Technology, 1999-2001+maintainer: Chris Dornan <chris@chrisdornan.com>+stability: Stable+homepage: https://github.com/haskell/xhtml+package-url:+synopsis: An XHTML combinator library+description: This package provides combinators for producing+             XHTML 1.0, including the Strict, Transitional and+             Frameset variants.+category: Web, XML, Pretty Printer+author: Bjorn Bringert+exposed: True+exposed-modules: Text.XHtml Text.XHtml.Frameset Text.XHtml.Strict+                 Text.XHtml.Transitional Text.XHtml.Debug Text.XHtml.Table+hidden-modules: Text.XHtml.Strict.Attributes+                Text.XHtml.Strict.Elements Text.XHtml.Frameset.Attributes+                Text.XHtml.Frameset.Elements Text.XHtml.Transitional.Attributes+                Text.XHtml.Transitional.Elements Text.XHtml.BlockTable+                Text.XHtml.Extras Text.XHtml.Internals+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/xhtml-3000.2.1+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/xhtml-3000.2.1+hs-libraries: HSxhtml-3000.2.1+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/xhtml-3000.2.1/xhtml.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/xhtml-3000.2.1+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: transformers+version: 0.3.0.0+id: transformers-0.3.0.0-6458c21515cab7c1cf21e53141557a1c+license: BSD3+copyright:+maintainer: Ross Paterson <ross@soi.city.ac.uk>+stability:+homepage:+package-url:+synopsis: Concrete functor and monad transformers+description: A portable library of functor and monad transformers, inspired by+             the paper \"Functional Programming with Overloading and Higher-Order+             Polymorphism\", by Mark P Jones,+             in /Advanced School of Functional Programming/, 1995+             (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>).+             .+             This package contains:+             .+             * the monad transformer class (in "Control.Monad.Trans.Class")+             .+             * concrete functor and monad transformers, each with associated+             operations and functions to lift operations associated with other+             transformers.+             .+             It can be used on its own in portable Haskell code, or with the monad+             classes in the @mtl@ or @monads-tf@ packages, which automatically+             lift operations introduced by monad transformers through other+             transformers.+category: Control+author: Andy Gill, Ross Paterson+exposed: True+exposed-modules: Control.Applicative.Backwards+                 Control.Applicative.Lift Control.Monad.IO.Class+                 Control.Monad.Trans.Class Control.Monad.Trans.Cont+                 Control.Monad.Trans.Error Control.Monad.Trans.Identity+                 Control.Monad.Trans.List Control.Monad.Trans.Maybe+                 Control.Monad.Trans.Reader Control.Monad.Trans.RWS+                 Control.Monad.Trans.RWS.Lazy Control.Monad.Trans.RWS.Strict+                 Control.Monad.Trans.State Control.Monad.Trans.State.Lazy+                 Control.Monad.Trans.State.Strict Control.Monad.Trans.Writer+                 Control.Monad.Trans.Writer.Lazy Control.Monad.Trans.Writer.Strict+                 Data.Functor.Compose Data.Functor.Constant Data.Functor.Identity+                 Data.Functor.Product Data.Functor.Reverse+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/transformers-0.3.0.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/transformers-0.3.0.0+hs-libraries: HStransformers-0.3.0.0+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/transformers-0.3.0.0/transformers.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/transformers-0.3.0.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: hoopl+version: 3.10.0.1+id: hoopl-3.10.0.1-267659e4b5b51c3d2e02f2a6d6f46936+license: BSD3+copyright:+maintainer: nr@cs.tufts.edu+stability:+homepage: http://ghc.cs.tufts.edu/hoopl/+package-url:+synopsis: A library to support dataflow analysis and optimization+description: Higher-order optimization library+             .+             See /Norman Ramsey, Joao Dias, and Simon Peyton Jones./+             <http://research.microsoft.com/en-us/um/people/simonpj/Papers/c--/hoopl-haskell10.pdf "Hoopl: A Modular, Reusable Library for Dataflow Analysis and Transformation"> /(2010)/ for more details.+category: Compilers/Interpreters+author: Norman Ramsey, Joao Dias, Simon Marlow and Simon Peyton Jones+exposed: True+exposed-modules: Compiler.Hoopl Compiler.Hoopl.Internals+                 Compiler.Hoopl.Wrappers Compiler.Hoopl.Passes.Dominator+                 Compiler.Hoopl.Passes.DList+hidden-modules: Compiler.Hoopl.Checkpoint+                Compiler.Hoopl.Collections Compiler.Hoopl.Combinators+                Compiler.Hoopl.Dataflow Compiler.Hoopl.Debug Compiler.Hoopl.Block+                Compiler.Hoopl.Graph Compiler.Hoopl.Label Compiler.Hoopl.MkGraph+                Compiler.Hoopl.Fuel Compiler.Hoopl.Pointed Compiler.Hoopl.Shape+                Compiler.Hoopl.Show Compiler.Hoopl.Unique Compiler.Hoopl.XUtil+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/hoopl-3.10.0.1+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/hoopl-3.10.0.1+hs-libraries: HShoopl-3.10.0.1+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/hoopl-3.10.0.1/hoopl.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/hoopl-3.10.0.1+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: bin-package-db+version: 0.0.0.0+id: bin-package-db-0.0.0.0-0f3da03684207f2dc4dce793df1db62e+license: BSD3+copyright:+maintainer: ghc-devs@haskell.org+stability:+homepage:+package-url:+synopsis: A binary format for the package database+description:+category:+author:+exposed: True+exposed-modules: Distribution.InstalledPackageInfo.Binary+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/bin-package-db-0.0.0.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/bin-package-db-0.0.0.0+hs-libraries: HSbin-package-db-0.0.0.0+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: Cabal-1.18.1.5-6478013104bde01737bfd67d34bbee0a+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         binary-0.7.1.0-f867dbbb69966feb9f5c4ef7695a70a5+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/bin-package-db-0.0.0.0/bin-package-db.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/bin-package-db-0.0.0.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: binary+version: 0.7.1.0+id: binary-0.7.1.0-f867dbbb69966feb9f5c4ef7695a70a5+license: BSD3+copyright:+maintainer: Lennart Kolmodin, Don Stewart <dons00@gmail.com>+stability: provisional+homepage: https://github.com/kolmodin/binary+package-url:+synopsis: Binary serialisation for Haskell values using lazy ByteStrings+description: Efficient, pure binary serialisation using lazy ByteStrings.+             Haskell values may be encoded to and from binary formats,+             written to disk as binary, or sent over the network.+             The format used can be automatically generated, or+             you can choose to implement a custom format if needed.+             Serialisation speeds of over 1 G\/sec have been observed,+             so this library should be suitable for high performance+             scenarios.+category: Data, Parsing+author: Lennart Kolmodin <kolmodin@gmail.com>+exposed: True+exposed-modules: Data.Binary Data.Binary.Put Data.Binary.Get+                 Data.Binary.Get.Internal Data.Binary.Builder+                 Data.Binary.Builder.Internal+hidden-modules: Data.Binary.Builder.Base Data.Binary.Class+                Data.Binary.Generic+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/binary-0.7.1.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/binary-0.7.1.0+hs-libraries: HSbinary-0.7.1.0+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         bytestring-0.10.4.0-d6f1d17d717e8652498cab8269a0acd5+         containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/binary-0.7.1.0/binary.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/binary-0.7.1.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: Cabal+version: 1.18.1.5+id: Cabal-1.18.1.5-6478013104bde01737bfd67d34bbee0a+license: BSD3+copyright: 2003-2006, Isaac Jones+           2005-2011, Duncan Coutts+maintainer: cabal-devel@haskell.org+stability:+homepage: http://www.haskell.org/cabal/+package-url:+synopsis: A framework for packaging Haskell software+description: The Haskell Common Architecture for Building Applications and+             Libraries: a framework defining a common interface for authors to more+             easily build their Haskell applications in a portable way.+             .+             The Haskell Cabal is part of a larger infrastructure for distributing,+             organizing, and cataloging Haskell libraries and tools.+category: Distribution+author: Isaac Jones <ijones@syntaxpolice.org>+        Duncan Coutts <duncan@community.haskell.org>+exposed: True+exposed-modules: Distribution.Compat.Environment+                 Distribution.Compat.Exception Distribution.Compat.ReadP+                 Distribution.Compiler Distribution.InstalledPackageInfo+                 Distribution.License Distribution.Make Distribution.ModuleName+                 Distribution.Package Distribution.PackageDescription+                 Distribution.PackageDescription.Check+                 Distribution.PackageDescription.Configuration+                 Distribution.PackageDescription.Parse+                 Distribution.PackageDescription.PrettyPrint+                 Distribution.PackageDescription.Utils Distribution.ParseUtils+                 Distribution.ReadE Distribution.Simple Distribution.Simple.Bench+                 Distribution.Simple.Build Distribution.Simple.Build.Macros+                 Distribution.Simple.Build.PathsModule+                 Distribution.Simple.BuildPaths Distribution.Simple.BuildTarget+                 Distribution.Simple.CCompiler Distribution.Simple.Command+                 Distribution.Simple.Compiler Distribution.Simple.Configure+                 Distribution.Simple.GHC Distribution.Simple.Haddock+                 Distribution.Simple.Hpc Distribution.Simple.Hugs+                 Distribution.Simple.Install Distribution.Simple.InstallDirs+                 Distribution.Simple.JHC Distribution.Simple.LHC+                 Distribution.Simple.LocalBuildInfo Distribution.Simple.NHC+                 Distribution.Simple.PackageIndex Distribution.Simple.PreProcess+                 Distribution.Simple.PreProcess.Unlit Distribution.Simple.Program+                 Distribution.Simple.Program.Ar Distribution.Simple.Program.Builtin+                 Distribution.Simple.Program.Db Distribution.Simple.Program.Find+                 Distribution.Simple.Program.GHC Distribution.Simple.Program.HcPkg+                 Distribution.Simple.Program.Hpc Distribution.Simple.Program.Ld+                 Distribution.Simple.Program.Run Distribution.Simple.Program.Script+                 Distribution.Simple.Program.Types Distribution.Simple.Register+                 Distribution.Simple.Setup Distribution.Simple.SrcDist+                 Distribution.Simple.Test Distribution.Simple.UHC+                 Distribution.Simple.UserHooks Distribution.Simple.Utils+                 Distribution.System Distribution.TestSuite Distribution.Text+                 Distribution.Verbosity Distribution.Version+                 Language.Haskell.Extension+hidden-modules: Distribution.Compat.CopyFile+                Distribution.Compat.TempFile Distribution.GetOpt+                Distribution.Simple.GHC.IPI641 Distribution.Simple.GHC.IPI642+                Paths_Cabal+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/Cabal-1.18.1.5+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/Cabal-1.18.1.5+hs-libraries: HSCabal-1.18.1.5+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         bytestring-0.10.4.0-d6f1d17d717e8652498cab8269a0acd5+         containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+         deepseq-1.3.0.2-63a1ab91b7017a28bb5d04cb1b5d2d02+         directory-1.2.1.0-07cd1f59e3c6cac5e3e180019c59a115+         filepath-1.3.0.2-25a474a9272ae6260626ce0d70ad1cab+         pretty-1.1.1.1-0984f47ffe93ef3983c80b96280f1c3a+         process-1.2.0.0-06c3215a79834ce4886ae686a0f81122+         time-1.4.2-9b3076800c33f8382c38628f35717951+         unix-2.7.0.1-f8658ba9ec1c4fba8a371a8e0f42ec6c+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/Cabal-1.18.1.5/Cabal.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/Cabal-1.18.1.5+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: template-haskell+version: 2.9.0.0+id: template-haskell-2.9.0.0-6d27c2b362b15abb1822f2f34b9ae7f9+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Support library for Template Haskell+description: This package provides modules containing facilities for manipulating+             Haskell source code using Template Haskell.+             .+             See <http://www.haskell.org/haskellwiki/Template_Haskell> for more+             information.+category: Template Haskell+author:+exposed: True+exposed-modules: Language.Haskell.TH Language.Haskell.TH.Lib+                 Language.Haskell.TH.Ppr Language.Haskell.TH.PprLib+                 Language.Haskell.TH.Quote Language.Haskell.TH.Syntax+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/template-haskell-2.9.0.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/template-haskell-2.9.0.0+hs-libraries: HStemplate-haskell-2.9.0.0+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+         pretty-1.1.1.1-0984f47ffe93ef3983c80b96280f1c3a+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/template-haskell-2.9.0.0/template-haskell.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/template-haskell-2.9.0.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: pretty+version: 1.1.1.1+id: pretty-1.1.1.1-0984f47ffe93ef3983c80b96280f1c3a+license: BSD3+copyright:+maintainer: David Terei <code@davidterei.com>+stability: Stable+homepage: http://github.com/haskell/pretty+package-url:+synopsis: Pretty-printing library+description: This package contains a pretty-printing library, a set of API's+             that provides a way to easily print out text in a consistent+             format of your choosing. This is useful for compilers and related+             tools.+             .+             This library was originally designed by John Hughes's and has since+             been heavily modified by Simon Peyton Jones.+category: Text+author:+exposed: True+exposed-modules: Text.PrettyPrint Text.PrettyPrint.HughesPJ+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/pretty-1.1.1.1+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/pretty-1.1.1.1+hs-libraries: HSpretty-1.1.1.1+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/pretty-1.1.1.1/pretty.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/pretty-1.1.1.1+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: hpc+version: 0.6.0.1+id: hpc-0.6.0.1-cca17f12dab542e09c423a74a4590c5d+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Code Coverage Library for Haskell+description: This package provides the code coverage library for Haskell.+             .+             See <http://www.haskell.org/haskellwiki/Haskell_program_coverage> for more+             information.+category: Control+author: Andy Gill+exposed: True+exposed-modules: Trace.Hpc.Util Trace.Hpc.Mix Trace.Hpc.Tix+                 Trace.Hpc.Reflect+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/hpc-0.6.0.1+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/hpc-0.6.0.1+hs-libraries: HShpc-0.6.0.1+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+         directory-1.2.1.0-07cd1f59e3c6cac5e3e180019c59a115+         time-1.4.2-9b3076800c33f8382c38628f35717951+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/hpc-0.6.0.1/hpc.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/hpc-0.6.0.1+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: process+version: 1.2.0.0+id: process-1.2.0.0-06c3215a79834ce4886ae686a0f81122+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Process libraries+description: This package contains libraries for dealing with system processes.+category: System+author:+exposed: True+exposed-modules: System.Cmd System.Process System.Process.Internals+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/process-1.2.0.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/process-1.2.0.0+hs-libraries: HSprocess-1.2.0.0+extra-libraries:+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/process-1.2.0.0/include+includes: runProcess.h+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         deepseq-1.3.0.2-63a1ab91b7017a28bb5d04cb1b5d2d02+         directory-1.2.1.0-07cd1f59e3c6cac5e3e180019c59a115+         filepath-1.3.0.2-25a474a9272ae6260626ce0d70ad1cab+         unix-2.7.0.1-f8658ba9ec1c4fba8a371a8e0f42ec6c+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/process-1.2.0.0/process.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/process-1.2.0.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: directory+version: 1.2.1.0+id: directory-1.2.1.0-07cd1f59e3c6cac5e3e180019c59a115+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: library for directory handling+description: This package provides a library for handling directories.+category: System+author:+exposed: True+exposed-modules: System.Directory+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/directory-1.2.1.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/directory-1.2.1.0+hs-libraries: HSdirectory-1.2.1.0+extra-libraries:+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/directory-1.2.1.0/include+includes: HsDirectory.h+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         filepath-1.3.0.2-25a474a9272ae6260626ce0d70ad1cab+         time-1.4.2-9b3076800c33f8382c38628f35717951+         unix-2.7.0.1-f8658ba9ec1c4fba8a371a8e0f42ec6c+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/directory-1.2.1.0/directory.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/directory-1.2.1.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: unix+version: 2.7.0.1+id: unix-2.7.0.1-f8658ba9ec1c4fba8a371a8e0f42ec6c+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: POSIX functionality+description: This package gives you access to the set of operating system+             services standardised by POSIX 1003.1b (or the IEEE Portable+             Operating System Interface for Computing Environments -+             IEEE Std. 1003.1).+             .+             The package is not supported under Windows (except under Cygwin).+category: System+author:+exposed: True+exposed-modules: System.Posix System.Posix.ByteString+                 System.Posix.Error System.Posix.Resource System.Posix.Time+                 System.Posix.Unistd System.Posix.User System.Posix.Signals+                 System.Posix.Signals.Exts System.Posix.Semaphore+                 System.Posix.SharedMem System.Posix.ByteString.FilePath+                 System.Posix.Directory System.Posix.Directory.ByteString+                 System.Posix.DynamicLinker.Module+                 System.Posix.DynamicLinker.Module.ByteString+                 System.Posix.DynamicLinker.Prim+                 System.Posix.DynamicLinker.ByteString System.Posix.DynamicLinker+                 System.Posix.Files System.Posix.Files.ByteString System.Posix.IO+                 System.Posix.IO.ByteString System.Posix.Env+                 System.Posix.Env.ByteString System.Posix.Process+                 System.Posix.Process.Internals System.Posix.Process.ByteString+                 System.Posix.Temp System.Posix.Temp.ByteString+                 System.Posix.Terminal System.Posix.Terminal.ByteString+hidden-modules: System.Posix.Directory.Common+                System.Posix.DynamicLinker.Common System.Posix.Files.Common+                System.Posix.IO.Common System.Posix.Process.Common+                System.Posix.Terminal.Common+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/unix-2.7.0.1+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/unix-2.7.0.1+hs-libraries: HSunix-2.7.0.1+extra-libraries: rt util dl pthread+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/unix-2.7.0.1/include+includes: HsUnix.h execvpe.h+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         bytestring-0.10.4.0-d6f1d17d717e8652498cab8269a0acd5+         time-1.4.2-9b3076800c33f8382c38628f35717951+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/unix-2.7.0.1/unix.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/unix-2.7.0.1+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: time+version: 1.4.2+id: time-1.4.2-9b3076800c33f8382c38628f35717951+license: BSD3+copyright:+maintainer: <ashley@semantic.org>+stability: stable+homepage: http://semantic.org/TimeLib/+package-url:+synopsis: A time library+description: A time library+category: System+author: Ashley Yakeley+exposed: True+exposed-modules: Data.Time.Calendar Data.Time.Calendar.MonthDay+                 Data.Time.Calendar.OrdinalDate Data.Time.Calendar.WeekDate+                 Data.Time.Calendar.Julian Data.Time.Calendar.Easter Data.Time.Clock+                 Data.Time.Clock.POSIX Data.Time.Clock.TAI Data.Time.LocalTime+                 Data.Time.Format Data.Time+hidden-modules: Data.Time.Calendar.Private Data.Time.Calendar.Days+                Data.Time.Calendar.Gregorian Data.Time.Calendar.JulianYearDay+                Data.Time.Clock.Scale Data.Time.Clock.UTC Data.Time.Clock.CTimeval+                Data.Time.Clock.UTCDiff Data.Time.LocalTime.TimeZone+                Data.Time.LocalTime.TimeOfDay Data.Time.LocalTime.LocalTime+                Data.Time.Format.Parse+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/time-1.4.2+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/time-1.4.2+hs-libraries: HStime-1.4.2+extra-libraries:+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/time-1.4.2/include+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         deepseq-1.3.0.2-63a1ab91b7017a28bb5d04cb1b5d2d02+         old-locale-1.0.0.6-50b0125c49f76af85dc7aa22975cdc34+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/time-1.4.2/time.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/time-1.4.2+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: old-locale+version: 1.0.0.6+id: old-locale-1.0.0.6-50b0125c49f76af85dc7aa22975cdc34+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: locale library+description: This package provides the ability to adapt to+             locale conventions such as date and time formats.+category: System+author:+exposed: True+exposed-modules: System.Locale+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/old-locale-1.0.0.6+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/old-locale-1.0.0.6+hs-libraries: HSold-locale-1.0.0.6+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/old-locale-1.0.0.6/old-locale.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/old-locale-1.0.0.6+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: containers+version: 0.5.5.1+id: containers-0.5.5.1-d4bd887fb97aa3a46cbadc13709b7653+license: BSD3+copyright:+maintainer: fox@ucw.cz+stability:+homepage:+package-url:+synopsis: Assorted concrete container types+description: This package contains efficient general-purpose implementations+             of various basic immutable container types.  The declared cost of+             each operation is either worst-case or amortized, but remains+             valid even if structures are shared.+category: Data Structures+author:+exposed: True+exposed-modules: Data.IntMap Data.IntMap.Lazy Data.IntMap.Strict+                 Data.IntSet Data.Map Data.Map.Lazy Data.Map.Strict Data.Set+                 Data.Graph Data.Sequence Data.Tree+hidden-modules: Data.BitUtil Data.IntMap.Base Data.IntSet.Base+                Data.Map.Base Data.Set.Base Data.StrictPair+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/containers-0.5.5.1+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/containers-0.5.5.1+hs-libraries: HScontainers-0.5.5.1+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         deepseq-1.3.0.2-63a1ab91b7017a28bb5d04cb1b5d2d02+         ghc-prim-0.3.1.0-a24f9c14c632d75b683d0f93283aea37+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/containers-0.5.5.1/containers.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/containers-0.5.5.1+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: bytestring+version: 0.10.4.0+id: bytestring-0.10.4.0-d6f1d17d717e8652498cab8269a0acd5+license: BSD3+copyright: Copyright (c) Don Stewart          2005-2009,+           (c) Duncan Coutts        2006-2013,+           (c) David Roundy         2003-2005,+           (c) Jasper Van der Jeugt 2010,+           (c) Simon Meier          2010-2013.+maintainer: Don Stewart <dons00@gmail.com>,+            Duncan Coutts <duncan@community.haskell.org>+stability:+homepage: https://github.com/haskell/bytestring+package-url:+synopsis: Fast, compact, strict and lazy byte strings with a list interface+description: An efficient compact, immutable byte string type (both strict and lazy)+             suitable for binary or 8-bit character data.+             .+             The 'ByteString' type represents sequences of bytes or 8-bit characters.+             It is suitable for high performance use, both in terms of large data+             quantities, or high speed requirements. The 'ByteString' functions follow+             the same style as Haskell\'s ordinary lists, so it is easy to convert code+             from using 'String' to 'ByteString'.+             .+             Two 'ByteString' variants are provided:+             .+             * Strict 'ByteString's keep the string as a single large array. This+             makes them convenient for passing data between C and Haskell.+             .+             * Lazy 'ByteString's use a lazy list of strict chunks which makes it+             suitable for I\/O streaming tasks.+             .+             The @Char8@ modules provide a character-based view of the same+             underlying 'ByteString' types. This makes it convenient to handle mixed+             binary and 8-bit character content (which is common in many file formats+             and network protocols).+             .+             The 'Builder' module provides an efficient way to build up 'ByteString's+             in an ad-hoc way by repeated concatenation. This is ideal for fast+             serialisation or pretty printing.+             .+             There is also a 'ShortByteString' type which has a lower memory overhead+             and can can be converted to or from a 'ByteString', but supports very few+             other operations. It is suitable for keeping many short strings in memory.+             .+             'ByteString's are not designed for Unicode. For Unicode strings you should+             use the 'Text' type from the @text@ package.+             .+             These modules are intended to be imported qualified, to avoid name clashes+             with "Prelude" functions, e.g.+             .+             > import qualified Data.ByteString as BS+category: Data+author: Don Stewart,+        Duncan Coutts+exposed: True+exposed-modules: Data.ByteString Data.ByteString.Char8+                 Data.ByteString.Unsafe Data.ByteString.Internal+                 Data.ByteString.Lazy Data.ByteString.Lazy.Char8+                 Data.ByteString.Lazy.Internal Data.ByteString.Short+                 Data.ByteString.Short.Internal Data.ByteString.Builder+                 Data.ByteString.Builder.Extra Data.ByteString.Builder.Prim+                 Data.ByteString.Builder.Internal+                 Data.ByteString.Builder.Prim.Internal Data.ByteString.Lazy.Builder+                 Data.ByteString.Lazy.Builder.Extras+                 Data.ByteString.Lazy.Builder.ASCII+hidden-modules: Data.ByteString.Builder.ASCII+                Data.ByteString.Builder.Prim.Binary+                Data.ByteString.Builder.Prim.ASCII+                Data.ByteString.Builder.Prim.Internal.Floating+                Data.ByteString.Builder.Prim.Internal.UncheckedShifts+                Data.ByteString.Builder.Prim.Internal.Base16+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/bytestring-0.10.4.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/bytestring-0.10.4.0+hs-libraries: HSbytestring-0.10.4.0+extra-libraries:+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/bytestring-0.10.4.0/include+includes: fpstring.h+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+         deepseq-1.3.0.2-63a1ab91b7017a28bb5d04cb1b5d2d02+         ghc-prim-0.3.1.0-a24f9c14c632d75b683d0f93283aea37+         integer-gmp-0.5.1.0-26579559b3647acf4f01d5edd9491a46+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/bytestring-0.10.4.0/bytestring.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/bytestring-0.10.4.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: deepseq+version: 1.3.0.2+id: deepseq-1.3.0.2-63a1ab91b7017a28bb5d04cb1b5d2d02+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Deep evaluation of data structures+description: This package provides methods for fully evaluating data structures+             (\"deep evaluation\"). Deep evaluation is often used for adding+             strictness to a program, e.g. in order to force pending exceptions,+             remove space leaks, or force lazy I/O to happen. It is also useful+             in parallel programs, to ensure pending work does not migrate to the+             wrong thread.+             .+             The primary use of this package is via the 'deepseq' function, a+             \"deep\" version of 'seq'. It is implemented on top of an 'NFData'+             typeclass (\"Normal Form Data\", data structures with no unevaluated+             components) which defines strategies for fully evaluating different+             data types.+             .+             If you want to automatically derive 'NFData' instances via the+             "GHC.Generics" facility, there is a companion package+             <http://hackage.haskell.org/package/deepseq-generics deepseq-generics>+             which builds on top of this package.+category: Control+author:+exposed: True+exposed-modules: Control.DeepSeq+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/deepseq-1.3.0.2+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/deepseq-1.3.0.2+hs-libraries: HSdeepseq-1.3.0.2+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+         base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/deepseq-1.3.0.2/deepseq.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/deepseq-1.3.0.2+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: array+version: 0.5.0.0+id: array-0.5.0.0-470385a50d2b78598af85cfe9d988e1b+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Mutable and immutable arrays+description: In addition to providing the "Data.Array" module+             <http://www.haskell.org/onlinereport/haskell2010/haskellch14.html as specified in the Haskell 2010 Language Report>,+             this package also defines the classes 'IArray' of+             immutable arrays and 'MArray' of arrays mutable within appropriate+             monads, as well as some instances of these classes.+category: Data Structures+author:+exposed: True+exposed-modules: Data.Array Data.Array.Base Data.Array.IArray+                 Data.Array.IO Data.Array.IO.Safe Data.Array.IO.Internals+                 Data.Array.MArray Data.Array.MArray.Safe Data.Array.ST+                 Data.Array.ST.Safe Data.Array.Storable Data.Array.Storable.Safe+                 Data.Array.Storable.Internals Data.Array.Unboxed Data.Array.Unsafe+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/array-0.5.0.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/array-0.5.0.0+hs-libraries: HSarray-0.5.0.0+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/array-0.5.0.0/array.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/array-0.5.0.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: filepath+version: 1.3.0.2+id: filepath-1.3.0.2-25a474a9272ae6260626ce0d70ad1cab+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage: http://www-users.cs.york.ac.uk/~ndm/filepath/+package-url:+synopsis: Library for manipulating FilePaths in a cross platform way.+description: A library for 'FilePath' manipulations, using Posix or Windows filepaths+             depending on the platform.+             .+             Both "System.FilePath.Posix" and "System.FilePath.Windows" provide+             the same interface. See either for examples and a list of the+             available functions.+category: System+author: Neil Mitchell+exposed: True+exposed-modules: System.FilePath System.FilePath.Posix+                 System.FilePath.Windows+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/filepath-1.3.0.2+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/filepath-1.3.0.2+hs-libraries: HSfilepath-1.3.0.2+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/filepath-1.3.0.2/filepath.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/filepath-1.3.0.2+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: base+version: 4.7.0.2+id: base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Basic libraries+description: This package contains the "Prelude" and its support libraries,+             and a large collection of useful libraries ranging from data+             structures to parsing combinators and debugging utilities.+category: Prelude+author:+exposed: True+exposed-modules: Control.Applicative Control.Arrow Control.Category+                 Control.Concurrent Control.Concurrent.Chan Control.Concurrent.MVar+                 Control.Concurrent.QSem Control.Concurrent.QSemN Control.Exception+                 Control.Exception.Base Control.Monad Control.Monad.Fix+                 Control.Monad.Instances Control.Monad.ST Control.Monad.ST.Lazy+                 Control.Monad.ST.Lazy.Safe Control.Monad.ST.Lazy.Unsafe+                 Control.Monad.ST.Safe Control.Monad.ST.Strict+                 Control.Monad.ST.Unsafe Control.Monad.Zip Data.Bits Data.Bool+                 Data.Char Data.Coerce Data.Complex Data.Data Data.Dynamic+                 Data.Either Data.Eq Data.Fixed Data.Foldable Data.Function+                 Data.Functor Data.IORef Data.Int Data.Ix Data.List Data.Maybe+                 Data.Monoid Data.OldTypeable Data.OldTypeable.Internal Data.Ord+                 Data.Proxy Data.Ratio Data.STRef Data.STRef.Lazy Data.STRef.Strict+                 Data.String Data.Traversable Data.Tuple Data.Type.Bool+                 Data.Type.Coercion Data.Type.Equality Data.Typeable+                 Data.Typeable.Internal Data.Unique Data.Version Data.Word+                 Debug.Trace Foreign Foreign.C Foreign.C.Error Foreign.C.String+                 Foreign.C.Types Foreign.Concurrent Foreign.ForeignPtr+                 Foreign.ForeignPtr.Safe Foreign.ForeignPtr.Unsafe Foreign.Marshal+                 Foreign.Marshal.Alloc Foreign.Marshal.Array Foreign.Marshal.Error+                 Foreign.Marshal.Pool Foreign.Marshal.Safe Foreign.Marshal.Unsafe+                 Foreign.Marshal.Utils Foreign.Ptr Foreign.Safe Foreign.StablePtr+                 Foreign.Storable GHC.Arr GHC.Base GHC.Char GHC.Conc GHC.Conc.IO+                 GHC.Conc.Signal GHC.Conc.Sync GHC.ConsoleHandler GHC.Constants+                 GHC.Desugar GHC.Enum GHC.Environment GHC.Err GHC.Exception GHC.Exts+                 GHC.Fingerprint GHC.Fingerprint.Type GHC.Float+                 GHC.Float.ConversionUtils GHC.Float.RealFracMethods GHC.Foreign+                 GHC.ForeignPtr GHC.GHCi GHC.Generics GHC.IO GHC.IO.Buffer+                 GHC.IO.BufferedIO GHC.IO.Device GHC.IO.Encoding+                 GHC.IO.Encoding.CodePage GHC.IO.Encoding.Failure+                 GHC.IO.Encoding.Iconv GHC.IO.Encoding.Latin1 GHC.IO.Encoding.Types+                 GHC.IO.Encoding.UTF16 GHC.IO.Encoding.UTF32 GHC.IO.Encoding.UTF8+                 GHC.IO.Exception GHC.IO.FD GHC.IO.Handle GHC.IO.Handle.FD+                 GHC.IO.Handle.Internals GHC.IO.Handle.Text GHC.IO.Handle.Types+                 GHC.IO.IOMode GHC.IOArray GHC.IORef GHC.IP GHC.Int GHC.List+                 GHC.MVar GHC.Num GHC.PArr GHC.Pack GHC.Profiling GHC.Ptr GHC.Read+                 GHC.Real GHC.ST GHC.STRef GHC.Show GHC.Stable GHC.Stack GHC.Stats+                 GHC.Storable GHC.TopHandler GHC.TypeLits GHC.Unicode GHC.Weak+                 GHC.Word Numeric Prelude System.CPUTime System.Console.GetOpt+                 System.Environment System.Exit System.IO System.IO.Error+                 System.IO.Unsafe System.Info System.Mem System.Mem.StableName+                 System.Mem.Weak System.Posix.Internals System.Posix.Types+                 System.Timeout Text.ParserCombinators.ReadP+                 Text.ParserCombinators.ReadPrec Text.Printf Text.Read Text.Read.Lex+                 Text.Show Text.Show.Functions Unsafe.Coerce GHC.Event+hidden-modules: Control.Monad.ST.Imp Control.Monad.ST.Lazy.Imp+                Foreign.ForeignPtr.Imp System.Environment.ExecutablePath+                GHC.Event.Arr GHC.Event.Array GHC.Event.Clock GHC.Event.Control+                GHC.Event.EPoll GHC.Event.IntTable GHC.Event.Internal+                GHC.Event.KQueue GHC.Event.Manager GHC.Event.PSQ GHC.Event.Poll+                GHC.Event.Thread GHC.Event.TimerManager GHC.Event.Unique+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/base-4.7.0.2+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/base-4.7.0.2+hs-libraries: HSbase-4.7.0.2+extra-libraries:+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/base-4.7.0.2/include+includes: HsBase.h+depends: ghc-prim-0.3.1.0-a24f9c14c632d75b683d0f93283aea37+         integer-gmp-0.5.1.0-26579559b3647acf4f01d5edd9491a46 builtin_rts+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/base-4.7.0.2/base.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/base-4.7.0.2+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: integer-gmp+version: 0.5.1.0+id: integer-gmp-0.5.1.0-26579559b3647acf4f01d5edd9491a46+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: Integer library based on GMP+description: This package provides the low-level implementation of the standard+             'Integer' type based on the+             <http://gmplib.org/ GNU Multiple Precision Arithmetic Library (GMP)>.+             .+             This package provides access to the internal representation of+             'Integer' as well as primitive operations with no proper error+             handling, and should only be used directly with the utmost care.+             .+             For more details about the design of @integer-gmp@, see+             <https://ghc.haskell.org/trac/ghc/wiki/Commentary/Libraries/Integer GHC Commentary: Libraries/Integer>.+category: Numerical+author:+exposed: True+exposed-modules: GHC.Integer GHC.Integer.GMP.Internals+                 GHC.Integer.GMP.Prim GHC.Integer.Logarithms+                 GHC.Integer.Logarithms.Internals+hidden-modules: GHC.Integer.Type+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/integer-gmp-0.5.1.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/integer-gmp-0.5.1.0+hs-libraries: HSinteger-gmp-0.5.1.0+extra-libraries: gmp+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/integer-gmp-0.5.1.0/include+includes:+depends: ghc-prim-0.3.1.0-a24f9c14c632d75b683d0f93283aea37+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/integer-gmp-0.5.1.0/integer-gmp.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/integer-gmp-0.5.1.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: ghc-prim+version: 0.3.1.0+id: ghc-prim-0.3.1.0-a24f9c14c632d75b683d0f93283aea37+license: BSD3+copyright:+maintainer: libraries@haskell.org+stability:+homepage:+package-url:+synopsis: GHC primitives+description: GHC primitives.+category: GHC+author:+exposed: True+exposed-modules: GHC.CString GHC.Classes GHC.Debug GHC.IntWord64+                 GHC.Magic GHC.PrimopWrappers GHC.Tuple GHC.Types GHC.Prim+hidden-modules:+trusted: False+import-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/ghc-prim-0.3.1.0+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/ghc-prim-0.3.1.0+hs-libraries: HSghc-prim-0.3.1.0+extra-libraries:+extra-ghci-libraries:+include-dirs:+includes:+depends: builtin_rts+hugs-options:+cc-options:+ld-options:+framework-dirs:+frameworks:+haddock-interfaces: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/ghc-prim-0.3.1.0/ghc-prim.haddock+haddock-html: /opt/ghc/7.8.4/share/doc/ghc/html/libraries/ghc-prim-0.3.1.0+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+---+name: rts+version: 1.0+id: builtin_rts+license: BSD3+copyright:+maintainer: glasgow-haskell-users@haskell.org+stability:+homepage:+package-url:+synopsis:+description:+category:+author:+exposed: True+exposed-modules:+hidden-modules:+trusted: False+import-dirs:+library-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/rts-1.0+hs-libraries: HSrts Cffi+extra-libraries: m rt dl+extra-ghci-libraries:+include-dirs: /opt/ghc/7.8.4/lib/ghc-7.8.4/include+includes: Stg.h+depends:+hugs-options:+cc-options:+ld-options: "-Wl,-u,ghczmprim_GHCziTypes_Izh_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Czh_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Fzh_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Dzh_static_info"+            "-Wl,-u,base_GHCziPtr_Ptr_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Wzh_static_info"+            "-Wl,-u,base_GHCziInt_I8zh_static_info"+            "-Wl,-u,base_GHCziInt_I16zh_static_info"+            "-Wl,-u,base_GHCziInt_I32zh_static_info"+            "-Wl,-u,base_GHCziInt_I64zh_static_info"+            "-Wl,-u,base_GHCziWord_W8zh_static_info"+            "-Wl,-u,base_GHCziWord_W16zh_static_info"+            "-Wl,-u,base_GHCziWord_W32zh_static_info"+            "-Wl,-u,base_GHCziWord_W64zh_static_info"+            "-Wl,-u,base_GHCziStable_StablePtr_static_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Izh_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Czh_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Fzh_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_Dzh_con_info"+            "-Wl,-u,base_GHCziPtr_Ptr_con_info"+            "-Wl,-u,base_GHCziPtr_FunPtr_con_info"+            "-Wl,-u,base_GHCziStable_StablePtr_con_info"+            "-Wl,-u,ghczmprim_GHCziTypes_False_closure"+            "-Wl,-u,ghczmprim_GHCziTypes_True_closure"+            "-Wl,-u,base_GHCziPack_unpackCString_closure"+            "-Wl,-u,base_GHCziIOziException_stackOverflow_closure"+            "-Wl,-u,base_GHCziIOziException_heapOverflow_closure"+            "-Wl,-u,base_ControlziExceptionziBase_nonTermination_closure"+            "-Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnMVar_closure"+            "-Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnSTM_closure"+            "-Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure"+            "-Wl,-u,base_GHCziWeak_runFinalizzerBatch_closure"+            "-Wl,-u,base_GHCziTopHandler_flushStdHandles_closure"+            "-Wl,-u,base_GHCziTopHandler_runIO_closure"+            "-Wl,-u,base_GHCziTopHandler_runNonIO_closure"+            "-Wl,-u,base_GHCziConcziIO_ensureIOManagerIsRunning_closure"+            "-Wl,-u,base_GHCziConcziIO_ioManagerCapabilitiesChanged_closure"+            "-Wl,-u,base_GHCziConcziSync_runSparks_closure"+            "-Wl,-u,base_GHCziConcziSignal_runHandlersPtr_closure"+framework-dirs:+frameworks:+haddock-interfaces:+haddock-html:+pkgroot: "/opt/ghc/7.8.4/lib/ghc-7.8.4"+