git.iko.soy/typeable/cabal2nix
on master help sign in
hackage2nix: filter Hackage tree with preferred-versions file

We consider only packages and/or package versions that satisfy the constraints in the preferred-versions file. This means that we won't distribute deprecated packages by default. Resolves https://github.com/NixOS/cabal2nix/issues/128. Resolves https://github.com/NixOS/cabal2nix/issues/185. Resolves https://github.com/NixOS/nixpkgs/issues/8924.

commit6c74a6bfe9c92fad7233a0224629a07c065e1ef4 authorPeter Simons <simons@cryp.to> dateThu 13 Aug 2015, 20:42 (11 years ago) parenta001e85
1 file changed+24−21
src/hackage2nix.hs+24−21
src/hackage2nix.hs+24−21
@@ -14,8 +14,8 @@ import Control.Monad.Par.Combinator
1414import Control.Monad.Par.IO
1515import Control.Monad.Trans ( liftIO )
1616import Data.Function
17+import System.FilePath
1718import Data.List
18−-- import Data.Char
1919import Data.Map.Strict ( Map )
2020import qualified Data.Map.Strict as Map
2121import Data.Maybe
@@ -36,7 +36,6 @@ import Distribution.Text
3636import Distribution.Version
3737import Language.Nix.Identifier
3838import Options.Applicative
39−-- import qualified Distribution.Compat.ReadP as Parse
4039
4140type Nixpkgs = PackageMap -- Map String (Set [String])
4241type PackageSet = Map String Version
@@ -53,6 +52,12 @@ resolveConstraint' (Dependency (PackageName name) vrange) hackage | Set.null vs
5352 | otherwise = Just (Set.findMax vs)
5453 where vs = Set.filter (`withinRange` vrange) (Map.keysSet (hackage Map.! name))
5554
55+satisfiesConstraint :: PackageIdentifier -> Constraint -> Bool
56+satisfiesConstraint (PackageIdentifier pn v) (Dependency cn vr) = (pn /= cn) || (v `withinRange` vr)
57+
58+satisfiesConstraints :: PackageIdentifier -> [Constraint] -> Bool
59+satisfiesConstraints p = all (satisfiesConstraint p)
60+
5661data Configuration = Configuration
5762 {
5863 -- |Target architecture. Used by 'finalizePackageDescription' to
@@ -111,12 +116,19 @@ main = do
111116
112117 hackage <- readHackage hackageRepository
113118 nixpkgs <- readNixpkgPackageMap nixpkgsRepository
119+ preferredVersions <- readPreferredVersions (hackageRepository </> "preferred-versions")
114120 let fixup = Map.delete "acme-everything" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
115121 . Map.delete "som" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
116122 . Map.delete "type" -- TODO: https://github.com/NixOS/cabal2nix/issues/163
117123 . Map.delete "dictionary-sharing" -- TODO: https://github.com/NixOS/cabal2nix/issues/175
124+ . Map.filter (/= Map.empty)
125+ . Map.mapWithKey (enforcePreferredVersions preferredVersions)
118126 runParIO $ generatePackageSet defaultConfiguration (fixup hackage) nixpkgs
119127
128+enforcePreferredVersions :: [Constraint] -> String -> Map Version GenericPackageDescription
129+ -> Map Version GenericPackageDescription
130+enforcePreferredVersions cs pkg = Map.filterWithKey (\v _ -> PackageIdentifier (PackageName pkg) v `satisfiesConstraints` cs)
131+
120132generatePackageSet :: Configuration -> Hackage -> Nixpkgs -> ParIO ()
121133generatePackageSet config hackage nixpkgs = do
122134 let
@@ -272,6 +284,16 @@ cabal2nix resolver cabal = (missingDeps, flags, drv)
272284 enableTest :: TestSuite -> TestSuite
273285 enableTest t = t { testEnabled = True }
274286
287+readPreferredVersions :: FilePath -> IO [Constraint]
288+readPreferredVersions path = mapMaybe parsePreferredVersionsLine . lines <$> readFile path
289+
290+
291+parsePreferredVersionsLine :: String -> Maybe Constraint
292+parsePreferredVersionsLine ('-':'-':_) = Nothing
293+parsePreferredVersionsLine l = case simpleParse l of
294+ Just c -> Just c
295+ Nothing -> error ("invalid preferred-versions line: " ++ show l)
296+
275297defaultConfiguration :: Configuration
276298defaultConfiguration = Configuration
277299 { platform = Platform X86_64 Linux
@@ -3880,22 +3902,3 @@ defaultConfiguration = Configuration
38803902 ]
38813903
38823904}
3883−
3884−-- instance Text Configuration where
3885−-- parse = do platform <- token (Parse.string "platform") >> token (Parse.char '=') >> parse
3886−-- return $ Configuration
3887−-- { platform = platform
3888−-- }
3889−
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
3893−
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 ',')))
3897−
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
3900−-- [] -> Nothing
3901−-- (r:_) -> Just r