diff --git a/cabal-install/Distribution/Client/Install.hs b/cabal-install/Distribution/Client/Install.hs index ba2ada576d0..58a4a8930ae 100644 --- a/cabal-install/Distribution/Client/Install.hs +++ b/cabal-install/Distribution/Client/Install.hs @@ -23,7 +23,10 @@ import Control.Monad ( when, unless ) import System.Directory ( getTemporaryDirectory, doesFileExist ) -import System.FilePath ((),(<.>)) +import System.FilePath + ( (), (<.>) ) +import System.IO + ( openFile, IOMode(AppendMode) ) import Distribution.Client.Dependency ( resolveDependenciesWithProgress, PackagesVersionPreference(..) @@ -61,6 +64,9 @@ import Distribution.Simple.Setup ( flagToMaybe ) import Distribution.Simple.Utils ( defaultPackageDesc, inDir, rawSystemExit, withTempDirectory ) +import Distribution.Simple.InstallDirs + ( fromPathTemplate, toPathTemplate + , initialPathTemplateEnv, substPathTemplate ) import Distribution.Package ( PackageIdentifier(..), Package(..), thisPackageVersion ) import Distribution.PackageDescription as PackageDescription @@ -144,9 +150,10 @@ installWithPlanner planner verbosity packageDB repos comp conf configFlags insta installPlan' <- executeInstallPlan installPlan $ \cpkg -> installConfiguredPackage configFlags cpkg $ \configFlags' apkg -> - installAvailablePackage verbosity apkg $ + installAvailablePackage verbosity apkg $ \pkg mpath -> installUnpackedPackage verbosity (setupScriptOptions installed) miscOptions configFlags' + pkg mpath useLogFile writeInstallPlanBuildReports installPlan' writeInstallPlanBuildLog installPlan' printBuildFailures installPlan' @@ -163,6 +170,14 @@ installWithPlanner planner verbosity packageDB repos comp conf configFlags insta useLoggingHandle = Nothing, useWorkingDir = Nothing } + useLogFile :: Maybe (PackageIdentifier -> FilePath) + useLogFile = fmap substLogFileName + (Cabal.flagToMaybe (installLogFile installFlags)) + substLogFileName path pkg = fromPathTemplate + . substPathTemplate env + . toPathTemplate + $ path + where env = initialPathTemplateEnv (packageId pkg) (compilerId comp) dryRun = Cabal.fromFlag (installDryRun installFlags) miscOptions = InstallMisc { rootCmd = if Cabal.fromFlag (Cabal.configUserInstall configFlags) @@ -315,8 +330,10 @@ installUnpackedPackage :: Verbosity -> Cabal.ConfigFlags -> GenericPackageDescription -> Maybe FilePath -- ^ Directory to change to before starting the installation. + -> Maybe (PackageIdentifier -> FilePath) -- ^ File to log output to (if any) -> IO BuildResult -installUnpackedPackage verbosity scriptOptions miscOptions configFlags pkg mpath +installUnpackedPackage verbosity scriptOptions miscOptions configFlags + pkg workingDir useLogFile = onFailure ConfigureFailed $ do setup configureCommand (filterConfigureFlags configFlags) onFailure BuildFailed $ do @@ -329,9 +346,14 @@ installUnpackedPackage verbosity scriptOptions miscOptions configFlags pkg mpath return BuildOk where buildCommand = Cabal.buildCommand defaultProgramConfiguration - setup cmd flags = + setup cmd flags = do + logFileHandle <- case useLogFile of + Nothing -> return Nothing + Just logFileName -> fmap Just $ + openFile (logFileName (packageId pkg)) AppendMode setupWrapper verbosity - scriptOptions { useWorkingDir = mpath } + scriptOptions { useLoggingHandle = logFileHandle + , useWorkingDir = workingDir } (Just $ PackageDescription.packageDescription pkg) cmd flags [] reexec cmd = do @@ -341,7 +363,7 @@ installUnpackedPackage verbosity scriptOptions miscOptions configFlags pkg mpath let self = bindir "cabal" <.> exeExtension weExist <- doesFileExist self if weExist - then inDir mpath $ + then inDir workingDir $ rawSystemExit verbosity cmd [self, "install", "--only" ,"--verbose=" ++ showForCabal verbosity] diff --git a/cabal-install/Distribution/Client/Setup.hs b/cabal-install/Distribution/Client/Setup.hs index e769e46edee..6b0ffb6ffba 100644 --- a/cabal-install/Distribution/Client/Setup.hs +++ b/cabal-install/Distribution/Client/Setup.hs @@ -204,7 +204,8 @@ data InstallFlags = InstallFlags { installDryRun :: Flag Bool, installOnly :: Flag Bool, installRootCmd :: Flag String, - installCabalVersion :: Flag Version + installCabalVersion :: Flag Version, + installLogFile :: Flag FilePath } defaultInstallFlags :: InstallFlags @@ -212,7 +213,8 @@ defaultInstallFlags = InstallFlags { installDryRun = Flag False, installOnly = Flag False, installRootCmd = mempty, - installCabalVersion = mempty + installCabalVersion = mempty, + installLogFile = mempty } installCommand :: CommandUI (Cabal.ConfigFlags, InstallFlags) @@ -241,6 +243,12 @@ installCommand = configureCommand { (reqArg "VERSION" (readP_to_E ("Cannot parse cabal lib version: "++) (fmap toFlag parse)) (map display . flagToList)) + + , option [] ["log-builds"] + "Log all builds to file (name template can use $pkgid, $compiler, $os, $arch)" + installLogFile (\v flags -> flags { installLogFile = v }) + (reqArg' "FILE" toFlag flagToList) + ] ++ case showOrParseArgs of -- TODO: remove when "cabal install" avoids ParseArgs -> option [] ["only"] @@ -257,7 +265,8 @@ instance Monoid InstallFlags where installDryRun = combine installDryRun, installOnly = combine installOnly, installRootCmd = combine installRootCmd, - installCabalVersion = combine installCabalVersion + installCabalVersion = combine installCabalVersion, + installLogFile = combine installLogFile } where combine field = field a `mappend` field b