From 6db998ef4e4269f5e1b41a868280868688573d0d Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Mon, 6 May 2024 11:28:32 +1000 Subject: [PATCH] Add pre and post build hooks Run a program (named "preBuildHook") before doing a package build and another program (named "postBuildHook") after the package is built. These programs are project local and need to be in the `cabalHooks` directory which is in the same directory as the `cabal.project` file. Co-authored: Moritz Angermann --- .../Client/ProjectBuilding/UnpackedPackage.hs | 32 +++++++++++++++++-- changelog.d/pr-9899 | 14 ++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 changelog.d/pr-9899 diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index 065334d5c6e..8dc7c159e3f 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -30,6 +30,7 @@ module Distribution.Client.ProjectBuilding.UnpackedPackage import Distribution.Client.Compat.Prelude import Prelude () +import Distribution.Client.Config import Distribution.Client.PackageHash (renderPackageHashInputs) import Distribution.Client.ProjectBuilding.Types import Distribution.Client.ProjectConfig @@ -100,8 +101,8 @@ import qualified Data.ByteString.Lazy.Char8 as LBS.Char8 import qualified Data.List.NonEmpty as NE import Control.Exception (ErrorCall, Handler (..), SomeAsyncException, assert, catches) -import System.Directory (canonicalizePath, createDirectoryIfMissing, doesDirectoryExist, doesFileExist, removeFile) -import System.FilePath (dropDrive, normalise, takeDirectory, (<.>), ()) +import System.Directory (canonicalizePath, createDirectoryIfMissing, doesDirectoryExist, doesFileExist, getCurrentDirectory, removeFile) +import System.FilePath (dropDrive, dropFileName, normalise, takeDirectory, (<.>), ()) import System.IO (Handle, IOMode (AppendMode), withFile) import System.Semaphore (SemaphoreName (..)) @@ -678,7 +679,32 @@ buildAndInstallUnpackedPackage runConfigure PBBuildPhase{runBuild} -> do noticeProgress ProgressBuilding - runBuild + hooksDir <- ( "cabalHooks") <$> getCurrentDirectory + -- run preBuildHook. If it returns with 0, we assume the build was + -- successful. If not, run the build. + code <- + rawSystemExitCode + verbosity + (Just srcdir) + (hooksDir "preBuildHook") + [ (unUnitId $ installedUnitId rpkg) + , (getSymbolicPath srcdir) + , (getSymbolicPath builddir) + ] + `catchIO` (\_ -> return (ExitFailure 10)) + when (code /= ExitSuccess) $ do + runBuild + -- not sure, if we want to care about a failed postBuildHook? + void $ + rawSystemExitCode + verbosity + (Just srcdir) + (hooksDir "postBuildHook") + [ (unUnitId $ installedUnitId rpkg) + , (getSymbolicPath srcdir) + , (getSymbolicPath builddir) + ] + `catchIO` (\_ -> return (ExitFailure 10)) PBHaddockPhase{runHaddock} -> do noticeProgress ProgressHaddock runHaddock diff --git a/changelog.d/pr-9899 b/changelog.d/pr-9899 new file mode 100644 index 00000000000..64f5f3fc619 --- /dev/null +++ b/changelog.d/pr-9899 @@ -0,0 +1,14 @@ +synopsis: Add pre and post build hooks +packages: cabal-install +prs: #9899 +issues: #9892 +significance: significant + +description: { + +- Run a program (named "preBuildHook") before doing a package build and another program + (named "postBuildHook") after the package is built. +- These programs are project local and need to be in the `cabalHooks` directory which is + in the same directory as the `cabal.project` file. +- The absence of these programs will be ignored. +}