@@ -7,7 +7,6 @@ import Control.Lens
7import Control.Monad
7import Control.Monad
8import Control.Monad.Par.Combinator
8import Control.Monad.Par.Combinator
9import Control.Monad.Par.IO
9import Control.Monad.Par.IO
10−import Control.Monad.Trans ( liftIO )
11import Data.List
10import Data.List
12import Data.Map.Strict ( Map )
11import Data.Map.Strict ( Map )
13import qualified Data.Map.Strict as Map
12import qualified Data.Map.Strict as Map
@@ -19,10 +18,9 @@ import Data.String
19import Distribution.Nixpkgs.Fetch
18import Distribution.Nixpkgs.Fetch
20import Distribution.Nixpkgs.Haskell
19import Distribution.Nixpkgs.Haskell
21import Distribution.Nixpkgs.Haskell.Constraint
20import Distribution.Nixpkgs.Haskell.Constraint
22−import Distribution.Nixpkgs.Haskell.FromCabal ( fromGenericPackageDescription )
21+import Distribution.Nixpkgs.Haskell.FromCabal
23−import Distribution.Nixpkgs.Haskell.FromCabal.Configuration
22+import Distribution.Nixpkgs.Haskell.FromCabal.Configuration as Config
24import Distribution.Nixpkgs.Haskell.FromCabal.Flags
23import Distribution.Nixpkgs.Haskell.FromCabal.Flags
25−import Distribution.Nixpkgs.Haskell.PackageSourceSpec
26import Distribution.Nixpkgs.Meta
24import Distribution.Nixpkgs.Meta
27import Distribution.Nixpkgs.PackageMap
25import Distribution.Nixpkgs.PackageMap
28import Distribution.Package
26import Distribution.Package
@@ -33,11 +31,12 @@ import Distribution.Version
33import HackageGit ( readHackage, Hackage )
31import HackageGit ( readHackage, Hackage )
34import Language.Nix
32import Language.Nix
35import Options.Applicative
33import Options.Applicative
36−import Paths_hackage2nix
34+import Paths_hackage2nix as Config
37import System.FilePath
36import System.FilePath
38import Text.PrettyPrint.HughesPJClass hiding ( (<>) )
37import Text.PrettyPrint.HughesPJClass hiding ( (<>) )
40−type Nixpkgs = PackageMap -- Map String (Set [String])
39+-- type Nixpkgs = PackageMap -- Map String (Set [String])
41type PackageSet = Map String Version
40type PackageSet = Map String Version
42type PackageMultiSet = Map String (Set Version)
41type PackageMultiSet = Map String (Set Version)
@@ -56,6 +55,8 @@ data Options = Options
56 { hackageRepository :: FilePath
55 { hackageRepository :: FilePath
57 , preferredVersionsFile :: Maybe FilePath
56 , preferredVersionsFile :: Maybe FilePath
58 , nixpkgsRepository :: FilePath
57 , nixpkgsRepository :: FilePath
58+ , ltsHaskellRepository :: FilePath
59+ , stackageNightlyRepository :: FilePath
59 , configFile :: FilePath
60 , configFile :: FilePath
60 , targetPlatform :: Platform
61 , targetPlatform :: Platform
@@ -65,14 +66,16 @@ options :: Parser Options
65options = Options
66options = Options
66 <$> strOption (long "hackage" <> help "path to Hackage git repository" <> value "hackage" <> showDefaultWith id <> metavar "PATH")
67 <$> strOption (long "hackage" <> help "path to Hackage git repository" <> value "hackage" <> showDefaultWith id <> metavar "PATH")
67 <*> optional (strOption (long "preferred-versions" <> help "path to Hackage preferred-versions file" <> value "hackage/preferred-versions" <> showDefault <> metavar "PATH"))
68 <*> optional (strOption (long "preferred-versions" <> help "path to Hackage preferred-versions file" <> value "hackage/preferred-versions" <> showDefault <> metavar "PATH"))
68− <*> strOption (long "nixpkgs" <> help "path to Nixpkgs repository" <> value "<nixpkgs>" <> showDefaultWith id <> metavar "PATH")
69+ <*> strOption (long "nixpkgs" <> help "path to Nixpkgs repository" <> value "nixpkgs" <> showDefaultWith id <> metavar "PATH")
70+ <*> strOption (long "lts-haskell" <> help "path to LTS Haskell repository" <> value "lts-haskell" <> showDefaultWith id <> metavar "PATH")
71+ <*> strOption (long "stackage-nightly" <> help "path to Stackage Nightly repository" <> value "stackage-nightly" <> showDefaultWith id <> metavar "PATH")
69 <*> strOption (long "config" <> help "path to configuration file" <> value "nixpkgs/pkgs/development/haskell-modules/configuration-hackage2nix.yaml" <> showDefaultWith id <> metavar "PATH")
72 <*> strOption (long "config" <> help "path to configuration file" <> value "nixpkgs/pkgs/development/haskell-modules/configuration-hackage2nix.yaml" <> showDefaultWith id <> metavar "PATH")
70 <*> option (fmap fromString str) (long "platform" <> help "target platform to generate package set for" <> value "x86_64-linux" <> showDefaultWith display <> metavar "PLATFORM")
73 <*> option (fmap fromString str) (long "platform" <> help "target platform to generate package set for" <> value "x86_64-linux" <> showDefaultWith display <> metavar "PLATFORM")
72pinfo :: ParserInfo Options
75pinfo :: ParserInfo Options
73pinfo = info
76pinfo = info
75− <*> infoOption ("hackage2nix " ++ display version) (long "version" <> help "Show version number")
78+ <*> infoOption ("hackage2nix " ++ display Config.version) (long "version" <> help "Show version number")
76 <*> options
79 <*> options
78 ( fullDesc
81 ( fullDesc
@@ -83,114 +86,111 @@ main :: IO ()
84 Options {..} <- execParser pinfo
87 Options {..} <- execParser pinfo
86− defaultConfiguration <- readConfiguration configFile
89+ config <- readConfiguration configFile
87− hackage <- readHackage hackageRepository
88 nixpkgs <- readNixpkgPackageMap nixpkgsRepository Nothing
90 nixpkgs <- readNixpkgPackageMap nixpkgsRepository Nothing
89 preferredVersions <- readPreferredVersions (fromMaybe (hackageRepository </> "preferred-versions") preferredVersionsFile)
91 preferredVersions <- readPreferredVersions (fromMaybe (hackageRepository </> "preferred-versions") preferredVersionsFile)
90 let fixup = Map.delete "acme-everything" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
92 let fixup = Map.delete "acme-everything" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
91 . Map.delete "som" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
93 . Map.delete "som" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
92 . Map.delete "type" -- TODO: https://github.com/NixOS/cabal2nix/issues/163
94 . Map.delete "type" -- TODO: https://github.com/NixOS/cabal2nix/issues/163
93 . Map.delete "dictionary-sharing" -- TODO: https://github.com/NixOS/cabal2nix/issues/175
95 . Map.delete "dictionary-sharing" -- TODO: https://github.com/NixOS/cabal2nix/issues/175
94− . Map.filter (/= Map.empty)
96+ hackage <- fixup <$> readHackage hackageRepository
95− . Map.mapWithKey (enforcePreferredVersions preferredVersions)
97+ snapshots <- runParIO (readStackage ltsHaskellRepository)
96− runParIO $ generatePackageSet targetPlatform defaultConfiguration (fixup hackage) nixpkgs
98−enforcePreferredVersions :: [Constraint] -> String -> Map Version GenericPackageDescription
99− -> Map Version GenericPackageDescription
100−enforcePreferredVersions cs pkg = Map.filterWithKey (\v _ -> PackageIdentifier (PackageName pkg) v `satisfiesConstraints` cs)
102−generatePackageSet :: Platform -> Configuration -> Hackage -> Nixpkgs -> ParIO ()
103−generatePackageSet targetPlatform config hackage nixpkgs = do
105− corePackageSet :: PackageSet
99+ corePackageSet :: PackageSet
106− corePackageSet = Map.fromList [ (name, v) | PackageIdentifier (PackageName name) v <- Set.toList (corePackages config) ]
100+ corePackageSet = Map.fromList [ (name, v) | PackageIdentifier (PackageName name) v <- Set.toList (Config.corePackages config) ]
108− latestVersionSet :: PackageSet
102+ latestVersionSet :: PackageSet
109− latestVersionSet = Map.map (Set.findMax . Map.keysSet) hackage
103+ latestVersionSet = Map.map (Set.findMax . Map.keysSet) (Map.filter (/= Map.empty) (Map.mapWithKey (enforcePreferredVersions preferredVersions) hackage))
111− defaultPackageOverridesSet :: PackageSet
105+ defaultPackageOverridesSet :: PackageSet
112− defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency (PackageName name) _) <- defaultPackageOverrides config ]
106+ defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency (PackageName name) _) <- defaultPackageOverrides config ]
114− generatedDefaultPackageSet :: PackageSet
108+ generatedDefaultPackageSet :: PackageSet
115− generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet
109+ generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet
117− latestCorePackageSet :: PackageSet
111+ latestCorePackageSet :: PackageSet
118− latestCorePackageSet = latestVersionSet `Map.intersection` corePackageSet
112+ latestCorePackageSet = latestVersionSet `Map.intersection` corePackageSet
120− latestOverridePackageSet :: PackageSet
114+ latestOverridePackageSet :: PackageSet
121− latestOverridePackageSet = latestVersionSet `Map.intersection` defaultPackageOverridesSet
115+ latestOverridePackageSet = latestVersionSet `Map.intersection` defaultPackageOverridesSet
123− extraPackageSet :: PackageMultiSet
117+ extraPackageSet :: PackageMultiSet
124− extraPackageSet = Map.unionsWith Set.union
118+ extraPackageSet = Map.unionsWith Set.union
125− [ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency (PackageName name) _) <- extraPackages config ]
119+ [ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency (PackageName name) _) <- extraPackages config ]
121+ stackagePackageSet :: PackageMultiSet
122+ stackagePackageSet = Map.fromListWith Set.union [ (unPackageName n, Set.singleton (Stackage.version spec)) | snapshot <- snapshots, (n, spec) <- Map.toList (packages snapshot) ]
127− db :: PackageMultiSet
124+ db :: PackageMultiSet
128− db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet
125+ db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet
129− , Map.map Set.singleton latestCorePackageSet
126+ , Map.map Set.singleton latestCorePackageSet
130− , Map.map Set.singleton latestOverridePackageSet
127+ , Map.map Set.singleton latestOverridePackageSet
131− , extraPackageSet
128+ , extraPackageSet
129+ , stackagePackageSet
134− haskellResolver :: Dependency -> Bool
132+ haskellResolver :: Dependency -> Bool
135− haskellResolver (Dependency (PackageName name) vrange)
133+ haskellResolver (Dependency (PackageName name) vrange)
136− | Just v <- Map.lookup name corePackageSet = v `withinRange` vrange
134+ | Just v <- Map.lookup name corePackageSet = v `withinRange` vrange
137− | Just v <- Map.lookup name generatedDefaultPackageSet = v `withinRange` vrange
135+ | Just v <- Map.lookup name generatedDefaultPackageSet = v `withinRange` vrange
138− | otherwise = False
136+ | otherwise = False
140− nixpkgsResolver :: Identifier -> Maybe Binding
138+ nixpkgsResolver :: Identifier -> Maybe Binding
141− nixpkgsResolver = resolve (Map.map (Set.map (over path ("pkgs":))) nixpkgs)
139+ nixpkgsResolver = resolve (Map.map (Set.map (over path ("pkgs":))) nixpkgs)
143− globalPackageMaintainers :: Map PackageName (Set Identifier)
141+ globalPackageMaintainers :: Map PackageName (Set Identifier)
144− globalPackageMaintainers = Map.unionsWith Set.union [ Map.singleton p (Set.singleton m) | (m,ps) <- Map.toList (packageMaintainers config), p <- Set.toList ps ]
142+ globalPackageMaintainers = Map.unionsWith Set.union [ Map.singleton p (Set.singleton m) | (m,ps) <- Map.toList (packageMaintainers config), p <- Set.toList ps ]
146− liftIO $ do putStrLn "/* hackage-packages.nix is an auto-generated file -- DO NOT EDIT! */"
144+ do putStrLn "/* hackage-packages.nix is an auto-generated file -- DO NOT EDIT! */"
147− putStrLn ""
145+ putStrLn ""
148− putStrLn "{ pkgs, stdenv, callPackage }:"
146+ putStrLn "{ pkgs, stdenv, callPackage }:"
149− putStrLn ""
147+ putStrLn ""
150− putStrLn "self: {"
148+ putStrLn "self: {"
151− putStrLn ""
149+ putStrLn ""
152− pkgs <- flip parMapM (Map.toAscList db) $ \(name, vs) -> do
150+ pkgs <- runParIO $ flip parMapM (Map.toAscList db) $ \(name, vs) -> do
153− defs <- forM (Set.toAscList vs) $ \pkgversion -> do
151+ let defs = flip map (Set.toAscList vs) $ \v ->
154− let -- TODO: Include list of broken dependencies in the generated output.
152+ let
155− descr = hackage Map.! name Map.! pkgversion
153+ pkgId :: PackageIdentifier
156−
154+ pkgId = PackageIdentifier (PackageName name) v
156+ isInDefaultPackageSet :: Bool
157+ isInDefaultPackageSet = maybe False (== v) (Map.lookup name generatedDefaultPackageSet)
159+ abort :: String -> a
160+ abort msg = error (display pkgId ++ ": " ++ msg)
162+ descr :: GenericPackageDescription
163+ descr = fromMaybe (abort "not on Hackage") (Map.lookup name hackage >>= Map.lookup v)
157− flagAssignment :: FlagAssignment
165+ flagAssignment :: FlagAssignment
158− flagAssignment = configureCabalFlags (packageId descr)
166+ flagAssignment = configureCabalFlags (packageId descr)
160− drv' :: Derivation
168+ sha256 :: String
161− drv' = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr
163− isInDefaultPackageSet :: Bool
164− isInDefaultPackageSet = maybe False (== pkgversion) (Map.lookup name generatedDefaultPackageSet)
167− attr = name ++ if isInDefaultPackageSet then [] else '_' : [ if c == '.' then '_' else c | c <- display pkgversion ]
170− sha256 | Just x <- lookup "X-Package-SHA256" (customFieldsPD (packageDescription descr)) = x
169+ sha256 = fromMaybe (abort "has no hash") (lookup "X-Package-SHA256" (customFieldsPD (packageDescription descr)))
171− | otherwise = error $ display (packageId descr) ++ " has no hash"
170+
173− srcSpec <- liftIO $ sourceFromHackage (Certain sha256) (name ++ "-" ++ display pkgversion)
172+ attr = name ++ if isInDefaultPackageSet then [] else '_' : [ if c == '.' then '_' else c | c <- display v ]
175− let drv = drv' & src .~ srcSpec
174+ drv :: Derivation
175+ drv = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr
176+ & src .~ DerivationSource "url" ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") "" sha256
176− & metaSection.hydraPlatforms %~ (`Set.difference` fromMaybe Set.empty (Map.lookup (PackageName name) (dontDistributePackages config)))
177+ & metaSection.hydraPlatforms %~ (`Set.difference` fromMaybe Set.empty (Map.lookup (PackageName name) (dontDistributePackages config)))
178+ & metaSection.maintainers .~ fromMaybe Set.empty (Map.lookup (PackageName name) globalPackageMaintainers)
177− & metaSection.hydraPlatforms %~ (if isInDefaultPackageSet then id else const Set.empty)
179+ & metaSection.hydraPlatforms %~ (if isInDefaultPackageSet then id else const Set.empty)
178− & metaSection.maintainers .~ fromMaybe Set.empty (Map.lookup (PackageName name) globalPackageMaintainers)
180+
180− isFromHackage :: Binding -> Bool
181− isFromHackage b = case view (reference . path) b of
185− overrides :: Doc
181+ overrides :: Doc
186− overrides = fcat $ punctuate space
187− [ pPrint b | b <- Set.toList (view (dependencies . each) drv), not (isFromHackage b) ]
182+ overrides = fcat $ punctuate space [ pPrint b | b <- Set.toList (view (dependencies . each) drv), not (isFromHackage b) ]
189− return $ nest 2 $ hang (doubleQuotes (text attr) <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi)
184+ render $ nest 2 $ hang (doubleQuotes (text attr) <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi)
190− return (intercalate "\n\n" (map render defs))
185+ return (intercalate "\n\n" defs)
192− liftIO $ mapM_ (\pkg -> putStrLn pkg >> putStrLn "") pkgs
187+ mapM_ (\pkg -> putStrLn pkg >> putStrLn "") pkgs
193− liftIO $ putStrLn "}"
188+ putStrLn "}"
190+isFromHackage :: Binding -> Bool
191+isFromHackage b = case view (reference . path) b of
195readPreferredVersions :: FilePath -> IO [Constraint]
195readPreferredVersions :: FilePath -> IO [Constraint]
196readPreferredVersions p = mapMaybe parsePreferredVersionsLine . lines <$> readFile p
196readPreferredVersions p = mapMaybe parsePreferredVersionsLine . lines <$> readFile p
@@ -200,326 +200,6 @@ parsePreferredVersionsLine [] = Nothing
200parsePreferredVersionsLine ('-':'-':_) = Nothing
200parsePreferredVersionsLine ('-':'-':_) = Nothing
201parsePreferredVersionsLine l = simpleParse l `mplus` error ("invalid preferred-versions line: " ++ show l)
201parsePreferredVersionsLine l = simpleParse l `mplus` error ("invalid preferred-versions line: " ++ show l)
203−
203+enforcePreferredVersions :: [Constraint] -> String -> Map Version GenericPackageDescription
204−
204+ -> Map Version GenericPackageDescription
205−-- {-# LANGUAGE OverloadedStrings #-}
205+enforcePreferredVersions cs pkg = Map.filterWithKey (\v _ -> PackageIdentifier (PackageName pkg) v `satisfiesConstraints` cs)
206−-- {-# LANGUAGE RecordWildCards #-}
208−-- module Main ( main ) where
210−-- import Control.Lens
211−-- -- import Control.Exception
212−-- import Control.Monad
213−-- import Control.Monad.Par.Combinator
214−-- import Control.Monad.Par.IO as ParIO
215−-- import Control.Monad.Par as Par
216−-- -- import Control.Monad.Trans ( liftIO )
217−-- -- import Data.List
218−-- import Data.Map.Strict ( Map )
219−-- import qualified Data.Map.Strict as Map
221−-- import Data.Monoid
222−-- import Data.Set ( Set )
223−-- import qualified Data.Set as Set
224−-- import Data.String
225−-- import Distribution.Compiler
226−-- import Distribution.Nixpkgs.Fetch
227−-- import Distribution.Nixpkgs.Haskell
228−-- -- import Distribution.Nixpkgs.Haskell.Constraint
229−-- import Distribution.Nixpkgs.Haskell.FromCabal ( fromGenericPackageDescription )
230−-- -- import Distribution.Nixpkgs.Haskell.FromCabal.Configuration
231−-- -- import Distribution.Nixpkgs.Haskell.FromCabal.Flags
232−-- import Distribution.Nixpkgs.Haskell.HackageGit ( readHackage, Hackage )
233−-- -- import Distribution.Nixpkgs.Haskell.PackageSourceSpec
234−-- -- import Distribution.Nixpkgs.Meta
235−-- import Distribution.Nixpkgs.PackageMap
236−-- import Distribution.Package
237−-- import Distribution.PackageDescription hiding ( options, buildDepends, extraLibs, buildTools )
238−-- import Distribution.System
239−-- import Distribution.Text
240−-- import Distribution.Version
241−-- import Language.Nix
242−-- import Options.Applicative
243−-- import qualified Paths_hackage2nix as Main
244−-- import System.FilePath
245−-- import Text.PrettyPrint.HughesPJClass hiding ( (<>) )
249−-- -- type Nixpkgs = PackageMap -- Map String (Set [String])
250−-- -- type PackageSet = Map PackageName Version
251−-- -- type PackageMultiSet = Map String (Set Version)
253−-- -- resolveConstraint :: Constraint -> Hackage -> Version
254−-- -- resolveConstraint c = fromMaybe (error msg) . resolveConstraint' c
255−-- -- where msg = "constraint " ++ display c ++ " cannot be resolved in Hackage"
257−-- -- resolveConstraint' :: Constraint -> Hackage -> Maybe Version
258−-- -- resolveConstraint' (Dependency (PackageName name) vrange) hackage
259−-- -- | Just vset' <- Map.lookup name hackage
260−-- -- , vset <- Set.filter (`withinRange` vrange) (Map.keysSet vset')
261−-- -- , not (Set.null vset) = Just (Set.findMax vset)
262−-- -- | otherwise = Nothing
264−-- data Options = Options
265−-- { hackageRepository :: FilePath
266−-- , preferredVersionsFile :: Maybe FilePath
267−-- , nixpkgsRepository :: FilePath
268−-- , ltsHaskellRepository :: FilePath
269−-- , stackageNightlyRepository :: FilePath
270−-- , configFile :: FilePath
271−-- , targetPlatform :: Platform
275−-- options :: Parser Options
277−-- <$> strOption (long "hackage" <> help "path to Hackage git repository" <> value "hackage" <> showDefaultWith id <> metavar "PATH")
278−-- <*> optional (strOption (long "preferred-versions" <> help "path to Hackage preferred-versions file" <> value "hackage/preferred-versions" <> showDefault <> metavar "PATH"))
279−-- <*> strOption (long "nixpkgs" <> help "path to Nixpkgs repository" <> value "/home/simons/src/cabal2nix/hackage2nix/nixpkgs" <> showDefaultWith id <> metavar "PATH")
280−-- <*> strOption (long "lts-haskell" <> help "path to LTS Haskell repository" <> value "lts-haskell" <> showDefaultWith id <> metavar "PATH")
281−-- <*> strOption (long "stackage-nightly" <> help "path to Stackage Nightly repository" <> value "stackage-nightly" <> showDefaultWith id <> metavar "PATH")
282−-- <*> strOption (long "config" <> help "path to configuration file" <> value "nixpkgs/pkgs/development/haskell-modules/configuration-hackage2nix.yaml" <> showDefaultWith id <> metavar "PATH")
283−-- <*> option (fmap fromString str) (long "platform" <> help "target platform to generate package set for" <> value "x86_64-linux" <> showDefaultWith display <> metavar "PLATFORM")
285−-- pinfo :: ParserInfo Options
288−-- <*> infoOption ("hackage2nix " ++ display Main.version) (long "version" <> help "Show version number")
292−-- <> header "hackage2nix converts a Hackage database into a hackage-packages.nix file."
297−-- Options {..} <- execParser pinfo
299−-- -- defaultConfiguration <- readConfiguration configFile
300−-- nixpkgs <- readNixpkgPackageMap "/home/simons/src/cabal2nix/hackage2nix/nixpkgs" Nothing
301−-- -- preferredVersions <- readPreferredVersions (fromMaybe (hackageRepository </> "preferred-versions") preferredVersionsFile)
302−-- let fixup = Map.delete "acme-everything" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
303−-- . Map.delete "som" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
304−-- . Map.delete "type" -- TODO: https://github.com/NixOS/cabal2nix/issues/163
305−-- . Map.delete "dictionary-sharing" -- TODO: https://github.com/NixOS/cabal2nix/issues/175
306−-- -- . Map.filter (/= Map.empty)
307−-- -- . Map.mapWithKey (enforcePreferredVersions preferredVersions)
308−-- hackage <- fixup <$> readHackage hackageRepository
309−-- snapshots <- ParIO.runParIO (readStackage ltsHaskellRepository)
312−-- allStackagePackages :: Map PackageName (Set Spec)
313−-- allStackagePackages = Map.unionsWith Set.union (map (Map.map Set.singleton . packages) snapshots)
315−-- notInStackage :: String -> Map Version GenericPackageDescription -> Bool
316−-- notInStackage n _ = isNothing (Map.lookup (PackageName n) allStackagePackages)
318−-- nonStackagePackages :: Map String Version
319−-- nonStackagePackages = Map.map (Set.findMax . Map.keysSet) (Map.filterWithKey notInStackage hackage)
321−-- allPackages :: Map PackageName (Set Spec)
322−-- allPackages = Map.union allStackagePackages
323−-- (Map.fromList [ (PackageName n, Set.singleton (Spec v Map.empty True True True)) | (n,v) <- Map.toList nonStackagePackages ])
325−-- hackagePackagesFile :: FilePath
326−-- hackagePackagesFile = nixpkgsRepository </> "pkgs/development/haskell-modules/hackage-packages.nix"
328−-- drvs :: Map PackageIdentifier Derivation
329−-- drvs = Map.unions (runPar (parMap (uncurry (formatPackages hackage nixpkgs targetPlatform)) (Map.toList allPackages)))
331−-- withFile hackagePackagesFile WriteMode $ \h -> do
332−-- hPutStrLn h "{ stdenv }:\n\nself: {"
333−-- forM_ (Map.toList drvs) $ \(pkgId, drv) -> do
334−-- hPutStrLn h $ render $ nest 2 $ hang (doubleQuotes (text (mangle pkgId)) <+> equals) 2 (pPrint drv <> semi)
338−-- mapM_ (formatSnapshot drvs nixpkgsRepository) snapshots
340−-- mangle :: PackageIdentifier -> String
341−-- mangle (PackageIdentifier (PackageName n) v) = n ++ '_' : [ if c == '.' then '_' else c | c <- display v ]
343−-- formatSnapshot :: Map PackageIdentifier Derivation -> FilePath -> Snapshot -> IO ()
344−-- formatSnapshot drvs nixpkgsRepository (Snapshot {..}) = do
346−-- snapshotId :: String
347−-- snapshotId = show (pPrint snapshot)
349−-- compilerId :: String
350−-- compilerId = filter (`notElem` ['.','-']) (display compiler)
352−-- ltsConfigFile :: FilePath
353−-- ltsConfigFile = nixpkgsRepository </> "pkgs/development/haskell-modules/configuration-" ++ snapshotId ++ ".nix"
355−-- withFile ltsConfigFile WriteMode $ \h -> do
356−-- hPutStrLn h "{ pkgs }:"
358−-- hPutStrLn h "self: super: {"
359−-- hPutStrLn h " # our compiler"
360−-- hPutStrLn h (" ghc = pkgs.haskell.compiler." ++ compilerId ++ ";")
362−-- hPutStrLn h " # core packaged provided by the compiler"
363−-- forM_ (Set.toAscList (Map.keysSet corePackages)) $ \(PackageName n) ->
364−-- unless (n == "ghc") (hPutStrLn h (" " ++ n ++ " = null;"))
366−-- hPutStrLn h " # Stackage"
367−-- forM_ (Map.toAscList packages) $ \(PackageName n, spec) -> do
368−-- let pkgId = PackageIdentifier (PackageName n) (version spec)
369−-- drv = drvs Map.! pkgId
370−-- hPutStrLn h (" \"" ++ n ++ "\" = self.callPackage self.\"" ++ mangle pkgId ++ "\" " ++ render (braces (overrides drv) <> semi))
374−-- formatPackages :: Hackage -> Map Identifier (Set Path) -> Platform -> PackageName -> Set Spec -> Map PackageIdentifier Derivation
375−-- formatPackages hackage nixpkgs targetPlatform pname specs = Map.fromList
376−-- [ (PackageIdentifier pname (version spec), formatPackage hackage nixpkgs targetPlatform pname spec) | spec <- Set.toList specs ]
378−-- formatPackage :: Hackage -> Map Identifier (Set Path) -> Platform -> PackageName -> Spec -> Derivation
379−-- formatPackage hackage nixpkgs targetPlatform pname spec =
381−-- pkgId :: PackageIdentifier
382−-- pkgId = PackageIdentifier pname (version spec)
384−-- abort :: String -> a
385−-- abort msg = error (display pkgId ++ ": " ++ msg)
387−-- nixpkgsResolver :: Identifier -> Maybe Binding
388−-- nixpkgsResolver = resolve (Map.map (Set.map (over path ("pkgs":))) nixpkgs)
390−-- pkgDescr :: GenericPackageDescription
391−-- pkgDescr | Just x <- Map.lookup (unPackageName pname) hackage >>= Map.lookup (version spec) = x
392−-- | otherwise = abort "not on hackage"
395−-- sha256 | Just x <- lookup "X-Package-SHA256" (customFieldsPD (packageDescription pkgDescr)) = x
396−-- | otherwise = abort "cannot find hash"
399−-- drv = fromGenericPackageDescription
403−-- (unknownCompilerInfo (CompilerId GHC (Version [7,10] [])) NoAbiTag)
404−-- (Map.toList (flagOverrides spec))
407−-- & src .~ DerivationSource "url" ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") "" sha256
408−-- & doCheck .~ runTests spec
409−-- & Distribution.Nixpkgs.Haskell.runHaddock .~ Stackage.runHaddock spec
414−-- -- generatePackageSet :: Platform -> Configuration -> Hackage -> Nixpkgs -> ParIO ()
415−-- -- generatePackageSet targetPlatform config hackage nixpkgs = do
417−-- -- corePackageSet :: PackageSet
418−-- -- corePackageSet = Map.fromList [ (name, v) | PackageIdentifier (PackageName name) v <- Set.toList (corePackages config) ]
420−-- -- latestVersionSet :: PackageSet
421−-- -- latestVersionSet = Map.map (Set.findMax . Map.keysSet) hackage
423−-- -- defaultPackageOverridesSet :: PackageSet
424−-- -- defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency (PackageName name) _) <- defaultPackageOverrides config ]
426−-- -- generatedDefaultPackageSet :: PackageSet
427−-- -- generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet
429−-- -- latestCorePackageSet :: PackageSet
430−-- -- latestCorePackageSet = latestVersionSet `Map.intersection` corePackageSet
432−-- -- latestOverridePackageSet :: PackageSet
433−-- -- latestOverridePackageSet = latestVersionSet `Map.intersection` defaultPackageOverridesSet
435−-- -- extraPackageSet :: PackageMultiSet
436−-- -- extraPackageSet = Map.unionsWith Set.union
437−-- -- [ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency (PackageName name) _) <- extraPackages config ]
439−-- -- db :: PackageMultiSet
440−-- -- db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet
441−-- -- , Map.map Set.singleton latestCorePackageSet
442−-- -- , Map.map Set.singleton latestOverridePackageSet
443−-- -- , extraPackageSet
446−-- -- haskellResolver :: Dependency -> Bool
447−-- -- haskellResolver (Dependency (PackageName name) vrange)
448−-- -- | Just v <- Map.lookup name corePackageSet = v `withinRange` vrange
449−-- -- | Just v <- Map.lookup name generatedDefaultPackageSet = v `withinRange` vrange
450−-- -- | otherwise = False
452−-- -- nixpkgsResolver :: Identifier -> Maybe Binding
453−-- -- nixpkgsResolver = resolve (Map.map (Set.map (over path ("pkgs":))) nixpkgs)
455−-- -- globalPackageMaintainers :: Map PackageName (Set Identifier)
456−-- -- globalPackageMaintainers = Map.unionsWith Set.union [ Map.singleton p (Set.singleton m) | (m,ps) <- Map.toList (packageMaintainers config), p <- Set.toList ps ]
458−-- -- liftIO $ do putStrLn "/* hackage-packages.nix is an auto-generated file -- DO NOT EDIT! */"
460−-- -- putStrLn "{ pkgs, stdenv, callPackage }:"
462−-- -- putStrLn "self: {"
464−-- -- pkgs <- flip parMapM (Map.toAscList db) $ \(name, vs) -> do
465−-- -- defs <- forM (Set.toAscList vs) $ \pkgversion -> do
466−-- -- let -- TODO: Include list of broken dependencies in the generated output.
467−-- -- descr = hackage Map.! name Map.! pkgversion
469−-- -- flagAssignment :: FlagAssignment
470−-- -- flagAssignment = configureCabalFlags (packageId descr)
472−-- -- drv' :: Derivation
473−-- -- drv' = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr
475−-- -- isInDefaultPackageSet :: Bool
476−-- -- isInDefaultPackageSet = maybe False (== pkgversion) (Map.lookup name generatedDefaultPackageSet)
479−-- -- attr = name ++ if isInDefaultPackageSet then [] else '_' : [ if c == '.' then '_' else c | c <- display pkgversion ]
481−-- -- sha256 :: String
482−-- -- sha256 | Just x <- lookup "X-Package-SHA256" (customFieldsPD (packageDescription descr)) = x
483−-- -- | otherwise = error $ display (packageId descr) ++ " has no hash"
485−-- -- srcSpec <- liftIO $ sourceFromHackage (Certain sha256) (name ++ "-" ++ display pkgversion)
487−-- -- let drv = drv' & src .~ srcSpec
488−-- -- & metaSection.hydraPlatforms %~ (`Set.difference` fromMaybe Set.empty (Map.lookup (PackageName name) (dontDistributePackages config)))
489−-- -- & metaSection.hydraPlatforms %~ (if isInDefaultPackageSet then id else const Set.empty)
490−-- -- & metaSection.maintainers .~ fromMaybe Set.empty (Map.lookup (PackageName name) globalPackageMaintainers)
492−-- -- isFromHackage :: Binding -> Bool
493−-- -- isFromHackage b = case view (reference . path) b of
494−-- -- ["self",_] -> True
497−-- -- overrides :: Doc
498−-- -- overrides = fcat $ punctuate space
499−-- -- [ pPrint b | b <- Set.toList (view (dependencies . each) drv), not (isFromHackage b) ]
501−-- -- return $ nest 2 $ hang (doubleQuotes (text attr) <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi)
502−-- -- return (intercalate "\n\n" (map render defs))
504−-- -- liftIO $ mapM_ (\pkg -> putStrLn pkg >> putStrLn "") pkgs
505−-- -- liftIO $ putStrLn "}"
507−-- -- readPreferredVersions :: FilePath -> IO [Constraint]
508−-- -- readPreferredVersions p = mapMaybe parsePreferredVersionsLine . lines <$> readFile p
510−-- -- parsePreferredVersionsLine :: String -> Maybe Constraint
511−-- -- parsePreferredVersionsLine [] = Nothing
512−-- -- parsePreferredVersionsLine ('-':'-':_) = Nothing
513−-- -- parsePreferredVersionsLine l = simpleParse l `mplus` error ("invalid preferred-versions line: " ++ show l)
515−-- -- enforcePreferredVersions :: [Constraint] -> String -> Map Version GenericPackageDescription
516−-- -- -> Map Version GenericPackageDescription
517−-- -- enforcePreferredVersions cs pkg = Map.filterWithKey (\v _ -> PackageIdentifier (PackageName pkg) v `satisfiesConstraints` cs)
519−-- overrides :: Derivation -> Doc
520−-- overrides drv = fcat $ punctuate space [ pPrint b | b <- Set.toList (view (dependencies . each) drv), not (isFromHackage b) ]
522−-- isFromHackage :: Binding -> Bool
523−-- isFromHackage b = case view (reference . path) b of
524−-- ["self",_] -> True