git.iko.soy/typeable/cabal2nix
on master help sign in
Merge pull request #312 from ksaric/ksaric/add-hackage-snapshot
144c61cPeter Simons
src/Cabal2nix.hs+12−1
@@ -12,6 +12,7 @@ import Data.Maybe ( fromMaybe )
12import Data.Monoid ( (<>) )
12import Data.Monoid ( (<>) )
13import qualified Data.Set as Set
13import qualified Data.Set as Set
14import Data.String
14import Data.String
15+import Data.Time
15import qualified Distribution.Compat.ReadP as P
16import qualified Distribution.Compat.ReadP as P
16import Distribution.Compiler
17import Distribution.Compiler
17import Distribution.Nixpkgs.Fetch
18import Distribution.Nixpkgs.Fetch
@@ -52,6 +53,7 @@ data Options = Options
52 , optCompiler :: CompilerId
53 , optCompiler :: CompilerId
53 , optSystem :: Platform
54 , optSystem :: Platform
54 , optSubpath :: Maybe FilePath
55 , optSubpath :: Maybe FilePath
56+ , optHackageSnapshot :: Maybe UTCTime
55 , optUrl :: String
57 , optUrl :: String
56 }
58 }
57 deriving (Show)
59 deriving (Show)
@@ -77,8 +79,17 @@ options = Options
77 <*> option (readP parse) (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith display)
79 <*> option (readP parse) (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith display)
78 <*> option (readP parsePlatform) (long "system" <> help "target system to use when evaluating the Cabal file" <> value buildPlatform <> showDefaultWith display)
80 <*> option (readP parsePlatform) (long "system" <> help "target system to use when evaluating the Cabal file" <> value buildPlatform <> showDefaultWith display)
79 <*> optional (strOption $ long "subpath" <> metavar "PATH" <> help "Path to Cabal file's directory relative to the URI (default is root directory)")
81 <*> optional (strOption $ long "subpath" <> metavar "PATH" <> help "Path to Cabal file's directory relative to the URI (default is root directory)")
82+ <*> optional (option utcTimeReader (long "hackage-snapshot" <> help "hackage snapshot time, ISO format"))
80 <*> strArgument (metavar "URI")
83 <*> strArgument (metavar "URI")
81
84
85+-- | A parser for the date. Hackage updates happen maybe once or twice a month.
86+-- Example: parseTime defaultTimeLocale "%FT%T%QZ" "2017-11-20T12:18:35Z" :: Maybe UTCTime
87+utcTimeReader :: ReadM UTCTime
88+utcTimeReader = eitherReader $ \arg ->
89+ case parseTimeM True defaultTimeLocale "%FT%T%QZ" arg of
90+ Nothing -> Left $ "Cannot parse date, ISO format used ('2017-11-20T12:18:35Z'): " ++ arg
91+ Just utcTime -> Right utcTime
92+
82readP :: P.ReadP a a -> ReadM a
93readP :: P.ReadP a a -> ReadM a
83readP p = eitherReader $ \s -> case [ r' | (r',"") <- P.readP_to_S p s ] of
94readP p = eitherReader $ \s -> case [ r' | (r',"") <- P.readP_to_S p s ] of
84 (r:_) -> Right r
95 (r:_) -> Right r
@@ -129,7 +140,7 @@ cabal2nix' :: [String] -> IO (Either Doc Derivation)
129cabal2nix' args = do
140cabal2nix' args = do
130 Options {..} <- handleParseResult $ execParserPure defaultPrefs pinfo args
141 Options {..} <- handleParseResult $ execParserPure defaultPrefs pinfo args
131
142
132− pkg <- getPackage optHpack optHackageDb $ Source optUrl (fromMaybe "" optRevision) (maybe UnknownHash Guess optSha256) (fromMaybe "" optSubpath)
143+ pkg <- getPackage optHpack optHackageDb optHackageSnapshot $ Source optUrl (fromMaybe "" optRevision) (maybe UnknownHash Guess optSha256) (fromMaybe "" optSubpath)
133
144
134 let
145 let
135 withHpackOverrides :: Derivation -> Derivation
146 withHpackOverrides :: Derivation -> Derivation
src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs+27−11
@@ -9,6 +9,7 @@ import Control.Monad.Trans.Maybe
9import Data.List ( isSuffixOf, isPrefixOf )
9import Data.List ( isSuffixOf, isPrefixOf )
10import qualified Data.Map as DB
10import qualified Data.Map as DB
11import Data.Maybe
11import Data.Maybe
12+import Data.Time
12import Distribution.Nixpkgs.Fetch
13import Distribution.Nixpkgs.Fetch
13import Distribution.Nixpkgs.Hashes
14import Distribution.Nixpkgs.Hashes
14import qualified Distribution.Nixpkgs.Haskell.Hackage as DB
15import qualified Distribution.Nixpkgs.Haskell.Hackage as DB
@@ -33,17 +34,29 @@ data Package = Package
33 }
34 }
34 deriving (Show)
35 deriving (Show)
35
36
37+getPackage :: Bool
36−getPackage :: Bool -- ^ Whether hpack should regenerate the cabal file
38+ -- ^ Whether hpack should regenerate the cabal file.
37− -> Maybe FilePath -> Source -> IO Package
39+ -> Maybe FilePath
40+ -- ^ The path to the Hackage database.
41+ -> Maybe UTCTime
42+ -- ^ If we have hackage-snapshot time.
43+ -> Source
44+ -> IO Package
38−getPackage optHpack optHackageDB source = do
45+getPackage optHpack optHackageDB optHackageSnapshot source = do
39− (derivSource, ranHpack, pkgDesc) <- fetchOrFromDB optHpack optHackageDB source
46+ (derivSource, ranHpack, pkgDesc) <- fetchOrFromDB optHpack optHackageDB optHackageSnapshot source
40 (\s -> Package s ranHpack pkgDesc) <$> maybe (sourceFromHackage (sourceHash source) (showPackageIdentifier pkgDesc) $ sourceCabalDir source) return derivSource
47 (\s -> Package s ranHpack pkgDesc) <$> maybe (sourceFromHackage (sourceHash source) (showPackageIdentifier pkgDesc) $ sourceCabalDir source) return derivSource
41
48
49+fetchOrFromDB :: Bool
42−fetchOrFromDB :: Bool -- ^ Whether hpack should regenerate the cabal file
50+ -- ^ Whether hpack should regenerate the cabal file
51+ -> Maybe FilePath
52+ -- ^ The path to the Hackage database.
53+ -> Maybe UTCTime
54+ -- ^ If we have hackage-snapshot time.
55+ -> Source
43− -> Maybe FilePath -> Source -> IO (Maybe DerivationSource, Bool, Cabal.GenericPackageDescription)
56+ -> IO (Maybe DerivationSource, Bool, Cabal.GenericPackageDescription)
44−fetchOrFromDB optHpack optHackageDB src
57+fetchOrFromDB optHpack optHackageDB optHackageSnapshot src
45 | "cabal://" `isPrefixOf` sourceUrl src = do
58 | "cabal://" `isPrefixOf` sourceUrl src = do
46− (msrc, pkgDesc) <- fromDB optHackageDB . drop (length "cabal://") $ sourceUrl src
59+ (msrc, pkgDesc) <- fromDB optHackageDB optHackageSnapshot . drop (length "cabal://") $ sourceUrl src
47 return (msrc, False, pkgDesc)
60 return (msrc, False, pkgDesc)
48 | otherwise = do
61 | otherwise = do
49 r <- fetch (\dir -> cabalFromPath optHpack (dir </> sourceCabalDir src)) src
62 r <- fetch (\dir -> cabalFromPath optHpack (dir </> sourceCabalDir src)) src
@@ -52,10 +65,13 @@ fetchOrFromDB optHpack optHackageDB src
52 Just (derivSource, (externalSource, ranHpack, pkgDesc)) -> do
65 Just (derivSource, (externalSource, ranHpack, pkgDesc)) -> do
53 return (derivSource <$ guard externalSource, ranHpack, pkgDesc)
66 return (derivSource <$ guard externalSource, ranHpack, pkgDesc)
54
67
68+fromDB :: Maybe FilePath
69+ -> Maybe UTCTime
70+ -> String
55−fromDB :: Maybe FilePath -> String -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)
71+ -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)
56−fromDB optHackageDB pkg = do
72+fromDB optHackageDB optHackageSnapshot pkg = do
57 dbPath <- maybe DB.hackageTarball return optHackageDB
73 dbPath <- maybe DB.hackageTarball return optHackageDB
58− db <- DB.readTarball Nothing dbPath
74+ db <- DB.readTarball optHackageSnapshot dbPath
59 vd <- maybe unknownPackageError return (DB.lookup name db >>= lookupVersion)
75 vd <- maybe unknownPackageError return (DB.lookup name db >>= lookupVersion)
60 let ds = case DB.tarballSha256 vd of
76 let ds = case DB.tarballSha256 vd of
61 Nothing -> Nothing
77 Nothing -> Nothing