git.iko.soy/typeable/cabal2nix
on master help sign in
Add support for (and require) Cabal 2.2.x.
commit9ef69957950af86e2e6a3eb82adc0514b27bc83b authorPeter Simons <simons@cryp.to> dateFri 9 Mar 2018, 13:54 (9 years ago) parentdda09f6
11 files changed+37−109
cabal2nix.cabal+4−4 hackage2nix/HackageGit.hs+4−9 src/Cabal2nix.hs+3−5 src/Distribution/Nixpkgs/Haskell/Derivation.hs+2−2 src/Distribution/Nixpkgs/Haskell/FromCabal.hs+2−1 src/Distribution/Nixpkgs/Haskell/FromCabal/Flags.hs+4−1 src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs+1−20 src/Distribution/Nixpkgs/Haskell/Hackage.hs+2−1 src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs+1−51 src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs+12−13 test/Main.hs+2−2
cabal2nix.cabal+4−4
@@ -97,7 +97,7 @@ library
9797 other-extensions: CPP DeriveGeneric FlexibleInstances MultiParamTypeClasses OverloadedStrings RecordWildCards ScopedTypeVariables StandaloneDeriving TemplateHaskell
9898 ghc-options: -Wall
9999 build-depends:
100− Cabal >2
100+ Cabal >2.2
101101 , aeson
102102 , ansi-wl-pprint
103103 , base <5
@@ -107,7 +107,7 @@ library
107107 , directory
108108 , distribution-nixpkgs >=1.1
109109 , filepath
110− , hackage-db >2
110+ , hackage-db >=2.0.1
111111 , hopenssl >=2
112112 , hpack >= 0.26
113113 , language-nix
@@ -153,7 +153,7 @@ executable hackage2nix
153153 hs-source-dirs: hackage2nix
154154 ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
155155 build-depends:
156− Cabal >2
156+ Cabal >2.2
157157 , aeson
158158 , base <5
159159 , bytestring
@@ -181,7 +181,7 @@ test-suite regression-test
181181 main-is: Main.hs
182182 hs-source-dirs: test
183183 build-depends: base
184− , Cabal > 2
184+ , Cabal >2.2
185185 , cabal2nix
186186 , filepath
187187 , language-nix
hackage2nix/HackageGit.hs+4−9
@@ -10,17 +10,15 @@ module HackageGit
1010import Control.Lens hiding ( (<.>) )
1111import Control.Monad
1212import Data.Aeson
13−import Data.ByteString.Char8 ( ByteString )
1413import qualified Data.ByteString.Char8 as BS
1514import Data.Map as Map
1615import Data.Set as Set
1716import Data.String
18−import Data.String.UTF8 ( toString, fromRep )
1917import Distribution.Nixpkgs.Hashes
2018import Distribution.Nixpkgs.Haskell.OrphanInstances ( )
2119import Distribution.Package
2220import Distribution.PackageDescription
23−import Distribution.PackageDescription.Parse ( parseGenericPackageDescription, ParseResult(..) )
21+import Distribution.PackageDescription.Parsec ( parseGenericPackageDescriptionMaybe )
2422import Distribution.Text
2523import Distribution.Version
2624import OpenSSL.Digest ( digest, digestByName )
@@ -42,18 +40,15 @@ getSubDirs path = do
4240 let isDirectory p = doesDirectoryExist (path </> p)
4341 getDirectoryContents path >>= filterM isDirectory . Prelude.filter (\x -> head x /= '.')
4442
45−decodeUTF8 :: ByteString -> String
46−decodeUTF8 = toString . fromRep
47−
4843type SHA256Hash = String
4944
5045readPackage :: FilePath -> PackageIdentifier -> IO (GenericPackageDescription, SHA256Hash)
5146readPackage dirPrefix (PackageIdentifier name version) = do
5247 let cabalFile = dirPrefix </> unPackageName name </> display version </> unPackageName name <.> "cabal"
5348 buf <- BS.readFile cabalFile
54− cabal <- case parseGenericPackageDescription (decodeUTF8 buf) of
55− ParseOk _ a -> return a
56− ParseFailed err -> fail (cabalFile ++ ": " ++ show err)
49+ cabal <- case parseGenericPackageDescriptionMaybe buf of
50+ Just a -> return a
51+ Nothing -> fail ("cannot parse cabal file " ++ cabalFile)
5752 return (cabal, printSHA256 (digest (digestByName "sha256") buf))
5853
5954declareLenses [d|
src/Cabal2nix.hs+3−5
@@ -19,13 +19,12 @@ import Distribution.Compiler
1919import Distribution.Nixpkgs.Fetch
2020import Distribution.Nixpkgs.Haskell
2121import Distribution.Nixpkgs.Haskell.FromCabal
22−import Distribution.Nixpkgs.Haskell.FromCabal.Normalize ( normalizeCabalFlags )
2322import Distribution.Nixpkgs.Haskell.FromCabal.Flags
2423import qualified Distribution.Nixpkgs.Haskell.FromCabal.PostProcess as PP (pkg)
2524import qualified Distribution.Nixpkgs.Haskell.Hackage as DB
2625import Distribution.Nixpkgs.Haskell.PackageSourceSpec
2726import Distribution.Nixpkgs.Meta
28−import Distribution.PackageDescription ( mkFlagName, FlagAssignment )
27+import Distribution.PackageDescription ( mkFlagName, mkFlagAssignment, FlagAssignment )
2928import Distribution.Package ( packageId )
3029import Distribution.Simple.Utils ( lowercase )
3130import Distribution.System
@@ -164,8 +163,7 @@ processPackage Options{..} pkg = do
164163 withHpackOverrides = if pkgRanHpack pkg then hpackOverrides else id
165164
166165 flags :: FlagAssignment
167− flags = normalizeCabalFlags $
168− configureCabalFlags (packageId (pkgCabal pkg)) ++ readFlagList optFlags
166+ flags = configureCabalFlags (packageId (pkgCabal pkg)) `mappend` readFlagList optFlags
169167
170168 deriv :: Derivation
171169 deriv = withHpackOverrides $ fromGenericPackageDescription (const True)
@@ -219,6 +217,6 @@ cabal2nix args = do
219217 Right d -> pPrint d
220218
221219readFlagList :: [String] -> FlagAssignment
222−readFlagList = map tagWithValue
220+readFlagList = mkFlagAssignment . map tagWithValue
223221 where tagWithValue ('-':fname) = (mkFlagName (lowercase fname), False)
224222 tagWithValue fname = (mkFlagName (lowercase fname), True)
src/Distribution/Nixpkgs/Haskell/Derivation.hs+2−2
@@ -23,7 +23,7 @@ import Distribution.Nixpkgs.Haskell.BuildInfo
2323import Distribution.Nixpkgs.Haskell.OrphanInstances ( )
2424import Distribution.Nixpkgs.Meta
2525import Distribution.Package
26−import Distribution.PackageDescription ( FlagAssignment, unFlagName )
26+import Distribution.PackageDescription ( FlagAssignment, unFlagName, unFlagAssignment )
2727import GHC.Generics ( Generic )
2828import Language.Nix
2929import Language.Nix.PrettyPrinting
@@ -140,7 +140,7 @@ instance Pretty Derivation where
140140 , Set.fromList ["fetch" ++ derivKind _src | derivKind _src /= "" && not isHackagePackage]
141141 ]
142142
143− renderedFlags = [ text "-f" <> (if enable then empty else char '-') <> text (unFlagName f) | (f, enable) <- _cabalFlags ]
143+ renderedFlags = [ text "-f" <> (if enable then empty else char '-') <> text (unFlagName f) | (f, enable) <- unFlagAssignment _cabalFlags ]
144144 ++ map text (toAscList _configureFlags)
145145 isHackagePackage = "mirror://hackage/" `isPrefixOf` derivUrl _src
146146 sourceAttr DerivationSource {..}
src/Distribution/Nixpkgs/Haskell/FromCabal.hs+2−1
@@ -11,6 +11,7 @@ import Data.Maybe
1111import Data.Set ( Set )
1212import qualified Data.Set as Set
1313import Distribution.Compiler
14+import Distribution.License
1415import Distribution.Nixpkgs.Haskell
1516import qualified Distribution.Nixpkgs.Haskell as Nix
1617import Distribution.Nixpkgs.Haskell.Constraint
@@ -115,7 +116,7 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package
115116 xrev = maybe 0 read (lookup "x-revision" customFieldsPD)
116117
117118 nixLicense :: Nix.License
118− nixLicense = fromCabalLicense license
119+ nixLicense = fromCabalLicense (either licenseFromSPDX id licenseRaw)
119120
120121 resolveInHackage :: Identifier -> Binding
121122 resolveInHackage i | (i^.ident) `elem` [ unPackageName n | (Dependency n _) <- missingDeps ] = bindNull i
src/Distribution/Nixpkgs/Haskell/FromCabal/Flags.hs+4−1
@@ -9,7 +9,10 @@ import Distribution.PackageDescription
99import Distribution.Version
1010
1111configureCabalFlags :: PackageIdentifier -> FlagAssignment
12−configureCabalFlags (PackageIdentifier name version)
12+configureCabalFlags = mkFlagAssignment . configureCabalFlags'
13+
14+configureCabalFlags' :: PackageIdentifier -> [(FlagName,Bool)]
15+configureCabalFlags' (PackageIdentifier name version)
1316 | name == "accelerate-examples"= [disable "opencl"]
1417 | name == "arithmoi" = [disable "llvm"]
1518 | name == "cabal-plan" = [enable "exe"]
src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs+1−20
@@ -1,17 +1,13 @@
11{-# LANGUAGE OverloadedStrings #-}
22
3−module Distribution.Nixpkgs.Haskell.FromCabal.Normalize ( normalize, normalizeCabalFlags ) where
3+module Distribution.Nixpkgs.Haskell.FromCabal.Normalize ( normalize ) where
44
55import Control.Lens
6−import Data.Function
7−import Data.List
86import qualified Data.Set as Set
97import Data.String
108import Distribution.Nixpkgs.Haskell
119import Distribution.Nixpkgs.Meta
1210import Distribution.Package
13−import Distribution.PackageDescription ( FlagAssignment, mkFlagName, unFlagName )
14−import Distribution.Simple.Utils ( lowercase )
1511import Language.Nix hiding ( quote )
1612
1713normalize :: Derivation -> Derivation
@@ -21,7 +17,6 @@ normalize drv = drv
2117 & over testDepends (normalizeBuildInfo (packageName drv))
2218 & over benchmarkDepends (normalizeBuildInfo (packageName drv))
2319 & over metaSection normalizeMeta
24− & over cabalFlags normalizeCabalFlags
2520 & jailbreak %~ (&& (packageName drv /= "jailbreak-cabal"))
2621
2722normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo
@@ -46,17 +41,3 @@ quote ('\\':c:cs) = '\\' : c : quote cs
4641quote ('"':cs) = '\\' : '"' : quote cs
4742quote (c:cs) = c : quote cs
4843quote [] = []
49−
50−-- | When a flag is specified multiple times, the last occurrence counts. Flag
51−-- names are spelled all lowercase.
52−--
53−-- >>> normalizeCabalFlags [(mkFlagName "foo", True), (mkFlagName "FOO", True), (mkFlagName "Foo", False)]
54−-- [(FlagName "foo",False)]
55−
56−normalizeCabalFlags :: FlagAssignment -> FlagAssignment
57−normalizeCabalFlags flags =
58− sortBy (compare `on` fst) $
59− reverse $
60− nubBy ((==) `on` fst) $
61− reverse
62− [ (mkFlagName (lowercase (unFlagName n)), b) | (n, b) <- flags ]
src/Distribution/Nixpkgs/Haskell/Hackage.hs+2−1
@@ -1,7 +1,8 @@
11module Distribution.Nixpkgs.Haskell.Hackage
22 ( HackageDB, PackageData, VersionData(..)
33 , hackageTarball, readTarball
4− ) where
4+ )
5+ where
56
67import Data.Map as Map
78import qualified Distribution.Hackage.DB.Parsed as P
src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs+1−51
@@ -8,62 +8,12 @@ import Data.String
88import qualified Data.Text as T
99import Data.Yaml
1010import Distribution.Compiler
11−import Distribution.License
1211import Distribution.Package
13−import Distribution.PackageDescription
1412import Distribution.System
1513import Distribution.Text
16−import Distribution.Types.CondTree
17−import Distribution.Types.ExecutableScope
18−import Distribution.Types.ForeignLib
19−import Distribution.Types.ForeignLibOption
20−import Distribution.Types.ForeignLibType
21−import Distribution.Types.IncludeRenaming
22−import Distribution.Types.Mixin
2314import Distribution.Version
24−import Language.Haskell.Extension
25−
26−instance NFData SetupBuildInfo
27−instance (NFData v, NFData c, NFData a) => NFData (CondTree v c a)
28−instance (NFData v, NFData c, NFData a) => NFData (CondBranch v c a)
29−instance NFData Arch
30−instance NFData Benchmark
31−instance NFData BenchmarkInterface
32−instance NFData BenchmarkType
33−instance NFData BuildInfo
34−instance NFData BuildType
35−instance NFData LibVersionInfo
36−instance NFData CompilerFlavor
37−instance NFData ConfVar
38−instance NFData ExecutableScope
39−instance NFData IncludeRenaming
40−instance NFData ForeignLibType
41−instance NFData ForeignLibOption
42−instance NFData Executable
43−instance NFData Extension
44−instance NFData Flag
45−instance NFData Mixin
46−instance NFData FlagName
47−instance NFData GenericPackageDescription
48−instance NFData KnownExtension
49−instance NFData Language
50−instance NFData Library
51−instance NFData ForeignLib
52−instance NFData License
53−instance NFData ModuleReexport
54−instance NFData ModuleRenaming
55−instance NFData OS
56−instance NFData PackageDescription
57−instance NFData RepoKind
58−instance NFData RepoType
59−instance NFData SourceRepo
60−instance NFData TestSuite
61−instance NFData TestSuiteInterface
62−instance NFData TestType
63−instance NFData a => NFData (Condition a)
64−instance NFData Platform
15+
6516instance NFData CompilerInfo
66−instance NFData CompilerId
6717instance NFData AbiTag
6818
6919instance IsString Version where
src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs+12−13
@@ -2,11 +2,12 @@ module Distribution.Nixpkgs.Haskell.PackageSourceSpec
22 ( Package(..), getPackage, getPackage', loadHackageDB, sourceFromHackage
33 ) where
44
5+import Control.DeepSeq (force)
56import qualified Control.Exception as Exception
67import Control.Monad
78import Control.Monad.IO.Class
89import Control.Monad.Trans.Maybe
9−import Control.DeepSeq (force)
10+import qualified Data.ByteString.Char8 as BS -- TODO: Deal with utf-8 encoding!!
1011import Data.List ( isSuffixOf, isPrefixOf )
1112import qualified Data.Map as DB
1213import Data.Maybe
@@ -17,11 +18,11 @@ import qualified Distribution.Nixpkgs.Haskell.Hackage as DB
1718import qualified Distribution.Package as Cabal
1819import Distribution.PackageDescription
1920import qualified Distribution.PackageDescription as Cabal
20−import Distribution.PackageDescription.Parse as Cabal
21+import Distribution.PackageDescription.Parsec as Cabal
2122import Distribution.Text ( simpleParse, display )
2223import Distribution.Version
23−import qualified Hpack.Render as Hpack
2424import qualified Hpack.Config as Hpack
25+import qualified Hpack.Render as Hpack
2526import OpenSSL.Digest ( digestString, digestByName )
2627import System.Directory ( doesDirectoryExist, doesFileExist, createDirectoryIfMissing, getHomeDirectory, getDirectoryContents )
2728import System.Exit ( exitFailure )
@@ -198,12 +199,12 @@ hpackDirectory dir = do
198199 Right (Hpack.DecodeResult pkg' _ _) -> do
199200 let hpackOutput = Hpack.renderPackage [] pkg'
200201 hash = printSHA256 $ digestString (digestByName "sha256") hpackOutput
201− case parseGenericPackageDescription hpackOutput of
202− ParseFailed perr -> liftIO $ do
203− hPutStrLn stderr $ "*** cannot parse hpack output: " ++ show perr
204− hPutStrLn stderr $ "*** hpack output:\n" ++ hpackOutput
202+ case parseGenericPackageDescriptionMaybe (BS.pack hpackOutput) of
203+ Nothing -> liftIO $ do
204+ hPutStrLn stderr "*** cannot parse hpack output:"
205+ hPutStrLn stderr hpackOutput
205206 fail "*** Exiting."
206− ParseOk _ pkg -> MaybeT $ return $ Just $ (,) True $ setCabalFileHash hash pkg
207+ Just pkg -> MaybeT $ return $ Just $ (,) True $ setCabalFileHash hash pkg
207208
208209cabalFromFile :: Bool -> FilePath -> MaybeT IO Cabal.GenericPackageDescription
209210cabalFromFile failHard file =
@@ -215,11 +216,9 @@ cabalFromFile failHard file =
215216 hSetEncoding h utf8
216217 hGetContents h >>= Exception.evaluate . force
217218 let hash = printSHA256 (digestString (digestByName "sha256") buf)
218− case parseGenericPackageDescription buf of
219− ParseFailed perr -> if failHard
220− then fail ("cannot parse " ++ show file ++ ": " ++ show perr)
221− else return Nothing
222− ParseOk _ pkg -> return $ Just $ setCabalFileHash hash pkg
219+ case parseGenericPackageDescriptionMaybe (BS.pack buf) of
220+ Nothing -> if failHard then fail ("cannot parse " ++ show file) else return Nothing
221+ Just pkg -> return $ Just $ setCabalFileHash hash pkg
223222
224223setCabalFileHash :: String -> GenericPackageDescription -> GenericPackageDescription
225224setCabalFileHash sha256 gpd = gpd { packageDescription = (packageDescription gpd) {
test/Main.hs+2−2
@@ -7,7 +7,7 @@ import Distribution.Nixpkgs.Fetch
77import Control.Lens
88import Distribution.Compiler
99import Distribution.PackageDescription
10−import Distribution.PackageDescription.Parse
10+import Distribution.PackageDescription.Parsec
1111import Distribution.System
1212import Distribution.Verbosity
1313import Distribution.Version
@@ -35,7 +35,7 @@ regressionTest cabalFile = do
3535 (\i -> Just (binding # (i, path # [i])))
3636 (Platform X86_64 Linux)
3737 (unknownCompilerInfo (CompilerId GHC (mkVersion [8,2])) NoAbiTag)
38− []
38+ mempty
3939 []
4040 gpd
4141 & src .~ DerivationSource