packages feed

cabal2nix 2.6 → 2.7

raw patch · 8 files changed

+112/−32 lines, 8 filesdep +hpackPVP ok

version bump matches the API change (PVP)

Dependencies added: hpack

API changes (from Hackage documentation)

+ Distribution.Nixpkgs.Haskell.FromCabal.PostProcess: pkg :: Identifier -> Binding
+ Distribution.Nixpkgs.Haskell.OrphanInstances: instance Data.String.IsString Distribution.Version.VersionRange
+ Distribution.Nixpkgs.Haskell.PackageSourceSpec: [pkgRanHpack] :: Package -> Bool
- Distribution.Nixpkgs.Haskell.PackageSourceSpec: Package :: DerivationSource -> GenericPackageDescription -> Package
+ Distribution.Nixpkgs.Haskell.PackageSourceSpec: Package :: DerivationSource -> Bool -> GenericPackageDescription -> Package
- Distribution.Nixpkgs.Haskell.PackageSourceSpec: getPackage :: Maybe FilePath -> Source -> IO Package
+ Distribution.Nixpkgs.Haskell.PackageSourceSpec: getPackage :: Bool -> Maybe FilePath -> Maybe UTCTime -> Source -> IO Package

Files

cabal2nix.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           cabal2nix-version:        2.6+version:        2.7 synopsis:       Convert Cabal files into Nix build instructions. description:    Convert Cabal files into Nix build instructions. Users of Nix can install the latest version by running:                 .@@ -101,6 +101,7 @@     , filepath     , hackage-db > 2     , hopenssl >= 2+    , hpack     , language-nix     , lens     , optparse-applicative@@ -150,6 +151,7 @@     , filepath     , hackage-db > 2     , hopenssl >= 2+    , hpack     , language-nix     , lens     , optparse-applicative@@ -183,6 +185,7 @@     , filepath     , hackage-db > 2     , hopenssl >= 2+    , hpack     , language-nix     , lens     , optparse-applicative@@ -223,6 +226,7 @@     , filepath     , hackage-db > 2     , hopenssl >= 2+    , hpack     , language-nix     , lens     , optparse-applicative
src/Cabal2nix.hs view
@@ -12,11 +12,13 @@ import Data.Monoid ( (<>) ) import qualified Data.Set as Set import Data.String+import Data.Time import qualified Distribution.Compat.ReadP as P import Distribution.Compiler import Distribution.Nixpkgs.Fetch import Distribution.Nixpkgs.Haskell import Distribution.Nixpkgs.Haskell.FromCabal+import qualified Distribution.Nixpkgs.Haskell.FromCabal.PostProcess as PP (pkg) import Distribution.Nixpkgs.Haskell.PackageSourceSpec import Distribution.Nixpkgs.Meta import Distribution.PackageDescription ( mkFlagName, FlagAssignment )@@ -36,6 +38,7 @@   , optMaintainer :: [String] --, optPlatform :: [String]       -- TODO: fix command line handling of platforms   , optHaddock :: Bool+  , optHpack :: Bool   , optDoCheck :: Bool   , optJailbreak :: Bool   , optRevision :: Maybe String@@ -50,6 +53,7 @@   , optCompiler :: CompilerId   , optSystem :: Platform   , optSubpath :: Maybe FilePath+  , optHackageSnapshot :: Maybe UTCTime   , optUrl :: String   }   deriving (Show)@@ -60,6 +64,7 @@           <*> many (strOption $ long "maintainer" <> metavar "MAINTAINER" <> help "maintainer of this package (may be specified multiple times)") --        <*> many (strOption $ long "platform" <> metavar "PLATFORM" <> help "supported build platforms (may be specified multiple times)")           <*> flag True False (long "no-haddock" <> help "don't run Haddock when building this package")+          <*> switch (long "hpack" <> help "run hpack before configuring this package (only non-hackage packages)")           <*> flag True False (long "no-check" <> help "don't run regression test suites of this package")           <*> switch (long "jailbreak" <> help "disregard version restrictions on build inputs")           <*> optional (strOption $ long "revision" <> help "revision to use when fetching from VCS")@@ -74,8 +79,17 @@           <*> option (readP parse) (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith display)           <*> option (readP parsePlatform) (long "system" <> help "target system to use when evaluating the Cabal file" <> value buildPlatform <> showDefaultWith display)           <*> optional (strOption $ long "subpath" <> metavar "PATH" <> help "Path to Cabal file's directory relative to the URI (default is root directory)")+          <*> optional (option utcTimeReader (long "hackage-snapshot" <> help "hackage snapshot time, ISO format"))           <*> strArgument (metavar "URI") +-- | A parser for the date. Hackage updates happen maybe once or twice a month.+-- Example: parseTime defaultTimeLocale "%FT%T%QZ" "2017-11-20T12:18:35Z" :: Maybe UTCTime+utcTimeReader :: ReadM UTCTime+utcTimeReader = eitherReader $ \arg ->+    case parseTimeM True defaultTimeLocale "%FT%T%QZ" arg of+        Nothing      -> Left $ "Cannot parse date, ISO format used ('2017-11-20T12:18:35Z'): " ++ arg+        Just utcTime -> Right utcTime+ readP :: P.ReadP a a -> ReadM a readP p = eitherReader $ \s -> case [ r' | (r',"") <- P.readP_to_S p s ] of                                     (r:_) -> Right r@@ -118,15 +132,21 @@ main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() ->   cabal2nix =<< getArgs +hpackOverrides :: Derivation -> Derivation+hpackOverrides = over phaseOverrides (++ "preConfigure = \"hpack\";")+               . set (libraryDepends . tool . contains (PP.pkg "hpack")) True+ cabal2nix' :: [String] -> IO (Either Doc Derivation) cabal2nix' args = do   Options {..} <- handleParseResult $ execParserPure defaultPrefs pinfo args -  pkg <- getPackage optHackageDb $ Source optUrl (fromMaybe "" optRevision) (maybe UnknownHash Guess optSha256) (fromMaybe "" optSubpath)+  pkg <- getPackage optHpack optHackageDb optHackageSnapshot $ Source optUrl (fromMaybe "" optRevision) (maybe UnknownHash Guess optSha256) (fromMaybe "" optSubpath)    let+      withHpackOverrides :: Derivation -> Derivation+      withHpackOverrides = if pkgRanHpack pkg then hpackOverrides else id       deriv :: Derivation-      deriv = fromGenericPackageDescription (const True)+      deriv = withHpackOverrides $ fromGenericPackageDescription (const True)                                             (\i -> Just (binding # (i, path # [i])))                                             optSystem                                             (unknownCompilerInfo optCompiler NoAbiTag)
src/Distribution/Nixpkgs/Haskell/FromCabal.hs view
@@ -17,7 +17,7 @@ import Distribution.Nixpkgs.Haskell.FromCabal.License import Distribution.Nixpkgs.Haskell.FromCabal.Name import Distribution.Nixpkgs.Haskell.FromCabal.Normalize-import Distribution.Nixpkgs.Haskell.FromCabal.PostProcess+import Distribution.Nixpkgs.Haskell.FromCabal.PostProcess (postProcess) import qualified Distribution.Nixpkgs.Meta as Nix import Distribution.Package import Distribution.PackageDescription
src/Distribution/Nixpkgs/Haskell/FromCabal/Flags.hs view
@@ -28,7 +28,7 @@                                   , enable "s3"                                   , enable "tahoe"                                   , enable "tdfa"-                                  , enable "testsuite"+                                  , ("testsuite", version `withinRange` "< 6.20170925")                                   , enable "torrentparser"                                   , enable "webapp"                                   , enable "webapp-secure"@@ -42,7 +42,7 @@                                 = [enable "externalLibsass"]  | name == "hmatrix"            = [enable "openblas"]  | name == "hslua"              = [enable "system-lua"]- | name == "idris"              = [enable "gmp", enable "ffi", enable "curses"]+ | name == "idris"              = [enable "gmp", enable "ffi", enable "curses", ("execonly", version `withinRange` (orLaterVersion (mkVersion [1,1,1]))) ]  | name == "io-streams"         = [enable "NoInteractiveTests"]  | name == "liquid-fixpoint"    = [enable "build-external"]  | name == "pandoc"             = [enable "https", disable "trypandoc"]
src/Distribution/Nixpkgs/Haskell/FromCabal/Name.hs view
@@ -130,6 +130,7 @@ libNixName "sass"                               = return "libsass" libNixName "sctp"                               = return "lksctp-tools" -- This is linux-specific, we should create a common attribute if we ever add sctp support for other systems. libNixName "sdl2"                               = return "SDL2"+libNixName "ssh2"                               = return "libssh2" libNixName "sndfile"                            = return "libsndfile" libNixName "sodium"                             = return "libsodium" libNixName "sqlite3"                            = return "sqlite"
src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} -module Distribution.Nixpkgs.Haskell.FromCabal.PostProcess ( postProcess ) where+module Distribution.Nixpkgs.Haskell.FromCabal.PostProcess ( postProcess, pkg ) where  import Control.Lens import Data.List.Split@@ -61,6 +61,7 @@   , ("gi-pangocairo", giCairoPhaseOverrides)                     -- https://github.com/haskell-gi/haskell-gi/issues/36   , ("gi-pango", giCairoPhaseOverrides)                     -- https://github.com/haskell-gi/haskell-gi/issues/36   , ("git-annex", gitAnnexHook)+  , ("git-annex >= 6.20170925", set doCheck False)      -- new version of git-annex require their test suite to be run inside of a git checkout   , ("github-backup", set (executableDepends . tool . contains (pkg "git")) True)   , ("git", set doCheck False)          -- https://github.com/vincenthz/hit/issues/33   , ("gi-webkit", webkitgtk24xHook)   -- https://github.com/haskell-gi/haskell-gi/issues/36@@ -70,10 +71,11 @@   , ("haddock", haddockHook) -- https://github.com/haskell/haddock/issues/511   , ("hakyll", set (testDepends . tool . contains (pkg "utillinux")) True) -- test suite depends on "rev"   , ("haskell-src-exts", set doCheck False)+  , ("hspec-core >= 2.4.4", hspecCoreOverrides)   , ("hfsevents", hfseventsOverrides)   , ("HFuse", set phaseOverrides hfusePreConfigure)   , ("hlibgit2 >= 0.18.0.14", set (testDepends . tool . contains (pkg "git")) True)-  , ("hmatrix", set phaseOverrides "preConfigure = \"sed -i hmatrix.cabal -e 's@/usr/@/dont/hardcode/paths/@'\";")+  , ("hmatrix", set phaseOverrides "preConfigure = \"sed -i hmatrix.cabal -e '/\\\\/usr\\\\//D'\";")   , ("holy-project", set doCheck False)         -- attempts to access the network   , ("hoogle", set testTarget "--test-option=--no-net")   , ("hsignal < 0.2.7.4", set phaseOverrides "prePatch = \"rm -v Setup.lhs\";") -- https://github.com/amcphail/hsignal/issues/1@@ -102,6 +104,7 @@   , ("qtah-cpp-qt5", set (libraryDepends . system . contains (bind "pkgs.qt5.qtbase")) True)   , ("qtah-qt5", set (libraryDepends . tool . contains (bind "pkgs.qt5.qtbase")) True)   , ("readline", over (libraryDepends . system) (Set.union (pkgs ["readline", "ncurses"])))+  , ("req", set doCheck False)  -- test suite requires network access   , ("sbv > 7", set (testDepends . system . contains (pkg "z3")) True)   , ("sdr", over (metaSection . platforms) (Set.filter (\(Platform arch _) -> arch == X86_64))) -- https://github.com/adamwalker/sdr/issues/2   , ("shake-language-c", set doCheck False) -- https://github.com/samplecount/shake-language-c/issues/26@@ -296,3 +299,6 @@                 . over (libraryDepends . pkgconfig) (replace (pkg "opencv") (pkg "opencv3"))                 . set (configureFlags . contains "--with-gcc=${stdenv.cc}/bin/c++") True                 . set (configureFlags . contains "--with-ld=${stdenv.cc}/bin/c++") True++hspecCoreOverrides :: Derivation -> Derivation   -- https://github.com/hspec/hspec/issues/330+hspecCoreOverrides = set phaseOverrides "testTarget = \"--test-option=--skip --test-option='Test.Hspec.Core.Runner.hspecResult runs specs in parallel'\";"
src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs view
@@ -69,6 +69,9 @@ instance IsString Version where   fromString = text2isString "Version" +instance IsString VersionRange where+  fromString = text2isString "VersionRange"+ instance IsString PackageIdentifier where   fromString = text2isString "PackageIdentifier" 
src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs view
@@ -9,6 +9,7 @@ import Data.List ( isSuffixOf, isPrefixOf ) import qualified Data.Map as DB import Data.Maybe+import Data.Time import Distribution.Nixpkgs.Fetch import Distribution.Nixpkgs.Hashes import qualified Distribution.Nixpkgs.Haskell.Hackage as DB@@ -18,6 +19,8 @@ import Distribution.PackageDescription.Parse as Cabal import Distribution.Text ( simpleParse, display ) import Distribution.Version+import qualified Hpack.Run as Hpack+import qualified Hpack.Config as Hpack import OpenSSL.Digest ( digestString, digestByName ) import System.Directory ( doesDirectoryExist, doesFileExist, createDirectoryIfMissing, getHomeDirectory, getDirectoryContents ) import System.Exit ( exitFailure )@@ -25,30 +28,50 @@ import System.IO ( hPutStrLn, stderr, hPutStr )  data Package = Package-  { pkgSource :: DerivationSource-  , pkgCabal :: Cabal.GenericPackageDescription+  { pkgSource   :: DerivationSource+  , pkgRanHpack :: Bool -- ^ If hpack generated a new cabal file+  , pkgCabal    :: Cabal.GenericPackageDescription   }   deriving (Show) -getPackage :: Maybe FilePath -> Source -> IO Package-getPackage optHackageDB source = do-  (derivSource, pkgDesc) <- fetchOrFromDB optHackageDB source-  flip Package pkgDesc <$> maybe (sourceFromHackage (sourceHash source) (showPackageIdentifier pkgDesc) $ sourceCabalDir source) return derivSource+getPackage :: Bool+           -- ^ Whether hpack should regenerate the cabal file.+           -> Maybe FilePath+           -- ^ The path to the Hackage database.+           -> Maybe UTCTime+           -- ^ If we have hackage-snapshot time.+           -> Source+           -> IO Package+getPackage optHpack optHackageDB optHackageSnapshot source = do+  (derivSource, ranHpack, pkgDesc) <- fetchOrFromDB optHpack optHackageDB optHackageSnapshot source+  (\s -> Package s ranHpack pkgDesc) <$> maybe (sourceFromHackage (sourceHash source) (showPackageIdentifier pkgDesc) $ sourceCabalDir source) return derivSource -fetchOrFromDB :: Maybe FilePath -> Source -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)-fetchOrFromDB optHackageDB src-  | "cabal://" `isPrefixOf` sourceUrl src = fromDB optHackageDB . drop (length "cabal://") $ sourceUrl src+fetchOrFromDB :: Bool+              -- ^ Whether hpack should regenerate the cabal file+              -> Maybe FilePath+              -- ^ The path to the Hackage database.+              -> Maybe UTCTime+              -- ^ If we have hackage-snapshot time.+              -> Source+              -> IO (Maybe DerivationSource, Bool, Cabal.GenericPackageDescription)+fetchOrFromDB optHpack optHackageDB optHackageSnapshot src+  | "cabal://" `isPrefixOf` sourceUrl src = do+      (msrc, pkgDesc) <- fromDB optHackageDB optHackageSnapshot . drop (length "cabal://") $ sourceUrl src+      return (msrc, False, pkgDesc)   | otherwise                             = do-    r <- fetch (\dir -> cabalFromPath (dir </> sourceCabalDir src)) src+    r <- fetch (\dir -> cabalFromPath optHpack (dir </> sourceCabalDir src)) src     case r of       Nothing -> fail "Failed to fetch source. Does the URL exist?"-      Just (derivSource, (externalSource, pkgDesc)) -> do-        return (derivSource <$ guard externalSource, pkgDesc)+      Just (derivSource, (externalSource, ranHpack, pkgDesc)) -> do+        return (derivSource <$ guard externalSource, ranHpack, pkgDesc) -fromDB :: Maybe FilePath -> String -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)-fromDB optHackageDB pkg = do+fromDB :: Maybe FilePath+       -> Maybe UTCTime+       -> String+       -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)+fromDB optHackageDB optHackageSnapshot pkg = do   dbPath <- maybe DB.hackageTarball return optHackageDB-  db <- DB.readTarball Nothing dbPath+  db <- DB.readTarball optHackageSnapshot dbPath   vd <- maybe unknownPackageError return (DB.lookup name db >>= lookupVersion)   let ds = case DB.tarballSha256 vd of              Nothing -> Nothing@@ -129,22 +152,45 @@   name = Cabal.unPackageName (Cabal.packageName pkgId)   version = Cabal.packageVersion pkgId -cabalFromPath :: FilePath -> MaybeT IO (Bool, Cabal.GenericPackageDescription)-cabalFromPath path = do+cabalFromPath :: Bool -- ^ Whether hpack should regenerate the cabal file+              -> FilePath -> MaybeT IO (Bool, Bool, Cabal.GenericPackageDescription)+cabalFromPath optHpack path = do   d <- liftIO $ doesDirectoryExist path-  (,) d <$> if d-    then cabalFromDirectory  path-    else cabalFromFile False path+  if d+  then do+    (ranHpack, pkg) <- cabalFromDirectory optHpack path+    return (d, ranHpack, pkg)+  else (,,) d False <$> cabalFromFile False path -cabalFromDirectory :: FilePath -> MaybeT IO Cabal.GenericPackageDescription-cabalFromDirectory dir = do+cabalFromDirectory :: Bool -- ^ Whether hpack should regenerate the cabal file+                   -> FilePath -> MaybeT IO (Bool, Cabal.GenericPackageDescription)+cabalFromDirectory True dir = hpackDirectory dir+cabalFromDirectory False dir = do   cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)   case cabals of-    [cabalFile] -> cabalFromFile True cabalFile-    _       -> liftIO $ fail ("Found zero or more than one cabal files: " ++ show cabals ++ ". Exiting.")+    [] -> do+      liftIO $ hPutStrLn stderr "*** found zero cabal files. Trying hpack..."+      hpackDirectory dir+    [cabalFile] -> (,) False <$> cabalFromFile True cabalFile+    _       -> liftIO $ fail ("*** found more than one cabal file (" ++ show cabals ++ "). Exiting.")  handleIO :: (Exception.IOException -> IO a) -> IO a -> IO a handleIO = Exception.handle++hpackDirectory :: FilePath -> MaybeT IO (Bool, Cabal.GenericPackageDescription)+hpackDirectory dir = do+  mPackage <- liftIO $ Hpack.readPackageConfig $ dir </> "package.yaml"+  case mPackage of+    Left err -> liftIO $ hPutStrLn stderr ("*** hpack error: " ++ show err ++ ". Exiting.") >> exitFailure+    Right (_, pkg') -> do+      let hpackOutput = Hpack.renderPackage Hpack.defaultRenderSettings 2 [] [] pkg'+          hash = printSHA256 $ digestString (digestByName "sha256") hpackOutput+      case parseGenericPackageDescription hpackOutput of+        ParseFailed perr -> liftIO $ do+          hPutStrLn stderr $ "*** cannot parse hpack output: " ++ show perr+          hPutStrLn stderr $ "*** hpack output:\n" ++ hpackOutput+          fail "*** Exiting."+        ParseOk _ pkg -> MaybeT $ return $ Just $ (,) True $ setCabalFileHash hash pkg  cabalFromFile :: Bool -> FilePath -> MaybeT IO Cabal.GenericPackageDescription cabalFromFile failHard file =