1 -----------------------------------------------------------------------------
3 -----------------------------------------------------------------------------
6 -- Module : Distribution.Client.Freeze
7 -- Copyright : (c) David Himmelstrup 2005
11 -- Maintainer : cabal-devel@gmail.com
12 -- Stability : provisional
13 -- Portability : portable
15 -- The cabal freeze command
16 module Distribution
.Client
.Freeze
21 import Distribution
.Client
.Compat
.Prelude
24 import Distribution
.Client
.Config
(SavedConfig
(..))
25 import Distribution
.Client
.Dependency
26 import Distribution
.Client
.IndexUtils
as IndexUtils
27 ( getInstalledPackages
30 import Distribution
.Client
.Sandbox
.PackageEnvironment
33 , showPackageEnvironment
34 , userPackageEnvironmentFile
36 import Distribution
.Client
.Setup
42 import Distribution
.Client
.SolverInstallPlan
46 import qualified Distribution
.Client
.SolverInstallPlan
as SolverInstallPlan
47 import Distribution
.Client
.Targets
48 import Distribution
.Client
.Types
50 import Distribution
.Solver
.Types
.ConstraintSource
51 import Distribution
.Solver
.Types
.LabeledPackageConstraint
52 import Distribution
.Solver
.Types
.OptionalStanza
53 import Distribution
.Solver
.Types
.PkgConfigDb
54 import Distribution
.Solver
.Types
.SolverId
56 import Distribution
.Client
.Errors
57 import Distribution
.Package
63 import Distribution
.Simple
.Compiler
68 import Distribution
.Simple
.PackageIndex
(InstalledPackageIndex
)
69 import Distribution
.Simple
.Program
72 import Distribution
.Simple
.Setup
77 import Distribution
.Simple
.Utils
84 import Distribution
.System
87 import Distribution
.Version
91 -- ------------------------------------------------------------
93 -- * The freeze command
95 -- ------------------------------------------------------------
97 -- | Freeze all of the dependencies by writing a constraints section
98 -- constraining each dependency to an exact version.
132 "No packages to be frozen. "
133 ++ "As this package has no dependencies."
139 "The following packages would be frozen:"
141 else freezePackages verbosity globalFlags pkgs
143 dryRun
= fromFlag
(freezeDryRun freezeFlags
)
145 -- | Get the list of packages whose versions would be frozen by the @freeze@
156 -> IO [SolverPlanPackage
]
166 installedPkgIndex
<- getInstalledPackages verbosity comp packageDBs progdb
167 sourcePkgDb
<- getSourcePackages verbosity repoCtxt
168 pkgConfigDb
<- readPkgConfigDb verbosity progdb
174 (packageIndex sourcePkgDb
)
175 [UserTargetLocalDir
"."]
177 sanityCheck pkgSpecifiers
188 sanityCheck
:: [PackageSpecifier UnresolvedSourcePackage
] -> IO ()
189 sanityCheck pkgSpecifiers
= do
190 when (not . null $ [n | n
@(NamedPackage _ _
) <- pkgSpecifiers
]) $
191 dieWithException verbosity UnexpectedNamedPkgSpecifiers
192 when (length pkgSpecifiers
/= 1) $
193 dieWithException verbosity UnexpectedSourcePkgSpecifiers
200 -> InstalledPackageIndex
203 -> [PackageSpecifier UnresolvedSourcePackage
]
204 -> IO [SolverPlanPackage
]
214 notice verbosity
"Resolving dependencies..."
217 foldProgress logMsg
(dieWithException verbosity
. FreezeException
) return $
224 return $ pruneInstallPlan installPlan pkgSpecifiers
226 resolverParams
:: DepResolverParams
229 ( if maxBackjumps
< 0
231 else Just maxBackjumps
233 . setIndependentGoals independentGoals
234 . setReorderGoals reorderGoals
235 . setCountConflicts countConflicts
236 . setFineGrainedConflicts fineGrainedConflicts
237 . setMinimizeConflictSet minimizeConflictSet
238 . setShadowPkgs shadowPkgs
239 . setStrongFlags strongFlags
240 . setAllowBootLibInstalls allowBootLibInstalls
241 . setOnlyConstrained onlyConstrained
242 . setSolverVerbosity verbosity
244 [ let pkg
= pkgSpecifierTarget pkgSpecifier
248 (PackagePropertyStanzas stanzas
)
249 in LabeledPackageConstraint pc ConstraintSourceFreeze
250 | pkgSpecifier
<- pkgSpecifiers
252 $ standardInstallPolicy installedPkgIndex sourcePkgDb pkgSpecifiers
254 logMsg message rest
= debug verbosity message
>> rest
257 [TestStanzas | testsEnabled
]
258 ++ [BenchStanzas | benchmarksEnabled
]
259 testsEnabled
= fromFlagOrDefault
False $ freezeTests freezeFlags
260 benchmarksEnabled
= fromFlagOrDefault
False $ freezeBenchmarks freezeFlags
262 reorderGoals
= fromFlag
(freezeReorderGoals freezeFlags
)
263 countConflicts
= fromFlag
(freezeCountConflicts freezeFlags
)
264 fineGrainedConflicts
= fromFlag
(freezeFineGrainedConflicts freezeFlags
)
265 minimizeConflictSet
= fromFlag
(freezeMinimizeConflictSet freezeFlags
)
266 independentGoals
= fromFlag
(freezeIndependentGoals freezeFlags
)
267 shadowPkgs
= fromFlag
(freezeShadowPkgs freezeFlags
)
268 strongFlags
= fromFlag
(freezeStrongFlags freezeFlags
)
269 maxBackjumps
= fromFlag
(freezeMaxBackjumps freezeFlags
)
270 allowBootLibInstalls
= fromFlag
(freezeAllowBootLibInstalls freezeFlags
)
271 onlyConstrained
= fromFlag
(freezeOnlyConstrained freezeFlags
)
273 -- | Remove all unneeded packages from an install plan.
275 -- A package is unneeded if it is either
277 -- 1) the package that we are freezing, or
279 -- 2) not a dependency (directly or transitively) of the package we are
280 -- freezing. This is useful for removing previously installed packages
281 -- which are no longer required from the install plan.
283 -- Invariant: @pkgSpecifiers@ must refer to packages which are not
284 -- 'PreExisting' in the 'SolverInstallPlan'.
287 -> [PackageSpecifier UnresolvedSourcePackage
]
288 -> [SolverPlanPackage
]
289 pruneInstallPlan installPlan pkgSpecifiers
=
291 SolverInstallPlan
.dependencyClosure installPlan pkgIds
294 [ PlannedId
(packageId pkg
)
295 | SpecificSourcePackage pkg
<- pkgSpecifiers
297 removeSelf
[thisPkg
] = filter (\pp
-> packageId pp
/= packageId thisPkg
)
300 "internal error: 'pruneInstallPlan' given "
301 ++ "unexpected package specifiers!"
303 freezePackages
:: Package pkg
=> Verbosity
-> GlobalFlags
-> [pkg
] -> IO ()
304 freezePackages verbosity globalFlags pkgs
= do
306 fmap (createPkgEnv
. addFrozenConstraints
) $
310 (flagToMaybe
. globalConstraintsFile
$ globalFlags
)
311 writeFileAtomic userPackageEnvironmentFile
$ showPkgEnv pkgEnv
313 addFrozenConstraints config
=
315 { savedConfigureExFlags
=
316 (savedConfigureExFlags config
)
317 { configExConstraints
= map constraint pkgs
321 ( pkgIdToConstraint
$ packageId pkg
322 , ConstraintSourceUserConfig userPackageEnvironmentFile
325 pkgIdToConstraint pkgId
=
327 (UserQualified UserQualToplevel
(packageName pkgId
))
328 (PackagePropertyVersion
$ thisVersion
(packageVersion pkgId
))
329 createPkgEnv config
= mempty
{pkgEnvSavedConfig
= config
}
330 showPkgEnv
= toUTF8LBS
. showPackageEnvironment
332 formatPkgs
:: Package pkg
=> [pkg
] -> [String]
333 formatPkgs
= map $ showPkg
. packageId
335 showPkg pid
= name pid
++ " == " ++ version pid
336 name
= prettyShow
. packageName
337 version
= prettyShow
. packageVersion