diff --git a/Cabal-hooks/src/Distribution/Simple/SetupHooks.hs b/Cabal-hooks/src/Distribution/Simple/SetupHooks.hs index aaf0419733a..014508f40dd 100644 --- a/Cabal-hooks/src/Distribution/Simple/SetupHooks.hs +++ b/Cabal-hooks/src/Distribution/Simple/SetupHooks.hs @@ -428,10 +428,10 @@ rather than directly using the v'Rules', v'Rule' and v'Action' constructors, which insulates us from internal changes to the t'Rules', t'Rule' and t'Action' datatypes, respectively. -We use 'declareRuleDependencies' to declare that the collection of rules as a -whole depends on. In this case, we declare that they depend on the contents of -the "searchDir" directory. This means that the rules will be computed anew -whenever the contents of this directory change. +We use 'addRuleMonitorss' to declare a monitored directory that the collection +of rules as a whole depends on. In this case, we declare that they depend on the +contents of the "searchDir" directory. This means that the rules will be +computed anew whenever the contents of this directory change. Additional convenience functions are also provided, such as the 'generateModules' function which can be used to generate a collection of modules ex nihilo without @@ -633,7 +633,7 @@ register_helper mkId mkDupIdErr i newX = do [] -> "" (_, SrcLoc { srcLocPackage = pkg }) : _ -> toShortText pkg --- | Declare a dependency for the collection of all rules. +-- | Declare additional monitored objects for the collection of all rules. -- -- When these monitored objects change, the rules are re-computed. addRuleMonitors :: Monad m => [ MonitorFileOrDir ] -> RulesT m () @@ -641,8 +641,6 @@ addRuleMonitors = RulesT . lift . lift . Writer.tell {-# INLINEABLE addRuleMonitors #-} -- | Find a file in the given search directories. --- --- findFileInDirs :: FilePath -> [FilePath] -> IO (Maybe Location) findFileInDirs file dirs = findFirstFile diff --git a/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs b/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs index 5e6dbc22034..f7f44718bdf 100644 --- a/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs +++ b/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs @@ -203,7 +203,7 @@ data PreConfPackageInputs = PreConfPackageInputs -- of this datatype. data PreConfPackageOutputs = PreConfPackageOutputs { buildOptions :: BuildOptions - , extraConfiguredPrograms :: ConfiguredProgs + , extraConfiguredProgs :: ConfiguredProgs } deriving (Generic, Show) @@ -217,7 +217,7 @@ noPreConfPackageOutputs :: PreConfPackageInputs -> PreConfPackageOutputs noPreConfPackageOutputs (PreConfPackageInputs{localBuildConfig = lbc}) = PreConfPackageOutputs { buildOptions = LBC.withBuildOptions lbc - , extraConfiguredPrograms = Map.empty + , extraConfiguredProgs = Map.empty } -- | Package-wide post-configure step. @@ -349,12 +349,12 @@ instance Semigroup PreConfPkgSemigroup where do PreConfPackageOutputs { buildOptions = opts1 - , extraConfiguredPrograms = progs1 + , extraConfiguredProgs = progs1 } <- f1 inputs PreConfPackageOutputs { buildOptions = opts2 - , extraConfiguredPrograms = progs2 + , extraConfiguredProgs = progs2 } <- f2 $ PreConfPackageInputs @@ -372,7 +372,7 @@ instance Semigroup PreConfPkgSemigroup where return $ PreConfPackageOutputs { buildOptions = opts2 - , extraConfiguredPrograms = progs1 <> progs2 + , extraConfiguredProgs = progs1 <> progs2 } -- | A newtype to hang off the @Semigroup PreConfComponentHook@ instance. diff --git a/Cabal/src/Distribution/Simple/SetupHooks/Rule.hs b/Cabal/src/Distribution/Simple/SetupHooks/Rule.hs index 5cbb186ddc8..e80e561927f 100644 --- a/Cabal/src/Distribution/Simple/SetupHooks/Rule.hs +++ b/Cabal/src/Distribution/Simple/SetupHooks/Rule.hs @@ -249,7 +249,8 @@ instance Binary Rule instance Structured Rule -- | A (fully resolved) location of a dependency or result of a rule, --- consisting of an absolute path and of a file path relative to that base path. +-- consisting of a base directory and of a file path relative to that base +-- directory path. -- -- In practice, this will be something like @( dir, toFilePath modName )@, -- where: @@ -324,7 +325,7 @@ newtype Action -- \^ Locations of the __dependencies__ of this action, -- as declared by the rule that this action is executing. -> NE.NonEmpty Location - -- \^ Locations in which the __results_ of this action + -- \^ Locations in which the __results__ of this action -- should be put. -> IO () } @@ -341,8 +342,9 @@ simpleAction f = Action{action = f} -- constructor. -- -- Actions are registered using 'registerAction', and rules are registered --- using 'registerRule'. Additional rule dependencies (whose changes should --- trigger rule recompilation) are declared using 'declareRuleDependencies'. +-- using 'registerRule'. One can declare additional monitored files or +-- directories using 'addRuleMonitors'; a change in these will trigger the +-- recomputation of all rules. -- -- The @env@ type parameter represents an extra argument, which usually -- consists of information known to Cabal such as 'LocalBuildInfo' and diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff1/Setup.hs b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/Setup.hs new file mode 100644 index 00000000000..4ad8e7121af --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/Setup.hs @@ -0,0 +1,7 @@ +module Main where + +import Distribution.Simple ( defaultMainWithSetupHooks ) +import SetupHooks ( setupHooks ) + +main :: IO () +main = defaultMainWithSetupHooks setupHooks diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff1/SetupHooks.hs b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/SetupHooks.hs new file mode 100644 index 00000000000..d81c48d93e4 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/SetupHooks.hs @@ -0,0 +1,18 @@ +module SetupHooks where + +import Distribution.Simple.SetupHooks + +import Control.Monad ( void ) + +setupHooks :: SetupHooks +setupHooks = + noSetupHooks + { configureHooks = + noConfigureHooks + { preConfComponentHook = Just pccHook } + } + +pccHook :: PreConfComponentHook +pccHook _ = return $ + PreConfComponentOutputs $ ComponentDiff $ CExe emptyExecutable + -- Bad: component is a library, but we returned an executable! diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff1/cabal.project b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup-hooks-bad-diff1-test.cabal b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup-hooks-bad-diff1-test.cabal new file mode 100644 index 00000000000..803546c52ab --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup-hooks-bad-diff1-test.cabal @@ -0,0 +1,16 @@ +cabal-version: 2.2 +name: setup-hooks-bad-diff1-test +version: 0.1.0.0 +synopsis: Test 1 for a bad component diff +license: BSD-3-Clause +author: NA +maintainer: NA +category: Testing +build-type: Hooks + +custom-setup + setup-depends: Cabal-hooks, base + +library + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup.out b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup.out new file mode 100644 index 00000000000..2fdce2d44c0 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring setup-hooks-bad-diff1-test-0.1.0.0... +Error: [Cabal-9491] +Hooks: mismatched component types in per-component configure hook. +Trying to apply an executable diff to a library. diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup.test.hs b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup.test.hs new file mode 100644 index 00000000000..0096ff04cef --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff1/setup.test.hs @@ -0,0 +1,3 @@ +import Test.Cabal.Prelude +main = setupTest $ do + fails $ setup "configure" [] diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff2/Setup.hs b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/Setup.hs new file mode 100644 index 00000000000..4ad8e7121af --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/Setup.hs @@ -0,0 +1,7 @@ +module Main where + +import Distribution.Simple ( defaultMainWithSetupHooks ) +import SetupHooks ( setupHooks ) + +main :: IO () +main = defaultMainWithSetupHooks setupHooks diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff2/SetupHooks.hs b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/SetupHooks.hs new file mode 100644 index 00000000000..1c79900b639 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/SetupHooks.hs @@ -0,0 +1,27 @@ +{-# LANGUAGE OverloadedStrings #-} + +module SetupHooks where + +import Distribution.Simple.SetupHooks + +import Control.Monad ( void ) + +setupHooks :: SetupHooks +setupHooks = + noSetupHooks + { configureHooks = + noConfigureHooks + { preConfComponentHook = Just pccHook } + } + +pccHook :: PreConfComponentHook +pccHook _ = return $ + -- Make invalid changes to a library + PreConfComponentOutputs $ ComponentDiff $ CLib $ + emptyLibrary + { libName = LSubLibName "hocus-pocus" + , libExposed = False + , libBuildInfo = + emptyBuildInfo + { buildable = False } + } diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff2/cabal.project b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup-hooks-bad-diff2-test.cabal b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup-hooks-bad-diff2-test.cabal new file mode 100644 index 00000000000..40126f278f3 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup-hooks-bad-diff2-test.cabal @@ -0,0 +1,16 @@ +cabal-version: 2.2 +name: setup-hooks-bad-diff2-test +version: 0.1.0.0 +synopsis: Test 2 for a bad component diff +license: BSD-3-Clause +author: NA +maintainer: NA +category: Testing +build-type: Hooks + +custom-setup + setup-depends: Cabal-hooks, base + +library + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup.out b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup.out new file mode 100644 index 00000000000..0c9286b42dc --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup.out @@ -0,0 +1,7 @@ +# Setup configure +Configuring setup-hooks-bad-diff2-test-0.1.0.0... +Error: [Cabal-7634] +Hooks: illegal component diff in per-component pre-configure hook for main library: + - cannot change the name of a component. + - cannot change component field 'libExposed'. + - cannot change BuildInfo field 'buildable'. diff --git a/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup.test.hs b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup.test.hs new file mode 100644 index 00000000000..0096ff04cef --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksBadDiff2/setup.test.hs @@ -0,0 +1,3 @@ +import Test.Cabal.Prelude +main = setupTest $ do + fails $ setup "configure" [] diff --git a/cabal-testsuite/PackageTests/SetupHooksCyclicRules/Setup.hs b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/Setup.hs new file mode 100644 index 00000000000..4ad8e7121af --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/Setup.hs @@ -0,0 +1,7 @@ +module Main where + +import Distribution.Simple ( defaultMainWithSetupHooks ) +import SetupHooks ( setupHooks ) + +main :: IO () +main = defaultMainWithSetupHooks setupHooks diff --git a/cabal-testsuite/PackageTests/SetupHooksCyclicRules/SetupHooks.hs b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/SetupHooks.hs new file mode 100644 index 00000000000..857915b1bc9 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/SetupHooks.hs @@ -0,0 +1,34 @@ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecursiveDo #-} + +module SetupHooks where + +import Distribution.Simple.SetupHooks + +import qualified Data.List.NonEmpty as NE ( NonEmpty(..) ) + +setupHooks :: SetupHooks +setupHooks = + noSetupHooks + { buildHooks = + noBuildHooks + { preBuildComponentRules = Just cyclicPreBuildRules + } + } + +cyclicPreBuildRules :: Rules PreBuildComponentInputs +cyclicPreBuildRules = rules $ \ (PreBuildComponentInputs { localBuildInfo = lbi, targetInfo = tgt }) -> do + let clbi = targetCLBI tgt + autogenDir = autogenComponentModulesDir lbi clbi + actId <- registerAction "a" $ simpleAction $ \ _ _ -> error "This should not run" + return $ mdo + r1 <- registerRule "r1" $ + simpleRule actId + [ RuleDependency $ RuleOutput r2 0 ] + ( ( autogenDir, "G2.hs" ) NE.:| [] ) + r2 <- registerRule "r2" $ + simpleRule actId + [ RuleDependency $ RuleOutput r1 0 ] + ( ( autogenDir, "G1.hs" ) NE.:| [] ) + return () diff --git a/cabal-testsuite/PackageTests/SetupHooksCyclicRules/cabal.project b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup-hooks-cyclic-rules-test.cabal b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup-hooks-cyclic-rules-test.cabal new file mode 100644 index 00000000000..d7c54b75abd --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup-hooks-cyclic-rules-test.cabal @@ -0,0 +1,18 @@ +cabal-version: 2.2 +name: setup-hooks-cyclic-rules-test +version: 0.1.0.0 +synopsis: Test for cyclic rules +license: BSD-3-Clause +author: NA +maintainer: NA +category: Testing +build-type: Hooks + +custom-setup + setup-depends: Cabal-hooks, base + +library + exposed-modules: G1, G2 + autogen-modules: G1, G2 + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup.out b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup.out new file mode 100644 index 00000000000..145aaee0f64 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup.out @@ -0,0 +1,9 @@ +# Setup configure +Configuring setup-hooks-cyclic-rules-test-0.1.0.0... +# Setup build +Error: [Cabal-9077] +Hooks: cycle in dependency structure of rules: + Rule: [(RuleId {ruleUnitId = "main", ruleId = "r2"})[0]] --> [setup.dist/work/dist/build/autogen/G2.hs] + | + `- Rule: [(RuleId {ruleUnitId = "main", ruleId = "r1"})[0]] --> [setup.dist/work/dist/build/autogen/G1.hs] + diff --git a/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup.test.hs b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup.test.hs new file mode 100644 index 00000000000..370c60bd0f1 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksCyclicRules/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +main = setupTest $ do + setup "configure" [] + fails $ setup "build" [] diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/Setup.hs b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/Setup.hs new file mode 100644 index 00000000000..4ad8e7121af --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/Setup.hs @@ -0,0 +1,7 @@ +module Main where + +import Distribution.Simple ( defaultMainWithSetupHooks ) +import SetupHooks ( setupHooks ) + +main :: IO () +main = defaultMainWithSetupHooks setupHooks diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/SetupHooks.hs b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/SetupHooks.hs new file mode 100644 index 00000000000..c554667cc59 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/SetupHooks.hs @@ -0,0 +1,28 @@ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE OverloadedStrings #-} + +module SetupHooks where + +import Distribution.Simple.SetupHooks + +import qualified Data.List.NonEmpty as NE ( NonEmpty(..) ) + +setupHooks :: SetupHooks +setupHooks = + noSetupHooks + { buildHooks = + noBuildHooks + { preBuildComponentRules = Just missingDepRules + } + } + +missingDepRules :: Rules PreBuildComponentInputs +missingDepRules = rules $ \ (PreBuildComponentInputs { localBuildInfo = lbi, targetInfo = tgt }) -> do + let clbi = targetCLBI tgt + autogenDir = autogenComponentModulesDir lbi clbi + actId <- registerAction "a" $ simpleAction $ \ _ _ -> error "This should not run" + return $ + registerRule_ "r" $ + simpleRule actId + [ FileDependency ( ".", "Missing.hs" ) ] + ( ( autogenDir, "G.hs" ) NE.:| [] ) diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/cabal.project b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup-hooks-missing-rule-dep-test.cabal b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup-hooks-missing-rule-dep-test.cabal new file mode 100644 index 00000000000..31a3143ab10 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup-hooks-missing-rule-dep-test.cabal @@ -0,0 +1,18 @@ +cabal-version: 2.2 +name: setup-hooks-missing-rule-dep-test +version: 0.1.0.0 +synopsis: Test for missing dependency in rules +license: BSD-3-Clause +author: NA +maintainer: NA +category: Testing +build-type: Hooks + +custom-setup + setup-depends: Cabal-hooks, base + +library + exposed-modules: G + autogen-modules: G + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup.out b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup.out new file mode 100644 index 00000000000..bfbd911994d --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup.out @@ -0,0 +1,6 @@ +# Setup configure +Configuring setup-hooks-missing-rule-dep-test-0.1.0.0... +# Setup build +Error: [Cabal-1071] +Pre-build rules: can't find source for rule dependency: + - Missing.hs diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup.test.hs b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup.test.hs new file mode 100644 index 00000000000..370c60bd0f1 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleDep/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +main = setupTest $ do + setup "configure" [] + fails $ setup "build" [] diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/Setup.hs b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/Setup.hs new file mode 100644 index 00000000000..4ad8e7121af --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/Setup.hs @@ -0,0 +1,7 @@ +module Main where + +import Distribution.Simple ( defaultMainWithSetupHooks ) +import SetupHooks ( setupHooks ) + +main :: IO () +main = defaultMainWithSetupHooks setupHooks diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/SetupHooks.hs b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/SetupHooks.hs new file mode 100644 index 00000000000..5c119cca170 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/SetupHooks.hs @@ -0,0 +1,28 @@ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE OverloadedStrings #-} + +module SetupHooks where + +import Distribution.Simple.SetupHooks + +import qualified Data.List.NonEmpty as NE ( NonEmpty(..) ) + +setupHooks :: SetupHooks +setupHooks = + noSetupHooks + { buildHooks = + noBuildHooks + { preBuildComponentRules = Just missingResRules + } + } + +missingResRules :: Rules PreBuildComponentInputs +missingResRules = rules $ \ (PreBuildComponentInputs { localBuildInfo = lbi, targetInfo = tgt }) -> do + let clbi = targetCLBI tgt + autogenDir = autogenComponentModulesDir lbi clbi + actId <- registerAction "a" $ simpleAction $ \ _ _ -> return () + return $ + registerRule_ "r" $ + simpleRule actId + [ ] + ( ( autogenDir, "G.hs" ) NE.:| [] ) diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/cabal.project b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup-hooks-missing-rule-res-test.cabal b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup-hooks-missing-rule-res-test.cabal new file mode 100644 index 00000000000..77159309464 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup-hooks-missing-rule-res-test.cabal @@ -0,0 +1,18 @@ +cabal-version: 2.2 +name: setup-hooks-missing-rule-res-test +version: 0.1.0.0 +synopsis: Test for missing result in rules +license: BSD-3-Clause +author: NA +maintainer: NA +category: Testing +build-type: Hooks + +custom-setup + setup-depends: Cabal-hooks, base + +library + exposed-modules: G + autogen-modules: G + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup.out b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup.out new file mode 100644 index 00000000000..5659bca63e1 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup.out @@ -0,0 +1,6 @@ +# Setup configure +Configuring setup-hooks-missing-rule-res-test-0.1.0.0... +# Setup build +Error: [Cabal-3498] +Pre-build rule did not generate expected result: + - setup.dist/work/dist/build/autogen/G.hs diff --git a/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup.test.hs b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup.test.hs new file mode 100644 index 00000000000..370c60bd0f1 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksMissingRuleRes/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +main = setupTest $ do + setup "configure" [] + fails $ setup "build" [] diff --git a/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/A.hs b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/A.hs new file mode 100644 index 00000000000..2f20e91a6c1 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/A.hs @@ -0,0 +1 @@ +module A where {} diff --git a/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/Setup.hs b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/Setup.hs new file mode 100644 index 00000000000..4ad8e7121af --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/Setup.hs @@ -0,0 +1,7 @@ +module Main where + +import Distribution.Simple ( defaultMainWithSetupHooks ) +import SetupHooks ( setupHooks ) + +main :: IO () +main = defaultMainWithSetupHooks setupHooks diff --git a/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/SetupHooks.hs b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/SetupHooks.hs new file mode 100644 index 00000000000..97305048493 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/SetupHooks.hs @@ -0,0 +1,60 @@ +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecursiveDo #-} + +module SetupHooks where + +import Distribution.Simple.SetupHooks +import Distribution.Simple.Utils ( rewriteFileEx, warn ) + +import Data.Foldable ( for_ ) +import qualified Data.List.NonEmpty as NE ( NonEmpty(..) ) +import Data.Traversable ( for ) + +import System.FilePath + ( (<.>), () ) + +setupHooks :: SetupHooks +setupHooks = + noSetupHooks + { buildHooks = + noBuildHooks + { preBuildComponentRules = Just preBuildRules + } + } + +-- Register three rules: +-- +-- r1: B --> C +-- r2: A --> B +-- r3: C --> D +-- +-- and check that we run them in dependency order, i.e. r2, r1, r3. +preBuildRules :: Rules PreBuildComponentInputs +preBuildRules = rules $ \ (PreBuildComponentInputs { buildingWhat = what, localBuildInfo = lbi, targetInfo = tgt }) -> do + let verbosity = buildingWhatVerbosity what + clbi = targetCLBI tgt + autogenDir = autogenComponentModulesDir lbi clbi + + mkAction inMod outMod = + simpleAction $ \ _ locs -> do + warn verbosity $ "Running rule: " ++ inMod ++ " --> " ++ outMod + let loc = autogenDir outMod <.> "hs" + rewriteFileEx verbosity loc $ + "module " ++ outMod ++ " where { import " ++ inMod ++ " }" + + mkRule actId input outMod = + simpleRule actId + [ input ] + ( ( autogenDir, outMod <.> "hs" ) NE.:| [] ) + + a1 <- registerAction "a1" $ mkAction "B" "C" + a2 <- registerAction "a2" $ mkAction "A" "B" + a3 <- registerAction "a3" $ mkAction "C" "D" + + return $ mdo + r1 <- registerRule "r1" $ mkRule a1 (RuleDependency $ RuleOutput r2 0) "C" -- B --> C + r2 <- registerRule "r2" $ mkRule a2 (FileDependency (".", "A.hs")) "B" -- A --> B + r3 <- registerRule "r3" $ mkRule a3 (RuleDependency $ RuleOutput r1 0) "D" -- C --> D + return () diff --git a/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/cabal.project b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup-hooks-rule-ordering-test.cabal b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup-hooks-rule-ordering-test.cabal new file mode 100644 index 00000000000..8a5c89c6dcd --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup-hooks-rule-ordering-test.cabal @@ -0,0 +1,18 @@ +cabal-version: 2.2 +name: setup-hooks-rule-ordering-test +version: 0.1.0.0 +synopsis: Test that we execute pre-build rules in the correct order +license: BSD-3-Clause +author: NA +maintainer: NA +category: Testing +build-type: Hooks + +custom-setup + setup-depends: Cabal, Cabal-hooks, base, filepath + +library + exposed-modules: A, B, C, D + autogen-modules: B, C, D + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup.out b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup.out new file mode 100644 index 00000000000..ccc3b1e7489 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup.out @@ -0,0 +1,8 @@ +# Setup configure +Configuring setup-hooks-rule-ordering-test-0.1.0.0... +# Setup build +Warning: Running rule: A --> B +Warning: Running rule: B --> C +Warning: Running rule: C --> D +Preprocessing library for setup-hooks-rule-ordering-test-0.1.0.0... +Building library for setup-hooks-rule-ordering-test-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup.test.hs b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup.test.hs new file mode 100644 index 00000000000..2df426a5dbf --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksRuleOrdering/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +main = setupTest $ do + setup "configure" [] + setup "build" [] diff --git a/cabal-testsuite/PackageTests/SetupHooksUnusedRules/Setup.hs b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/Setup.hs new file mode 100644 index 00000000000..4ad8e7121af --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/Setup.hs @@ -0,0 +1,7 @@ +module Main where + +import Distribution.Simple ( defaultMainWithSetupHooks ) +import SetupHooks ( setupHooks ) + +main :: IO () +main = defaultMainWithSetupHooks setupHooks diff --git a/cabal-testsuite/PackageTests/SetupHooksUnusedRules/SetupHooks.hs b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/SetupHooks.hs new file mode 100644 index 00000000000..ca53c76da20 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/SetupHooks.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE OverloadedStrings #-} + +module SetupHooks where + +import Distribution.Simple.SetupHooks + +import qualified Data.List.NonEmpty as NE ( NonEmpty(..) ) + +setupHooks :: SetupHooks +setupHooks = + noSetupHooks + { buildHooks = + noBuildHooks + { preBuildComponentRules = Just unusedPreBuildRules + } + } + +unusedPreBuildRules :: Rules PreBuildComponentInputs +unusedPreBuildRules = rules $ \ (PreBuildComponentInputs { localBuildInfo = lbi, targetInfo = tgt }) -> do + let clbi = targetCLBI tgt + autogenDir = autogenComponentModulesDir lbi clbi + actId <- registerAction "a" $ simpleAction $ \ _ _ -> error "This should not run" + return $ do + registerRule_ "r1" $ + simpleRule actId [] + ( ( autogenDir, "X.hs" ) NE.:| [ ( autogenDir, "Y.hs" ) ] ) + registerRule_ "r2" $ + simpleRule actId [] + ( ( autogenDir, "Z.what" ) NE.:| [] ) diff --git a/cabal-testsuite/PackageTests/SetupHooksUnusedRules/cabal.project b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup-hooks-unused-rules-test.cabal b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup-hooks-unused-rules-test.cabal new file mode 100644 index 00000000000..f16733b1edb --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup-hooks-unused-rules-test.cabal @@ -0,0 +1,16 @@ +cabal-version: 2.2 +name: setup-hooks-unused-rules-test +version: 0.1.0.0 +synopsis: Test for unused pre-build rules +license: BSD-3-Clause +author: NA +maintainer: NA +category: Testing +build-type: Hooks + +custom-setup + setup-depends: Cabal-hooks, base + +library + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup.out b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup.out new file mode 100644 index 00000000000..a6343b4d14d --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup.out @@ -0,0 +1,9 @@ +# Setup configure +Configuring setup-hooks-unused-rules-test-0.1.0.0... +# Setup build +Warning: The following rules are not demanded and will not be run: + - RuleId {ruleUnitId = "main", ruleId = "r1"}, generating [setup.dist/work/dist/build/autogen/X.hs, setup.dist/work/dist/build/autogen/Y.hs] + - RuleId {ruleUnitId = "main", ruleId = "r2"}, generating [setup.dist/work/dist/build/autogen/Z.what] +Perhaps some autogenerated modules were not declared at the configure stage? +Preprocessing library for setup-hooks-unused-rules-test-0.1.0.0... +Building library for setup-hooks-unused-rules-test-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup.test.hs b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup.test.hs new file mode 100644 index 00000000000..2df426a5dbf --- /dev/null +++ b/cabal-testsuite/PackageTests/SetupHooksUnusedRules/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +main = setupTest $ do + setup "configure" [] + setup "build" [] diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index 677fcdce098..3dc04706a90 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -127,6 +127,7 @@ executable test-runtime-deps directory, Cabal, Cabal-syntax, + Cabal-hooks, filepath, transformers, bytestring, diff --git a/cabal.project.buildinfo b/cabal.project.buildinfo index 839f35c5805..25ed5d8d11f 100644 --- a/cabal.project.buildinfo +++ b/cabal.project.buildinfo @@ -1,5 +1,6 @@ packages: Cabal-syntax/ packages: Cabal/ +packages: Cabal-hooks/ packages: Cabal-described packages: buildinfo-reference-generator/ tests: False diff --git a/cabal.project.doctest b/cabal.project.doctest index dac9b0d88a9..5c2d1fe2261 100644 --- a/cabal.project.doctest +++ b/cabal.project.doctest @@ -1,5 +1,6 @@ packages: Cabal-syntax/ packages: Cabal/ +packages: Cabal-hooks packages: cabal-testsuite/ packages: cabal-install/ packages: solver-benchmarks/ diff --git a/cabal.project.libonly b/cabal.project.libonly index 59873fd4ad1..92465594424 100644 --- a/cabal.project.libonly +++ b/cabal.project.libonly @@ -1,4 +1,4 @@ -packages: Cabal-syntax/ Cabal/ cabal-testsuite/ +packages: Cabal-syntax/ Cabal/ Cabal-hooks/ cabal-testsuite/ packages: Cabal-QuickCheck/ packages: Cabal-tree-diff diff --git a/cabal.project.release b/cabal.project.release index 8d171824287..9d98c00cbb9 100644 --- a/cabal.project.release +++ b/cabal.project.release @@ -1,5 +1,6 @@ packages: Cabal-syntax/ packages: Cabal/ +packages: Cabal-hooks/ packages: cabal-install-solver/ packages: cabal-install/ tests: False diff --git a/cabal.project.validate b/cabal.project.validate index d3583c31b0e..2b05ee4dac0 100644 --- a/cabal.project.validate +++ b/cabal.project.validate @@ -2,6 +2,7 @@ import: cabal.project.latest-ghc packages: Cabal-syntax/ packages: Cabal/ +packages: Cabal-hooks/ packages: cabal-testsuite/ packages: cabal-install/ packages: solver-benchmarks/ @@ -28,6 +29,8 @@ package Cabal-syntax ghc-options: -Werror package Cabal ghc-options: -Werror +package Cabal-hooks + ghc-options: -Werror package cabal-testsuite ghc-options: -Werror package cabal-install diff --git a/cabal.project.validate.libonly b/cabal.project.validate.libonly index 3baafa1661a..a2e5c2708cf 100644 --- a/cabal.project.validate.libonly +++ b/cabal.project.validate.libonly @@ -1,5 +1,6 @@ packages: Cabal-syntax/ packages: Cabal/ +packages: Cabal-hooks/ packages: cabal-testsuite/ packages: Cabal-QuickCheck/ packages: Cabal-tree-diff diff --git a/cabal.project.weeder b/cabal.project.weeder index 5fa8357bd6a..5ff25e38631 100644 --- a/cabal.project.weeder +++ b/cabal.project.weeder @@ -6,6 +6,7 @@ packages: Cabal-syntax/ packages: Cabal/ +packages: Cabal-hooks/ packages: cabal-install/ tests: False diff --git a/validate.sh b/validate.sh index aa60c17ab20..00977744c1f 100755 --- a/validate.sh +++ b/validate.sh @@ -280,7 +280,7 @@ if [ -z "$STEPS" ]; then STEPS="$STEPS time-summary" fi -TARGETS="Cabal cabal-testsuite Cabal-tests Cabal-QuickCheck Cabal-tree-diff Cabal-described" +TARGETS="Cabal Cabal-hooks cabal-testsuite Cabal-tests Cabal-QuickCheck Cabal-tree-diff Cabal-described" if ! $LIBONLY; then TARGETS="$TARGETS cabal-install cabal-install-solver cabal-benchmarks"; fi if $BENCHMARKS; then TARGETS="$TARGETS solver-benchmarks"; fi