
New patches:

[Change dependency resolution algorithm.
Thomas Schilling <nominolo@gmail.com>**20080413131807
 
 There were two reasons to do this.  Firstly, this formulation makes it
 easier to add the --constraint command line flag that adds additional
 constraints on the packages that should be used.
 
 Secondly, with the orgininal algorithm it was possible to satisfy the
 constraint "foo < 1, foo > 2" if we had two versions of package "foo"
 which each satisfy one constraint.  This patch fixes this by requiring
 the same package to satisfy both constraints (which of course is
 impossible in this case).
] {
hunk ./Distribution/PackageDescription/Configuration.hs 73
+import Data.Map ( Map, unionsWith, fromListWith, toList )
hunk ./Distribution/PackageDescription/Configuration.hs 227
-  -> [CondTree ConfVar [d] a]    
-  -> ([d] -> DepTestRslt [d])  -- ^ Dependency test function.
-  -> (Either [d] -- missing dependencies
-       ([a], [d], [(String, Bool)]))
+  -> [CondTree ConfVar [Dependency] a]    
+  -> ([Dependency] -> DepTestRslt [Dependency])  -- ^ Dependency test function.
+  -> (Either [Dependency] -- missing dependencies
+       ([a], [Dependency], [(String, Bool)]))
hunk ./Distribution/PackageDescription/Configuration.hs 236
-    -- Check dependencies only once; might avoid some duplicate efforts.
-    preCheckedTrees = map ( mapTreeConstrs (\d -> (checkDeps d,d))
-                          . mapTreeConds (fst . simplifyWithSysParams os arch impl) )
-                        trees
+    -- simplify trees by (partially) evaluating all conditions and converting
+    -- dependencies to dependency maps.
+    simplifiedTrees = map ( mapTreeConstrs toDepMap  -- convert to maps
+                          . mapTreeConds (fst . simplifyWithSysParams os arch impl))
+                          trees
hunk ./Distribution/PackageDescription/Configuration.hs 249
-                         $ preCheckedTrees
-        in case mconcat depss of
+                         $ simplifiedTrees
+            deps = (fromDepMap $ unionsWith IntersectVersionRanges depss)
+        in case (checkDeps deps, deps) of
hunk ./Distribution/PackageDescription/Configuration.hs 287
+toDepMap :: [Dependency] -> Map String VersionRange
+toDepMap ds = fromListWith IntersectVersionRanges [ (p,vr) | Dependency p vr <- ds ]
hunk ./Distribution/PackageDescription/Configuration.hs 290
+fromDepMap :: Map String VersionRange -> [Dependency]
+fromDepMap m = [ Dependency p vr | (p,vr) <- toList m ]
}

[Fix/Add documentation.
Thomas Schilling <nominolo@gmail.com>**20080413131839] {
hunk ./Distribution/PackageDescription/Configuration.hs 340
-finalizePackageDescription
-  :: Package pkg
+-- | Create a package description with all configurations resolved.
+--
+-- This function takes a `GenericPackageDescription` and several environment
+-- parameters and tries to generate `PackageDescription` by finding a flag
+-- assignment that result in satisfiable dependencies.
+--
+-- It takes as inputs a not necessarily complete specifications of flags
+-- assignments, an optional package index as well as platform parameters.  If
+-- some flags are not assigned explicitly, this function will try to pick an
+-- assignment that causes this function to succeed.  The package index is
+-- optional since on some platforms we cannot determine which packages have
+-- been installed before.  When no package index is supplied, every dependency
+-- is assumed to be satisfiable, therefore all not explicitly assigned flags
+-- will get their default values.
+--
+-- This function will fail if it cannot find a flag assignment that leads to
+-- satisfiable dependencies.  (It will not try alternative assignments for
+-- explicitly specified flags.)  In case of failure it will return a /minimum/
+-- number of dependencies that could not be satisfied.  On success, it will
+-- return the package description and the full flag assignment chosen.
+-- 
+finalizePackageDescription ::
+     Package pkg
hunk ./Distribution/PackageDescription/Configuration.hs 427
--- description, e.g., the source dirctory might either be the default or a
+-- description, e.g., the source directory might either be the default or a
}

[Add simple test case for the dependency resolution case.  This should
Thomas Schilling <nominolo@gmail.com>**20080413132002
 go into the test suite one day.
] {
hunk ./Distribution/PackageDescription/Configuration.hs 419
+{-
+let tst_p = (CondNode [1::Int] [Distribution.Package.Dependency "a" AnyVersion] [])
+let tst_p2 = (CondNode [1::Int] [Distribution.Package.Dependency "a" (EarlierVersion (Version [1,0] [])), Distribution.Package.Dependency "a" (LaterVersion (Version [2,0] []))] [])
+
+let p_index = Distribution.Simple.PackageIndex.fromList [Distribution.Package.PackageIdentifier "a" (Version [0,5] []), Distribution.Package.PackageIdentifier "a" (Version [2,5] [])]
+let look = not . null . Distribution.Simple.PackageIndex.lookupDependency p_index
+let looks ds = mconcat $ map (\d -> if look d then DepOk else MissingDeps [d]) ds
+resolveWithFlags [] Distribution.System.Linux Distribution.System.I386 (Distribution.Compiler.GHC,Version [6,8,2] []) [tst_p] looks   ===>  Right ...
+resolveWithFlags [] Distribution.System.Linux Distribution.System.I386 (Distribution.Compiler.GHC,Version [6,8,2] []) [tst_p2] looks  ===>  Left ...
+-}
}

