File: Setup.hs

package info (click to toggle)
haskell-stack 2.15.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,568 kB
  • sloc: haskell: 37,057; makefile: 6; ansic: 5
file content (76 lines) | stat: -rw-r--r-- 3,752 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module Main
  ( main
  ) where

import           Data.List ( nub, sortOn )
import           Distribution.InstalledPackageInfo
                   ( sourcePackageId, installedUnitId )
import           Distribution.Package ( UnitId, packageVersion, packageName )
import           Distribution.PackageDescription
                   ( PackageDescription (), Executable (..) )
import           Distribution.Pretty ( prettyShow )
import           Distribution.Simple
                   ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )
import           Distribution.Simple.BuildPaths ( autogenPackageModulesDir )
import           Distribution.Simple.LocalBuildInfo
                   ( installedPkgs, withLibLBI, withExeLBI, LocalBuildInfo ()
                   , ComponentLocalBuildInfo (componentPackageDeps)
                   )
import           Distribution.Simple.PackageIndex
                   ( allPackages, dependencyClosure )
import           Distribution.Simple.Setup
                   ( BuildFlags (..), ReplFlags (..), fromFlag )
import           Distribution.Simple.Utils
                   ( rewriteFileEx, createDirectoryIfMissingVerbose )
import           Distribution.Types.PackageName ( unPackageName )
import           Distribution.Types.UnqualComponentName
                   ( unUnqualComponentName )
import           Distribution.Verbosity ( Verbosity, normal )
import           System.FilePath ( (</>) )

main :: IO ()
main = defaultMainWithHooks simpleUserHooks
  { buildHook = \pkg lbi hooks flags -> do
      generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi
      buildHook simpleUserHooks pkg lbi hooks flags
    -- The 'cabal repl' hook corresponds to the 'cabal build' hook and is added
    -- because, with a Cabal-based cradle, Haskell Language Server makes use of
    -- 'cabal repl'.
  , replHook = \pkg lbi hooks flags args -> do
      generateBuildModule (fromFlag (replVerbosity flags)) pkg lbi
      replHook simpleUserHooks pkg lbi hooks flags args
  }

generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
generateBuildModule verbosity pkg lbi = do
  let dir = autogenPackageModulesDir lbi
  createDirectoryIfMissingVerbose verbosity True dir
  withLibLBI pkg lbi $ \_ libcfg -> do
    withExeLBI pkg lbi $ \exe clbi ->
      rewriteFileEx normal (dir </> "Build_" ++ exeName' exe ++ ".hs") $ unlines
        [ "module Build_" ++ exeName' exe
        , "  ( deps"
        , "  ) where"
        , ""
        , "deps :: [String]"
        , "deps = " ++ show (formatdeps (transDeps libcfg clbi))
        ]
  where
    exeName' = unUnqualComponentName . exeName
    formatdeps = map formatone . sortOn unPackageName'
    formatone p = unPackageName' p ++ "-" ++ prettyShow (packageVersion p)
    unPackageName' = unPackageName . packageName
    transDeps xs ys =
      either (map sourcePackageId . allPackages) handleDepClosureFailure $ dependencyClosure allInstPkgsIdx availInstPkgIds
      where
        allInstPkgsIdx = installedPkgs lbi
        allInstPkgIds = map installedUnitId $ allPackages allInstPkgsIdx
        -- instPkgIds includes `stack-X.X.X`, which is not a dependency hence is missing from allInstPkgsIdx. Filter that out.
        availInstPkgIds = filter (`elem` allInstPkgIds) $ testDeps xs ys
        handleDepClosureFailure unsatisfied =
          error $
            "Computation of transitive dependencies failed." ++
            if null unsatisfied then "" else " Unresolved dependencies: " ++ show unsatisfied

testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [UnitId]
testDeps xs ys = map fst $ nub $ componentPackageDeps xs ++ componentPackageDeps ys