Skip to content

Commit b5522ec

Browse files
committed
Hooks: use the appropriate Cabal unit ID
This commit updates the logic in SetupWrapper for determining which installed Cabal unit ID to use. When we are compiling a package with build-type Hooks via an external Setup executable, we need to add a dependency on Cabal. However, we must be sure to use the same version of Cabal that the Cabal-hooks dependency depends on, to avoid #11331. Fixes #11331
1 parent 8e8a839 commit b5522ec

5 files changed

Lines changed: 104 additions & 3 deletions

File tree

cabal-install/src/Distribution/Client/SetupWrapper.hs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -908,8 +908,22 @@ getExternalSetupMethod verbosity options pkg bt = do
908908
[] ->
909909
dieWithException verbosity $ InstalledCabalVersion (packageName pkg) (useCabalVersion options)
910910
pkgs ->
911-
let ipkginfo = fromMaybe err $ safeHead . snd . bestVersion fst $ pkgs
912-
err = error "Distribution.Client.installedCabalVersion: empty version list"
911+
let ipkginfo
912+
-- If using build-type: Hooks, pick the Cabal unit Id that is
913+
-- a dependency of Cabal-hooks (#11331).
914+
--
915+
-- This is not very elegant, but the alternative of adding a
916+
-- Cabal dependency BEFORE solving is not appropriate, because
917+
-- we only need Cabal to compile Setup.hs. It would be wrong to
918+
-- impose a Cabal dependency in the general case
919+
-- (e.g. compiling an external Hooks executable).
920+
| bt == Hooks
921+
, Just (cabalHooksCompId, _) <- find (isCabalHooksPkgId . snd) (useDependencies options)
922+
, Just cabalHooksIPI <- PackageIndex.lookupComponentId index cabalHooksCompId
923+
, Just cabalIPI <- find (isCabalPkgId . IPI.sourcePackageId) $ mapMaybe (PackageIndex.lookupUnitId index) (IPI.depends cabalHooksIPI)
924+
= cabalIPI
925+
| let err = error "Distribution.Client.installedCabalVersion: empty version list"
926+
= fromMaybe err $ safeHead . snd . bestVersion fst $ pkgs
913927
in return
914928
( packageVersion ipkginfo
915929
, Just . IPI.installedComponentId $ ipkginfo
@@ -1166,6 +1180,7 @@ getExternalSetupMethod verbosity options pkg bt = do
11661180
hPutStr logHandle output
11671181
return $ i setupProgFile
11681182

1169-
isCabalPkgId, isBasePkgId :: PackageIdentifier -> Bool
1183+
isCabalPkgId, isCabalHooksPkgId, isBasePkgId :: PackageIdentifier -> Bool
11701184
isCabalPkgId (PackageIdentifier pname _) = pname == mkPackageName "Cabal"
1185+
isCabalHooksPkgId (PackageIdentifier pname _) = pname == mkPackageName "Cabal-hooks"
11711186
isBasePkgId (PackageIdentifier pname _) = pname == mkPackageName "base"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE OverloadedRecordDot #-}
3+
4+
module SetupHooks (setupHooks) where
5+
6+
-- Cabal
7+
import Distribution.Simple.Flag (fromFlag)
8+
import Distribution.Simple.Setup (CommonSetupFlags (..))
9+
import qualified Distribution.Simple.Utils as Utils
10+
import Distribution.Types.LocalBuildConfig (PackageBuildDescr (..))
11+
import Distribution.Verbosity
12+
13+
-- Cabal-hooks
14+
import qualified Distribution.Simple.SetupHooks as SetupHooks
15+
16+
--------------------------------------------------------------------------------
17+
18+
setupHooks :: SetupHooks.SetupHooks
19+
setupHooks = SetupHooks.noSetupHooks {
20+
SetupHooks.configureHooks = myConfigureHooks
21+
}
22+
23+
myConfigureHooks :: SetupHooks.ConfigureHooks
24+
myConfigureHooks = SetupHooks.noConfigureHooks {
25+
SetupHooks.postConfPackageHook = Just myPostConfPackageHook
26+
}
27+
28+
myPostConfPackageHook :: SetupHooks.PostConfPackageInputs -> IO ()
29+
myPostConfPackageHook pcpi = do
30+
Utils.notice verb "Hello, world"
31+
where
32+
verb = getVerbosity pcpi.packageBuildDescr
33+
34+
getVerbosity :: PackageBuildDescr -> Verbosity
35+
getVerbosity pbd =
36+
fromFlag pbd.configFlags.configCommonFlags.setupVerbosity
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
cabal-version: 3.14
2+
name: T11331
3+
version: 0.1.0.0
4+
synopsis: Test for Cabal bug 11331
5+
license: BSD-3-Clause
6+
author: NA
7+
maintainer: NA
8+
category: Testing
9+
build-type: Hooks
10+
11+
custom-setup
12+
setup-depends:
13+
base, Cabal-hooks
14+
15+
library
16+
default-language: Haskell2010
17+
-- The test adds "build-depends: containers" for a specific version of containers
18+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages: .
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Test.Cabal.Prelude
2+
import System.Directory ( copyFile )
3+
4+
-- Test for https://github.com/haskell/cabal/issues/11331
5+
main = cabalTest $ do
6+
7+
mpkgdb <- testPackageDbPath <$> getTestEnv
8+
case mpkgdb of
9+
Nothing -> skip "Cabal-hooks library unavailable."
10+
Just _pkgdb -> recordMode DoNotRecord $ do
11+
12+
cwd <- testCurrentDir <$> getTestEnv
13+
let
14+
cabalTemplate = cwd </> "T11331.cabal.in"
15+
cabalFile = cwd </> "T11331.cabal"
16+
17+
-- Add a dependency on 'containers == 0.7' to the library stanza.
18+
liftIO $ do
19+
copyFile cabalTemplate cabalFile
20+
appendFile cabalFile " build-depends: containers == 0.7"
21+
22+
cabal "v2-build" []
23+
24+
cabal "v2-clean" []
25+
26+
-- Change the dependency to 'containers == 0.8'
27+
liftIO $ do
28+
copyFile cabalTemplate cabalFile
29+
appendFile cabalFile " build-depends: containers == 0.8"
30+
31+
cabal "v2-build" []

0 commit comments

Comments
 (0)