Skip to content

Commit 6c74a6b

Browse files
committed
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 #128. Resolves #185. Resolves NixOS/nixpkgs#8924.
1 parent a001e85 commit 6c74a6b

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

src/hackage2nix.hs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import Control.Monad.Par.Combinator
1414
import Control.Monad.Par.IO
1515
import Control.Monad.Trans ( liftIO )
1616
import Data.Function
17+
import System.FilePath
1718
import Data.List
18-
-- import Data.Char
1919
import Data.Map.Strict ( Map )
2020
import qualified Data.Map.Strict as Map
2121
import Data.Maybe
@@ -36,7 +36,6 @@ import Distribution.Text
3636
import Distribution.Version
3737
import Language.Nix.Identifier
3838
import Options.Applicative
39-
-- import qualified Distribution.Compat.ReadP as Parse
4039

4140
type Nixpkgs = PackageMap -- Map String (Set [String])
4241
type 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+
5661
data 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+
120132
generatePackageSet :: Configuration -> Hackage -> Nixpkgs -> ParIO ()
121133
generatePackageSet 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+
275297
defaultConfiguration :: Configuration
276298
defaultConfiguration = 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

0 commit comments

Comments
 (0)