agda / agda

Agda is a dependently typed programming language / interactive theorem prover.

Home Page:https://wiki.portal.chalmers.se/agda/pmwiki.php

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Future: cabal build-type `Setup` will be phased out in favor of `Hooks`

andreasabel opened this issue · comments

In the long run, cabal build-type Setup will be phased out in favor of Hooks.
The authors of Hooks (in development) at WellTyped have provided a patch we can use in the future (thanks @alt-romes!):
https://gitlab.haskell.org/mpickering/hooks-setup-testing/-/blob/a664eb3cf456ad8e6e4f922406f1f904575339b5/patches/Agda-2.6.3.patch

diff --git a/Agda.cabal b/Agda.cabal
index 306f81f..5aa17c3 100644
--- a/Agda.cabal
+++ b/Agda.cabal
@@ -1,7 +1,7 @@
 name:            Agda
 version:         2.6.3
 cabal-version:   1.24
-build-type:      Custom
+build-type:      Hooks
 license:         OtherLicense
 license-file:    LICENSE
 copyright:       (c) 2005-2023 The Agda Team.
@@ -172,7 +172,7 @@ flag optimise-heavily
 
 custom-setup
   setup-depends:  base >= 4.9.0.0 && < 4.18
-                , Cabal >= 1.24.0.0 && < 3.9
+                , Cabal >= 1.24.0.0 && < 3.12
                 , directory >= 1.2.6.2 && < 1.4
                 , filepath >= 1.4.1.0 && < 1.5
                 , process >= 1.4.2.0 && < 1.7
diff --git a/Setup.hs b/SetupHooks.hs
similarity index 53%
rename from Setup.hs
rename to SetupHooks.hs
index 3a42cd2..5dd1b3c 100644
--- a/Setup.hs
+++ b/SetupHooks.hs
@@ -1,16 +1,19 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE NondecreasingIndentation #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module SetupHooks ( setupHooks ) where
 
 import Data.Maybe
 
 import Distribution.Simple
 import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Install (installFileGlob)
 import Distribution.Simple.Setup
+import Distribution.Simple.SetupHooks
 import Distribution.Simple.BuildPaths (exeExtension)
+import Distribution.Types.TargetInfo (TargetInfo(..))
 import Distribution.PackageDescription
-#if MIN_VERSION_Cabal(2,3,0)
 import Distribution.System ( buildPlatform )
-#endif
 import System.FilePath
 import System.Directory (makeAbsolute, removeFile)
 import System.Environment (getEnvironment)
@@ -19,58 +22,52 @@ import System.Exit
 import System.IO
 import System.IO.Error (isDoesNotExistError)
 
-import Control.Monad (forM_, unless)
+import Control.Monad (when, unless)
 import Control.Exception (bracket, catch, throwIO)
