PageRenderTime 25ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/packages/cabal-install-0.6.2/Distribution/Client/Configure.hs

https://github.com/Lainepress/hp-2009.2.0.2
Haskell | 210 lines | 160 code | 18 blank | 32 comment | 6 complexity | b5ee30854116514b70b0842796739e8d MD5 | raw file
  1. -----------------------------------------------------------------------------
  2. -- |
  3. -- Module : Distribution.Client.Configure
  4. -- Copyright : (c) David Himmelstrup 2005,
  5. -- Duncan Coutts 2005
  6. -- License : BSD-like
  7. --
  8. -- Maintainer : cabal-devel@haskell.org
  9. -- Portability : portable
  10. --
  11. -- High level interface to configuring a package.
  12. -----------------------------------------------------------------------------
  13. module Distribution.Client.Configure (
  14. configure,
  15. ) where
  16. import Data.Monoid
  17. ( Monoid(mempty) )
  18. import qualified Data.Map as Map
  19. import Distribution.Client.Dependency
  20. ( resolveDependenciesWithProgress
  21. , PackageConstraint(..)
  22. , PackagesPreference(..), PackagesPreferenceDefault(..)
  23. , PackagePreference(..)
  24. , Progress(..), foldProgress, )
  25. import qualified Distribution.Client.InstallPlan as InstallPlan
  26. import Distribution.Client.InstallPlan (InstallPlan)
  27. import Distribution.Client.IndexUtils as IndexUtils
  28. ( getAvailablePackages )
  29. import Distribution.Client.Setup
  30. ( ConfigExFlags(..), configureCommand, filterConfigureFlags )
  31. import Distribution.Client.Types as Available
  32. ( AvailablePackage(..), AvailablePackageSource(..), Repo(..)
  33. , AvailablePackageDb(..), ConfiguredPackage(..) )
  34. import Distribution.Client.SetupWrapper
  35. ( setupWrapper, SetupScriptOptions(..), defaultSetupScriptOptions )
  36. import Distribution.Simple.Compiler
  37. ( CompilerId(..), Compiler(compilerId), PackageDB(..) )
  38. import Distribution.Simple.Program (ProgramConfiguration )
  39. import Distribution.Simple.Configure (getInstalledPackages)
  40. import Distribution.Simple.Setup
  41. ( ConfigFlags(..), toFlag, flagToMaybe, fromFlagOrDefault )
  42. import qualified Distribution.Simple.PackageIndex as PackageIndex
  43. import Distribution.Simple.PackageIndex (PackageIndex)
  44. import Distribution.Simple.Utils
  45. ( defaultPackageDesc )
  46. import Distribution.Package
  47. ( PackageName, packageName, packageVersion
  48. , Package(..), Dependency(..), thisPackageVersion )
  49. import qualified Distribution.PackageDescription as PackageDescription
  50. import Distribution.PackageDescription
  51. ( PackageDescription )
  52. import Distribution.PackageDescription.Parse
  53. ( readPackageDescription )
  54. import Distribution.PackageDescription.Configuration
  55. ( finalizePackageDescription )
  56. import Distribution.InstalledPackageInfo
  57. ( InstalledPackageInfo )
  58. import Distribution.Version
  59. ( VersionRange(AnyVersion, ThisVersion) )
  60. import Distribution.Simple.Utils as Utils
  61. ( notice, info, die )
  62. import Distribution.System
  63. ( Platform(Platform), buildPlatform )
  64. import Distribution.Verbosity as Verbosity
  65. ( Verbosity )
  66. -- | Configure the package found in the local directory
  67. configure :: Verbosity
  68. -> PackageDB
  69. -> [Repo]
  70. -> Compiler
  71. -> ProgramConfiguration
  72. -> ConfigFlags
  73. -> ConfigExFlags
  74. -> [String]
  75. -> IO ()
  76. configure verbosity packageDB repos comp conf
  77. configFlags configExFlags extraArgs = do
  78. installed <- getInstalledPackages verbosity comp packageDB conf
  79. available <- getAvailablePackages verbosity repos
  80. progress <- planLocalPackage verbosity comp configFlags configExFlags
  81. installed available
  82. notice verbosity "Resolving dependencies..."
  83. maybePlan <- foldProgress (\message rest -> info verbosity message >> rest)
  84. (return . Left) (return . Right) progress
  85. case maybePlan of
  86. Left message -> do
  87. info verbosity message
  88. setupWrapper verbosity (setupScriptOptions installed) Nothing
  89. configureCommand (const configFlags) extraArgs
  90. Right installPlan -> case InstallPlan.ready installPlan of
  91. [pkg@(ConfiguredPackage (AvailablePackage _ _ LocalUnpackedPackage) _ _)] ->
  92. configurePackage verbosity
  93. (InstallPlan.planPlatform installPlan)
  94. (InstallPlan.planCompiler installPlan)
  95. (setupScriptOptions installed)
  96. configFlags pkg extraArgs
  97. _ -> die $ "internal error: configure install plan should have exactly "
  98. ++ "one local ready package."
  99. where
  100. setupScriptOptions index = SetupScriptOptions {
  101. useCabalVersion = maybe AnyVersion ThisVersion
  102. (flagToMaybe (configCabalVersion configExFlags)),
  103. useCompiler = Just comp,
  104. -- Hack: we typically want to allow the UserPackageDB for finding the
  105. -- Cabal lib when compiling any Setup.hs even if we're doing a global
  106. -- install. However we also allow looking in a specific package db.
  107. -- TODO: if we specify a specific db then we do not look in the user
  108. -- package db but we probably should ie [global, user, specific]
  109. usePackageDB = if packageDB == GlobalPackageDB then UserPackageDB
  110. else packageDB,
  111. usePackageIndex = if packageDB == GlobalPackageDB then Nothing
  112. else index,
  113. useProgramConfig = conf,
  114. useDistPref = fromFlagOrDefault
  115. (useDistPref defaultSetupScriptOptions)
  116. (configDistPref configFlags),
  117. useLoggingHandle = Nothing,
  118. useWorkingDir = Nothing
  119. }
  120. -- | Make an 'InstallPlan' for the unpacked package in the current directory,
  121. -- and all its dependencies.
  122. --
  123. planLocalPackage :: Verbosity -> Compiler
  124. -> ConfigFlags -> ConfigExFlags
  125. -> Maybe (PackageIndex InstalledPackageInfo)
  126. -> AvailablePackageDb
  127. -> IO (Progress String String InstallPlan)
  128. planLocalPackage verbosity comp configFlags configExFlags installed
  129. (AvailablePackageDb _ availablePrefs) = do
  130. pkg <- readPackageDescription verbosity =<< defaultPackageDesc verbosity
  131. let -- The trick is, we add the local package to the available index and
  132. -- remove it from the installed index. Then we ask to resolve a
  133. -- dependency on exactly that package. So the resolver ends up having
  134. -- to pick the local package.
  135. available' = PackageIndex.insert localPkg mempty
  136. installed' = PackageIndex.deletePackageId (packageId localPkg) `fmap` installed
  137. localPkg = AvailablePackage {
  138. packageInfoId = packageId pkg,
  139. Available.packageDescription = pkg,
  140. packageSource = LocalUnpackedPackage
  141. }
  142. targets = [packageName pkg]
  143. constraints = [PackageVersionConstraint (packageName pkg)
  144. (ThisVersion (packageVersion pkg))
  145. ,PackageFlagsConstraint (packageName pkg)
  146. (configConfigurationsFlags configFlags)]
  147. ++ [ PackageVersionConstraint name ver
  148. | Dependency name ver <- configConstraints configFlags ]
  149. preferences = mergePackagePrefs PreferLatestForSelected
  150. availablePrefs configExFlags
  151. return $ resolveDependenciesWithProgress buildPlatform (compilerId comp)
  152. installed' available' preferences constraints targets
  153. mergePackagePrefs :: PackagesPreferenceDefault
  154. -> Map.Map PackageName VersionRange
  155. -> ConfigExFlags
  156. -> PackagesPreference
  157. mergePackagePrefs defaultPref availablePrefs configExFlags =
  158. PackagesPreference defaultPref $
  159. -- The preferences that come from the hackage index
  160. [ PackageVersionPreference name ver
  161. | (name, ver) <- Map.toList availablePrefs ]
  162. -- additional preferences from the config file or command line
  163. ++ [ PackageVersionPreference name ver
  164. | Dependency name ver <- configPreferences configExFlags ]
  165. -- | Call an installer for an 'AvailablePackage' but override the configure
  166. -- flags with the ones given by the 'ConfiguredPackage'. In particular the
  167. -- 'ConfiguredPackage' specifies an exact 'FlagAssignment' and exactly
  168. -- versioned package dependencies. So we ignore any previous partial flag
  169. -- assignment or dependency constraints and use the new ones.
  170. --
  171. configurePackage :: Verbosity
  172. -> Platform -> CompilerId
  173. -> SetupScriptOptions
  174. -> ConfigFlags
  175. -> ConfiguredPackage
  176. -> [String]
  177. -> IO ()
  178. configurePackage verbosity (Platform arch os) comp scriptOptions configFlags
  179. (ConfiguredPackage (AvailablePackage _ gpkg _) flags deps) extraArgs =
  180. setupWrapper verbosity
  181. scriptOptions (Just pkg) configureCommand configureFlags extraArgs
  182. where
  183. configureFlags = filterConfigureFlags configFlags {
  184. configConfigurationsFlags = flags,
  185. configConstraints = map thisPackageVersion deps,
  186. configVerbosity = toFlag verbosity
  187. }
  188. pkg = case finalizePackageDescription flags
  189. (Nothing :: Maybe (PackageIndex PackageDescription))
  190. os arch comp [] gpkg of
  191. Left _ -> error "finalizePackageDescription ConfiguredPackage failed"
  192. Right (desc, _) -> desc