git.iko.soy/typeable/cabal2nix
on master help sign in
Use deepseq-generics to auto-generate the NFData instances.

Also added a small test suite to verify that this stuff actually works.

commitca1e570fd754dcd323b2247e70af9610680fdbb3 authorPeter Simons <simons@cryp.to> dateTue 13 Jan 2015, 15:20 (12 years ago) parentafab77a
7 files changed+73−32
cabal2nix.cabal+18−4 release.nix+1−1 src/Distribution/NixOS/Derivation/Cabal.hs+8−13 src/Distribution/NixOS/Derivation/License.hs+5−5 src/Distribution/NixOS/Derivation/Meta.hs+5−4 src/Distribution/NixOS/Fetch.hs+9−5 test/spec.hs+27
cabal2nix.cabal+18−4
@@ -60,8 +60,8 @@ Executable cabal2nix
6060 hs-source-dirs: src
6161 Build-Depends: base >= 3 && < 5, regex-posix, pretty, Cabal >= 1.18,
6262 filepath, directory, process, hackage-db >= 1.11, transformers,
63− deepseq, bytestring, SHA
64− Extensions: PatternGuards, RecordWildCards, CPP
63+ deepseq, bytestring, SHA, deepseq-generics
64+ Extensions: PatternGuards, RecordWildCards, CPP, DeriveGeneric, StandaloneDeriving
6565 Ghc-Options: -Wall
6666 other-modules: Cabal2Nix.CorePackages
6767 Cabal2Nix.Flags
@@ -86,9 +86,9 @@ Executable hackage2nix
8686 Build-Depends: base >= 3 && < 5, regex-posix, pretty, Cabal >= 1.18,
8787 filepath, directory, process, hackage-db >= 1.11, transformers, deepseq,
8888 containers, mtl, monad-par, monad-par-extras, bytestring, SHA, aeson,
89− split, utf8-string
89+ split, utf8-string, deepseq-generics
9090 Ghc-Options: -Wall -threaded -rtsopts -with-rtsopts=-N
91− Extensions: PatternGuards, RecordWildCards, CPP
91+ Extensions: PatternGuards, RecordWildCards, CPP, DeriveGeneric, StandaloneDeriving
9292 other-modules: Cabal2Nix.CorePackages
9393 Cabal2Nix.Flags
9494 Cabal2Nix.Generate
@@ -107,4 +107,18 @@ Test-Suite doctest-cabal2nix
107107 type: exitcode-stdio-1.0
108108 main-is: doc-test.hs
109109 hs-source-dirs: test
110+ Extensions: PatternGuards, RecordWildCards, CPP, DeriveGeneric, StandaloneDeriving
110111 build-depends: base, doctest
112+
113+Test-Suite self-test
114+ type: exitcode-stdio-1.0
115+ main-is: spec.hs
116+ hs-source-dirs: src, test
117+ Extensions: PatternGuards, RecordWildCards, CPP, DeriveGeneric, StandaloneDeriving
118+ build-depends: base, regex-posix, pretty, Cabal >= 1.18,
119+ filepath, directory, process, hackage-db >= 1.11, transformers, deepseq,
120+ containers, mtl, monad-par, monad-par-extras, bytestring, SHA, aeson,
121+ split, utf8-string, deepseq-generics, hspec, QuickCheck
122+ other-modules: Distribution.NixOS.Derivation.Cabal
123+ Distribution.NixOS.Derivation.License
124+ Distribution.NixOS.Derivation.Meta
release.nix+1−1
@@ -29,7 +29,7 @@ in
2929 hackage-db monad-par monad-par-extras mtl pretty process
3030 regex-posix SHA split transformers utf8-string
3131 ];
32− testDepends = with haskellPackages; [ base doctest ];
32+ testDepends = with haskellPackages; [ base doctest QuickCheck deepseq-generics hspec ];
3333 homepage = "http://github.com/NixOS/cabal2nix";
3434 description = "Convert Cabal files into Nix build instructions";
3535 license = pkgs.stdenv.lib.licenses.bsd3;
src/Distribution/NixOS/Derivation/Cabal.hs+8−13
@@ -1,4 +1,5 @@
1−{-# LANGUAGE PatternGuards, RecordWildCards, CPP #-}
1+{-# LANGUAGE PatternGuards, RecordWildCards, CPP, DeriveGeneric, StandaloneDeriving #-}
2+{-# OPTIONS_GHC -fno-warn-orphans #-} -- for FlagName below
23{- |
34 Module : Distribution.NixOS.Derivation.Cabal
45 License : BSD3
@@ -20,7 +21,7 @@ module Distribution.NixOS.Derivation.Cabal
2021 )
2122 where
2223
23−import Control.DeepSeq
24+import Control.DeepSeq.Generics
2425import Data.Char
2526import Data.Function
2627import Data.List
@@ -35,6 +36,7 @@ import Distribution.PackageDescription ( PackageDescription )
3536#endif
3637import Distribution.PackageDescription ( FlagAssignment, FlagName(..) )
3738import Distribution.Text
39+import GHC.Generics ( Generic )
3840
3941-- | A represtation of Nix expressions for building Haskell packages.
4042-- The data type correspond closely to the definition of
@@ -67,7 +69,7 @@ data Derivation = MkDerivation
6769 , editedCabalFile :: String
6870 , metaSection :: Meta
6971 }
70− deriving (Show, Eq, Ord)
72+ deriving (Show, Eq, Ord, Generic)
7173
7274instance Text Derivation where
7375 disp = renderDerivation
@@ -76,17 +78,10 @@ instance Text Derivation where
7678instance Package Derivation where
7779 packageId deriv = PackageIdentifier (PackageName (pname deriv)) (version deriv)
7880
79−instance NFData Derivation where
80− rnf (MkDerivation a b c d e f g h i j k l m n o p q r t u v w x) =
81− a `deepseq` b `deepseq` c `deepseq` d `deepseq` e `deepseq` f `deepseq` g `deepseq`
82− h `deepseq` i `deepseq` j `deepseq` k `deepseq` l `deepseq` m `deepseq` n `deepseqFlagAssignment`
83− o `deepseq` p `deepseq` q `deepseq` r `deepseq` t `deepseq` u `deepseq` v `deepseq`
84− w `deepseq` x `deepseq` ()
81+instance NFData Derivation where rnf = genericRnf
8582
86−-- FlagName has no NFData instance in old version of Cabal.
87−deepseqFlagAssignment :: FlagAssignment -> a -> a
88−deepseqFlagAssignment [] b = b
89−deepseqFlagAssignment ((FlagName n, v):as) b = n `deepseq` v `deepseq` as `deepseqFlagAssignment` b
83+deriving instance Generic FlagName
84+instance NFData FlagName where rnf = genericRnf
9085
9186renderDerivation :: Derivation -> Doc
9287renderDerivation deriv =
src/Distribution/NixOS/Derivation/License.hs+5−5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE DeriveGeneric #-}
12{- |
23 Module : Distribution.NixOS.Derivation.License
34 License : BSD3
@@ -13,10 +14,11 @@
1314
1415module Distribution.NixOS.Derivation.License ( License(..) ) where
1516
16−import Control.DeepSeq
17+import Control.DeepSeq.Generics
1718import Data.Maybe
1819import Distribution.NixOS.PrettyPrinting
1920import Distribution.Text
21+import GHC.Generics ( Generic )
2022
2123-- | The representation for licenses used in Nix derivations. Known
2224-- licenses are Nix expressions -- such as @stdenv.lib.licenses.bsd3@
@@ -44,13 +46,11 @@ import Distribution.Text
4446
4547data License = Known String
4648 | Unknown (Maybe String)
47− deriving (Show, Eq, Ord)
49+ deriving (Show, Eq, Ord, Generic)
4850
4951instance Text License where
5052 disp (Known x) = text x
5153 disp (Unknown x) = string (fromMaybe "unknown" x)
5254 parse = error "parsing Distribution.NixOS.Derivation.License is not supported yet"
5355
54−instance NFData License where
55− rnf (Known s) = rnf s
56− rnf (Unknown s) = rnf s
56+instance NFData License where rnf = genericRnf
src/Distribution/NixOS/Derivation/Meta.hs+5−4
@@ -1,3 +1,4 @@
1+{-# LANGUAGE DeriveGeneric #-}
12{- |
23 Module : Distribution.NixOS.Derivation.Meta
34 License : BSD3
@@ -17,10 +18,11 @@ module Distribution.NixOS.Derivation.Meta
1718 )
1819 where
1920
20−import Control.DeepSeq
21+import Control.DeepSeq.Generics
2122import Distribution.NixOS.Derivation.License
2223import Distribution.NixOS.PrettyPrinting
2324import Distribution.Text
25+import GHC.Generics ( Generic )
2426
2527-- | A representation of the @meta@ section used in Nix expressions.
2628--
@@ -51,14 +53,13 @@ data Meta = Meta
5153 , maintainers :: [String] -- ^ list of maintainers from @pkgs\/lib\/maintainers.nix@
5254 , broken :: Bool -- ^ set to @true@ if the build is known to fail
5355 }
54− deriving (Show, Eq, Ord)
56+ deriving (Show, Eq, Ord, Generic)
5557
5658instance Text Meta where
5759 disp = renderMeta
5860 parse = error "parsing Distribution.NixOS.Derivation.Cabal.Meta is not supported yet"
5961
60−instance NFData Meta where
61− rnf (Meta a b c d e f g) = a `deepseq` b `deepseq` c `deepseq` d `deepseq` e `deepseq` f `deepseq` g `deepseq` ()
62+instance NFData Meta where rnf = genericRnf
6263
6364renderMeta :: Meta -> Doc
6465renderMeta meta = vcat
src/Distribution/NixOS/Fetch.hs+9−5
@@ -1,6 +1,7 @@
11{-# LANGUAGE OverloadedStrings #-}
22{-# LANGUAGE RecordWildCards #-}
33{-# LANGUAGE ScopedTypeVariables #-}
4+{-# LANGUAGE DeriveGeneric #-}
45module Distribution.NixOS.Fetch
56 ( Source(..)
67 , DerivationSource(..), fromDerivationSource
@@ -9,11 +10,12 @@ module Distribution.NixOS.Fetch
910 ) where
1011
1112import Control.Applicative
12−import Control.DeepSeq
13+import Control.DeepSeq.Generics
1314import Control.Monad
1415import Control.Monad.IO.Class
1516import Control.Monad.Trans.Maybe
1617import Data.Maybe
18+import GHC.Generics ( Generic )
1719import System.Directory
1820import System.Environment
1921import System.Exit
@@ -26,7 +28,9 @@ data Source = Source
2628 , sourceRevision :: String -- ^ Revision to use. For protocols where this doesn't make sense (such as HTTP), this
2729 -- should be the empty string.
2830 , sourceHash :: Maybe String -- ^ The expected hash of the source, if available.
29− } deriving (Show, Eq, Ord)
31+ } deriving (Show, Eq, Ord, Generic)
32+
33+instance NFData Source where rnf = genericRnf
3034
3135-- | A source for a derivation. It always needs a hash and also has a protocol attached to it (url, git, svn, ...).
3236-- A @DerivationSource@ also always has it's revision fully resolved (not relative revisions like @master@, @HEAD@, etc).
@@ -35,10 +39,10 @@ data DerivationSource = DerivationSource
3539 , derivUrl :: String -- ^ URL to fetch from.
3640 , derivRevision :: String -- ^ Revision to use. Leave empty if the fetcher doesn't support revisions.
3741 , derivHash :: String -- ^ The hash of the source.
38− } deriving (Show, Eq, Ord)
42+ }
43+ deriving (Show, Eq, Ord, Generic)
3944
40−instance NFData DerivationSource where
41− rnf (DerivationSource a b c d) = a `deepseq` b `deepseq` c `deepseq` d `deepseq` ()
45+instance NFData DerivationSource where rnf = genericRnf
4246
4347fromDerivationSource :: DerivationSource -> Source
4448fromDerivationSource DerivationSource{..} = Source derivUrl derivRevision $ Just derivHash
test/spec.hsnew file+27
@@ -0,0 +1,27 @@
1+module Main ( main ) where
2+
3+import Test.QuickCheck
4+import Test.Hspec
5+import Test.Hspec.QuickCheck
6+import Control.DeepSeq
7+import Control.Exception
8+import Distribution.NixOS.Derivation.License
9+import Distribution.NixOS.Derivation.Meta
10+
11+main :: IO ()
12+main = do
13+ hspec $ do
14+ describe "DeepSeq instances work properly for" $ do
15+ it "License" $ mapM_ hitsBottom [Known undefined, Unknown (Just undefined)]
16+ it "Meta" $ do let meta = Meta "" "" (Unknown Nothing) [] [] [] False
17+ mapM_ hitsBottom
18+ [ meta { homepage = undefined }
19+ , meta { description = undefined }
20+ , meta { license = undefined }
21+ , meta { platforms = undefined }
22+ , meta { maintainers = undefined }
23+ , meta { broken = undefined }
24+ ]
25+
26+hitsBottom :: NFData a => a -> Expectation
27+hitsBottom x = evaluate (rnf x) `shouldThrow` anyErrorCall