-
-main :: IO ()
-main = defaultMainWithHooks userhooks
-
-userhooks :: UserHooks
-userhooks = simpleUserHooks
-  { copyHook  = copyHook'
-  , instHook  = instHook'
-  }
-
--- Install and copy hooks are default, but amended with .agdai files in data-files.
-instHook' :: PackageDescription -> LocalBuildInfo -> UserHooks -> InstallFlags -> IO ()
-instHook' pd lbi hooks flags = instHook simpleUserHooks pd' lbi hooks flags where
-  pd' = pd { dataFiles = concatMap expandAgdaExt $ dataFiles pd }
-
--- Andreas, 2020-04-25, issue #4569: defer 'generateInterface' until after
--- the library has been copied to a destination where it can be found.
--- @cabal build@ will likely no longer produce the .agdai files, but @cabal install@ does.
-copyHook' :: PackageDescription -> LocalBuildInfo -> UserHooks -> CopyFlags -> IO ()
-copyHook' pd lbi hooks flags = do
-  -- Copy library and executable etc.
-  copyHook simpleUserHooks pd lbi hooks flags
-  unless (skipInterfaces lbi) $ do
-    -- Generate .agdai files.
-    generateInterfaces pd lbi
-    -- Copy again, now including the .agdai files.
-    copyHook simpleUserHooks pd' lbi hooks flags
-  where
-  pd' = pd
-    { dataFiles = concatMap expandAgdaExt $ dataFiles pd
-      -- Andreas, 2020-04-25, issue #4569:
-      -- I tried clearing some fields to avoid copying again.
-      -- However, cabal does not like me messing with the PackageDescription.
-      -- Clearing @library@ or @executables@ leads to internal errors.
-      -- Thus, we just copy things again.  Not a terrible problem.
-    -- , library       = Nothing
-    -- , executables   = []
-    -- , subLibraries  = []
-    -- , foreignLibs   = []
-    -- , testSuites    = []
-    -- , benchmarks    = []
-    -- , extraSrcFiles = []
-    -- , extraTmpFiles = []
-    -- , extraDocFiles = []
+import Data.Foldable (for_)
+
+setupHooks :: SetupHooks
+setupHooks =
+  noSetupHooks
+    { buildHooks =
+        noBuildHooks
+          { postBuildComponentHook = Just $
+              \ _ lbi tgt ->
+                when   ( isMainExecutable tgt ) $
+                unless ( skipInterfaces lbi ) $
+                  generateInterfaces lbi
+          }
+    , copyHooks =
+        noCopyHooks
+          { postCopyComponentHook = Just $
+              \ lbi flags tgt ->
+                when   ( isMainExecutable tgt ) $
+                unless ( skipInterfaces lbi ) $
+                  copyInterfaceFiles lbi flags
+          }
     }
 
--- Used to add .agdai files to data-files
-expandAgdaExt :: FilePath -> [FilePath]
-expandAgdaExt fp | takeExtension fp == ".agda" = [ fp, toIFile fp ]
-                 | otherwise                   = [ fp ]
+isMainExecutable :: TargetInfo -> Bool
+isMainExecutable ( TargetInfo { targetComponent = comp } )
+  | CExeName "agda" <- componentName comp
+  = True
+  | otherwise
+  = False
+
+-- | For each ".agda" file in the data files stanza of the package description,
+-- copy the corresponding ".agdai" interface file.
+copyInterfaceFiles :: LocalBuildInfo -> CopyFlags -> IO ()
+copyInterfaceFiles lbi flags = do
+  let pd  = localPkgDescr lbi
+      src = dataDir pd
+      dst = datadir $ absoluteInstallDirs pd lbi ( fromFlag $ copyDest flags )
+  for_ ( dataFiles pd ) $ \ fp ->
+    when ( takeExtension fp == ".agda" ) $
+      installFileGlob
+        ( fromFlag $ copyVerbosity flags )
+        ( specVersion pd )
+        ( src, dst )
+        ( toIFile fp )
 
 toIFile :: FilePath -> FilePath
 toIFile file = replaceExtension file ".agdai"
@@ -80,15 +77,16 @@ toIFile file = replaceExtension file ".agdai"
 skipInterfaces :: LocalBuildInfo -> Bool
 skipInterfaces lbi = fromPathTemplate (progSuffix lbi) == "-quicker"
 
-generateInterfaces :: PackageDescription -> LocalBuildInfo -> IO ()
-generateInterfaces pd lbi = do
+generateInterfaces :: LocalBuildInfo -> IO ()
+generateInterfaces lbi = do
 
   -- for debugging, these are examples how you can inspect the flags...
   -- print $ flagAssignment lbi
   -- print $ fromPathTemplate $ progSuffix lbi
 
   -- then...
-  let bdir = buildDir lbi
+  let pd = localPkgDescr lbi
+      bdir = buildDir lbi
       agda = bdir </> "agda" </> "agda" <.> agdaExeExtension
 
   ddir <- makeAbsolute $ "src" </> "data"
@@ -102,7 +100,7 @@ generateInterfaces pd lbi = do
   let builtins = filter ((== ".agda") . takeExtension) (dataFiles pd)
 
   -- Remove all existing .agdai files.
-  forM_ builtins $ \fp -> do
+  for_ builtins $ \fp -> do
     let fullpathi = toIFile (ddir </> fp)
 
         handleExists e | isDoesNotExistError e = return ()
@@ -140,8 +138,4 @@ generateInterfaces pd lbi = do
   return ()
 
 agdaExeExtension :: String
-#if MIN_VERSION_Cabal(2,3,0)
 agdaExeExtension = exeExtension buildPlatform
-#else
-agdaExeExtension = exeExtension
-#endif