@@ -14,8 +14,8 @@ import Control.Monad.Par.Combinator
14import Control.Monad.Par.IO
14import Control.Monad.Par.IO
15import Control.Monad.Trans ( liftIO )
15import Control.Monad.Trans ( liftIO )
16import Data.Function
16import Data.Function
17+import System.FilePath
17import Data.List
18import Data.List
19import Data.Map.Strict ( Map )
19import Data.Map.Strict ( Map )
20import qualified Data.Map.Strict as Map
20import qualified Data.Map.Strict as Map
21import Data.Maybe
21import Data.Maybe
@@ -36,7 +36,6 @@ import Distribution.Text
36import Distribution.Version
36import Distribution.Version
37import Language.Nix.Identifier
37import Language.Nix.Identifier
38import Options.Applicative
38import Options.Applicative
39−-- import qualified Distribution.Compat.ReadP as Parse
41type Nixpkgs = PackageMap -- Map String (Set [String])
40type Nixpkgs = PackageMap -- Map String (Set [String])
42type PackageSet = Map String Version
41type PackageSet = Map String Version
@@ -53,6 +52,12 @@ resolveConstraint' (Dependency (PackageName name) vrange) hackage | Set.null vs
53 | otherwise = Just (Set.findMax vs)
52 | otherwise = Just (Set.findMax vs)
54 where vs = Set.filter (`withinRange` vrange) (Map.keysSet (hackage Map.! name))
53 where vs = Set.filter (`withinRange` vrange) (Map.keysSet (hackage Map.! name))
55+satisfiesConstraint :: PackageIdentifier -> Constraint -> Bool
56+satisfiesConstraint (PackageIdentifier pn v) (Dependency cn vr) = (pn /= cn) || (v `withinRange` vr)
58+satisfiesConstraints :: PackageIdentifier -> [Constraint] -> Bool
59+satisfiesConstraints p = all (satisfiesConstraint p)
56data Configuration = Configuration
61data Configuration = Configuration
58 -- |Target architecture. Used by 'finalizePackageDescription' to
63 -- |Target architecture. Used by 'finalizePackageDescription' to
@@ -111,12 +116,19 @@ main = do
112 hackage <- readHackage hackageRepository
117 hackage <- readHackage hackageRepository
113 nixpkgs <- readNixpkgPackageMap nixpkgsRepository
118 nixpkgs <- readNixpkgPackageMap nixpkgsRepository
119+ preferredVersions <- readPreferredVersions (hackageRepository </> "preferred-versions")
114 let fixup = Map.delete "acme-everything" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
120 let fixup = Map.delete "acme-everything" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
115 . Map.delete "som" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
121 . Map.delete "som" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
116 . Map.delete "type" -- TODO: https://github.com/NixOS/cabal2nix/issues/163
122 . Map.delete "type" -- TODO: https://github.com/NixOS/cabal2nix/issues/163
117 . Map.delete "dictionary-sharing" -- TODO: https://github.com/NixOS/cabal2nix/issues/175
123 . Map.delete "dictionary-sharing" -- TODO: https://github.com/NixOS/cabal2nix/issues/175
124+ . Map.filter (/= Map.empty)
125+ . Map.mapWithKey (enforcePreferredVersions preferredVersions)
118 runParIO $ generatePackageSet defaultConfiguration (fixup hackage) nixpkgs
126 runParIO $ generatePackageSet defaultConfiguration (fixup hackage) nixpkgs
128+enforcePreferredVersions :: [Constraint] -> String -> Map Version GenericPackageDescription
129+ -> Map Version GenericPackageDescription
130+enforcePreferredVersions cs pkg = Map.filterWithKey (\v _ -> PackageIdentifier (PackageName pkg) v `satisfiesConstraints` cs)
120generatePackageSet :: Configuration -> Hackage -> Nixpkgs -> ParIO ()
132generatePackageSet :: Configuration -> Hackage -> Nixpkgs -> ParIO ()
121generatePackageSet config hackage nixpkgs = do
133generatePackageSet config hackage nixpkgs = do
@@ -272,6 +284,16 @@ cabal2nix resolver cabal = (missingDeps, flags, drv)
272 enableTest :: TestSuite -> TestSuite
284 enableTest :: TestSuite -> TestSuite
273 enableTest t = t { testEnabled = True }
285 enableTest t = t { testEnabled = True }
287+readPreferredVersions :: FilePath -> IO [Constraint]
288+readPreferredVersions path = mapMaybe parsePreferredVersionsLine . lines <$> readFile path
291+parsePreferredVersionsLine :: String -> Maybe Constraint
292+parsePreferredVersionsLine ('-':'-':_) = Nothing
293+parsePreferredVersionsLine l = case simpleParse l of
295+ Nothing -> error ("invalid preferred-versions line: " ++ show l)
275defaultConfiguration :: Configuration
297defaultConfiguration :: Configuration
276defaultConfiguration = Configuration
298defaultConfiguration = Configuration
277 { platform = Platform X86_64 Linux
299 { platform = Platform X86_64 Linux
@@ -3880,22 +3902,3 @@ defaultConfiguration = Configuration
3884−-- instance Text Configuration where
3885−-- parse = do platform <- token (Parse.string "platform") >> token (Parse.char '=') >> parse
3886−-- return $ Configuration
3887−-- { platform = platform
3890−-- token :: Parse.ReadP r a -> Parse.ReadP r a
3891−-- -- token p = p >>= \r -> Parse.skipSpaces >> return r
3892−-- token p = Parse.skipSpaces >> p
3894−-- listOf :: Parse.ReadP r a -> Parse.ReadP r [a]
3895−-- listOf p = Parse.between (token (Parse.char '[')) (token (Parse.char ']'))
3896−-- (Parse.sepBy (token p) (token (Parse.char ',')))
3898−-- run :: Parse.ReadP a a -> String -> Maybe a
3899−-- run p str = case [ r' | (r', s) <- Parse.readP_to_S (Parse.skipSpaces >> p) str, all isSpace s ] of