[Add 'readP_to_E' function that takes the longest parse.
Thomas Schilling <nominolo@gmail.com>**20080413182042] {
hunk ./Distribution/ReadE.hs 48
+   readP_to_E
hunk ./Distribution/ReadE.hs 53
+import Data.Char ( isSpace )
hunk ./Distribution/ReadE.hs 78
-
+readP_to_E :: (String -> ErrorMsg) -> ReadP a a -> ReadE a
+readP_to_E err r = 
+    ReadE $ \txt -> case [ p | (p, s) <- readP_to_S r txt
+                         , all isSpace s ]
+                    of [] -> Left (err txt)
+                       (p:_) -> Right p
+    
}

[Fix #224.  We do not yet warn if the user specified a dependency that
Thomas Schilling <nominolo@gmail.com>**20080413182659
 did not occur in the package (it is just silently ignored.)
] {
hunk ./Distribution/PackageDescription/Configuration.hs 74
+import qualified Data.Map as M
hunk ./Distribution/PackageDescription/Configuration.hs 228
+  -> [Dependency]  -- ^ Additional constraints
hunk ./Distribution/PackageDescription/Configuration.hs 233
-resolveWithFlags dom os arch impl trees checkDeps =
+       -- ^ In the returned dependencies, there will be no duplicates by name
+resolveWithFlags dom os arch impl constrs trees checkDeps =
hunk ./Distribution/PackageDescription/Configuration.hs 239
+    extraConstrs = toDepMap constrs
+ 
hunk ./Distribution/PackageDescription/Configuration.hs 247
+    -- version to combine dependencies where the result will only contain keys
+    -- from the left (first) map.  If a key also exists in the right map, both
+    -- constraints will be intersected.
+    leftJoin :: Map String VersionRange -> Map String VersionRange
+             -> Map String VersionRange
+    leftJoin left extra =
+        M.foldWithKey tightenConstraint left extra
+      where tightenConstraint n c l =
+                case M.lookup n l of
+                  Nothing -> l
+                  Just vr -> M.insert n (IntersectVersionRanges vr c) l
+
hunk ./Distribution/PackageDescription/Configuration.hs 267
-            deps = (fromDepMap $ unionsWith IntersectVersionRanges depss)
+            deps = fromDepMap $ leftJoin (unionsWith IntersectVersionRanges depss)
+                                         extraConstrs
hunk ./Distribution/PackageDescription/Configuration.hs 387
+  -> [Dependency]  -- ^ Additional constraints
hunk ./Distribution/PackageDescription/Configuration.hs 393
-finalizePackageDescription userflags mpkgs os arch impl
+finalizePackageDescription userflags mpkgs os arch impl constraints
hunk ./Distribution/PackageDescription/Configuration.hs 418
-        case resolveWithFlags flagChoices os arch impl condTrees check of
+        case resolveWithFlags flagChoices os arch impl constraints condTrees check of
hunk ./Distribution/Simple/Configure.hs 298
+                       (configConstraints cfg)
hunk ./Distribution/Simple/Setup.hs 71
-import Distribution.Text (display)
+import Distribution.Text (display, parse)
+import Distribution.Package ( Dependency(..) )
hunk ./Distribution/Simple/Setup.hs 252
+    configConstraints :: [Dependency], -- ^Additional constraints for
+                                       -- dependencies
hunk ./Distribution/Simple/Setup.hs 463
+      ,option "" ["constraint"]
+         "A list of additional constraints on the dependencies."
+         configConstraints (\v flags -> flags { configConstraints = v})
+         (reqArg "DEPENDENCY" 
+                 (readP_to_E (const "dependency expected") ((\x -> [x]) `fmap` parse))
+                 (map (\x -> display x)))
hunk ./Distribution/Simple/Setup.hs 516
+    configConstraints   = mempty,
hunk ./Distribution/Simple/Setup.hs 544
+    configConstraints   = combine configConstraints,
}

Context:

[Check for the required cabal version early in parsing
Duncan Coutts <duncan@haskell.org>**20080409154655
 Previously we only checked the "cabal-version" field after parsing
 and all other configure processing. If the package really needs a
 later Cabal version it is of course highly likely that parsing or
 configure are going to fail and the user is not going to get the
 helpful error message about the version of Cabal required. So now
 we do the check early during parsing. If a later version is
 required and parsing subsequently fails, we now report the version
 issue, not the subsequent parse error. If parsing succeeds we
 still issue a warning which should be a useful hint to the user if
 subsequent configure processing fails.
] 
[Use relative file paths in .cabal parse error messages
Duncan Coutts <duncan@haskell.org>**20080409154030
 Do this by normalising the file path in the error message
 and when looking for .cabal files, by looking in '.' rather
 than the absolute path of the current directory.
] 
[Remove unused import
Duncan Coutts <duncan@haskell.org>**20080409073352] 
[Fix for detecting ~/.cabal/ dir as a .cabal file
Duncan Coutts <duncan@haskell.org>**20080409073236
 Which happened if you use cabal configure in your home dir.
 Now produced the right error message, or if you actually put
 a cabal project in your home dir, it might actually work.
 Also, do the same fix for findHookedPackageDesc.
] 
[Fix spelling in error message
Duncan Coutts <duncan@haskell.org>**20080408134610] 
[Fix names of profiling libs
Duncan Coutts <duncan@haskell.org>**20080407013449
 I broke this recently when refactoring. Restore the original behaviour.
 Was generating "libHSfoo_p-1.0.a" when it should be "libHSfoo-1.0_p.a".
] 
[TAG 1.5.1
Duncan Coutts <duncan@haskell.org>**20080329181329] 
Patch bundle hash:
aba971297e66ba0f816674d869149ed5173a7684
