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
64 import Distribution
.Simple
.PackageIndex
(InstalledPackageIndex
)
65 import Distribution
.Simple
.Program
68 import Distribution
.Simple
.Setup
73 import Distribution
.Simple
.Utils
80 import Distribution
.System
83 import Distribution
.Version
87 -- ------------------------------------------------------------
89 -- * The freeze command
91 -- ------------------------------------------------------------
93 -- | Freeze all of the dependencies by writing a constraints section
94 -- constraining each dependency to an exact version.
128 "No packages to be frozen. "
129 ++ "As this package has no dependencies."
135 "The following packages would be frozen:"
137 else freezePackages verbosity globalFlags pkgs
139 dryRun
= fromFlag
(freezeDryRun freezeFlags
)
141 -- | Get the list of packages whose versions would be frozen by the @freeze@
152 -> IO [SolverPlanPackage
]
162 installedPkgIndex
<- getInstalledPackages verbosity comp packageDBs progdb
163 sourcePkgDb
<- getSourcePackages verbosity repoCtxt
164 pkgConfigDb
<- readPkgConfigDb verbosity progdb
170 (packageIndex sourcePkgDb
)
171 [UserTargetLocalDir
"."]
173 sanityCheck pkgSpecifiers
184 sanityCheck
:: [PackageSpecifier UnresolvedSourcePackage
] -> IO ()
185 sanityCheck pkgSpecifiers
= do
186 when (not . null $ [n | n
@(NamedPackage _ _
) <- pkgSpecifiers
]) $
187 dieWithException verbosity UnexpectedNamedPkgSpecifiers
188 when (length pkgSpecifiers
/= 1) $
189 dieWithException verbosity UnexpectedSourcePkgSpecifiers
196 -> InstalledPackageIndex
199 -> [PackageSpecifier UnresolvedSourcePackage
]
200 -> IO [SolverPlanPackage
]
210 notice verbosity
"Resolving dependencies..."
213 foldProgress logMsg
(dieWithException verbosity
. FreezeException
) return $
220 return $ pruneInstallPlan installPlan pkgSpecifiers
222 resolverParams
:: DepResolverParams
225 ( if maxBackjumps
< 0
227 else Just maxBackjumps
229 . setIndependentGoals independentGoals
230 . setReorderGoals reorderGoals
231 . setCountConflicts countConflicts
232 . setFineGrainedConflicts fineGrainedConflicts
233 . setMinimizeConflictSet minimizeConflictSet
234 . setShadowPkgs shadowPkgs
235 . setStrongFlags strongFlags
236 . setAllowBootLibInstalls allowBootLibInstalls
237 . setOnlyConstrained onlyConstrained
238 . setSolverVerbosity verbosity
240 [ let pkg
= pkgSpecifierTarget pkgSpecifier
244 (PackagePropertyStanzas stanzas
)
245 in LabeledPackageConstraint pc ConstraintSourceFreeze
246 | pkgSpecifier
<- pkgSpecifiers
248 $ standardInstallPolicy installedPkgIndex sourcePkgDb pkgSpecifiers
250 logMsg message rest
= debug verbosity message
>> rest
253 [TestStanzas | testsEnabled
]
254 ++ [BenchStanzas | benchmarksEnabled
]
255 testsEnabled
= fromFlagOrDefault
False $ freezeTests freezeFlags
256 benchmarksEnabled
= fromFlagOrDefault
False $ freezeBenchmarks freezeFlags
258 reorderGoals
= fromFlag
(freezeReorderGoals freezeFlags
)
259 countConflicts
= fromFlag
(freezeCountConflicts freezeFlags
)
260 fineGrainedConflicts
= fromFlag
(freezeFineGrainedConflicts freezeFlags
)
261 minimizeConflictSet
= fromFlag
(freezeMinimizeConflictSet freezeFlags
)
262 independentGoals
= fromFlag
(freezeIndependentGoals freezeFlags
)
263 shadowPkgs
= fromFlag
(freezeShadowPkgs freezeFlags
)
264 strongFlags
= fromFlag
(freezeStrongFlags freezeFlags
)
265 maxBackjumps
= fromFlag
(freezeMaxBackjumps freezeFlags
)
266 allowBootLibInstalls
= fromFlag
(freezeAllowBootLibInstalls freezeFlags
)
267 onlyConstrained
= fromFlag
(freezeOnlyConstrained freezeFlags
)
269 -- | Remove all unneeded packages from an install plan.
271 -- A package is unneeded if it is either
273 -- 1) the package that we are freezing, or
275 -- 2) not a dependency (directly or transitively) of the package we are
276 -- freezing. This is useful for removing previously installed packages
277 -- which are no longer required from the install plan.
279 -- Invariant: @pkgSpecifiers@ must refer to packages which are not
280 -- 'PreExisting' in the 'SolverInstallPlan'.
283 -> [PackageSpecifier UnresolvedSourcePackage
]
284 -> [SolverPlanPackage
]
285 pruneInstallPlan installPlan pkgSpecifiers
=
287 SolverInstallPlan
.dependencyClosure installPlan pkgIds
290 [ PlannedId
(packageId pkg
)
291 | SpecificSourcePackage pkg
<- pkgSpecifiers
293 removeSelf
[thisPkg
] = filter (\pp
-> packageId pp
/= packageId thisPkg
)
296 "internal error: 'pruneInstallPlan' given "
297 ++ "unexpected package specifiers!"
299 freezePackages
:: Package pkg
=> Verbosity
-> GlobalFlags
-> [pkg
] -> IO ()
300 freezePackages verbosity globalFlags pkgs
= do
302 fmap (createPkgEnv
. addFrozenConstraints
) $
306 (flagToMaybe
. globalConstraintsFile
$ globalFlags
)
307 writeFileAtomic userPackageEnvironmentFile
$ showPkgEnv pkgEnv
309 addFrozenConstraints config
=
311 { savedConfigureExFlags
=
312 (savedConfigureExFlags config
)
313 { configExConstraints
= map constraint pkgs
317 ( pkgIdToConstraint
$ packageId pkg
318 , ConstraintSourceUserConfig userPackageEnvironmentFile
321 pkgIdToConstraint pkgId
=
323 (UserQualified UserQualToplevel
(packageName pkgId
))
324 (PackagePropertyVersion
$ thisVersion
(packageVersion pkgId
))
325 createPkgEnv config
= mempty
{pkgEnvSavedConfig
= config
}
326 showPkgEnv
= toUTF8LBS
. showPackageEnvironment
328 formatPkgs
:: Package pkg
=> [pkg
] -> [String]
329 formatPkgs
= map $ showPkg
. packageId
331 showPkg pid
= name pid
++ " == " ++ version pid
332 name
= prettyShow
. packageName
333 version
= prettyShow
. packageVersion