packages feed

cabal2nix 1.73 → 2.0

raw patch · 41 files changed

+2468/−2102 lines, 41 filesdep +SHAdep +aesondep +ansi-wl-pprintdep −doctestdep −regex-posixdep ~Cabaldep ~basedep ~deepseqsetup-changednew-component:exe:hackage2nix

Dependencies added: SHA, aeson, ansi-wl-pprint, bytestring, cabal2nix, distribution-nixpkgs, language-nix, lens, monad-par, monad-par-extras, optparse-applicative, split, stackage-types, text, time, utf8-string, yaml

Dependencies removed: doctest, regex-posix

Dependency ranges changed: Cabal, base, deepseq, hackage-db, pretty

Files

− README.md
@@ -1,182 +0,0 @@-How to maintain Haskell Packages in Nix-=======================================--## Overview over the tool-chain--There are two utilities, `cabal2nix` and `hackage4nix`, that automate-maintenance to a large extent. We intend to merge them into one program,-eventually, but the necessary re-factoring hasn't been done yet since-this is not a high priority.--### Cabal2nix--`cabal2nix` converts a single Cabal file into a single Nix build-expression. For example:--    $ cabal2nix cabal://yesod-0.9.1-    { cabal, attoparsecText, blazeBuilder, blazeHtml, hamlet, httpTypes-    , monadControl, parsec, shakespeareCss, shakespeareJs, text, time-    , transformers, unixCompat, wai, waiExtra, warp, yesodAuth-    , yesodCore, yesodForm, yesodJson, yesodPersistent-    }:--    cabal.mkDerivation (self: {-      pname = "yesod";-      version = "0.9.1";-      sha256 = "1ag3lca75lrriycbscspb5yyishacgxjx0rybc3x4z1dqnkn1r71";-      isLibrary = true;-      isExecutable = true;-      buildDepends = [-        attoparsecText blazeBuilder blazeHtml hamlet httpTypes monadControl-        parsec shakespeareCss shakespeareJs text time transformers-        unixCompat wai waiExtra warp yesodAuth yesodCore yesodForm-        yesodJson yesodPersistent-      ];-      meta = {-        homepage = "http://www.yesodweb.com/";-        description = "Creation of type-safe, RESTful web applications";-        license = self.stdenv.lib.licenses.bsd3;-        platforms = self.ghc.meta.platforms;-      };-    })--Cabal files can be referred to using the magic URL-`cabal://NAME-VERSION`, which will automatically download the file from-Hackage. Alternatively, a direct `http://host/path/pkg.cabal` URL can be-provided, as well as a `file:///local/path/pkg.cabal` URI that doesn't-depend on network access. However, if the source hash is not already in `cabal2nix`'s cache or-provided using the `--sha256` option, `cabal2nix` still needs to download the source code to-compute the hash, which obviously still causes network traffic.-Run the utility with `--help` to see the complete list of supported command line flags.--To add a new package to Nix, checkout the Nixpkgs project from-https://github.com/nixos/nixpkgs.git and run--    $ cd pkgs/development/libraries/haskell-    $ mkdir foo-    $ cabal2nix cabal://foo-1.0 >foo/default.nix--Then add an appropriate attribute to-`pkgs/top-level/haskell-packages.nix`, for example:--    foo = callPackage ../development/libraries/haskell/foo {};--`cabal2nix` can also build derivations for projects from other-sources than hackage. You only need to provide an URI that points-to a cabal project. The most common usecase for this is probably to-generate a derivation for a project on the local file system:--    aeson:$ cabal2nix ./.-    # This file was auto-generated by cabal2nix. Please do NOT edit manually!--    { cabal, attoparsec, blazeBuilder, deepseq, dlist, hashable, HUnit-    , mtl, QuickCheck, scientific, syb, testFramework-    , testFrameworkHunit, testFrameworkQuickcheck2, text, time-    , unorderedContainers, vector-    }--    cabal.mkDerivation (self: {-      pname = "aeson";-      version = "0.7.0.2";-      src = ./.;-      buildDepends = [-        attoparsec blazeBuilder deepseq dlist hashable mtl scientific syb-        text time unorderedContainers vector-      ];-      testDepends = [-        attoparsec HUnit QuickCheck testFramework testFrameworkHunit-        testFrameworkQuickcheck2 text time unorderedContainers vector-      ];-      meta = {-        homepage = "https://github.com/bos/aeson";-        description = "Fast JSON parsing and encoding";-        license = self.stdenv.lib.licenses.bsd3;-        platforms = self.ghc.meta.platforms;-      };-    })--This derivation will not fetch from hackage, but instead use the directory which-contains the derivation as the source repository.--`cabal2nix` currently supports the following respository types:--* directory-* source archive (zip, tar.gz, ...) from http or https URL or local file.-* git, mercurial, svn or bazaar repository--### Hackage4nix--The `hackage4nix` utility re-generates *all* expressions found in the-`nixpkgs` database in place. This is useful to ensure that all packages-have been generated with a recent version of the tool-chain.-Furthermore, `hackage4nix` adds default settings for the-`meta.maintainers` and `meta.platforms` attribute if these aren't-configured yet. Generally speaking, running--    $ hackage4nix pkgs--in your checked-out copy of the Nixpkgs tree should be a *no-op* ----i.e. no files should change! If there are changes, these indicate that a-file has been modified manually, and then these changes must be-investigated to find out what is going on.--Last but not least, `hackage4nix` generates a list of all updates-available from Hackage. (Run `cabal update` to make sure that your local-copy of the Hackage database is up-to-date!) For example:--    $ hackage4nix pkgs-    The following updates are available:--    WebBits-Html-1.0.1:-      cabal2nix cabal://WebBits-Html-1.0.2 >pkgs/pkgs/development/libraries/haskell/WebBits-Html/default.nix--    happstack-server-6.1.6:-      cabal2nix cabal://happstack-server-6.2.1 >pkgs/pkgs/development/libraries/haskell/happstack/happstack-server.nix-      cabal2nix cabal://happstack-server-6.2.2 >pkgs/pkgs/development/libraries/haskell/happstack/happstack-server.nix--    primitive-0.3.1:-      cabal2nix cabal://primitive-0.4 >pkgs/pkgs/development/libraries/haskell/primitive/default.nix--    repa-2.1.1.5:-      cabal2nix cabal://repa-2.1.1.6 >pkgs/pkgs/development/libraries/haskell/repa/default.nix--    unix-compat-0.2.2.1:-      cabal2nix cabal://unix-compat-0.3 >pkgs/pkgs/development/libraries/haskell/unix-compat/default.nix--    vector-0.7.1:-      cabal2nix cabal://vector-0.8 >pkgs/pkgs/development/libraries/haskell/vector/default.nix--These updates can be performed automatically by running the `cabal2nix`-command given by `hackage4nix`. If there is more than one possible-update, then all of them will be shown. Note, however, that some updates-break compilation of other packages, because they depend on very-specific versions of their build inputs, so please be careful when-performing updates!--## Current State of Affairs--The tool-chain is stable. As of today, 2013-04-12, virtually all Haskell-packages available in Nix have been generated automatically from their-Cabal files. There are only a handful of exceptions, which we cannot-generate because these packages aren't available on Hackage. The list of-those packages is hard-coded into the-[`hackage4nix.hs`](https://github.com/NixOS/cabal2nix/blob/master/src/hackage4nix.hs)-binary in the function `badPackagePaths`.--Furthermore, Hackage4Nix will not re-generate packages that have been-patched, i.e. that define any of the following attributes:--        (pre|post)Configure-        (pre|post)Install-        patchPhase-        patches--These packages are considered for updates, however.--The complete list of Haskell packages available in Nix is generated by-the tool [`package-list`](http://github.com/peti/package-list),-and published at <http://cryp.to/haskell-in-nixpkgs.txt>. Hackage picks-it up from there and generates links on each package's homepage to the-corresponding page in Hydra automatically. See [ticket-875](http://www.haskell.org/pipermail/cabal-devel/2011-August/007714.html) for further-details.
− Setup.hs
@@ -1,15 +0,0 @@-module Main ( main ) where--import Distribution.Simple-import Distribution.Simple.LocalBuildInfo ( withPrograms )-import Distribution.Simple.Program ( userSpecifyArgs )--main :: IO ()-main = defaultMainWithHooks $-         simpleUserHooks `modify_haddockHook` \oldHH pkg lbi hooks flags ->-           (\lbi' -> oldHH pkg lbi' hooks flags) $-             lbi `modify_withPrograms` \oldWP ->-               userSpecifyArgs "haddock" ["--optghc=-D__HADDOCK__"] oldWP-  where-    modify_haddockHook  hooks f = hooks { haddockHook  = f (haddockHook  hooks) }-    modify_withPrograms lbi   f = lbi   { withPrograms = f (withPrograms lbi)   }
+ Setup.lhs view
@@ -0,0 +1,40 @@+#! /usr/bin/env runhaskell++> module Main ( main ) where+>+> import Data.Char+> import Data.Maybe+> import Distribution.PackageDescription+> import Distribution.Simple+> import Distribution.Simple.LocalBuildInfo+> import Distribution.Simple.Program+> import Distribution.Simple.Setup+>+> main :: IO ()+> main = defaultMainWithHooks simpleUserHooks+>        { hookedPrograms = map simpleProgram programs+>        , confHook = configure+>        }+>+> programs :: [String]+> programs = ["nix-instantiate", "nix-build", "nix-env", "nix-store"]+>+> configure :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo+> configure (gpd, hbi) flags = do+>   lbi' <- confHook simpleUserHooks (gpd, hbi) flags+>   let paths = map (\p -> (p, maybe p programPath (lookupProgram (simpleProgram p) (withPrograms lbi)))) programs+>       descr = localPkgDescr lbi'+>       lib = fromJust (library descr)+>       libbi = libBuildInfo lib+>       lbi = lbi' { localPkgDescr = descr+>                    { library = Just (lib { libBuildInfo = libbi { cppOptions = cppOptions libbi ++ map fmtCppArg paths } })+>                    }+>                  }+>   return lbi+>+> fmtCppArg :: (String, FilePath) -> String+> fmtCppArg (prg, path) = "-DPATH_TO_" ++ map mangle prg ++ "=" ++ show path+>   where+>     mangle :: Char -> Char+>     mangle '-' = '_'+>     mangle c = toUpper c
cabal2nix.cabal view
@@ -1,107 +1,182 @@-Name:                   cabal2nix-Version:                1.73-Copyright:              Peter Simons, Andres Loeh-License:                BSD3-License-File:           LICENSE-Author:                 Peter Simons <simons@cryp.to>, Andres Loeh <mail@andres-loeh.de>-Maintainer:             Nix Developers <nix-dev@lists.science.uu.nl>-Homepage:               http://github.com/NixOS/cabal2nix-Category:               Distribution-Synopsis:               Convert Cabal files into Nix build instructions-Cabal-Version:          >= 1.8-Build-Type:             Custom-Tested-With:            GHC >= 7.0.4 && <= 7.8.3-Data-files:             README.md-Description:-  The @cabal2nix@ utility converts Cabal files into Nix build instructions. The-  commandline syntax is:-  .-  > Usage: cabal2nix [options] url-to-cabal-file-or-repo-  >   -h             --help                   show this help text-  >   -v             --version                print version-  >                  --hackage-db=FILEPATH    path to the local hackage db in tar format-  >                  --sha256=HASH            sha256 hash of source tarball-  >   -m MAINTAINER  --maintainer=MAINTAINER  maintainer of this package (may be specified multiple times)-  >   -p PLATFORM    --platform=PLATFORM      supported build platforms (may be specified multiple times)-  >                  --jailbreak              don't honor version restrictions on build inputs-  >                  --no-haddock             don't run Haddock when building this package-  >                  --no-check               don't run regression test suites of this package-  >                  --no-hyperlink-source    don't add pretty-printed source code to the documentation-  >-  > Recognized URI schemes:-  >-  >   cabal://pkgname-pkgversion       download the specified package from Hackage-  >   cabal://pkgname                  download latest version of the specified package from Hackage-  >   http://host/path                 fetch the Cabal file via HTTP-  >   file:///local/path               load the Cabal file from the local disk-  >   /local/path.cabal                abbreviated version of file URI-  >   <git/svn/bzr/hg URL>             download the source from the specified repository-  .-  The only required argument is the path to the cabal file. For example:-  .-  > cabal2nix http://hackage.haskell.org/packages/archive/cabal2nix/1.73/cabal2nix.cabal-  > cabal2nix cabal://cabal2nix-1.73-  .-  If the @--sha256@ option has not been specified, cabal2nix calls-  @nix-prefetch-url@ to determine the hash automatically. This causes-  network traffic, obviously.-  .-  If the argument refers to a source repository instead of a cabal file,-  cabal2nix will use that source repository to fetch from instead of hackage.-  Currently, cabal2nix supports directories, archives (fetched via http or https) and-  git, mercurial, svn or bazaar repositories.+-- This file has been generated from package.yaml by hpack version 0.14.1.+--+-- see: https://github.com/sol/hpack -Source-Repository head-  Type:                 git-  Location:             git://github.com/NixOS/cabal2nix.git+name:           cabal2nix+version:        2.0+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:+                > nix-env -i cabal2nix+category:       Distribution, Nix+homepage:       https://github.com/nixos/cabal2nix#readme+bug-reports:    https://github.com/nixos/cabal2nix/issues+author:         Peter Simons,+                Andres Loeh,+                Benno Fünfstück,+                Mateusz Kowalczyk,+                Mathijs Kwik,+                Michael Alan Dorman,+                Shea Levy,+                Dmitry Malikov,+                Eric Seidel,+                Nikolay Amiantov,+                Aycan iRiCAN,+                John Wiegley,+                Philipp Hausmann,+                Spencer Janssen,+                William Casarin,+                Adam Vogt,+                Bryan Gardiner,+                Corey O'Connor,+                Cray Elliott,+                Felix Kunzmann,+                Gabriel Ebner,+                Gergely Risko,+                John Albietz,+                John Chee,+                Jussi Maki,+                Mark Laws,+                Mark Wotton,+                Matvey Aksenov,+                Nicolas Rolland,+                Oliver Charles,+                Pascal Wittmann,+                Patrick John Wheeler,+                Raymond Gauthier,+                Renzo Carbonara,+                Sibi,+                Tanner Doshier,+                Tom Hunger,+                Viktar Basharymau,+                danbst,+                karsten gebbert,+                laMudri,+                Александр Цамутали+maintainer:     Peter Simons <simons@cryp.to>+license:        BSD3+license-file:   LICENSE+tested-with:    GHC > 7.10 && < 8.1+build-type:     Simple+cabal-version:  >= 1.10 -Executable cabal2nix-  main-is:              cabal2nix.hs-  hs-source-dirs:       src-  Build-Depends:        base >= 3 && < 5, regex-posix, pretty, Cabal >= 1.18,-                        filepath, directory, process, hackage-db >= 1.11, transformers, deepseq-  Extensions:           PatternGuards, RecordWildCards, CPP-  Ghc-Options:          -Wall-  other-modules:        Cabal2Nix.CorePackages-                        Cabal2Nix.Flags-                        Cabal2Nix.Generate-                        Cabal2Nix.Package-                        Cabal2Nix.License-                        Cabal2Nix.Name-                        Cabal2Nix.Normalize-                        Cabal2Nix.PostProcess-                        Cabal2Nix.Version-                        Distribution.NixOS.Fetch-                        Distribution.NixOS.Derivation.Cabal-                        Distribution.NixOS.Derivation.License-                        Distribution.NixOS.Derivation.Meta-                        Distribution.NixOS.PrettyPrinting-                        Distribution.NixOS.Regex+source-repository head+  type: git+  location: https://github.com/nixos/cabal2nix -Executable hackage4nix-  main-is:              hackage4nix.hs-  hs-source-dirs:       src-  Build-Depends:        base >= 3 && < 5, regex-posix, pretty, Cabal >= 1.18,-                        mtl, containers, directory, filepath, hackage-db >= 1.11,-                        transformers, process, deepseq-  Extensions:           PatternGuards, RecordWildCards, CPP-  Ghc-Options:          -Wall-  other-modules:        Cabal2Nix.CorePackages-                        Cabal2Nix.Flags-                        Cabal2Nix.Generate-                        Cabal2Nix.License-                        Cabal2Nix.Name-                        Cabal2Nix.Normalize-                        Cabal2Nix.PostProcess-                        Distribution.NixOS.Fetch-                        Distribution.NixOS.Derivation.Cabal-                        Distribution.NixOS.Derivation.License-                        Distribution.NixOS.Derivation.Meta-                        Distribution.NixOS.PrettyPrinting-                        Distribution.NixOS.Regex+library+  hs-source-dirs:+      src+  ghc-options: -Wall+  build-depends:+      aeson+    , ansi-wl-pprint+    , base < 5+    , bytestring+    , Cabal > 1.24+    , containers+    , deepseq >= 1.4+    , directory+    , distribution-nixpkgs+    , filepath+    , hackage-db+    , language-nix+    , lens+    , optparse-applicative+    , pretty >= 1.1.2+    , process+    , SHA+    , split+    , text+    , transformers+    , yaml+  exposed-modules:+      Distribution.Nixpkgs.Fetch+      Distribution.Nixpkgs.Haskell+      Distribution.Nixpkgs.Haskell.BuildInfo+      Distribution.Nixpkgs.Haskell.Constraint+      Distribution.Nixpkgs.Haskell.Derivation+      Distribution.Nixpkgs.Haskell.FromCabal+      Distribution.Nixpkgs.Haskell.FromCabal.Configuration+      Distribution.Nixpkgs.Haskell.FromCabal.Flags+      Distribution.Nixpkgs.Haskell.FromCabal.License+      Distribution.Nixpkgs.Haskell.FromCabal.Name+      Distribution.Nixpkgs.Haskell.FromCabal.Normalize+      Distribution.Nixpkgs.Haskell.FromCabal.PostProcess+      Distribution.Nixpkgs.Haskell.Hackage+      Distribution.Nixpkgs.Haskell.OrphanInstances+      Distribution.Nixpkgs.Haskell.PackageSourceSpec+  other-modules:+      Paths_cabal2nix+  default-language: Haskell2010 -Test-Suite doctest-cabal2nix-  type:                 exitcode-stdio-1.0-  main-is:              doc-test.hs-  hs-source-dirs:       test-  build-depends:        base, doctest+executable cabal2nix+  main-is: Main.hs+  hs-source-dirs:+      cabal2nix+  ghc-options: -Wall+  build-depends:+      aeson+    , ansi-wl-pprint+    , base < 5+    , bytestring+    , Cabal > 1.24+    , containers+    , deepseq >= 1.4+    , directory+    , distribution-nixpkgs+    , filepath+    , hackage-db+    , language-nix+    , lens+    , optparse-applicative+    , pretty >= 1.1.2+    , process+    , SHA+    , split+    , text+    , transformers+    , yaml+    , cabal2nix+  other-modules:+      Paths_cabal2nix+  default-language: Haskell2010++executable hackage2nix+  main-is: Main.hs+  hs-source-dirs:+      hackage2nix+  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      aeson+    , ansi-wl-pprint+    , base < 5+    , bytestring+    , Cabal > 1.24+    , containers+    , deepseq >= 1.4+    , directory+    , distribution-nixpkgs+    , filepath+    , hackage-db+    , language-nix+    , lens+    , optparse-applicative+    , pretty >= 1.1.2+    , process+    , SHA+    , split+    , text+    , transformers+    , yaml+    , cabal2nix+    , monad-par+    , monad-par-extras+    , mtl+    , stackage-types+    , time+    , utf8-string+  other-modules:+      Paths_cabal2nix+      HackageGit+      Stackage+  default-language: Haskell2010
+ cabal2nix/Main.hs view
@@ -0,0 +1,161 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-}++module Main ( main ) where++import Control.Exception ( bracket )+import Control.Lens+import Data.Maybe ( fromMaybe )+import qualified Data.Set as Set+import qualified Distribution.Compat.ReadP as P+import Distribution.Compiler+import Distribution.Nixpkgs.Fetch+import Distribution.Nixpkgs.Haskell+import Distribution.Nixpkgs.Haskell.FromCabal+import Distribution.Nixpkgs.Haskell.PackageSourceSpec+import Distribution.Nixpkgs.Meta+import Distribution.PackageDescription ( FlagName(..), FlagAssignment )+import Distribution.Simple.Utils ( lowercase )+import Distribution.System+import Distribution.Text+import Language.Nix+import Options.Applicative+import Paths_cabal2nix ( version )+import System.IO ( hFlush, stdout, stderr )+import qualified Text.PrettyPrint.ANSI.Leijen as P2 hiding ( (<$>), (<>) )+import Text.PrettyPrint.HughesPJClass ( Doc, Pretty(..), text, vcat, hcat, semi )++data Options = Options+  { optSha256 :: Maybe String+  , optMaintainer :: [String]+--, optPlatform :: [String]                                         -- TODO: fix command line handling of platforms+  , optHaddock :: Bool+  , optDoCheck :: Bool+  , optJailbreak :: Bool+  , optRevision :: Maybe String+  , optHyperlinkSource :: Bool+  , optEnableLibraryProfiling :: Bool+  , optEnableExecutableProfiling :: Bool+  , optEnableProfiling :: Maybe Bool+  , optExtraArgs :: [String]+  , optHackageDb :: Maybe FilePath+  , optNixShellOutput :: Bool+  , optFlags :: [String]+  , optCompiler :: CompilerId+  , optSystem :: Platform+  , optUrl :: String+  }+  deriving (Show)++options :: Parser Options+options = Options+          <$> optional (strOption $ long "sha256" <> metavar "HASH" <> help "sha256 hash of source tarball")+          <*> 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")+          <*> 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")+          <*> flag True False (long "no-hyperlink-source" <> help "don't generate pretty-printed source code for the documentation")+          <*> switch (long "enable-library-profiling" <> help "enable library profiling in the generated build")+          <*> switch (long "enable-executable-profiling" <> help "enable executable profiling in the generated build")+          <*> optional (switch (long "enable-profiling" <> help "enable both library and executable profiling in the generated build"))+          <*> many (strOption $ long "extra-arguments" <> help "extra parameters required for the function body")+          <*> optional (strOption $ long "hackage-db" <> metavar "PATH" <> help "path to the local hackage db in tar format")+          <*> switch (long "shell" <> help "generate output suitable for nix-shell")+          <*> many (strOption $ short 'f' <> long "flag" <> help "Cabal flag (may be specified multiple times)")+          <*> 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)+          <*> strArgument (metavar "URI")++readP :: P.ReadP a a -> ReadM a+readP p = eitherReader $ \s -> case [ r' | (r',"") <- P.readP_to_S p s ] of+                                    (r:_) -> Right r+                                    _     -> Left ("invalid value " ++ show s)++parsePlatform :: P.ReadP r Platform+parsePlatform = do arch <- P.choice [P.string "i686" >> return I386, P.string "x86_64" >> return X86_64]+                   _ <- P.char '-'+                   os <- P.choice [P.string "linux" >> return Linux, P.string "darwin" >> return OSX]+                   return (Platform arch os)++pinfo :: ParserInfo Options+pinfo = info+        (   helper+        <*> infoOption ("cabal2nix " ++ display version) (long "version" <> help "Show version number")+        <*> options+        )+        (  fullDesc+        <> header "cabal2nix converts Cabal files into build instructions for Nix."+        <> progDescDoc (Just (P2.vcat+                     [ P2.text ""+                     , P2.text "Recognized URI schemes:"+                     , P2.text ""+                     , P2.text "  cabal://pkgname-pkgversion     download the specified package from Hackage"+                     , P2.text "  cabal://pkgname                download latest version of this package from Hackage"+                     , P2.text "  file:///local/path             load the Cabal file from the local disk"+                     , P2.text "  /local/path                    abbreviated version of file URI"+                     , P2.text "  <git/svn/bzr/hg URL>           download the source from the specified repository"+                     , P2.text ""+                     , P2.fillSep (map P2.text (words (  "If the URI refers to a cabal file, information for building the package "+                                                      ++ "will be retrieved from that file, but hackage will be used as a source "+                                                      ++ "for the derivation. Otherwise, the supplied URI will be used to as the "+                                                      ++ "souce for the derivation and the information is taken from the cabal file "+                                                      ++ "at the root of the downloaded source."+                                                      )))+                     ]))+        )++main :: IO ()+main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do+  Options {..} <- execParser pinfo++  pkg <- getPackage optHackageDb $ Source optUrl (fromMaybe "" optRevision) (maybe UnknownHash Guess optSha256)++  let+      deriv :: Derivation+      deriv = fromGenericPackageDescription (const True)+                                            (\i -> Just (binding # (i, path # [i])))+                                            optSystem+                                            (unknownCompilerInfo optCompiler NoAbiTag)+                                            (readFlagList optFlags)+                                            []+                                            (pkgCabal pkg)+              & src .~ pkgSource pkg+              & runHaddock .~ optHaddock+              & jailbreak .~ optJailbreak+              & hyperlinkSource .~ optHyperlinkSource+              & enableLibraryProfiling .~ (fromMaybe False optEnableProfiling || optEnableLibraryProfiling)+              & enableExecutableProfiling .~ (fromMaybe False optEnableProfiling || optEnableExecutableProfiling)+              & metaSection.maintainers .~ Set.fromList (map (review ident) optMaintainer)+--            & metaSection.platforms .~ Set.fromList optPlatform+              & doCheck &&~ optDoCheck+              & extraFunctionArgs %~ Set.union (Set.fromList ("stdenv":map (review ident) optExtraArgs))++      shell :: Doc+      shell = vcat+              [ text "{ nixpkgs ? import <nixpkgs> {}, compiler ? \"default\" }:"+              , text ""+              , text "let"+              , text ""+              , text "  inherit (nixpkgs) pkgs;"+              , text ""+              , hcat [ text "  f = ", pPrint deriv, semi ]+              , text ""+              , text "  haskellPackages = if compiler == \"default\""+              , text "                       then pkgs.haskellPackages"+              , text "                       else pkgs.haskell.packages.${compiler};"+              , text ""+              , text "  drv = haskellPackages.callPackage f {};"+              , text ""+              , text "in"+              , text ""+              , text "  if pkgs.lib.inNixShell then drv.env else drv"+              ]++  print (if optNixShellOutput then shell else pPrint deriv)++readFlagList :: [String] -> FlagAssignment+readFlagList = map tagWithValue+  where tagWithValue ('-':fname) = (FlagName (lowercase fname), False)+        tagWithValue fname       = (FlagName (lowercase fname), True)
+ hackage2nix/HackageGit.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}++module HackageGit where++import Control.Monad+import Control.Lens hiding ( (<.>) )+import Data.Aeson+import Data.ByteString.Char8 ( ByteString )+import qualified Data.ByteString.Char8 as BS+import Data.ByteString.Lazy.Char8 ( fromStrict )+import Data.Digest.Pure.SHA ( sha256, showDigest )+import Data.Map as Map+import Data.Set as Set+import Data.String+import Data.String.UTF8 ( toString, fromRep )+import Distribution.Nixpkgs.Haskell.OrphanInstances ( )+import Distribution.Package+import Distribution.PackageDescription+import Distribution.PackageDescription.Parse ( parsePackageDescription, ParseResult(..) )+import Distribution.Text+import Distribution.Version+import System.Directory+import System.FilePath++type Hackage = Map PackageName (Set Version)++readHackage :: FilePath -> IO Hackage+readHackage path = getSubDirs path >>= foldM discoverPackageVersions mempty+  where+    discoverPackageVersions :: Hackage -> String -> IO Hackage+    discoverPackageVersions db pkg = do+      vs <- getSubDirs (path </> pkg)+      return (Map.insert (PackageName pkg) (Set.fromList (Prelude.map fromString vs)) db)++getSubDirs :: FilePath -> IO [FilePath]+getSubDirs path = do+  let isDirectory p = doesDirectoryExist (path </> p)+  getDirectoryContents path >>= filterM isDirectory . Prelude.filter (\x -> head x /= '.')++decodeUTF8 :: ByteString -> String+decodeUTF8 = toString . fromRep++type SHA256Hash = String++readPackage :: FilePath -> PackageIdentifier -> IO (GenericPackageDescription, SHA256Hash)+readPackage dirPrefix (PackageIdentifier name version) = do+  let cabalFile = dirPrefix </> unPackageName name </> display version </> unPackageName name <.> "cabal"+  buf <- BS.readFile cabalFile+  cabal <- case parsePackageDescription (decodeUTF8 buf) of+             ParseOk _ a  -> return a+             ParseFailed err -> fail (cabalFile ++ ": " ++ show err)+  return (cabal, mkSHA256 buf)++mkSHA256 :: ByteString -> SHA256Hash+mkSHA256 = showDigest . sha256 . fromStrict++declareLenses [d|+  data Meta = Meta { hashes :: Map String String+                   , locations :: [String]+                   , pkgsize :: Int+                   }+    deriving (Show)+  |]++instance FromJSON Meta where+  parseJSON (Object v) = Meta+                         <$> v .: "package-hashes"+                         <*> v .: "package-locations"+                         <*> v .: "package-size"+  parseJSON o          = fail ("invalid Cabal metadata: " ++ show o)++readPackageMeta :: FilePath -> PackageIdentifier -> IO Meta+readPackageMeta dirPrefix (PackageIdentifier name version) = do+  let metaFile = dirPrefix </> unPackageName name </> display version </> unPackageName name <.> "json"+  buf <- BS.readFile metaFile+  case eitherDecodeStrict buf of+    Left msg -> fail (metaFile ++ ": " ++ msg)+    Right x  -> return x
+ hackage2nix/Main.hs view
@@ -0,0 +1,259 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++module Main ( main ) where++import Control.Lens+import Control.Monad+import Control.Monad.Par.Combinator+import Control.Monad.Par.IO+import Control.Monad.Trans ( liftIO )+import Data.List+import Data.Map.Strict ( Map )+import qualified Data.Map.Strict as Map+import Data.Maybe+import Data.Monoid+import Data.Set ( Set )+import qualified Data.Set as Set+import Data.String+import Distribution.Nixpkgs.Fetch+import Distribution.Nixpkgs.Haskell as Derivation+import Distribution.Nixpkgs.Haskell.Constraint+import Distribution.Nixpkgs.Haskell.FromCabal+import Distribution.Nixpkgs.Haskell.FromCabal.Configuration as Config+import Distribution.Nixpkgs.Haskell.FromCabal.Flags+import Distribution.Nixpkgs.Meta+import Distribution.Nixpkgs.PackageMap+import Distribution.Package+import Distribution.PackageDescription hiding ( options, buildDepends, extraLibs, buildTools )+import Distribution.System+import Distribution.Text+import Distribution.Version+import HackageGit+import Language.Nix+import Options.Applicative+import qualified Paths_cabal2nix as Main+import Stackage+import System.FilePath+import System.IO+import Text.PrettyPrint.HughesPJClass hiding ( (<>) )++type PackageSet = Map PackageName Version+type PackageMultiSet = Map PackageName (Set Version)++data CLI = CLI+  { hackageRepository :: FilePath+  , preferredVersionsFile :: Maybe FilePath+  , nixpkgsRepository :: FilePath+  , ltsHaskellRepository :: FilePath+  , stackageNightlyRepository :: FilePath+  , configFile :: FilePath+  , targetPlatform :: Platform+  }+  deriving (Show)++main :: IO ()+main = do+  let cliOptions :: Parser CLI+      cliOptions = CLI+        <$> strOption (long "hackage" <> help "path to Hackage git repository" <> value "hackage" <> showDefaultWith id <> metavar "PATH")+        <*> optional (strOption (long "preferred-versions" <> help "path to Hackage preferred-versions file" <> value "hackage/preferred-versions" <> showDefault <> metavar "PATH"))+        <*> strOption (long "nixpkgs" <> help "path to Nixpkgs repository" <> value "nixpkgs" <> showDefaultWith id <> metavar "PATH")+        <*> strOption (long "lts-haskell" <> help "path to LTS Haskell repository" <> value "lts-haskell" <> showDefaultWith id <> metavar "PATH")+        <*> strOption (long "stackage-nightly" <> help "path to Stackage Nightly repository" <> value "stackage-nightly" <> showDefaultWith id <> metavar "PATH")+        <*> strOption (long "config" <> help "path to configuration file inside of Nixpkgs" <> value "pkgs/development/haskell-modules/configuration-hackage2nix.yaml" <> showDefaultWith id <> metavar "PATH")+        <*> option (fmap fromString str) (long "platform" <> help "target platform to generate package set for" <> value "x86_64-linux" <> showDefaultWith display <> metavar "PLATFORM")++      pinfo :: ParserInfo CLI+      pinfo = info+              (   helper+              <*> infoOption ("hackage2nix " ++ display Main.version) (long "version" <> help "Show version number")+              <*> cliOptions+              )+              (  fullDesc+              <> header "hackage2nix converts a Hackage database into a hackage-packages.nix file."+              )+  CLI {..} <- execParser pinfo++  config' <- readConfiguration (nixpkgsRepository </>  configFile)+  nixpkgs <- readNixpkgPackageMap nixpkgsRepository Nothing+  preferredVersions <- readPreferredVersions (fromMaybe (hackageRepository </> "preferred-versions") preferredVersionsFile)+  let fixup = Map.delete "acme-everything"      -- TODO: https://github.com/NixOS/cabal2nix/issues/164+            . Map.delete "som"                  -- TODO: https://github.com/NixOS/cabal2nix/issues/164+            . Map.delete "type"                 -- TODO: https://github.com/NixOS/cabal2nix/issues/163+  hackage <- fixup <$> readHackage hackageRepository+  snapshots <- runParIO (readLTSHaskell ltsHaskellRepository)+  nightly <- readStackageNightly stackageNightlyRepository+  let+      config :: Configuration+      config = config' { defaultPackageOverrides = [ Dependency n (thisVersion (Stackage.version spec)) | (n, spec) <- Map.toList (packages nightly) ] }++      hackagePackagesFile :: FilePath+      hackagePackagesFile = nixpkgsRepository </> "pkgs/development/haskell-modules/hackage-packages.nix"++      corePackageSet :: PackageSet+      corePackageSet = Map.fromList [ (name, v) | PackageIdentifier name v <- Set.toList (Config.corePackages config) ]++      latestVersionSet :: PackageSet+      latestVersionSet = Map.map Set.findMax (Map.filter (not . Set.null) (Map.mapWithKey (enforcePreferredVersions preferredVersions) hackage))++      defaultPackageOverridesSet :: PackageSet+      defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency name _) <- defaultPackageOverrides config ]++      generatedDefaultPackageSet :: PackageSet+      generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet++      latestCorePackageSet :: PackageSet+      latestCorePackageSet = latestVersionSet `Map.intersection` corePackageSet++      latestOverridePackageSet :: PackageSet+      latestOverridePackageSet = latestVersionSet `Map.intersection` defaultPackageOverridesSet++      extraPackageSet :: PackageMultiSet+      extraPackageSet = Map.unionsWith Set.union+                          [ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency name _) <- extraPackages config ]++      stackagePackageSet :: Map PackageName (Map Version Spec)+      stackagePackageSet = Map.fromListWith (Map.unionWith mergeSpecs) [ (n, Map.singleton (Stackage.version spec) spec) | snapshot <- nightly:snapshots, (n, spec) <- Map.toList (packages snapshot) ]++      db :: PackageMultiSet+      db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet+                                    , Map.map Set.singleton latestCorePackageSet+                                    , Map.map Set.singleton latestOverridePackageSet+                                    , extraPackageSet+                                    , Map.map Map.keysSet stackagePackageSet+                                    ]++      haskellResolver :: Dependency -> Bool+      haskellResolver (Dependency name vrange)+        | Just v <- Map.lookup name corePackageSet                = v `withinRange` vrange+        | Just v <- Map.lookup name generatedDefaultPackageSet    = v `withinRange` vrange+        | otherwise                                               = False++      nixpkgsResolver :: Identifier -> Maybe Binding+      nixpkgsResolver = resolve (Map.map (Set.map (over path ("pkgs":))) nixpkgs)++      globalPackageMaintainers :: Map PackageName (Set Identifier)+      globalPackageMaintainers = Map.unionsWith Set.union [ Map.singleton p (Set.singleton m) | (m,ps) <- Map.toList (packageMaintainers config), p <- Set.toList ps ]++  pkgs <- runParIO $ flip parMapM (Map.toAscList db) $ \(name, vs) -> do+    defs <- forM (Set.toAscList vs) $ \v -> liftIO $ do+      let pkgId :: PackageIdentifier+          pkgId = PackageIdentifier name v++      (descr, cabalSHA256) <- readPackage hackageRepository pkgId+      meta <- readPackageMeta hackageRepository pkgId++      let isInDefaultPackageSet :: Bool+          isInDefaultPackageSet = maybe False (== v) (Map.lookup name generatedDefaultPackageSet)++          tarballSHA256 :: SHA256Hash+          tarballSHA256 = fromMaybe (error (display pkgId ++ ": meta data has no hash for the tarball"))+                                    (view (hashes . at "SHA256") meta)++          spec :: Spec+          spec = Spec v True True `fromMaybe` (Map.lookup name stackagePackageSet >>= Map.lookup v)++          flagAssignment :: FlagAssignment                  -- We don't use the flags from Stackage Nightly here, because+          flagAssignment = configureCabalFlags pkgId        -- they are chosen specifically for GHC 7.10.2.++          attr :: String+          attr = if isInDefaultPackageSet then unPackageName name else mangle pkgId++          drv :: Derivation+          drv = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr+                  & src .~ DerivationSource "url" ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") "" tarballSHA256+                  & editedCabalFile .~ cabalSHA256+                  & Derivation.runHaddock &&~ Stackage.runHaddock spec+                  & doCheck &&~ runTests spec+                  & metaSection.hydraPlatforms %~ (`Set.difference` Map.findWithDefault Set.empty name (dontDistributePackages config))+                  & metaSection.maintainers .~ Map.findWithDefault Set.empty name globalPackageMaintainers+                  & metaSection.hydraPlatforms %~ (if isInDefaultPackageSet then id else const Set.empty)++          overrides :: Doc+          overrides = fcat $ punctuate space [ disp b <> semi | b <- Set.toList (view (dependencies . each) drv), not (isFromHackage b) ]+      return $ render $ nest 2 $+        hang (doubleQuotes (text  attr) <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi)++    return (intercalate "\n\n" defs)++  withFile hackagePackagesFile WriteMode $ \h -> do+    hPutStrLn h "/* hackage-packages.nix is an auto-generated file -- DO NOT EDIT! */"+    hPutStrLn h ""+    hPutStrLn h "{ pkgs, stdenv, callPackage }:"+    hPutStrLn h ""+    hPutStrLn h "self: {"+    hPutStrLn h ""+    mapM_ (\pkg -> hPutStrLn h pkg >> hPutStrLn h "") pkgs+    hPutStrLn h "}"++  void $ runParIO $ flip parMapM snapshots $ \Snapshot {..} -> liftIO $ do+     let allPackages :: PackageSet+         allPackages = Map.difference+                         (Map.fromList [ (name, Stackage.version spec) | (name, spec) <- Map.toList packages ] `Map.union` generatedDefaultPackageSet)+                         corePackages'++         ltsConfigFile :: FilePath+         ltsConfigFile = nixpkgsRepository </> "pkgs/development/haskell-modules/configuration-" ++ show (pPrint snapshot) ++ ".nix"++         corePackages' :: PackageSet+         corePackages' = corePackages `Map.union` Map.fromList [("Cabal", Version [] []), ("rts", Version [] [])]++     withFile ltsConfigFile WriteMode $ \h -> do+       hPutStrLn h "{ pkgs }:"+       hPutStrLn h ""+       hPutStrLn h "with import ./lib.nix { inherit pkgs; };"+       hPutStrLn h ""+       hPutStrLn h "self: super: {"+       hPutStrLn h ""+       hPutStrLn h "  # core libraries provided by the compiler"+       forM_ (Map.keys corePackages') $ \n ->+         unless (n == "ghc") (hPutStrLn h ("  " ++ unPackageName n ++ " = null;"))+       hPutStrLn h ""+       hPutStrLn h ("  # " ++ show (pPrint snapshot) ++ " packages")+       forM_ (Map.toList allPackages) $ \(name, v) -> do+         let pkgId = PackageIdentifier name v++             isInDefaultPackageSet :: Bool+             isInDefaultPackageSet = maybe False (== v) (Map.lookup name generatedDefaultPackageSet)++             isInStackage :: Bool+             isInStackage = isJust (Map.lookup name packages)+         case (isInStackage,isInDefaultPackageSet) of+           (True,True)   -> return ()           -- build is visible and enabled+           (True,False)  -> hPutStrLn h ("  " ++ show (unPackageName name) ++ " = doDistribute super." ++ show (mangle pkgId) ++ ";")+           (False,True)  -> hPutStrLn h ("  " ++ show (unPackageName name) ++ " = dontDistribute super." ++ show (unPackageName name) ++ ";")+           (False,False) -> fail ("logic error processing " ++ display pkgId ++ " in " ++  show (pPrint snapshot))+       hPutStrLn h ""+       hPutStrLn h "}"+++isFromHackage :: Binding -> Bool+isFromHackage b = case view (reference . path) b of+                    ["self",_] -> True+                    _ -> False++readPreferredVersions :: FilePath -> IO [Constraint]+readPreferredVersions p = mapMaybe parsePreferredVersionsLine . lines <$> readFile p++parsePreferredVersionsLine :: String -> Maybe Constraint+parsePreferredVersionsLine [] = Nothing+parsePreferredVersionsLine ('-':'-':_) = Nothing+parsePreferredVersionsLine l = simpleParse l `mplus` error ("invalid preferred-versions line: " ++ show l)++enforcePreferredVersions :: [Constraint] -> PackageName -> Set Version -> Set Version+enforcePreferredVersions cs pkg = Set.filter (\v -> PackageIdentifier pkg v `satisfiesConstraints` cs)++resolveConstraint :: Constraint -> Hackage -> Version+resolveConstraint c = fromMaybe (error msg) . resolveConstraint' c+  where msg = "constraint " ++ display c ++ " cannot be resolved in Hackage"++resolveConstraint' :: Constraint -> Hackage -> Maybe Version+resolveConstraint' (Dependency name vrange) hackage+  | Just vset' <- Map.lookup name hackage+  , vset <- Set.filter (`withinRange` vrange) vset'+  , not (Set.null vset)         = Just (Set.findMax vset)+  | otherwise                   = Nothing++mangle :: PackageIdentifier -> String+mangle (PackageIdentifier (PackageName name) v) = name ++ '_' : [ if c == '.' then '_' else c | c <- display v ]
+ hackage2nix/Stackage.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Stackage where++import Control.DeepSeq+import Control.Exception ( assert )+import Control.Monad+import Control.Monad.Par.Combinator+import Control.Monad.Par.IO+import Control.Monad.Trans+import Data.List+import Data.List.Split+import Data.Map as Map+import Data.Maybe+import Data.Time.Calendar+import Data.Yaml+import Distribution.Compiler+import Distribution.Nixpkgs.Haskell.OrphanInstances ( )+import Distribution.Package+import Distribution.Version+import GHC.Generics ( Generic )+import Stackage.Types hiding ( display )+import System.Directory+import System.FilePath+import Text.PrettyPrint.HughesPJClass++data Spec = Spec+            { version :: Version+  --        , flagOverrides :: Map FlagName Bool+            , runTests :: Bool+            , runHaddock :: Bool+  --        , runLinuxBuilds :: Bool+            }+  deriving (Show, Generic)++instance Eq Spec where+  a == b = version a == version b++instance Ord Spec where+  compare a b = compare (version a) (version b)++data Snapshot = Snapshot+            { snapshot :: SnapshotType+            , compiler :: CompilerId+            , corePackages :: Map PackageName Version+            , packages :: Map PackageName Spec+            }+  deriving (Show, Generic)++deriving instance Generic SnapshotType+instance NFData Spec+instance NFData Snapshot+instance NFData SnapshotType++instance Pretty SnapshotType where+  pPrint STNightly = text "stackage-nightly"+  pPrint (STNightly2 _) = text "stackage-nightly"+  pPrint (STLTS m n) = text "lts-" <> int m <> char '.' <> int n++readLTSHaskell :: FilePath -> ParIO [Snapshot]+readLTSHaskell dirPath = do+  filePaths <- liftIO (listFiles dirPath)+  parMapM (liftIO . readSnapshot) [ dirPath </> p | p <- filePaths, takeExtension p == ".yaml" ]++readStackageNightly :: FilePath -> IO Snapshot+readStackageNightly dirPath = do+  filePaths <- liftIO (listFiles dirPath)+  let filePath = maximum [ p | p <- filePaths, takeExtension p == ".yaml" ]+  readSnapshot (dirPath </> filePath)++readSnapshot :: FilePath -> IO Snapshot+readSnapshot p = fmap (fromBuildPlan (parseSnapshotType (takeFileName p))) (readBuildPlan p)++parseSnapshotType :: FilePath -> SnapshotType+parseSnapshotType p+  | "lts-" `isPrefixOf` p+  , [major,minor] <- splitOn "." (drop 4 (dropExtension p))+                = STLTS (read major) (read minor)+  | "nightly-" `isPrefixOf` p+  , [year,month,day] <- splitOn "-" (drop 8 (dropExtension p))+                = STNightly2 (fromGregorian (read year) (read month) (read day))+  | otherwise   = error ("parseSnapshotType: invalid file name " ++ p)++readBuildPlan :: FilePath -> IO BuildPlan+readBuildPlan = fmap fromJust . decodeFile++fromBuildPlan :: SnapshotType -> BuildPlan -> Snapshot+fromBuildPlan snt bp = Snapshot snt+                                (CompilerId GHC (siGhcVersion (bpSystemInfo bp)))+                                (siCorePackages (bpSystemInfo bp))+                                (Map.map fromPackagePlan (bpPackages bp))++fromPackagePlan :: PackagePlan -> Spec+fromPackagePlan pp = Spec (ppVersion pp)+    --                    (pcFlagOverrides ppc)+                          (pcTests ppc == ExpectSuccess)+                          (pcHaddocks ppc == ExpectSuccess)+    --                    (not (pcSkipBuild ppc))+  where ppc = ppConstraints pp++listFiles :: FilePath -> IO [FilePath]+listFiles path = do+  let isFile p = doesFileExist (path </> p)+  getDirectoryContents path >>= filterM isFile . Prelude.filter (\x -> head x /= '.')++mergeSpecs :: Spec -> Spec -> Spec+mergeSpecs a b = Spec { version = assert (version a == version b) version a+         --           , flagOverrides = flagOverrides a+                      , runTests = runTests a && runTests b+                      , runHaddock = runHaddock a && runHaddock b+         --           , runLinuxBuilds = runLinuxBuilds a+                      }
− src/Cabal2Nix/CorePackages.hs
@@ -1,43 +0,0 @@-module Cabal2Nix.CorePackages ( corePackages, coreBuildTools ) where---- | List of packages shipped with ghc and therefore at the moment not in--- nixpkgs. This should probably be configurable at first. Later, it might--- be good to actually include them as dependencies, but set them to null--- if GHC provides them (as different GHC versions vary).------ The commented packages have previously been non-core, so we don't filter--- them.-corePackages :: [String]-corePackages = [-    "array",-    "base",-    "bin-package-db",-    "bytestring",-    -- "Cabal",-    "containers",-    "directory",-    -- "extensible-exceptions",-    "ffi",-    -- "filepath",-    "ghc",-    "ghc-binary",-    "ghc-prim",-    "haskell2010", -- new as core, but doesn't work in older GHCs anyway-    "haskell98",-    "hpc",-    "integer-gmp",-    "old-locale",-    "old-time",-    "pretty",-    "process",-    -- "random",-    "template-haskell",-    -- "time",-    "unix"-  ]--coreBuildTools :: [String]-coreBuildTools = [-    "ghc",-    "hsc2hs"-  ]
− src/Cabal2Nix/Flags.hs
@@ -1,31 +0,0 @@-module Cabal2Nix.Flags ( configureCabalFlags ) where--import Distribution.Package-import Distribution.PackageDescription--configureCabalFlags :: PackageIdentifier -> FlagAssignment-configureCabalFlags (PackageIdentifier (PackageName name) _)- | name == "arithmoi"           = [disable "llvm"]- | name == "accelerate-examples"= [disable "opencl"]- | name == "diagrams-builder"   = [enable "cairo", enable "svg", enable "ps", enable "rasterific"]- | name == "folds"              = [disable "test-hlint"]- | name == "git-annex"          = [enable "Assistant" , enable "Production"]- | name == "haskeline"          = [enable "terminfo"]- | name == "haste-compiler"     = [enable "portable"]- | name == "hslua"              = [enable "system-lua"]- | name == "hxt"                = [enable "network-uri"]- | name == "idris"              = [enable "gmp", enable "ffi"]- | name == "io-streams"         = [enable "NoInteractiveTests"]- | name == "pandoc"             = [enable "https", enable "make-pandoc-man-pages"]- | name == "reactive-banana-wx" = [disable "buildExamples"]- | name == "snap-server"        = [enable "openssl"]- | name == "xmobar"             = [enable "all_extensions"]- | name == "xmonad-extras"      = [disable "with_hlist", enable "with_split", enable "with_parsec"]- | name == "yi"                 = [enable "pango", enable "vty"]- | otherwise                    = []--enable :: String -> (FlagName,Bool)-enable name = (FlagName name, True)--disable :: String -> (FlagName,Bool)-disable name = (FlagName name, False)
− src/Cabal2Nix/Generate.hs
@@ -1,66 +0,0 @@-module Cabal2Nix.Generate ( cabal2nix ) where--import Cabal2Nix.Flags-import Cabal2Nix.License-import Cabal2Nix.Normalize-import Cabal2Nix.PostProcess-import Data.Maybe-import Distribution.Compiler-import Distribution.NixOS.Derivation.Cabal-import qualified Distribution.Package as Cabal-import qualified Distribution.PackageDescription as Cabal-import Distribution.PackageDescription.Configuration-import Distribution.System--cabal2nix :: Cabal.GenericPackageDescription -> Derivation-cabal2nix cabal = normalize $ postProcess MkDerivation-  { pname          = let Cabal.PackageName x = Cabal.pkgName pkg in x-  , version        = Cabal.pkgVersion pkg-  , src            = error "cabal2nix left the src field undefined"-  , isLibrary      = isJust (Cabal.library tpkg)-  , isExecutable   = not (null (Cabal.executables tpkg))-  , extraFunctionArgs = []-  , buildDepends   = map unDep deps-  , testDepends    = map unDep tstDeps ++ concatMap Cabal.extraLibs tests-  , buildTools     = map unDep tools-  , extraLibs      = libs-  , pkgConfDeps    = pcs-  , configureFlags = []-  , cabalFlags     = configureCabalFlags pkg-  , runHaddock     = True-  , jailbreak      = False-  , doCheck        = True-  , testTarget     = ""-  , hyperlinkSource = True-  , enableSplitObjs = True-  , phaseOverrides = ""-  , metaSection    = Meta-                   { homepage       = Cabal.homepage descr-                   , description    = Cabal.synopsis descr-                   , license        = fromCabalLicense (Cabal.license descr)-                   , platforms      = []-                   , hydraPlatforms = []-                   , maintainers    = []-                   }-  }-  where-    descr   = Cabal.packageDescription cabal-    pkg     = Cabal.package descr-    deps    = Cabal.buildDepends tpkg-    tests   = map Cabal.testBuildInfo (Cabal.testSuites tpkg)-    libDeps = map Cabal.libBuildInfo (maybeToList (Cabal.library tpkg))-    exeDeps = map Cabal.buildInfo (Cabal.executables tpkg)-    tstDeps = concatMap Cabal.buildTools tests ++ concatMap Cabal.pkgconfigDepends tests ++-              concatMap Cabal.targetBuildDepends tests-    tools   = concatMap Cabal.buildTools (libDeps ++ exeDeps)-    libs    = concatMap Cabal.extraLibs (libDeps ++ exeDeps)-    pcs     = map unDep (concatMap Cabal.pkgconfigDepends (libDeps ++ exeDeps))-    Right (tpkg, _) = finalizePackageDescription-                        (configureCabalFlags pkg)-                        (const True)-                        (Platform I386 Linux)                   -- shouldn't be hardcoded-                        (CompilerId GHC (Version [7,6,3] []))   -- dito-                        [] cabal--unDep :: Cabal.Dependency -> String-unDep (Cabal.Dependency (Cabal.PackageName x) _) = x
− src/Cabal2Nix/License.hs
@@ -1,27 +0,0 @@-module Cabal2Nix.License ( fromCabalLicense ) where--import Distribution.NixOS.Derivation.License-import Distribution.License ( License(..) )-import Data.Version--fromCabalLicense :: Distribution.License.License -> Distribution.NixOS.Derivation.License.License-fromCabalLicense (GPL Nothing)                          = Unknown (Just "GPL")-fromCabalLicense (GPL (Just (Version [2] [])))          = Known "self.stdenv.lib.licenses.gpl2"-fromCabalLicense (GPL (Just (Version [3] [])))          = Known "self.stdenv.lib.licenses.gpl3"-fromCabalLicense (LGPL Nothing)                         = Unknown (Just "LGPL")-fromCabalLicense (LGPL (Just (Version [2,1] [])))       = Known "self.stdenv.lib.licenses.lgpl21"-fromCabalLicense (LGPL (Just (Version [2] [])))         = Known "self.stdenv.lib.licenses.lgpl2"-fromCabalLicense (LGPL (Just (Version [3] [])))         = Known "self.stdenv.lib.licenses.gpl3"-fromCabalLicense (AGPL Nothing)                         = Unknown (Just "AGPL")-fromCabalLicense (AGPL (Just (Version [3] [])))         = Known "self.stdenv.lib.licenses.agpl3"-fromCabalLicense (AGPL (Just (Version [3,0] [])))       = Known "self.stdenv.lib.licenses.agpl3"-fromCabalLicense (UnknownLicense "BSD2")                = Known "self.stdenv.lib.licenses.bsd2"-fromCabalLicense BSD3                                   = Known "self.stdenv.lib.licenses.bsd3"-fromCabalLicense BSD4                                   = Unknown (Just "BSD4")-fromCabalLicense MIT                                    = Known "self.stdenv.lib.licenses.mit"-fromCabalLicense PublicDomain                           = Known "self.stdenv.lib.licenses.publicDomain"-fromCabalLicense AllRightsReserved                      = Known "self.stdenv.lib.licenses.unfree"-fromCabalLicense (Apache Nothing)                       = Known "self.stdenv.lib.licenses.asl20"-fromCabalLicense (Apache (Just (Version [2,0] [])))     = Known "self.stdenv.lib.licenses.asl20"-fromCabalLicense OtherLicense                           = Unknown Nothing-fromCabalLicense l                                      = error $ "Cabal2Nix.License.fromCabalLicense: unknown license " ++ show l
− src/Cabal2Nix/Name.hs
@@ -1,131 +0,0 @@-module Cabal2Nix.Name ( toNixName, libNixName, buildToolNixName ) where--import Data.Char---- | Map Cabal names to Nix attribute names.-toNixName :: String -> String-toNixName []      = error "toNixName: empty string is not a valid argument"-toNixName name    = f name-  where-    f []                            = []-    f ('-':c:cs) | c `notElem` "-"  = toUpper c : f cs-    f ('-':_)                       = error ("unexpected package name " ++ show name)-    f (c:cs)                        = c : f cs---- | Map libraries to Nix packages.--- TODO: This should probably be configurable. We also need to consider the--- possibility of name clashes with Haskell libraries. I have included--- identity mappings to incicate that I have verified their correctness.-libNixName :: String -> [String]-libNixName "adns"                               = return "adns"-libNixName "alsa"                               = return "alsaLib"-libNixName "appindicator-0.1"                   = return "appindicator"-libNixName "appindicator3-0.1"                  = return "appindicator"-libNixName "asound"                             = return "alsaLib"-libNixName "awesomium-1.6.5"                    = return "awesomium"-libNixName "bz2"                                = return "bzip2"-libNixName "cairo-pdf"                          = return "cairo"-libNixName "cairo-ps"                           = return "cairo"-libNixName "cairo"                              = return "cairo"-libNixName "cairo-svg"                          = return "cairo"-libNixName "CEGUIBase-0.7.7"                    = return "CEGUIBase"-libNixName "CEGUIOgreRenderer-0.7.7"            = return "CEGUIOgreRenderer"-libNixName "clutter-1.0"                        = return "clutter"-libNixName "crypto"                             = return "openssl"-libNixName "crypt"                              = []  -- provided by glibc-libNixName "c++"                                = [] -- What is that?-libNixName "dl"                                 = []  -- provided by glibc-libNixName "gconf-2.0"                          = return "gconf"-libNixName "gdk-2.0"                            = return "gtk"-libNixName "gdk-pixbuf-2.0"                     = return "gdk_pixbuf"-libNixName "gdk-x11-2.0"                        = return "gdk_x11"-libNixName "gio-2.0"                            = return "glib"-libNixName "glib-2.0"                           = return "glib"-libNixName "GL"                                 = return "mesa"-libNixName "GLU"                                = ["freeglut","mesa"]-libNixName "glut"                               = ["freeglut","mesa"]-libNixName "gmime-2.4"                          = return "gmime"-libNixName "gnome-keyring-1"                    = return "gnome_keyring"-libNixName "gnome-keyring"                      = return "gnome_keyring"-libNixName "gnome-vfs-2.0"                      = return "gnome_vfs"-libNixName "gnome-vfs-module-2.0"               = return "gnome_vfs_module"-libNixName "gobject-2.0"                        = return "glib"-libNixName "gstreamer-0.10"                     = return "gstreamer"-libNixName "gstreamer-audio-0.10"               = return "gstreamer-audio"-libNixName "gstreamer-base-0.10"                = return "gstreamer-base"-libNixName "gstreamer-controller-0.10"          = return "gstreamer-controller"-libNixName "gstreamer-dataprotocol-0.10"        = return "gstreamer-dataprotocol"-libNixName "gstreamer-net-0.10"                 = return "gstreamer-net"-libNixName "gstreamer-plugins-base-0.10"        = return "gstreamer-plugins-base"-libNixName "gthread-2.0"                        = return "glib"-libNixName "gtk+-2.0"                           = return "gtk"-libNixName "gtk+-3.0"                           = return "gtk3"-libNixName "gtkglext-1.0"                       = return "gtkglext"-libNixName "gtksourceview-2.0"                  = return "gtksourceview"-libNixName "gtksourceview-3.0"                  = return "gtksourceview"-libNixName "gtk-x11-2.0"                        = return "gtk_x11"-libNixName "icudata"                            = return "icu"-libNixName "icui18n"                            = return "icu"-libNixName "icuuc"                              = return "icu"-libNixName "idn"                                = return "libidn"-libNixName "IL"                                 = return "libdevil"-libNixName "iw"                                 = return "wirelesstools"-libNixName "jack"                               = return "jack2"-libNixName "jpeg"                               = return "libjpeg"-libNixName "libglade-2.0"                       = return "libglade"-libNixName "libgsasl"                           = return "gsasl"-libNixName "librsvg-2.0"                        = return "librsvg"-libNixName "libsoup-gnome-2.4"                  = return "libsoup"-libNixName "libusb-1.0"                         = return "libusb"-libNixName "libxml-2.0"                         = return "libxml2"-libNixName "libzip"                             = return "libzip"-libNixName "libzmq"                             = return "zeromq"-libNixName "m"                                  = []  -- in stdenv-libNixName "mono-2.0"                           = return "mono"-libNixName "ncursesw"                           = return "ncurses"-libNixName "notify"                             = return "libnotify"-libNixName "panelw"                             = return "ncurses"-libNixName "pangocairo"                         = return "pango"-libNixName "pcap"                               = return "libpcap"-libNixName "pcre"                               = return "pcre"-libNixName "pfs-1.2"                            = return "pfstools"-libNixName "png"                                = return "libpng"-libNixName "poppler-glib"                       = return "popplerGlib"-libNixName "portaudio-2.0"                      = return "portaudio"-libNixName "pq"                                 = return "postgresql"-libNixName "pthread"                            = []-libNixName "python-3.3"                         = return "python3"-libNixName "ruby1.8"                            = return "ruby"-libNixName "sane-backends"                      = return "saneBackends"-libNixName "SDL2-2.0"                           = return "SDL2"-libNixName "sdl2"                               = return "SDL2"-libNixName "sndfile"                            = return "libsndfile"-libNixName "sqlite3"                            = return "sqlite"-libNixName "ssl"                                = return "openssl"-libNixName "stdc++.dll"                         = [] -- What is that?-libNixName "stdc++"                             = [] -- What is that?-libNixName "systemd-journal"                    = return "systemd"-libNixName "vte-2.90"                           = return "vte"-libNixName "webkit-1.0"                         = return "webkit"-libNixName "webkitgtk-3.0"                      = return "webkitgtk"-libNixName "X11"                                = return "libX11"-libNixName "Xext"                               = return "libXext"-libNixName "xft"                                = return "libXft"-libNixName "Xi"                                 = return "libXi"-libNixName "xml2"                               = return "libxml2"-libNixName "Xpm"                                = return "libXpm"-libNixName "Xrandr"                             = return "libXrandr"-libNixName "Xss"                                = return "libXScrnSaver"-libNixName "Xtst"                               = return "libXtst"-libNixName "Xxf86vm"                            = return "libXxf86vm"-libNixName "zmq"                                = return "zeromq"-libNixName "z"                                  = return "zlib"-libNixName x                                    = return x---- | Map build tool names to Nix attribute names.-buildToolNixName :: String -> [String]-buildToolNixName "cabal"                        = return "cabalInstall"-buildToolNixName "gtk2hsC2hs"                   = return "gtk2hsBuildtools"-buildToolNixName "gtk2hsHookGenerator"          = return "gtk2hsBuildtools"-buildToolNixName "gtk2hsTypeGen"                = return "gtk2hsBuildtools"-buildToolNixName x                              = return (toNixName x)
− src/Cabal2Nix/Normalize.hs
@@ -1,70 +0,0 @@-{-# LANGUAGE RecordWildCards #-}--module Cabal2Nix.Normalize ( normalize, normalizeList ) where--import Distribution.NixOS.Derivation.Cabal-import Cabal2Nix.Name-import Cabal2Nix.CorePackages-import Data.List-import Data.Char-import Data.Function-import Distribution.NixOS.Regex ( regsubmatch )--normalize :: Derivation -> Derivation-normalize deriv@(MkDerivation {..}) = deriv-  { buildDepends = normalizeNixNames (filter (`notElem` (pname : corePackages)) buildDepends)-  , testDepends  = normalizeNixNames (filter (`notElem` (pname : corePackages)) testDepends)-  , buildTools   = normalizeNixBuildTools (filter (`notElem` coreBuildTools) buildTools)-  , extraLibs    = normalizeNixLibs extraLibs-  , pkgConfDeps  = normalizeNixLibs pkgConfDeps-  , metaSection  = normalizeMeta metaSection-  }--normalizeMeta :: Meta -> Meta-normalizeMeta meta@(Meta {..}) = meta-  { description = normalizeDescription description-  , maintainers = normalizeMaintainers maintainers-  , platforms   = normalizePlatforms platforms-  }--normalizeDescription :: String -> String-normalizeDescription desc-  | null desc                                             = []-  | last desc == '.' && length (filter ('.'==) desc) == 1 = normalizeDescription (init desc)-  | otherwise                                             = quote (unwords (words desc))--quote :: String -> String-quote ('\\':c:cs) = '\\' : c : quote cs-quote ('"':cs)    = '\\' : '"' : quote cs-quote (c:cs)      = c : quote cs-quote []          = []--normalizeList :: [String] -> [String]-normalizeList = nub . sortBy (compare `on` map toLower)--normalizeNixNames :: [String] -> [String]-normalizeNixNames = normalizeList . map toNixName--normalizeNixLibs :: [String] -> [String]-normalizeNixLibs = normalizeList . concatMap libNixName--normalizeNixBuildTools :: [String] -> [String]-normalizeNixBuildTools = normalizeList . concatMap buildToolNixName---- |Strip the "self.ghc.meta.platforms" prefix from platform names, filter--- duplicates, and sort the resulting list alphabetically.------ >>> normalizeMaintainers ["self.stdenv.lib.maintainers.foobar", "foobar"]--- ["foobar"]------ >>> normalizeMaintainers ["any.prefix.is.recognized.yo", "abc.def"]--- ["def","yo"]--normalizeMaintainers :: [String] -> [String]-normalizeMaintainers maints = normalizeList-  [ (m `regsubmatch` "^([^.].*\\.)?([^.]+)$") !! 1 | m <- maints ]--normalizePlatforms :: [String] -> [String]-normalizePlatforms [] = ["self.ghc.meta.platforms"]-normalizePlatforms plats = normalizeList-  [ if '.' `elem` p then p else "self.stdenv.lib.platforms." ++ p | p <- plats ]
− src/Cabal2Nix/Package.hs
@@ -1,145 +0,0 @@-module Cabal2Nix.Package where--import Control.Applicative-import Control.Monad-import Control.Monad.IO.Class-import Control.Monad.Trans.Maybe-import Data.List ( isSuffixOf, isPrefixOf )-import Data.Maybe ( listToMaybe )-import Distribution.NixOS.Derivation.Cabal-import Distribution.NixOS.Fetch-import Distribution.Text ( simpleParse )-import System.Directory ( doesDirectoryExist, doesFileExist, createDirectoryIfMissing, getHomeDirectory, getDirectoryContents )-import System.Exit ( exitFailure )-import System.FilePath ( (</>), (<.>) )-import System.IO ( hPutStrLn, stderr, hPutStr )--import qualified Distribution.Hackage.DB as DB-import qualified Distribution.Package as Cabal-import qualified Distribution.PackageDescription as Cabal-import qualified Distribution.PackageDescription.Parse as Cabal-import qualified Distribution.ParseUtils as ParseUtils--import qualified Control.Exception as Exception--data Package = Package-  { source :: DerivationSource-  , cabal :: Cabal.GenericPackageDescription-  }-  deriving (Show)--getPackage :: Maybe String -> Source -> IO Package-getPackage optHackageDB source = do-  (derivSource, pkgDesc) <- fetchOrFromDB optHackageDB source-  flip Package pkgDesc <$> maybe (sourceFromHackage (sourceHash source) $ showPackageIdentifier pkgDesc) return derivSource---fetchOrFromDB :: Maybe String -> Source -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)-fetchOrFromDB optHackageDB src-  | "cabal://" `isPrefixOf` sourceUrl src = fmap ((,) Nothing) . fromDB optHackageDB . drop (length "cabal://") $ sourceUrl src-  | otherwise                             = do-    r <- fetch cabalFromPath src-    case r of-      Nothing ->-        hPutStrLn stderr "*** failed to fetch source. Does the URL exist?" >> exitFailure-      Just (derivSource, (externalSource, pkgDesc)) ->-        return (derivSource <$ guard externalSource, pkgDesc)--fromDB :: Maybe String -> String -> IO Cabal.GenericPackageDescription-fromDB optHackageDB pkg = do-  pkgDesc <- (lookupVersion <=< DB.lookup name) <$> maybe DB.readHackage DB.readHackage' optHackageDB-  case pkgDesc of-    Just r -> return r-    Nothing -> hPutStrLn stderr "*** no such package in the cabal database (did you run cabal update?). " >> exitFailure- where-  Just pkgId = simpleParse pkg-  Cabal.PackageName name = Cabal.pkgName pkgId-  version = Cabal.pkgVersion pkgId--  lookupVersion :: DB.Map DB.Version Cabal.GenericPackageDescription -> Maybe Cabal.GenericPackageDescription-  lookupVersion-    | null (versionBranch version) = fmap snd . listToMaybe . reverse . DB.toAscList-    | otherwise                    = DB.lookup version---readFileMay :: String -> IO (Maybe String)-readFileMay file = do-  e <- doesFileExist file-  if e-    then Just <$> readFile file-    else return Nothing--hashCachePath :: String -> IO String-hashCachePath pid = do-  home <- getHomeDirectory-  let cacheDir = home </> ".cache/cabal2nix"-  createDirectoryIfMissing True cacheDir-  return $ cacheDir </> pid <.> "sha256"--sourceFromHackage :: Maybe String -> String -> IO DerivationSource-sourceFromHackage optHash pkgId = do-  cacheFile <- hashCachePath pkgId-  let cachedHash = MaybeT $ maybe (readFileMay cacheFile) (return . Just) optHash-      url = "mirror://hackage/" ++ pkgId ++ ".tar.gz"--  -- Use the cached hash (either from cache file or given on cmdline via sha256 opt)-  -- if available, otherwise download from hackage to compute hash.-  maybeHash <- runMaybeT $ cachedHash <|> derivHash . fst <$> fetchWith (False, "url", []) (Source url "" Nothing)-  case maybeHash of-    Just hash ->-      -- We need to force the hash here. If we didn't do this, then when reading the-      -- hash from the cache file, the cache file will still be open for reading-      -- (because lazy io) when writeFile opens the file again for writing. By forcing-      -- the hash here, we ensure that the file is closed before opening it again.-      seq (length hash) $-      DerivationSource "url" url "" hash <$ writeFile cacheFile hash-    Nothing -> do-      hPutStr stderr $ unlines-        [ "*** cannot compute hash. (Not a hackage project?)"-        , " If your project is not on hackage, please supply the path to the root directory of"-        , " the project, not to the cabal file."-        , ""-        , " If your project is on hackage but you still want to specify the hash manually, you"-        , " can use the --sha256 option."-        ]-      exitFailure--showPackageIdentifier :: Cabal.GenericPackageDescription -> String-showPackageIdentifier pkgDesc = name ++ "-" ++ showVersion version where-  pkgId = Cabal.package . Cabal.packageDescription $ pkgDesc-  Cabal.PackageName name = Cabal.packageName pkgId-  version = Cabal.packageVersion pkgId--cabalFromPath :: FilePath -> MaybeT IO (Bool, Cabal.GenericPackageDescription)-cabalFromPath path = do-  d <- liftIO $ doesDirectoryExist path-  (,) d <$> if d-    then cabalFromDirectory  path-    else cabalFromFile False path--cabalFromDirectory :: FilePath -> MaybeT IO Cabal.GenericPackageDescription-cabalFromDirectory dir = do-  cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)-  case cabals of-    [cabalFile] -> cabalFromFile True cabalFile-    _       -> liftIO $ hPutStrLn stderr "*** found zero or more than one cabal file. Exiting." >> exitFailure--handleIO :: (Exception.IOException -> IO a) -> IO a -> IO a-handleIO = Exception.handle--cabalFromFile :: Bool -> FilePath -> MaybeT IO Cabal.GenericPackageDescription-cabalFromFile failHard file =-  -- readFile throws an error if it's used on binary files which contain sequences-  -- that do not represent valid characters. To catch that exception, we need to-  -- wrap the whole block in `catchIO`, because of lazy IO. The `case` will force-  -- the reading of the file, so we will always catch the expression here.-  MaybeT $ handleIO (const $ return Nothing) $ do-    content <- readFile file-    case Cabal.parsePackageDescription content of-      Cabal.ParseFailed e | failHard -> do-        let (line, err) = ParseUtils.locatedErrorMsg e-            msg = maybe "" ((++ ": ") . show) line ++ err-        putStrLn $ "*** error parsing cabal file: " ++ msg-        exitFailure-      Cabal.ParseFailed _  -> return Nothing-      Cabal.ParseOk     _ a -> return (Just a)
− src/Cabal2Nix/PostProcess.hs
@@ -1,322 +0,0 @@-{-# LANGUAGE RecordWildCards #-}--module Cabal2Nix.PostProcess ( postProcess ) where--import Data.List-import Distribution.NixOS.Derivation.Cabal--postProcess :: Derivation -> Derivation-postProcess deriv@(MkDerivation {..})-  | pname == "aeson" && version > Version [0,7] []-                                = deriv { buildDepends = "blazeBuilder":buildDepends }-  | pname == "Agda"             = deriv { buildTools = "emacs":buildTools, phaseOverrides = agdaPostInstall }-  | pname == "alex" && version < Version [3,1] []-                                = deriv { buildTools = "perl":buildTools }-  | pname == "alex" && version >= Version [3,1] []-                                = deriv { buildTools = "perl":"happy":buildTools }-  | pname == "bindings-GLFW"    = deriv { extraLibs = "libXext":"libXfixes":extraLibs }-  | pname == "bits-extras"      = deriv { configureFlags = "--ghc-option=-lgcc_s":configureFlags, extraLibs = filter (/= "gcc_s") extraLibs }-  | pname == "Cabal"            = deriv { phaseOverrides = "preCheck = \"unset GHC_PACKAGE_PATH; export HOME=$NIX_BUILD_TOP\";" }-  | pname == "cabal2nix"        = deriv { doCheck = True, phaseOverrides = cabal2nixDoCheckHook }-  | pname == "cabal-bounds"     = deriv { buildTools = "cabalInstall":buildTools }-  | pname == "cabal-install" && version >= Version [0,14] []-                                = deriv { phaseOverrides = cabalInstallPostInstall }-  | pname == "cairo"            = deriv { extraLibs = "pkgconfig":"libc":"cairo":"zlib":extraLibs }-  | pname == "cookie"           = deriv { phaseOverrides = cookieDoCheckHook }-  | pname == "cuda"             = deriv { phaseOverrides = cudaConfigurePhase, extraLibs = "cudatoolkit":"nvidia_x11":"self.stdenv.cc":extraLibs }-  | pname == "darcs"            = deriv { phaseOverrides = darcsInstallPostInstall }-  | pname == "dns"              = deriv { testTarget = "spec" }-  | pname == "doctest"          = deriv { runHaddock = True, phaseOverrides = doctestNoHaddock }-  | pname == "editline"         = deriv { extraLibs = "libedit":extraLibs }-  | pname == "epic"             = deriv { extraLibs = "gmp":"boehmgc":extraLibs, buildTools = "happy":buildTools }-  | pname == "either"           = deriv { runHaddock = True, phaseOverrides = eitherNoHaddock }-  | pname == "ghc-heap-view"    = deriv { phaseOverrides = ghciPostInstall }-  | pname == "ghc-mod"          = deriv { phaseOverrides = ghcModPostInstall, buildTools = "emacs":"makeWrapper":buildTools }-  | pname == "ghc-parser"       = deriv { buildTools = "cpphs":"happy":buildTools, phaseOverrides = ghcParserPatchPhase }-  | pname == "ghc-paths"        = deriv { phaseOverrides = ghcPathsPatches }-  | pname == "ghc-vis"          = deriv { phaseOverrides = ghciPostInstall }-  | pname == "git-annex"        = deriv { phaseOverrides = gitAnnexOverrides, buildTools = "git":"rsync":"gnupg1":"curl":"wget":"lsof":"openssh":"which":"bup":"perl":buildTools }-  | pname == "github-backup"    = deriv { buildTools = "git":buildTools }-  | pname == "glade"            = deriv { extraLibs = "pkgconfig":"libc":extraLibs, pkgConfDeps = "gtkC":delete "gtk" pkgConfDeps }-  | pname == "glib"             = deriv { extraLibs = "pkgconfig":"libc":extraLibs }-  | pname == "gloss-raster"     = deriv { extraLibs = "llvm":extraLibs }-  | pname == "GLUT"             = deriv { extraLibs = "glut":"libSM":"libICE":"libXmu":"libXi":"mesa":extraLibs }-  | pname == "graphviz"         = deriv { testDepends = "systemGraphviz":testDepends }-  | pname == "gtk"              = deriv { extraLibs = "pkgconfig":"libc":extraLibs }-  | pname == "gtkglext"         = deriv { pkgConfDeps = "pangox_compat":pkgConfDeps }-  | pname == "gtk2hs-buildtools"= deriv { buildDepends = "hashtables":buildDepends }-  | pname == "gtksourceview2"   = deriv { extraLibs = "pkgconfig":"libc":extraLibs }-  | pname == "haddock" && version < Version [2,14] []-                                = deriv { buildTools = "alex":"happy":buildTools }-  | pname == "haddock"          = deriv { phaseOverrides = haddockPreCheck }-  | pname == "hakyll"           = deriv { testDepends = "utillinux":testDepends }-  | pname == "happy"            = deriv { buildTools = "perl":buildTools }-  | pname == "haskeline"        = deriv { buildDepends = "utf8String":buildDepends }-  | pname == "haskell-src"      = deriv { buildTools = "happy":buildTools }-  | pname == "haskell-src-meta" = deriv { buildDepends = "uniplate":buildDepends }-  | pname == "HFuse"            = deriv { phaseOverrides = hfusePreConfigure }-  | pname == "highlighting-kate"= highlightingKatePostProcessing deriv-  | pname == "hlibgit2"         = deriv { testDepends = "git":testDepends }-  | pname == "HList"            = deriv { buildTools = "diffutils":buildTools }-  | pname == "hmatrix"          = deriv { extraLibs = "liblapack":"blas": filter (/= "lapack") extraLibs }-  | pname == "hmatrix-special"  = deriv { extraLibs = "gsl":extraLibs }-  | pname == "hoogle"           = deriv { testTarget = "--test-option=--no-net" }-  | pname == "hspec"            = deriv { doCheck = False }-  | pname == "hsyslog"          = deriv { phaseOverrides = hsyslogNoHaddock }-  | pname == "HTTP" && version >= Version [4000,2,14] []-                                = deriv { runHaddock = True, phaseOverrides = httpNoHaddock }-  | pname == "GlomeVec"         = deriv { buildTools = "llvm":buildTools }-  | pname == "idris"            = deriv { buildTools = "happy":buildTools, extraLibs = "gmp":"boehmgc":extraLibs }-  | pname == "language-c-quote" = deriv { buildTools = "alex":"happy":buildTools }-  | pname == "language-java"    = deriv { buildDepends = "syb":buildDepends }-  | pname == "leksah-server"    = deriv { buildDepends = "process-leksah":buildDepends }-  | pname == "lhs2tex"          = deriv { extraLibs = "texLive":extraLibs, phaseOverrides = lhs2texPostInstall }-  | pname == "libffi"           = deriv { extraLibs = delete "ffi" extraLibs }-  | pname == "liquid-fixpoint"  = deriv { buildTools = "ocaml":buildTools }-  | pname == "llvm-base"        = deriv { extraLibs = "llvm":extraLibs }-  | pname == "llvm-general"     = deriv { doCheck = False }-  | pname == "llvm-general-pure"= deriv { doCheck = False }-  | pname == "MFlow"            = deriv { buildTools = "cpphs":buildTools }-  | pname == "markdown-unlit"   = deriv { runHaddock = True, phaseOverrides = markdownUnlitNoHaddock }-  | pname == "multiarg"         = deriv { buildDepends = "utf8String":buildDepends }-  | pname == "mime-mail"        = deriv { extraFunctionArgs = ["sendmail ? \"sendmail\""], phaseOverrides = mimeMailConfigureFlags }-  | pname == "mysql"            = deriv { buildTools = "mysqlConfig":buildTools, extraLibs = "zlib":extraLibs }-  | pname == "ncurses"          = deriv { phaseOverrides = ncursesPatchPhase }-  | pname == "Omega"            = deriv { testDepends = delete "stdc++" testDepends }-  | pname == "OpenAL"           = deriv { extraLibs = "openal":extraLibs }-  | pname == "OpenGL"           = deriv { extraLibs = "mesa":"libX11":extraLibs }-  | pname == "pandoc"           = deriv { buildDepends = "alex":"happy":buildDepends }-  | pname == "pango"            = deriv { extraLibs = "pkgconfig":"libc":extraLibs }-  | pname == "pcap"             = deriv { extraLibs = "libpcap":extraLibs }-  | pname == "persistent"       = deriv { extraLibs = "sqlite3":extraLibs }-  | pname == "poppler"          = deriv { extraLibs = "libc":extraLibs }-  | pname == "purescript"       = deriv { testDepends = "nodejs":testDepends }-  | pname == "QuickCheck" && version >= Version [2,7,3] []-                                = deriv { runHaddock = True, phaseOverrides = quickCheckNoHaddock }-  | pname == "repa-algorithms"  = deriv { extraLibs = "llvm":extraLibs }-  | pname == "repa-examples"    = deriv { extraLibs = "llvm":extraLibs }-  | pname == "saltine"          = deriv { extraLibs = map (\x -> if x == "sodium" then "libsodium" else x) extraLibs }-  | pname == "SDL-image"        = deriv { extraLibs = "SDL_image":extraLibs }-  | pname == "SDL-mixer"        = deriv { extraLibs = "SDL_mixer":extraLibs }-  | pname == "SDL-ttf"          = deriv { extraLibs = "SDL_ttf":extraLibs }-  | pname == "sloane"           = deriv { phaseOverrides = sloanePostInstall }-  | pname == "split" && version == Version [0,2,2] []-                                = deriv { doCheck = True, phaseOverrides = splitDoCheck }-  | pname == "structured-haskell-mode" = deriv { buildTools = "emacs":buildTools, phaseOverrides = structuredHaskellModePostInstall }-  | pname == "svgcairo"         = deriv { extraLibs = "libc":extraLibs }-  | pname == "syb" && version == Version [0,4,2] []-                                = deriv { doCheck = True, phaseOverrides = sybDoCheck }-  | pname == "tar"              = deriv { runHaddock = True, phaseOverrides = tarNoHaddock }-  | pname == "terminfo"         = deriv { extraLibs = "ncurses":extraLibs }-  | pname == "threadscope"      = deriv { configureFlags = "--ghc-options=-rtsopts":configureFlags }-  | pname == "thyme"            = deriv { buildTools = "cpphs":buildTools }-  | pname == "transformers" && version >= Version [0,4,1] []-                                = deriv { runHaddock = True, phaseOverrides = transformersNoHaddock }-  | pname == "tz"               = deriv { extraFunctionArgs = ["pkgs_tzdata"], phaseOverrides = "preConfigure = \"export TZDIR=${pkgs_tzdata}/share/zoneinfo\";" }-  | pname == "vacuum"           = deriv { extraLibs = "ghcPaths":extraLibs }-  | pname == "vector"           = deriv { configureFlags = "${self.stdenv.lib.optionalString self.stdenv.isi686 \"--ghc-options=-msse2\"}":configureFlags }-  | pname == "wxc"              = deriv { extraLibs = "wxGTK":"mesa":"libX11":extraLibs, phaseOverrides = wxcPostInstall }-  | pname == "wxcore"           = deriv { extraLibs = "wxGTK":"mesa":"libX11":extraLibs }-  | pname == "X11" && version >= Version [1,6] []-                                = deriv { extraLibs = "libXinerama":"libXext":"libXrender":extraLibs }-  | pname == "X11"              = deriv { extraLibs = "libXinerama":"libXext":extraLibs }-  | pname == "X11-xft"          = deriv { extraLibs = "pkgconfig":"freetype":"fontconfig":extraLibs-                                        , configureFlags = "--extra-include-dirs=${freetype}/include/freetype2":configureFlags-                                        }-  | pname == "xmonad"           = deriv { phaseOverrides = xmonadPostInstall }-  | pname == "yi"               = deriv { runHaddock = True, phaseOverrides = yiFixHaddock }-  | otherwise                   = deriv--cudaConfigurePhase :: String-cudaConfigurePhase = unlines-  [ "# Perhaps this should be the default in cabal.nix ..."-  , "#"-  , "# The cudatoolkit provides both 64 and 32-bit versions of the"-  , "# library. GHC's linker fails if the wrong version is found first."-  , "# We solve this by eliminating lib64 from the path on 32-bit"-  , "# platforms and putting lib64 first on 64-bit platforms."-  , "libPaths = if self.stdenv.is64bit then \"lib64 lib\" else \"lib\";"-  , "configurePhase = ''"-  , "  for i in Setup.hs Setup.lhs; do"-  , "    test -f $i && ghc --make $i"-  , "  done"-  , "  for p in $extraBuildInputs $propagatedNativeBuildInputs; do"-  , "    if [ -d \"$p/include\" ]; then"-  , "      extraLibDirs=\"$extraLibDirs --extra-include-dir=$p/include\""-  , "    fi"-  , "    for d in $libPaths; do"-  , "      if [ -d \"$p/$d\" ]; then"-  , "        extraLibDirs=\"$extraLibDirs --extra-lib-dir=$p/$d\""-  , "      fi"-  , "    done"-  , "  done"-  , "  ./Setup configure --verbose --prefix=\"$out\" $libraryProfiling $extraLibDirs $configureFlags"-  , "'';"-  ]--ghcModPostInstall :: String-ghcModPostInstall = unlines-  [ "configureFlags = \"--datasubdir=${self.pname}-${self.version}\";"-  , "postInstall = ''"-  , "  cd $out/share/$pname-$version"-  , "  make"-  , "  rm Makefile"-  , "  cd .."-  , "  ensureDir \"$out/share/emacs\""-  , "  mv $pname-$version emacs/site-lisp"-  , "  wrapProgram $out/bin/ghc-mod --add-flags \\"-  , "    \"\\$(${self.ghc.GHCGetPackages} ${self.ghc.version} \\\"\\$(dirname \\$0)\\\" \\\"-g -package-db -g\\\")\""-  , "  wrapProgram $out/bin/ghc-modi --add-flags \\"-  , "    \"\\$(${self.ghc.GHCGetPackages} ${self.ghc.version} \\\"\\$(dirname \\$0)\\\" \\\"-g -package-db -g\\\")\""-  , "'';"-  ]--wxcPostInstall :: String-wxcPostInstall = unlines-  [ "postInstall = ''"-  , "  cp -v dist/build/libwxc.so.${self.version} $out/lib/libwxc.so"-  , "'';"-  ]--cabalInstallPostInstall :: String-cabalInstallPostInstall = unlines-  [ "postInstall = ''"-  , "  mkdir $out/etc"-  , "  mv bash-completion $out/etc/bash_completion.d"-  , "'';"-  ]--darcsInstallPostInstall :: String-darcsInstallPostInstall = unlines-  [ "postInstall = ''"-  , "  mkdir -p $out/etc/bash_completion.d"-  , "  mv contrib/darcs_completion $out/etc/bash_completion.d/darcs"-  , "'';"-  ]--highlightingKatePostProcessing :: Derivation -> Derivation-highlightingKatePostProcessing deriv@(MkDerivation {..}) = deriv-  { phaseOverrides = "prePatch = \"sed -i -e 's|regex-pcre-builtin >= .*|regex-pcre|' highlighting-kate.cabal\";"-  , buildDepends = "regex-pcre" : filter (/="regex-pcre-builtin") buildDepends-  }--xmonadPostInstall :: String-xmonadPostInstall = unlines-  [ "postInstall = ''"-  , "  shopt -s globstar"-  , "  mkdir -p $out/share/man/man1"-  , "  mv \"$out/\"**\"/man/\"*.1 $out/share/man/man1/"-  , "'';"-  , "patches = ["-  , "  # Patch to make xmonad use XMONAD_{GHC,XMESSAGE} (if available)."-  , "  ./xmonad_ghc_var_0.11.patch"-  , "];"-  ]--yiFixHaddock :: String-yiFixHaddock = "noHaddock = self.stdenv.lib.versionOlder self.ghc.version \"7.8\";"--gitAnnexOverrides :: String-gitAnnexOverrides = unlines-  [ "preConfigure = \"export HOME=$TEMPDIR\";"-  , "installPhase = \"./Setup install\";"-  , "checkPhase = ''"-  , "  cp dist/build/git-annex/git-annex git-annex"-  , "  ./git-annex test"-  , "'';"-  , "propagatedUserEnvPkgs = [git lsof];"-  ]--ghciPostInstall :: String-ghciPostInstall = unlines-  [ "postInstall = ''"-  , "  ensureDir \"$out/share/ghci\""-  , "  ln -s \"$out/share/$pname-$version/ghci\" \"$out/share/ghci/$pname\""-  , "'';"-  ]--hfusePreConfigure :: String-hfusePreConfigure = unlines-  [ "preConfigure = ''"-  , "  sed -i -e \"s@  Extra-Lib-Dirs:         /usr/local/lib@  Extra-Lib-Dirs:         ${fuse}/lib@\" HFuse.cabal"-  , "'';"-  ]--ghcPathsPatches :: String-ghcPathsPatches = "patches = [ ./ghc-paths-nix.patch ];"--lhs2texPostInstall :: String-lhs2texPostInstall = unlines-  [ "postInstall = ''"-  , "  mkdir -p \"$out/share/doc/$name\""-  , "  cp doc/Guide2.pdf $out/share/doc/$name"-  , "  mkdir -p \"$out/nix-support\""-  , "'';"-  ]--ncursesPatchPhase :: String-ncursesPatchPhase = "patchPhase = \"find . -type f -exec sed -i -e 's|ncursesw/||' {} \\\\;\";"--doctestNoHaddock, markdownUnlitNoHaddock :: String-markdownUnlitNoHaddock = "noHaddock = self.stdenv.lib.versionOlder self.ghc.version \"7.4\";"-doctestNoHaddock = markdownUnlitNoHaddock--cabal2nixDoCheckHook :: String-cabal2nixDoCheckHook = "doCheck = self.stdenv.lib.versionOlder \"7.8\" self.ghc.version;"--cookieDoCheckHook :: String-cookieDoCheckHook = "doCheck = self.stdenv.lib.versionOlder \"7.8\" self.ghc.version;"--eitherNoHaddock :: String-eitherNoHaddock = "noHaddock = self.stdenv.lib.versionOlder self.ghc.version \"7.6\";"--httpNoHaddock, quickCheckNoHaddock, tarNoHaddock, transformersNoHaddock, hsyslogNoHaddock :: String-httpNoHaddock = "noHaddock = self.stdenv.lib.versionOlder self.ghc.version \"6.11\";"-quickCheckNoHaddock = httpNoHaddock-tarNoHaddock = httpNoHaddock-transformersNoHaddock = httpNoHaddock-hsyslogNoHaddock = httpNoHaddock--agdaPostInstall :: String-agdaPostInstall = unlines-  [ "postInstall = ''"-  , "  $out/bin/agda -c --no-main $(find $out/share -name Primitive.agda)"-  , "  $out/bin/agda-mode compile"-  , "'';"-  ]--structuredHaskellModePostInstall :: String-structuredHaskellModePostInstall = unlines-  [ "postInstall = ''"-  , "  emacs -L elisp --batch -f batch-byte-compile \"elisp/\"*.el"-  , "  install -d $out/share/emacs/site-lisp"-  , "  install \"elisp/\"*.el \"elisp/\"*.elc  $out/share/emacs/site-lisp"-  , "'';"-  ]--sloanePostInstall :: String-sloanePostInstall = unlines-  [ "postInstall = ''"-  , "  mkdir -p $out/share/man/man1"-  , "  cp sloane.1 $out/share/man/man1/"-  , "'';"-  ]--mimeMailConfigureFlags :: String-mimeMailConfigureFlags = unlines-  [ "configureFlags = \"--ghc-option=-DMIME_MAIL_SENDMAIL_PATH=\\\"${sendmail}\\\"\";"-  ]--sybDoCheck, splitDoCheck :: String-sybDoCheck = "doCheck = self.stdenv.lib.versionOlder self.ghc.version \"7.9\";"-splitDoCheck = sybDoCheck--haddockPreCheck :: String-haddockPreCheck = "preCheck = \"unset GHC_PACKAGE_PATH\";"--ghcParserPatchPhase :: String-ghcParserPatchPhase = unlines-  [ "patchPhase = ''"-  , "  substituteInPlace build-parser.sh --replace \"/bin/bash\" \"$SHELL\""-  , "'';"-  ]
− src/Cabal2Nix/Version.hs
@@ -1,7 +0,0 @@-module Cabal2Nix.Version where--import Data.Version (showVersion)-import Paths_cabal2nix (version)--version :: String-version = showVersion Paths_cabal2nix.version
− src/Distribution/NixOS/Derivation/Cabal.hs
@@ -1,195 +0,0 @@-{-# LANGUAGE PatternGuards, RecordWildCards, CPP #-}-{- |-   Module      :  Distribution.NixOS.Derivation.Cabal-   License     :  BSD3--   Maintainer  :  nix-dev@cs.uu.nl-   Stability   :  provisional-   Portability :  PatternGuards--   A represtation of Nix expressions based on Cabal builder defined in-   @pkgs\/development\/libraries\/haskell\/cabal\/cabal.nix@.--}--module Distribution.NixOS.Derivation.Cabal-  ( Derivation(..)-  , parseDerivation-  , DerivationSource(..)-  , module Distribution.NixOS.Derivation.Meta-  , module Data.Version-  )-  where--import Control.DeepSeq-import Data.Char-import Data.Function-import Data.List-import Data.Version-import Distribution.NixOS.Derivation.Meta-import Distribution.NixOS.Fetch-import Distribution.NixOS.PrettyPrinting-import Distribution.NixOS.Regex hiding ( empty )-import Distribution.Package-#ifdef __HADDOCK__-import Distribution.PackageDescription ( PackageDescription )-#endif-import Distribution.PackageDescription ( FlagAssignment, FlagName(..) )-import Distribution.Text---- | A represtation of Nix expressions for building Haskell packages.--- The data type correspond closely to the definition of--- 'PackageDescription' from Cabal.------ Note that the "Text" instance definition provides pretty-printing,--- but no parsing as of now!-data Derivation = MkDerivation-  { pname               :: String-  , version             :: Version-  , src                 :: DerivationSource-  , isLibrary           :: Bool-  , isExecutable        :: Bool-  , extraFunctionArgs   :: [String]-  , buildDepends        :: [String]-  , testDepends         :: [String]-  , buildTools          :: [String]-  , extraLibs           :: [String]-  , pkgConfDeps         :: [String]-  , configureFlags      :: [String]-  , cabalFlags          :: FlagAssignment-  , runHaddock          :: Bool-  , jailbreak           :: Bool-  , doCheck             :: Bool-  , testTarget          :: String-  , hyperlinkSource     :: Bool-  , enableSplitObjs     :: Bool-  , phaseOverrides      :: String-  , metaSection         :: Meta-  }-  deriving (Show, Eq, Ord)--instance Text Derivation where-  disp  = renderDerivation-  parse = error "parsing Distribution.NixOS.Derivation.Cabal.Derivation is not supported yet"--instance Package Derivation where-  packageId deriv = PackageIdentifier (PackageName (pname deriv)) (version deriv)--instance NFData Derivation where-  rnf (MkDerivation a b c d e f g h i j k l m n o p q r t u v) =-    a `deepseq` b `deepseq` c `deepseq` d `deepseq` e `deepseq` f `deepseq` g `deepseq`-    h `deepseq` i `deepseq` j `deepseq` k `deepseq` l `deepseq` m `deepseqFlagAssignment` n `deepseq`-    o `deepseq` p `deepseq` q `deepseq` r `deepseq` t `deepseq` u `deepseq` v `deepseq` ()---- FlagName has no NFData instance in old version of Cabal.-deepseqFlagAssignment :: FlagAssignment -> a -> a-deepseqFlagAssignment [] b = b-deepseqFlagAssignment ((FlagName n, v):as) b = n `deepseq` v `deepseq` as `deepseqFlagAssignment` b--renderDerivation :: Derivation -> Doc-renderDerivation deriv =-  text "# This file was auto-generated by cabal2nix. Please do NOT edit manually!" $$-  text "" $$-  funargs (map text ("cabal" : inputs)) $$ vcat-  [ text ""-  , text "cabal.mkDerivation" <+> lparen <> text "self" <> colon <+> lbrace-  , nest 2 $ vcat-    [ attr "pname"   $ string (pname deriv)-    , attr "version" $ doubleQuotes (disp (version deriv))-    , sourceAttr (src deriv)-    , boolattr "isLibrary" (not (isLibrary deriv) || isExecutable deriv) (isLibrary deriv)-    , boolattr "isExecutable" (not (isLibrary deriv) || isExecutable deriv) (isExecutable deriv)-    , listattr "buildDepends" empty (buildDepends deriv)-    , listattr "testDepends" empty (testDepends deriv)-    , listattr "buildTools" empty (buildTools deriv)-    , listattr "extraLibraries" empty (extraLibs deriv)-    , listattr "pkgconfigDepends" empty (pkgConfDeps deriv)-    , onlyIf renderedFlags $ attr "configureFlags" $ doubleQuotes (sep renderedFlags)-    , boolattr "enableSplitObjs"  (not (enableSplitObjs deriv)) (enableSplitObjs deriv)-    , boolattr "noHaddock" (not (runHaddock deriv)) (not (runHaddock deriv))-    , boolattr "jailbreak" (jailbreak deriv) (jailbreak deriv)-    , boolattr "doCheck" (not (doCheck deriv)) (doCheck deriv)-    , onlyIf (testTarget deriv) $ attr "testTarget" $ string (testTarget deriv)-    , boolattr "hyperlinkSource" (not (hyperlinkSource deriv)) (hyperlinkSource deriv)-    , onlyIf (phaseOverrides deriv) $ vcat ((map text . lines) (phaseOverrides deriv))-    , disp (metaSection deriv)-    ]-  , rbrace <> rparen-  , text ""-  ]-  where-    inputs = nub $ sortBy (compare `on` map toLower) $ filter (/="cabal") $ filter (not . isPrefixOf "self.") $-              buildDepends deriv ++ testDepends deriv ++ buildTools deriv ++ extraLibs deriv ++ pkgConfDeps deriv ++ extraFunctionArgs deriv-           ++ ["fetch" ++ derivKind (src deriv) | derivKind (src deriv) /= "" && not isHackagePackage]-    renderedFlags =  [ text "-f" <> (if enable then empty else char '-') <> text f | (FlagName f, enable) <- cabalFlags deriv ]-                  ++ map text (configureFlags deriv)-    isHackagePackage = "mirror://hackage/" `isPrefixOf` derivUrl (src deriv)-    sourceAttr (DerivationSource{..})-      | isHackagePackage = attr "sha256" $ string derivHash-      | derivKind /= "" = vcat-         [ text "src" <+> equals <+> text ("fetch" ++ derivKind) <+> lbrace-         , nest 2 $ vcat-           [ attr "url" $ string derivUrl-           , attr "sha256" $ string derivHash-           , if derivRevision /= "" then attr "rev" (string derivRevision) else empty-           ]-         , rbrace <> semi-         ]-      | otherwise = attr "src" $ text derivUrl---- | A very incomplete parser that extracts 'pname', 'version',--- 'sha256', 'platforms', 'hydraPlatforms', 'maintainers', 'doCheck',--- 'jailbreak', and 'runHaddock' from the given Nix expression.-parseDerivation :: String -> Maybe Derivation-parseDerivation buf-  | buf =~ "cabal.mkDerivation"-  , [name]    <- buf `regsubmatch` "pname *= *\"([^\"]+)\""-  , [vers']   <- buf `regsubmatch` "version *= *\"([^\"]+)\""-  , Just vers <- simpleParse vers'-  , sha       <- buf `regsubmatch` "sha256 *= *\"([^\"]+)\""-  , sr        <- buf `regsubmatch` "src *= *([^;]+);"-  , url       <- buf `regsubmatch` "url *= *\"?([^;\"]+)\"? *;"-  , rev       <- buf `regsubmatch` "rev *= *\"([^\"]+)\""-  , hplats    <- buf `regsubmatch` "hydraPlatforms *= *([^;]+);"-  , plats     <- buf `regsubmatch` "platforms *= *([^;]+);"-  , maint     <- buf `regsubmatch` "maintainers *= *(with [^;]+;)? \\[([^\"]+)]"-  , noHaddock <- buf `regsubmatch` "noHaddock *= *(true|false) *;"-  , jailBreak <- buf `regsubmatch` "jailbreak *= *(true|false) *;"-  , docheck   <- buf `regsubmatch` "doCheck *= *(true|false) *;"-  , hyperlSrc <- buf `regsubmatch` "hyperlinkSource *= *(true|false) *;"-  , splitObj  <- buf `regsubmatch` "enableSplitObjs *= *(true|false) *;"-              = Just MkDerivation-                  { pname          = name-                  , version        = vers-                  , src            = case (sr,url) of-                                       ([]   , _      ) -> DerivationSource "url" ("mirror://hackage/" ++ name ++ "-" ++ vers' ++ ".tar.gz") "" $ head sha-                                       (sr':_, []     ) -> DerivationSource "" sr' "" ""-                                       (sr':_, url':_ ) -> DerivationSource (drop (length "fetch") . head . words $ sr')-                                                                           url' (head $ rev ++ [""]) $ head sha--                  , isLibrary      = False-                  , isExecutable   = False-                  , extraFunctionArgs = []-                  , buildDepends   = []-                  , testDepends    = []-                  , buildTools     = []-                  , extraLibs      = []-                  , pkgConfDeps    = []-                  , configureFlags = []-                  , cabalFlags     = []-                  , runHaddock     = noHaddock /= ["true"]-                  , jailbreak      = jailBreak == ["true"]-                  , doCheck        = docheck == ["true"] || null docheck-                  , testTarget     = ""-                  , hyperlinkSource = hyperlSrc == ["true"] || null hyperlSrc-                  , enableSplitObjs = splitObj  /= ["false"]-                  , phaseOverrides = ""-                  , metaSection  = Meta-                                   { homepage       = ""-                                   , description    = ""-                                   , license        = Unknown Nothing-                                   , maintainers    = if null maint then [] else concatMap words (tail maint)-                                   , platforms      = concatMap words (map (map (\c -> if c == '+' then ' ' else c)) plats)-                                   , hydraPlatforms = concatMap words (map (map (\c -> if c == '+' then ' ' else c)) hplats)-                                   }-                  }-  | otherwise = Nothing
− src/Distribution/NixOS/Derivation/License.hs
@@ -1,56 +0,0 @@-{- |-   Module      :  Distribution.NixOS.Derivation.License-   License     :  BSD3--   Maintainer  :  nix-dev@cs.uu.nl-   Stability   :  provisional-   Portability :  portable--   Known licenses in Nix expressions are represented using the-   attributes defined in @pkgs\/lib\/licenses.nix@, and unknown licenses-   are represented as a literal string.- -}--module Distribution.NixOS.Derivation.License ( License(..) ) where--import Control.DeepSeq-import Data.Maybe-import Distribution.NixOS.PrettyPrinting-import Distribution.Text---- | The representation for licenses used in Nix derivations. Known--- licenses are Nix expressions -- such as @stdenv.lib.licenses.bsd3@--- --, so their exact \"name\" is not generally known, because the path--- to @stdenv@ depends on the context defined in the expression. In--- Cabal expressions, for example, the BSD3 license would have to be--- referred to as @self.stdenv.lib.licenses.bsd3@. Other expressions,--- however, use different paths to the @licenses@ record.. Because of--- this station, this library cannot provide an abstract data type that--- encompasses all known licenses. Instead, the @License@ type just--- distinguishes references to known and unknown licenses. The--- difference between the two is in the way they are pretty-printed:------ > > putStrLn (display (Known "stdenv.lib.license.gpl2"))--- > stdenv.lib.license.gpl2--- >--- > > putStrLn (display (Unknown (Just "GPL")))--- > "GPL"--- >--- > > putStrLn (display (Unknown Nothing))--- > "unknown"------ Note that the "Text" instance definition provides pretty-printing,--- but no parsing as of now!--data License = Known String-             | Unknown (Maybe String)-  deriving (Show, Eq, Ord)--instance Text License where-  disp (Known x)   = text x-  disp (Unknown x) = string (fromMaybe "unknown" x)-  parse = error "parsing Distribution.NixOS.Derivation.License is not supported yet"--instance NFData License where-  rnf (Known s) = rnf s-  rnf (Unknown s) = rnf s
− src/Distribution/NixOS/Derivation/Meta.hs
@@ -1,80 +0,0 @@-{- |-   Module      :  Distribution.NixOS.Derivation.Meta-   License     :  BSD3--   Maintainer  :  nix-dev@cs.uu.nl-   Stability   :  provisional-   Portability :  portable--   A representation of the @meta@ section used in Nix expressions. A-   detailed description can be found in section 4, \"Meta-attributes\",-   of the Nixpkgs manual at <http://nixos.org/nixpkgs/docs.html>.- -}--module Distribution.NixOS.Derivation.Meta-  ( Meta(..)-  , module Distribution.NixOS.Derivation.License-  )-  where--import Control.DeepSeq-import Distribution.NixOS.Derivation.License-import Distribution.NixOS.PrettyPrinting-import Distribution.Text---- | A representation of the @meta@ section used in Nix expressions.------ >>> :{---   putStrLn (display (Meta "http://example.org" "an example package" (Unknown Nothing)---                      ["stdenv.lib.platforms."++x | x <- ["unix","cygwin"]]---                      ["stdenv.lib.platforms.none"]---                      ["joe","jane"]))--- :}--- meta = {---   homepage = "http://example.org";---   description = "an example package";---   license = "unknown";---   platforms = stdenv.lib.platforms.unix ++ stdenv.lib.platforms.cygwin;---   hydraPlatforms = stdenv.lib.platforms.none;---   maintainers = with self.stdenv.lib.maintainers; [ joe jane ];--- };------ Note that the "Text" instance definition provides pretty-printing,--- but no parsing as of now!--data Meta = Meta-  { homepage       :: String    -- ^ URL of the package homepage-  , description    :: String    -- ^ short description of the package-  , license        :: License   -- ^ licensing terms-  , platforms      :: [String]  -- ^ list of supported platforms (from @pkgs\/lib\/platforms.nix@)-  , hydraPlatforms :: [String]  -- ^ list of platforms built by Hydra (from @pkgs\/lib\/platforms.nix@)-  , maintainers    :: [String]  -- ^ list of maintainers from @pkgs\/lib\/maintainers.nix@-  }-  deriving (Show, Eq, Ord)--instance Text Meta where-  disp  = renderMeta-  parse = error "parsing Distribution.NixOS.Derivation.Cabal.Meta is not supported yet"--instance NFData Meta where-  rnf (Meta a b c d e f) = a `deepseq` b `deepseq` c `deepseq` d `deepseq` e `deepseq` f `deepseq` ()--renderMeta :: Meta -> Doc-renderMeta meta = vcat-  [ text "meta" <+> equals <+> lbrace-  , nest 2 $ vcat-    [ onlyIf (homepage meta) $ attr "homepage" $ string (homepage meta)-    , onlyIf (description meta) $ attr "description" $ string (description meta)-    , attr "license" $ disp (license meta)-    , onlyIf (platforms meta) $ sep-      [ text "platforms" <+> equals, renderPlatformList (platforms meta) ]-    , onlyIf (hydraPlatforms meta) $ sep-      [ text "hydraPlatforms" <+> equals, renderPlatformList (hydraPlatforms meta) ]-    , listattr "maintainers" (text "with self.stdenv.lib.maintainers;") (maintainers meta)-    ]-  , rbrace <> semi-  ]--renderPlatformList :: [String] -> Doc-renderPlatformList plats =-  nest 2 (fsep $ punctuate (text " ++") $ map text plats) <> semi
− src/Distribution/NixOS/Fetch.hs
@@ -1,142 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ScopedTypeVariables #-}-module Distribution.NixOS.Fetch-  ( Source(..)-  , DerivationSource(..), fromDerivationSource-  , fetch-  , fetchWith-  ) where--import Control.Applicative-import Control.DeepSeq-import Control.Monad-import Control.Monad.IO.Class-import Control.Monad.Trans.Maybe-import Data.Maybe-import System.Directory-import System.Environment-import System.Exit-import System.IO-import System.Process---- | A source is a location from which we can fetch, such as a HTTP URL, a GIT URL, ....-data Source = Source-  { sourceUrl       :: String       -- ^ URL to fetch from.-  , sourceRevision  :: String       -- ^ Revision to use. For protocols where this doesn't make sense (such as HTTP), this-                                    --   should be the empty string.-  , sourceHash      :: Maybe String -- ^ The expected hash of the source, if available.-  } deriving (Show, Eq, Ord)---- | A source for a derivation. It always needs a hash and also has a protocol attached to it (url, git, svn, ...).--- A @DerivationSource@ also always has it's revision fully resolved (not relative revisions like @master@, @HEAD@, etc).-data DerivationSource = DerivationSource-  { derivKind     :: String -- ^ The kind of the source. The name of the build-support fetch derivation should be fetch<kind>.-  , derivUrl      :: String -- ^ URL to fetch from.-  , derivRevision :: String -- ^ Revision to use. Leave empty if the fetcher doesn't support revisions.-  , derivHash     :: String -- ^ The hash of the source.-  } deriving (Show, Eq, Ord)--instance NFData DerivationSource where-  rnf (DerivationSource a b c d) = a `deepseq` b `deepseq` c `deepseq` d `deepseq` ()--fromDerivationSource :: DerivationSource -> Source-fromDerivationSource DerivationSource{..} = Source derivUrl derivRevision $ Just derivHash---- | Fetch a source, trying any of the various nix-prefetch-* scripts.-fetch :: forall a. (String -> MaybeT IO a)      -- ^ This function is passed the output path name as an argument.-                                                -- It should return 'Nothing' if the file doesn't match the expected format.-                                                -- This is required, because we cannot always check if a download succeeded otherwise.-      -> Source                                 -- ^ The source to fetch from.-      -> IO (Maybe (DerivationSource, a))       -- ^ The derivation source and the result of the processing function. Returns Nothing if the download failed.-fetch f = runMaybeT . fetchers where-  fetchers :: Source -> MaybeT IO (DerivationSource, a)-  fetchers source = msum . (fetchLocal source :) $ map (\fetcher -> fetchWith fetcher source >>= process)-    [ (False, "zip", [])-    , (False, "url", [])-    , (True, "git", ["--fetch-submodules"])-    , (True, "hg", [])-    , (True, "svn", [])-    , (True, "bzr", [])-    ]--  -- | Remove '/' from the end of the path. Nix doesn't accept paths that-  -- end in a slash.-  stripSlashSuffix :: String -> String-  stripSlashSuffix = reverse . dropWhile (== '/') . reverse--  fetchLocal :: Source -> MaybeT IO (DerivationSource, a)-  fetchLocal src = do-    let path = stripSlashSuffix $ stripPrefix "file://" $ sourceUrl src-    existsFile <- liftIO $ doesFileExist path-    existsDir  <- liftIO $ doesDirectoryExist path-    guard $ existsDir || existsFile-    let path' | '/' `elem` path = path-              | otherwise       = "./" ++ path-    process (DerivationSource "" path' "" "", path') <|> localArchive path'--  localArchive :: FilePath -> MaybeT IO (DerivationSource, a)-  localArchive path = do-    absolutePath <- liftIO $ canonicalizePath path-    unpacked <- snd <$> fetchWith (False, "zip", []) (Source ("file://" ++ absolutePath) "" Nothing)-    process (DerivationSource "" absolutePath "" "", unpacked)--  process :: (DerivationSource, FilePath) -> MaybeT IO (DerivationSource, a)-  process (derivSource, file) = (,) derivSource <$> f file---- | Like 'fetch', but allows to specify which script to use.-fetchWith :: (Bool, String, [String]) -> Source -> MaybeT IO (DerivationSource, FilePath)-fetchWith (supportsRev, kind, addArgs) source = do-  unless ((sourceRevision source /= "") || isNothing (sourceHash source) || not supportsRev) $-    liftIO (hPutStrLn stderr "** need a revision for VCS when the hash is given. skipping.") >> mzero--  MaybeT $ liftIO $ do-    envs <- getEnvironment-    (Nothing, Just stdoutH, _, processH) <- createProcess (proc script args)-      { env = Just $ ("PRINT_PATH", "1") : envs-      , std_in = Inherit-      , std_err = Inherit-      , std_out = CreatePipe-      }--    exitCode <- waitForProcess processH-    case exitCode of-      ExitSuccess   -> fmap Just . processOutputSwitch . lines =<< hGetContents stdoutH-      ExitFailure _ -> return Nothing-- where--   script :: String-   script = "nix-prefetch-" ++ kind--   args :: [String]-   args = addArgs ++ sourceUrl source : [ sourceRevision source | supportsRev ] ++ maybeToList (sourceHash source)--   processOutputWithRev :: [String] -> IO (DerivationSource, FilePath)-   processOutputWithRev [rev,hash,path] = return (DerivationSource kind (sourceUrl source) (extractRevision rev) hash, path)-   processOutputWithRev out = unexpectedOutput out--   extractRevision :: String -> String-   extractRevision = unwords . drop 3 . words -- drop the "<vcs> revision is" prefix--   processOutput :: [String] -> IO (DerivationSource, FilePath)-   processOutput [hash,path] = return (DerivationSource kind (sourceUrl source) (sourceRevision source) hash, path)-   processOutput out = unexpectedOutput out--   unexpectedOutput :: [String] -> IO a-   unexpectedOutput out = do-     hPutStrLn stderr $ "*** unexpected output from " ++ "nix-prefetch-" ++ kind ++ " script: "-     hPutStr   stderr $ unlines out-     exitFailure--   processOutputSwitch :: [String] -> IO (DerivationSource, FilePath)-   processOutputSwitch-     | supportsRev && isNothing (sourceHash source) = processOutputWithRev-     | otherwise                                   = processOutput--stripPrefix :: Eq a => [a] -> [a] -> [a]-stripPrefix prefix as-  | prefix' == prefix = stripped-  | otherwise = as- where-  (prefix', stripped) = splitAt (length prefix) as
− src/Distribution/NixOS/PrettyPrinting.hs
@@ -1,56 +0,0 @@-{- |-   Module      :  Distribution.NixOS.PrettyPrinting-   License     :  BSD3--   Maintainer  :  nix-dev@cs.uu.nl-   Stability   :  provisional-   Portability :  portable--   Internal pretty-printing helpers for Nix expressions.--}--module Distribution.NixOS.PrettyPrinting-  ( onlyIf-  , listattr-  , boolattr-  , attr-  , string-  , funargs-  , module Text.PrettyPrint-  )-  where--import Text.PrettyPrint--attr :: String -> Doc -> Doc-attr n v = text n <+> equals <+> v <> semi--onlyIf :: [a] -> Doc -> Doc-onlyIf p d = if not (null p) then d else empty--boolattr :: String -> Bool -> Bool -> Doc-boolattr n p v = if p then attr n (bool v) else empty--listattr :: String -> Doc -> [String] -> Doc-listattr n prefix vs = onlyIf vs $-                sep [ text n <+> equals <+> prefix <+> lbrack,-                      nest 2 $ fsep $ map text vs,-                      rbrack <> semi-                    ]--bool :: Bool -> Doc-bool True  = text "true"-bool False = text "false"--string :: String -> Doc-string = doubleQuotes . text--prepunctuate :: Doc -> [Doc] -> [Doc]-prepunctuate _ []     = []-prepunctuate p (d:ds) = d : map (p <>) ds--funargs :: [Doc] -> Doc-funargs xs = sep [-               lbrace <+> fcat (prepunctuate (comma <> text " ") $ map (nest 2) xs),-               rbrace <> colon-             ]
− src/Distribution/NixOS/Regex.hs
@@ -1,25 +0,0 @@-{-# LANGUAGE PatternGuards, CPP #-}-{- |-   Module      :  Distribution.NixOS.Derivation.Cabal-   License     :  BSD3--   Maintainer  :  nix-dev@cs.uu.nl-   Stability   :  provisional-   Portability :  PatternGuards--   A represtation of Nix expressions based on Cabal builder defined in-   @pkgs\/development\/libraries\/haskell\/cabal\/cabal.nix@.--}--module Distribution.NixOS.Regex-  ( module Text.Regex.Posix-  , regsubmatch-  )-  where--import Text.Regex.Posix--regsubmatch :: String -> String -> [String]-regsubmatch buf patt = let (_,_,_,x) = f in x-  where f :: (String,String,String,[String])-        f = match (makeRegexOpts compExtended execBlank patt) buf
+ src/Distribution/Nixpkgs/Fetch.hs view
@@ -0,0 +1,155 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE DeriveGeneric #-}++module Distribution.Nixpkgs.Fetch+  ( Source(..)+  , Hash(..)+  , DerivationSource(..), fromDerivationSource+  , fetch+  , fetchWith+  ) where++import Control.Applicative+import Control.DeepSeq+import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.Trans.Maybe+import Data.Aeson+import qualified Data.ByteString.Lazy.Char8 as BS+import GHC.Generics ( Generic )+import System.Directory+import System.Environment+import System.Exit+import System.IO+import System.Process++-- | A source is a location from which we can fetch, such as a HTTP URL, a GIT URL, ....+data Source = Source+  { sourceUrl       :: String       -- ^ URL to fetch from.+  , sourceRevision  :: String       -- ^ Revision to use. For protocols where this doesn't make sense (such as HTTP), this+                                    --   should be the empty string.+  , sourceHash      :: Hash         -- ^ The expected hash of the source, if available.+  } deriving (Show, Eq, Ord, Generic)++instance NFData Source++data Hash = Certain String | Guess String | UnknownHash+  deriving (Show, Eq, Ord, Generic)++instance NFData Hash++isUnknown :: Hash -> Bool+isUnknown UnknownHash = True+isUnknown _           = False++hashToList :: Hash -> [String]+hashToList (Certain s) = [s]+hashToList _           = []++-- | A source for a derivation. It always needs a hash and also has a protocol attached to it (url, git, svn, ...).+-- A @DerivationSource@ also always has it's revision fully resolved (not relative revisions like @master@, @HEAD@, etc).+data DerivationSource = DerivationSource+  { derivKind     :: String -- ^ The kind of the source. The name of the build-support fetch derivation should be fetch<kind>.+  , derivUrl      :: String -- ^ URL to fetch from.+  , derivRevision :: String -- ^ Revision to use. Leave empty if the fetcher doesn't support revisions.+  , derivHash     :: String -- ^ The hash of the source.+  }+  deriving (Show, Eq, Ord, Generic)++instance NFData DerivationSource++instance FromJSON DerivationSource where+  parseJSON (Object o) = DerivationSource (error "undefined DerivationSource.kind")+        <$> o .: "url"+        <*> o .: "rev"+        <*> o .: "sha256"+  parseJSON _ = error "invalid DerivationSource"++fromDerivationSource :: DerivationSource -> Source+fromDerivationSource DerivationSource{..} = Source derivUrl derivRevision $ Certain derivHash++-- | Fetch a source, trying any of the various nix-prefetch-* scripts.+fetch :: forall a. (String -> MaybeT IO a)      -- ^ This function is passed the output path name as an argument.+                                                -- It should return 'Nothing' if the file doesn't match the expected format.+                                                -- This is required, because we cannot always check if a download succeeded otherwise.+      -> Source                                 -- ^ The source to fetch from.+      -> IO (Maybe (DerivationSource, a))       -- ^ The derivation source and the result of the processing function. Returns Nothing if the download failed.+fetch f = runMaybeT . fetchers where+  fetchers :: Source -> MaybeT IO (DerivationSource, a)+  fetchers source = msum . (fetchLocal source :) $ map (\fetcher -> fetchWith fetcher source >>= process)+    [ (False, "zip", [])+    , (False, "url", [])+    , (True, "git", ["--fetch-submodules"])+    , (True, "hg", [])+    , (True, "svn", [])+    , (True, "bzr", [])+    ]++  -- | Remove '/' from the end of the path. Nix doesn't accept paths that+  -- end in a slash.+  stripSlashSuffix :: String -> String+  stripSlashSuffix = reverse . dropWhile (== '/') . reverse++  fetchLocal :: Source -> MaybeT IO (DerivationSource, a)+  fetchLocal src = do+    let path = stripSlashSuffix $ stripPrefix "file://" $ sourceUrl src+    existsFile <- liftIO $ doesFileExist path+    existsDir  <- liftIO $ doesDirectoryExist path+    guard $ existsDir || existsFile+    let path' | '/' `elem` path = path+              | otherwise       = "./" ++ path+    process (DerivationSource "" path' "" "", path') <|> localArchive path'++  localArchive :: FilePath -> MaybeT IO (DerivationSource, a)+  localArchive path = do+    absolutePath <- liftIO $ canonicalizePath path+    unpacked <- snd <$> fetchWith (False, "zip", []) (Source ("file://" ++ absolutePath) "" UnknownHash)+    process (DerivationSource "" absolutePath "" "", unpacked)++  process :: (DerivationSource, FilePath) -> MaybeT IO (DerivationSource, a)+  process (derivSource, file) = (,) derivSource <$> f file++-- | Like 'fetch', but allows to specify which script to use.+fetchWith :: (Bool, String, [String]) -> Source -> MaybeT IO (DerivationSource, FilePath)+fetchWith (supportsRev, kind, addArgs) source = do+  unless ((sourceRevision source /= "") || isUnknown (sourceHash source) || not supportsRev) $+    liftIO (hPutStrLn stderr "** need a revision for VCS when the hash is given. skipping.") >> mzero++  MaybeT $ liftIO $ do+    envs <- getEnvironment+    (Nothing, Just stdoutH, _, processH) <- createProcess (proc script args)+      { env = Just $ ("PRINT_PATH", "1") : envs+      , std_in = Inherit+      , std_err = Inherit+      , std_out = CreatePipe+      }++    exitCode <- waitForProcess processH+    case exitCode of+      ExitFailure _ -> return Nothing+      ExitSuccess   -> do+        buf <- BS.hGetContents stdoutH+        let (l:ls) = reverse (BS.lines buf)+            buf'   = BS.unlines (reverse ls)+        case length ls of+          0 -> return Nothing+          1 -> return (Just (DerivationSource kind (sourceUrl source) "" (BS.unpack (head ls))  , sourceUrl source))+          _ -> case eitherDecode buf' of+                 Left err -> error ("invalid JSON: " ++ err ++ " in " ++ show buf')+                 Right ds -> return (Just (ds { derivKind = kind }, BS.unpack l))+ where++   script :: String+   script = "nix-prefetch-" ++ kind++   args :: [String]+   args = addArgs ++ sourceUrl source : [ sourceRevision source | supportsRev ] ++ hashToList (sourceHash source)++stripPrefix :: Eq a => [a] -> [a] -> [a]+stripPrefix prefix as+  | prefix' == prefix = stripped+  | otherwise = as+ where+  (prefix', stripped) = splitAt (length prefix) as
+ src/Distribution/Nixpkgs/Haskell.hs view
@@ -0,0 +1,8 @@+module Distribution.Nixpkgs.Haskell+  ( module Distribution.Nixpkgs.Haskell.BuildInfo+  , module Distribution.Nixpkgs.Haskell.Derivation+  )+  where++import Distribution.Nixpkgs.Haskell.BuildInfo+import Distribution.Nixpkgs.Haskell.Derivation
+ src/Distribution/Nixpkgs/Haskell/BuildInfo.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TemplateHaskell       #-}++module Distribution.Nixpkgs.Haskell.BuildInfo+  ( BuildInfo+  , haskell, pkgconfig, system, tool, pPrintBuildInfo+  )+  where++import Control.DeepSeq+import Control.Lens+import Data.Set ( Set )+import Data.Set.Lens+import GHC.Generics ( Generic )+import Language.Nix+import Language.Nix.PrettyPrinting++data BuildInfo = BuildInfo+  { _haskell   :: Set Binding+  , _pkgconfig :: Set Binding+  , _system    :: Set Binding+  , _tool      :: Set Binding+  }+  deriving (Show, Eq, Generic)++makeLenses ''BuildInfo++instance Each BuildInfo BuildInfo (Set Binding) (Set Binding) where+  each f (BuildInfo a b c d) = BuildInfo <$> f a <*> f b <*> f c <*> f d++instance Monoid BuildInfo where+  mempty = BuildInfo mempty mempty mempty mempty+  BuildInfo w1 x1 y1 z1 `mappend` BuildInfo w2 x2 y2 z2 = BuildInfo (w1 `mappend` w2) (x1 `mappend` x2) (y1 `mappend` y2) (z1 `mappend` z2)++instance NFData BuildInfo++pPrintBuildInfo :: String -> BuildInfo -> Doc+pPrintBuildInfo prefix bi = vcat+  [ setattr (prefix++"HaskellDepends") empty (setOf (haskell.folded.localName.ident) bi)+  , setattr (prefix++"SystemDepends")  empty (setOf (system.folded.localName.ident) bi)+  , setattr (prefix++"PkgconfigDepends") empty (setOf (pkgconfig.folded.localName.ident) bi)+  , setattr (prefix++"ToolDepends") empty (setOf (tool.folded.localName.ident) bi)+  ]
+ src/Distribution/Nixpkgs/Haskell/Constraint.hs view
@@ -0,0 +1,15 @@+module Distribution.Nixpkgs.Haskell.Constraint+  ( Constraint, satisfiesConstraint, satisfiesConstraints+  ) where++import Distribution.Package+import Distribution.Version+import Distribution.Nixpkgs.Haskell.OrphanInstances ( )++type Constraint = Dependency++satisfiesConstraint :: PackageIdentifier -> Constraint -> Bool+satisfiesConstraint (PackageIdentifier pn v) (Dependency cn vr) = (pn /= cn) || (v `withinRange` vr)++satisfiesConstraints :: PackageIdentifier -> [Constraint] -> Bool+satisfiesConstraints p = all (satisfiesConstraint p)
+ src/Distribution/Nixpkgs/Haskell/Derivation.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}++module Distribution.Nixpkgs.Haskell.Derivation+  ( Derivation, nullDerivation, pkgid, revision, src, isLibrary, isExecutable+  , extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags+  , cabalFlags, runHaddock, jailbreak, doCheck, testTarget, hyperlinkSource, enableSplitObjs+  , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides, editedCabalFile, metaSection+  , dependencies, setupDepends+  )+  where++import Control.DeepSeq+import Control.Lens+import Data.List+import Data.Set ( Set )+import qualified Data.Set as Set+import Data.Set.Lens+import Distribution.Nixpkgs.Fetch+import Distribution.Nixpkgs.Haskell.BuildInfo+import Distribution.Nixpkgs.Haskell.OrphanInstances ( )+import Distribution.Nixpkgs.Meta+import Distribution.Package+import Distribution.PackageDescription ( FlagAssignment, FlagName(..) )+import GHC.Generics ( Generic )+import Language.Nix+import Language.Nix.PrettyPrinting++-- | A represtation of Nix expressions for building Haskell packages.+-- The data type correspond closely to the definition of+-- 'PackageDescription' from Cabal.++data Derivation = MkDerivation+  { _pkgid                      :: PackageIdentifier+  , _revision                   :: Int+  , _src                        :: DerivationSource+  , _isLibrary                  :: Bool+  , _isExecutable               :: Bool+  , _extraFunctionArgs          :: Set Identifier+  , _setupDepends               :: BuildInfo+  , _libraryDepends             :: BuildInfo+  , _executableDepends          :: BuildInfo+  , _testDepends                :: BuildInfo+  , _configureFlags             :: Set String+  , _cabalFlags                 :: FlagAssignment+  , _runHaddock                 :: Bool+  , _jailbreak                  :: Bool+  , _doCheck                    :: Bool+  , _testTarget                 :: String+  , _hyperlinkSource            :: Bool+  , _enableLibraryProfiling     :: Bool+  , _enableExecutableProfiling  :: Bool+  , _enableSplitObjs            :: Bool+  , _phaseOverrides             :: String+  , _editedCabalFile            :: String+  , _metaSection                :: Meta+  }+  deriving (Show, Eq, Generic)++nullDerivation :: Derivation+nullDerivation = MkDerivation+  { _pkgid = error "undefined Derivation.pkgid"+  , _revision = error "undefined Derivation.revision"+  , _src = error "undefined Derivation.src"+  , _isLibrary = error "undefined Derivation.isLibrary"+  , _isExecutable = error "undefined Derivation.isExecutable"+  , _extraFunctionArgs = error "undefined Derivation.extraFunctionArgs"+  , _setupDepends = error "undefined Derivation.setupDepends"+  , _libraryDepends = error "undefined Derivation.libraryDepends"+  , _executableDepends = error "undefined Derivation.executableDepends"+  , _testDepends = error "undefined Derivation.testDepends"+  , _configureFlags = error "undefined Derivation.configureFlags"+  , _cabalFlags = error "undefined Derivation.cabalFlags"+  , _runHaddock = error "undefined Derivation.runHaddock"+  , _jailbreak = error "undefined Derivation.jailbreak"+  , _doCheck = error "undefined Derivation.doCheck"+  , _testTarget = error "undefined Derivation.testTarget"+  , _hyperlinkSource = error "undefined Derivation.hyperlinkSource"+  , _enableLibraryProfiling = error "undefined Derivation.enableLibraryProfiling"+  , _enableExecutableProfiling = error "undefined Derivation.enableExecutableProfiling"+  , _enableSplitObjs = error "undefined Derivation.enableSplitObjs"+  , _phaseOverrides = error "undefined Derivation.phaseOverrides"+  , _editedCabalFile = error "undefined Derivation.editedCabalFile"+  , _metaSection = error "undefined Derivation.metaSection"+  }++makeLenses ''Derivation++makeLensesFor [("_setupDepends", "dependencies"), ("_libraryDepends", "dependencies"), ("_executableDepends", "dependencies"), ("_testDepends", "dependencies")] ''Derivation++instance Package Derivation where+  packageId = view pkgid++instance NFData Derivation++instance Pretty Derivation where+  pPrint drv@(MkDerivation {..}) = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat+    [ text "mkDerivation" <+> lbrace+    , nest 2 $ vcat+      [ attr "pname"   $ doubleQuotes $ disp (packageName _pkgid)+      , attr "version" $ doubleQuotes $ disp (packageVersion _pkgid)+      , sourceAttr _src+      , onlyIf (_revision > 0) $ attr "revision" $ doubleQuotes $ int _revision+      , onlyIf (not (null _editedCabalFile) && _revision > 0) $ attr "editedCabalFile" $ string _editedCabalFile+      , listattr "configureFlags" empty (map (show . show) renderedFlags)+      , boolattr "isLibrary" (not _isLibrary || _isExecutable) _isLibrary+      , boolattr "isExecutable" (not _isLibrary || _isExecutable) _isExecutable+      , onlyIf (_setupDepends /= mempty) $ pPrintBuildInfo "setup" _setupDepends+      , onlyIf (_libraryDepends /= mempty) $ pPrintBuildInfo "library" _libraryDepends+      , onlyIf (_executableDepends /= mempty) $ pPrintBuildInfo "executable" _executableDepends+      , onlyIf (_testDepends /= mempty) $ pPrintBuildInfo "test" _testDepends+      , boolattr "enableLibraryProfiling" _enableLibraryProfiling _enableLibraryProfiling+      , boolattr "enableExecutableProfiling" _enableExecutableProfiling _enableExecutableProfiling+      , boolattr "enableSplitObjs"  (not _enableSplitObjs) _enableSplitObjs+      , boolattr "doHaddock" (not _runHaddock) _runHaddock+      , boolattr "jailbreak" _jailbreak _jailbreak+      , boolattr "doCheck" (not _doCheck) _doCheck+      , onlyIf (not (null _testTarget)) $ attr "testTarget" $ string _testTarget+      , boolattr "hyperlinkSource" (not _hyperlinkSource) _hyperlinkSource+      , onlyIf (not (null _phaseOverrides)) $ vcat ((map text . lines) _phaseOverrides)+      , pPrint _metaSection+      ]+    , rbrace+    ]+    where+      inputs :: Set String+      inputs = Set.unions [ Set.map (view ident) _extraFunctionArgs+                          , setOf (dependencies . each . folded . localName . ident) drv+                          , Set.fromList ["fetch" ++ derivKind _src | derivKind _src /= "" && not isHackagePackage]+                          ]++      renderedFlags = [ text "-f" <> (if enable then empty else char '-') <> text f | (FlagName f, enable) <- _cabalFlags ]+                      ++ map text (toAscList _configureFlags)+      isHackagePackage = "mirror://hackage/" `isPrefixOf` derivUrl _src+      sourceAttr (DerivationSource{..})+        | isHackagePackage = attr "sha256" $ string derivHash+        | derivKind /= "" = vcat+           [ text "src" <+> equals <+> text ("fetch" ++ derivKind) <+> lbrace+           , nest 2 $ vcat+             [ attr "url" $ string derivUrl+             , attr "sha256" $ string derivHash+             , if derivRevision /= "" then attr "rev" (string derivRevision) else empty+             ]+           , rbrace <> semi+           ]+        | otherwise = attr "src" $ text derivUrl
+ src/Distribution/Nixpkgs/Haskell/FromCabal.hs view
@@ -0,0 +1,138 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++module Distribution.Nixpkgs.Haskell.FromCabal+  ( HaskellResolver, NixpkgsResolver+  , fromGenericPackageDescription , fromPackageDescription+  )+  where++import Control.Arrow ( second )+import Control.Lens+import Data.Maybe+import Data.Set ( Set )+import qualified Data.Set as Set+import Distribution.Compiler+import Distribution.Nixpkgs.Haskell+import qualified Distribution.Nixpkgs.Haskell as Nix+import Distribution.Nixpkgs.Haskell.Constraint+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 qualified Distribution.Nixpkgs.Meta as Nix+import Distribution.Package+import Distribution.PackageDescription+import qualified Distribution.PackageDescription as Cabal+import Distribution.PackageDescription.Configuration+import Distribution.System+import Distribution.Text ( display )+import Distribution.Version+import Language.Nix++type HaskellResolver = Dependency -> Bool+type NixpkgsResolver = Identifier -> Maybe Binding++fromGenericPackageDescription :: HaskellResolver -> NixpkgsResolver -> Platform -> CompilerInfo ->  FlagAssignment -> [Constraint] -> GenericPackageDescription -> Derivation+fromGenericPackageDescription haskellResolver nixpkgsResolver arch compiler flags constraints descr'' =+  -- TODO: This logic needs simplification and cleanup. :-(+  case finalize haskellResolver of+    Left _ -> case finalize jailbrokenResolver of+                Left missing -> case finalize (const True) of+                                  Left missing' -> error $ "finalizePackageDescription complains about missing dependencies \+                                                           \even though we told it that everything exists: " ++ show missing'+                                  Right (descr_,_) -> fromPackageDescription haskellResolver nixpkgsResolver True missing flags descr_+                Right _      -> fromPackageDescription haskellResolver nixpkgsResolver True [] flags descr+    Right _ -> fromPackageDescription haskellResolver nixpkgsResolver False [] flags descr+  where+    descr :: PackageDescription+    Right (descr,_) = finalize jailbrokenResolver++    -- We have to call the Cabal finalizer several times with different resolver functions, and this+    -- convenience function makes our code shorter.+    finalize :: HaskellResolver -> Either [Dependency] (PackageDescription,FlagAssignment)+    finalize resolver = finalizePackageDescription flags resolver arch compiler constraints descr'++    jailbrokenResolver :: HaskellResolver+    jailbrokenResolver (Dependency pkg _) = haskellResolver (Dependency pkg anyVersion)++    -- A variant of the cabal file that has all test suites enabled to ensure+    -- that their dependencies are recognized by finalizePackageDescription.+    descr' :: GenericPackageDescription+    descr' = descr'' { condTestSuites = flaggedTests }++    flaggedTests :: [(String, CondTree ConfVar [Dependency] TestSuite)]+    flaggedTests = map (second (mapTreeData enableTest)) (condTestSuites descr'')++    enableTest :: TestSuite -> TestSuite+    enableTest t = t { testEnabled = True }++fromPackageDescription :: HaskellResolver -> NixpkgsResolver -> Bool -> [Dependency] -> FlagAssignment -> PackageDescription -> Derivation+fromPackageDescription haskellResolver nixpkgsResolver mismatchedDeps missingDeps flags (PackageDescription {..}) = normalize $ postProcess $ nullDerivation+    & isLibrary .~ isJust library+    & pkgid .~ package+    & revision .~ xrev+    & isLibrary .~ isJust library+    & isExecutable .~ not (null executables)+    & extraFunctionArgs .~ mempty+    & libraryDepends .~ maybe mempty (convertBuildInfo . libBuildInfo) library+    & executableDepends .~ mconcat (map (convertBuildInfo . buildInfo) executables)+    & testDepends .~ mconcat (map (convertBuildInfo . testBuildInfo) testSuites)+    & Nix.setupDepends .~ maybe mempty convertSetupBuildInfo setupBuildInfo+    & configureFlags .~ mempty+    & cabalFlags .~ flags+    & runHaddock .~ maybe True (not . null . exposedModules) library+    & jailbreak .~ (mismatchedDeps || not (null missingDeps))+    & doCheck .~ True+    & testTarget .~ mempty+    & hyperlinkSource .~ True+    & enableSplitObjs .~ True+    & enableLibraryProfiling .~ False+    & enableExecutableProfiling .~ False+    & phaseOverrides .~ mempty+    & editedCabalFile .~ (if xrev > 0+                             then fromMaybe (error (display package ++ ": X-Cabal-File-Hash field is missing")) (lookup "X-Cabal-File-Hash" customFieldsPD)+                             else "")+    & metaSection .~ ( Nix.nullMeta+                     & Nix.homepage .~ homepage+                     & Nix.description .~ synopsis+                     & Nix.license .~ fromCabalLicense license+                     & Nix.platforms .~ Nix.allKnownPlatforms+                     & Nix.hydraPlatforms .~ Nix.allKnownPlatforms+                     & Nix.maintainers .~ mempty+                     & Nix.broken .~ not (null missingDeps)+                     )+  where+    xrev = maybe 0 read (lookup "x-revision" customFieldsPD)++    resolveInHackage :: Identifier -> Binding+    resolveInHackage i | (i^.ident) `elem` [ n | (Dependency (PackageName n) _) <- missingDeps ] = bindNull i+                       | otherwise = binding # (i, path # ["self",i])   -- TODO: "self" shouldn't be hardcoded.++    goodScopes :: Set [Identifier]+    goodScopes = Set.fromList (map ("pkgs":) [[], ["xorg"], ["xlibs"], ["gnome"], ["gnome3"], ["kde4"]])++    resolveInNixpkgs :: Identifier -> Binding+    resolveInNixpkgs i+      | i `elem` ["clang","lldb","llvm"] = binding # (i, path # ["self","llvmPackages",i])     -- TODO: evil!+      | i `elem` ["gtk2","gtk3"]         = binding # (i, path # ["pkgs","gnome2","gtk"])+      | Just p <- nixpkgsResolver i, init (view (reference . path) p) `Set.member` goodScopes = p+      | otherwise                        = bindNull i++    resolveInHackageThenNixpkgs :: Identifier -> Binding+    resolveInHackageThenNixpkgs i | haskellResolver (Dependency (PackageName (i^.ident)) anyVersion) = resolveInHackage i+                                  | otherwise = resolveInNixpkgs i++    convertBuildInfo :: Cabal.BuildInfo -> Nix.BuildInfo+    convertBuildInfo Cabal.BuildInfo {..} = mempty+      & haskell .~ Set.fromList [ resolveInHackage (toNixName x) | (Dependency x _) <- targetBuildDepends ]+      & system .~ Set.fromList [ resolveInNixpkgs y | x <- extraLibs, y <- libNixName x ]+      & pkgconfig .~ Set.fromList [ resolveInNixpkgs y | Dependency (PackageName x) _ <- pkgconfigDepends, y <- libNixName x ]+      & tool .~ Set.fromList [ resolveInHackageThenNixpkgs y | Dependency (PackageName x) _ <- buildTools, y <- buildToolNixName x ]++    convertSetupBuildInfo :: Cabal.SetupBuildInfo -> Nix.BuildInfo+    convertSetupBuildInfo bi = mempty+      & haskell .~ Set.fromList [ resolveInHackage (toNixName x) | (Dependency x _) <- Cabal.setupDepends bi ]++bindNull :: Identifier -> Binding+bindNull i = binding # (i, path # ["null"])
+ src/Distribution/Nixpkgs/Haskell/FromCabal/Configuration.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP               #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DeriveGeneric #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Distribution.Nixpkgs.Haskell.FromCabal.Configuration ( Configuration(..), readConfiguration, assertConsistency ) where++import Control.DeepSeq+import Control.Lens+import Control.Monad+import Data.Map as Map+import Data.Set as Set+import Data.Text as T+import Data.Yaml+import Distribution.Compiler+import Distribution.Nixpkgs.Haskell.Constraint+import Distribution.Package+import Distribution.System+import GHC.Generics ( Generic )+import Language.Nix.Identifier++data Configuration = Configuration+  {+  -- |Target compiler. Used by 'finalizePackageDescription' to choose+  -- appropriate flags and dependencies.+    compilerInfo :: CompilerInfo++  -- |Compiler core packages that are also found on Hackage.+  , corePackages :: Set PackageIdentifier++  -- |These packages replace the latest respective version during+  -- dependency resolution.+  , defaultPackageOverrides :: [Constraint]++  -- |These packages are added to the generated set, but the play no+  -- role during dependency resolution.+  , extraPackages :: [Constraint]++  -- |We know that these packages won't build, so we give them an empty+  -- meta.hydraPlatforms attribute to avoid cluttering our Hydra output with+  -- lots of failure messages.+  , dontDistributePackages :: Map PackageName (Set Platform)++  -- |This information is used by the @hackage2nix@ utility to determine the+  -- 'maintainers' for a given Haskell package.+  , packageMaintainers :: Map Identifier (Set PackageName)+  }+  deriving (Show, Generic)++instance NFData Configuration++instance FromJSON Configuration where+  parseJSON (Object o) = Configuration+        <$> o .:? "compiler" .!= unknownCompilerInfo buildCompilerId NoAbiTag+        <*> o .:? "core-packages" .!= mempty+        <*> o .:? "default-package-overrides" .!= mempty+        <*> o .:? "extra-packages" .!= mempty+        <*> o .:? "dont-distribute-packages" .!= mempty+        <*> o .:? "package-maintainers" .!= mempty+  parseJSON _ = error "invalid Configuration"++instance FromJSON Identifier where+  parseJSON (String s) = pure (review ident (T.unpack s))+  parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Nix identifier")++-- aeson-0.11 introduces a general instance, so we just need a couple+-- of specific ones+#if MIN_VERSION_aeson(0,11,0)+instance (FromJSON v) => FromJSON (Map Identifier v) where+  parseJSON = fmap (Map.mapKeys parseKey) . parseJSON++instance (FromJSON v) => FromJSON (Map PackageName v) where+  parseJSON = fmap (Map.mapKeys parseKey) . parseJSON++parseKey :: (FromJSON k) => Text -> k+parseKey s = either error id (parseEither parseJSON (String s))+#else+instance (Ord k, FromJSON k, FromJSON v) => FromJSON (Map k v) where+  parseJSON  = fmap (Map.mapKeys parseKey) . parseJSON+    where+      parseKey :: FromJSON k => Text -> k+      parseKey s = either error id (parseEither parseJSON (String s))+#endif++readConfiguration :: FilePath -> IO Configuration+readConfiguration path =+  decodeFile path >>= maybe (fail ("invalid config file at " ++ show path)) assertConsistency++assertConsistency :: Monad m => Configuration -> m Configuration+assertConsistency cfg@(Configuration {..}) = do+  let report msg = fail ("*** configuration error: " ++ msg)++      maintainedPackages = Set.unions (Map.elems packageMaintainers)+      disabledPackages = Map.keysSet dontDistributePackages+      disabledMaintainedPackages = maintainedPackages `Set.intersection` disabledPackages+  unless (Set.null disabledMaintainedPackages) $+    report ("disabled packages that have a maintainer: " ++ show disabledMaintainedPackages)++  return cfg
+ src/Distribution/Nixpkgs/Haskell/FromCabal/Flags.hs view
@@ -0,0 +1,57 @@+module Distribution.Nixpkgs.Haskell.FromCabal.Flags ( configureCabalFlags ) where++import Distribution.Package+import Distribution.PackageDescription+import Data.Version++configureCabalFlags :: PackageIdentifier -> FlagAssignment+configureCabalFlags (PackageIdentifier (PackageName name) version)+ | name == "accelerate-examples"= [disable "opencl"]+ | name == "arithmoi"           = [disable "llvm"]+ | name == "darcs"              = [enable "library", enable "force-char8-encoding"]+ | name == "diagrams-builder"   = [enable "cairo", enable "svg", enable "ps", enable "rasterific"]+ | name == "folds"              = [disable "test-hlint"]+ | name == "git-annex"          = [ enable "assistant"+                                  , enable "cryptonite"+                                  , enable "dbus"+                                  , enable "desktopnotify"+                                  , enable "dns"+                                  , enable "feed"+                                  , enable "inotify"+                                  , enable "pairing"+                                  , enable "production"+                                  , enable "quvi"+                                  , enable "s3"+                                  , enable "tahoe"+                                  , enable "tdfa"+                                  , enable "testsuite"+                                  , enable "torrentparser"+                                  , enable "webapp"+                                  , enable "webapp-secure"+                                  , enable "webdav"+                                  , enable "xmpp"+                                  ]+ | name == "haskeline"          = [enable "terminfo"]+ | name == "haste-compiler"     = [enable "portable"]+ | name == "highlighting-kate"  = [enable "pcre-light"]+ | name == "hlibsass" && version >= Version [0,1,5] []+                                = [enable "externalLibsass"]+ | name == "hmatrix"            = [enable "openblas"]+ | name == "hslua"              = [enable "system-lua"]+ | name == "idris"              = [enable "gmp", enable "ffi", enable "curses"]+ | name == "io-streams"         = [enable "NoInteractiveTests"]+ | name == "liquid-fixpoint"    = [enable "build-external"]+ | name == "pandoc"             = [enable "https", disable "trypandoc"]+ | name == "reactive-banana-wx" = [disable "buildExamples"]+ | name == "snap-server"        = [enable "openssl"]+ | name == "xmobar"             = [enable "all_extensions"]+ | name == "xmonad-extras"      = [disable "with_hlist", enable "with_split", enable "with_parsec"]+ | name == "yaml"               = [enable "system-libyaml"]+ | name == "yi"                 = [enable "pango", enable "vty"]+ | otherwise                    = []++enable :: String -> (FlagName,Bool)+enable name = (FlagName name, True)++disable :: String -> (FlagName,Bool)+disable name = (FlagName name, False)
+ src/Distribution/Nixpkgs/Haskell/FromCabal/License.hs view
@@ -0,0 +1,30 @@+module Distribution.Nixpkgs.Haskell.FromCabal.License ( fromCabalLicense ) where++import Distribution.Nixpkgs.License+import Distribution.License ( License(..) )+import Data.Version++fromCabalLicense :: Distribution.License.License -> Distribution.Nixpkgs.License.License+fromCabalLicense (GPL Nothing)                          = Unknown (Just "GPL")+fromCabalLicense (GPL (Just (Version [2] [])))          = Known "stdenv.lib.licenses.gpl2"+fromCabalLicense (GPL (Just (Version [3] [])))          = Known "stdenv.lib.licenses.gpl3"+fromCabalLicense (LGPL Nothing)                         = Unknown (Just "LGPL")+fromCabalLicense (LGPL (Just (Version [2,1] [])))       = Known "stdenv.lib.licenses.lgpl21"+fromCabalLicense (LGPL (Just (Version [2] [])))         = Known "stdenv.lib.licenses.lgpl2"+fromCabalLicense (LGPL (Just (Version [3] [])))         = Known "stdenv.lib.licenses.lgpl3"+fromCabalLicense (AGPL Nothing)                         = Unknown (Just "AGPL")+fromCabalLicense (AGPL (Just (Version [3] [])))         = Known "stdenv.lib.licenses.agpl3"+fromCabalLicense (AGPL (Just (Version [3,0] [])))       = Known "stdenv.lib.licenses.agpl3"+fromCabalLicense (MPL (Version [2,0] []))               = Known "stdenv.lib.licenses.mpl20"+fromCabalLicense BSD2                                   = Known "stdenv.lib.licenses.bsd2"+fromCabalLicense BSD3                                   = Known "stdenv.lib.licenses.bsd3"+fromCabalLicense BSD4                                   = Known "stdenv.lib.licenses.bsdOriginal"+fromCabalLicense MIT                                    = Known "stdenv.lib.licenses.mit"+fromCabalLicense PublicDomain                           = Known "stdenv.lib.licenses.publicDomain"+fromCabalLicense UnspecifiedLicense                     = Known "stdenv.lib.licenses.unfree"+fromCabalLicense AllRightsReserved                      = Known "stdenv.lib.licenses.unfree"+fromCabalLicense (Apache Nothing)                       = Known "stdenv.lib.licenses.asl20"+fromCabalLicense (Apache (Just (Version [2,0] [])))     = Known "stdenv.lib.licenses.asl20"+fromCabalLicense ISC                                    = Known "stdenv.lib.licenses.isc"+fromCabalLicense OtherLicense                           = Unknown Nothing+fromCabalLicense l                                      = error $ "Distribution.Nixpkgs.Haskell.FromCabal.License.fromCabalLicense: unknown license " ++ show l
+ src/Distribution/Nixpkgs/Haskell/FromCabal/Name.hs view
@@ -0,0 +1,198 @@+{-# LANGUAGE OverloadedStrings #-}++module Distribution.Nixpkgs.Haskell.FromCabal.Name ( toNixName, libNixName, buildToolNixName ) where++import Data.String+import Distribution.Package+import Language.Nix++-- | Map Cabal names to Nix attribute names.+toNixName :: PackageName -> Identifier+toNixName (PackageName "") = error "toNixName: invalid empty package name"+toNixName (PackageName n)  = fromString n++-- | Map libraries to Nix packages.+--+-- TODO: This list should not be hard-coded here; it belongs into the Nixpkgs+-- repository.++libNixName :: String -> [Identifier]+libNixName ""                                   = []+libNixName "adns"                               = return "adns"+libNixName "alsa"                               = return "alsaLib"+libNixName "alut"                               = return "freealut"+libNixName "appindicator-0.1"                   = return "appindicator"+libNixName "appindicator3-0.1"                  = return "appindicator"+libNixName "asound"                             = return "alsaLib"+libNixName "awesomium-1.6.5"                    = return "awesomium"+libNixName "b2"                                 = return "libb2"+libNixName "bz2"                                = return "bzip2"+libNixName "c++"                                = []  -- What is that?+libNixName "cairo"                              = return "cairo"+libNixName "cairo-pdf"                          = return "cairo"+libNixName "cairo-ps"                           = return "cairo"+libNixName "cairo-svg"                          = return "cairo"+libNixName "CEGUIBase-0.7.7"                    = return "CEGUIBase"+libNixName "CEGUIOgreRenderer-0.7.7"            = return "CEGUIOgreRenderer"+libNixName "clutter-1.0"                        = return "clutter"+libNixName "crypt"                              = []  -- provided by glibc+libNixName "crypto"                             = return "openssl"+libNixName "curses"                             = return "ncurses"+libNixName "dl"                                 = []  -- provided by glibc+libNixName "fftw3"                              = return "fftw"+libNixName "fftw3f"                             = return "fftwFloat"+libNixName "gconf"                              = return "GConf"+libNixName "gconf-2.0"                          = return "GConf"+libNixName "gdk-2.0"                            = return "gdk2"+libNixName "gdk-3.0"                            = return "gdk3"+libNixName "gdk-pixbuf-2.0"                     = return "gdk_pixbuf"+libNixName "gdk-x11-2.0"                        = return "gdk_x11"+libNixName "gio-2.0"                            = return "glib"+libNixName "GL"                                 = return "mesa"+libNixName "glib-2.0"                           = return "glib"+libNixName "GLU"                                = ["freeglut","mesa"]+libNixName "glut"                               = ["freeglut","mesa"]+libNixName "gmime-2.4"                          = return "gmime"+libNixName "gnome-keyring"                      = return "gnome_keyring"+libNixName "gnome-keyring-1"                    = return "gnome_keyring"+libNixName "gnome-vfs-2.0"                      = return "gnome_vfs"+libNixName "gnome-vfs-module-2.0"               = return "gnome_vfs_module"+libNixName "gobject-2.0"                        = return "glib"+libNixName "gobject-introspection-1.0"          = return "gobjectIntrospection"+libNixName "gstreamer-0.10"                     = return "gstreamer"+libNixName "gstreamer-1.0"                      = return "gstreamer"+libNixName "gstreamer-audio-0.10"               = return "gst_plugins_base"+libNixName "gstreamer-audio-1.0"                = return "gst_plugins_base"+libNixName "gstreamer-base-0.10"                = return "gst_plugins_base"+libNixName "gstreamer-base-1.0"                 = return "gst_plugins_base"+libNixName "gstreamer-controller-0.10"          = return "gstreamer"+libNixName "gstreamer-dataprotocol-0.10"        = return "gstreamer"+libNixName "gstreamer-net-0.10"                 = return "gst_plugins_base"+libNixName "gstreamer-plugins-base-0.10"        = return "gst_plugins_base"+libNixName "gstreamer-video-1.0"                = return "gst_plugins_base"+libNixName "gthread-2.0"                        = return "glib"+libNixName "gtk+-2.0"                           = return "gtk2"+libNixName "gtk+-3.0"                           = return "gtk3"+libNixName "gtk-x11-2.0"                        = return "gtk_x11"+libNixName "gtkglext-1.0"                       = return "gtkglext"+libNixName "gtksourceview-2.0"                  = return "gtksourceview"+libNixName "gtksourceview-3.0"                  = return "gtksourceview"+libNixName "hidapi-libusb"                      = return "hidapi"+libNixName "icudata"                            = return "icu"+libNixName "icui18n"                            = return "icu"+libNixName "icuuc"                              = return "icu"+libNixName "idn"                                = return "libidn"+libNixName "IL"                                 = return "libdevil"+libNixName "ImageMagick"                        = return "imagemagick"+libNixName "Imlib2"                             = return "imlib2"+libNixName "iw"                                 = return "wirelesstools"+libNixName "jack"                               = return "libjack2"+libNixName "javascriptcoregtk-3.0"              = return "javascriptcoregtk"+libNixName "javascriptcoregtk-4.0"              = return "javascriptcoregtk"+libNixName "jpeg"                               = return "libjpeg"+libNixName "lapack"                             = return "liblapack"+libNixName "ldap"                               = return "openldap"+libNixName "libavutil"                          = return "ffmpeg"+libNixName "libglade-2.0"                       = return "libglade"+libNixName "libgsasl"                           = return "gsasl"+libNixName "libpcre"                            = return "pcre"+libNixName "libR"                               = return "R"+libNixName "librsvg-2.0"                        = return "librsvg"+libNixName "libsoup-2.4"                        = return "libsoup"+libNixName "libsoup-gnome-2.4"                  = return "libsoup"+libNixName "libsystemd"                         = return "systemd"+libNixName "libusb-1.0"                         = return "libusb"+libNixName "libxml-2.0"                         = return "libxml2"+libNixName "libzip"                             = return "libzip"+libNixName "libzmq"                             = return "zeromq"+libNixName "m"                                  = []  -- in stdenv+libNixName "magic"                              = return "file"+libNixName "MagickWand"                         = return "imagemagick"+libNixName "mono-2.0"                           = return "mono"+libNixName "mpi"                                = return "openmpi"+libNixName "ncursesw"                           = return "ncurses"+libNixName "netsnmp"                            = return "net_snmp"+libNixName "notify"                             = return "libnotify"+libNixName "odbc"                               = return "unixODBC"+libNixName "openblas"                           = return "openblasCompat"+libNixName "panelw"                             = return "ncurses"+libNixName "pangocairo"                         = return "pango"+libNixName "pcap"                               = return "libpcap"+libNixName "pfs-1.2"                            = return "pfstools"+libNixName "png"                                = return "libpng"+libNixName "poppler-glib"                       = return "poppler"+libNixName "portaudio-2.0"                      = return "portaudio"+libNixName "pq"                                 = return "postgresql"+libNixName "pthread"                            = []+libNixName "pulse-simple"                       = return "libpulseaudio"+libNixName "python-3.3"                         = return "python33"+libNixName "python-3.4"                         = return "python34"+libNixName "Qt5Core"                            = return "qt5"+libNixName "Qt5Gui"                             = return "qt5"+libNixName "Qt5Qml"                             = return "qt5"+libNixName "Qt5Quick"                           = return "qt5"+libNixName "Qt5Widgets"                         = return "qt5"+libNixName "rt"                                 = [] -- in glibc+libNixName "rtlsdr"                             = return "rtl-sdr"+libNixName "ruby1.8"                            = return "ruby"+libNixName "sane-backends"                      = return "saneBackends"+libNixName "sass"                               = return "libsass"+libNixName "sdl2"                               = return "SDL2"+libNixName "SDL2-2.0"                           = return "SDL2"+libNixName "sndfile"                            = return "libsndfile"+libNixName "sodium"                             = return "libsodium"+libNixName "sqlite3"                            = return "sqlite"+libNixName "ssl"                                = return "openssl"+libNixName "stdc++"                             = [] -- What is that?+libNixName "stdc++.dll"                         = [] -- What is that?+libNixName "systemd-journal"                    = return "systemd"+libNixName "taglib_c"                           = return "taglib"+libNixName "tag_c"                              = return "taglib"+libNixName "udev"                               = return "systemd";+libNixName "uuid"                               = return "libossp_uuid";+libNixName "vte-2.90"                           = return "vte"+libNixName "vte-2.91"                           = return "vte"+libNixName "wayland-client"                     = return "wayland"+libNixName "wayland-cursor"                     = return "wayland"+libNixName "wayland-egl"                        = return "mesa"+libNixName "wayland-server"                     = return "wayland"+libNixName "webkit-1.0"                         = return "webkit"+libNixName "webkit2gtk-4.0"                     = return "webkit2gtk"+libNixName "webkit2gtk-web-extension-4.0"       = return "webkit2gtk-web-extension"+libNixName "webkitgtk"                          = return "webkit"+libNixName "webkitgtk-3.0"                      = return "webkit"+libNixName "X11"                                = return "libX11"+libNixName "xau"                                = return "libXau"+libNixName "Xcursor"                            = return "libXcursor"+libNixName "xerces-c"                           = return "xercesc"+libNixName "Xext"                               = return "libXext"+libNixName "xft"                                = return "libXft"+libNixName "Xi"                                 = return "libXi"+libNixName "Xinerama"                           = return "libXinerama"+libNixName "xkbcommon"                          = return "libxkbcommon"+libNixName "xml2"                               = return "libxml2"+libNixName "Xpm"                                = return "libXpm"+libNixName "Xrandr"                             = return "libXrandr"+libNixName "Xrender"                            = return "libXrender"+libNixName "Xss"                                = return "libXScrnSaver"+libNixName "Xtst"                               = return "libXtst"+libNixName "Xxf86vm"                            = return "libXxf86vm"+libNixName "yaml-0.1"                           = return "libyaml"+libNixName "z"                                  = return "zlib"+libNixName "zmq"                                = return "zeromq"+libNixName x                                    = return (fromString x)++-- | Map build tool names to Nix attribute names.+buildToolNixName :: String -> [Identifier]+buildToolNixName ""                             = return (error "buildToolNixName: invalid empty dependency name")+buildToolNixName "cabal"                        = return "cabal-install"+buildToolNixName "ghc"                          = []+buildToolNixName "gtk2hsC2hs"                   = return "gtk2hs-buildtools"+buildToolNixName "gtk2hsHookGenerator"          = return "gtk2hs-buildtools"+buildToolNixName "gtk2hsTypeGen"                = return "gtk2hs-buildtools"+buildToolNixName "hsc2hs"                       = []+buildToolNixName "nix-build"                    = return "nix"+buildToolNixName "nix-env"                      = return "nix"+buildToolNixName "nix-instantiate"              = return "nix"+buildToolNixName "nix-store"                    = return "nix"+buildToolNixName x                              = return (fromString x)
+ src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs view
@@ -0,0 +1,57 @@+module Distribution.Nixpkgs.Haskell.FromCabal.Normalize ( normalize, normalizeCabalFlags ) where++import Control.Lens+import Data.Function+import Data.List+import qualified Data.Set as Set+import Data.String+import Distribution.Nixpkgs.Haskell+import Distribution.Nixpkgs.Meta+import Distribution.Package+import Distribution.PackageDescription ( FlagAssignment, FlagName(..) )+import Distribution.Simple.Utils ( lowercase )+import Language.Nix hiding ( quote )++normalize :: Derivation -> Derivation+normalize drv = drv+  & over libraryDepends (normalizeBuildInfo (packageName drv))+  & over executableDepends (normalizeBuildInfo (packageName drv))+  & over testDepends (normalizeBuildInfo (packageName drv))+  & over metaSection normalizeMeta+  & over cabalFlags normalizeCabalFlags+  & jailbreak %~ (&& (packageName drv /= PackageName "jailbreak-cabal"))++normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo+normalizeBuildInfo (PackageName pname) bi = bi+  & haskell %~ Set.filter (\b -> view localName b /= fromString pname)+  & tool %~ Set.filter (\b -> view localName b /= fromString pname)++normalizeMeta :: Meta -> Meta+normalizeMeta meta = meta+  & description %~ normalizeSynopsis+  & platforms %~ Set.intersection allKnownPlatforms+  & hydraPlatforms %~ Set.intersection (meta^.platforms)++normalizeSynopsis :: String -> String+normalizeSynopsis desc+  | null desc                                             = []+  | last desc == '.' && length (filter ('.'==) desc) == 1 = normalizeSynopsis (init desc)+  | otherwise                                             = quote (unwords (words desc))++quote :: String -> String+quote ('\\':c:cs) = '\\' : c : quote cs+quote ('"':cs)    = '\\' : '"' : quote cs+quote (c:cs)      = c : quote cs+quote []          = []++-- |When a flag is specified multiple times, the first occurrence+-- counts. This is counter-intuitive, IMHO, but it's how cabal does it.+-- Flag names are spelled in all lowercase.+--+-- >>> normalizeCabalFlags [(FlagName "foo", True), (FlagName "FOO", True), (FlagName "Foo", False)]+-- [(FlagName "foo",True)]++normalizeCabalFlags :: FlagAssignment -> FlagAssignment+normalizeCabalFlags flags' = nubBy ((==) `on` fst) (sortBy (compare `on` fst) flags)+  where+    flags = [ (FlagName (lowercase n), b) | (FlagName n, b) <- flags' ]
+ src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs view
@@ -0,0 +1,383 @@+{-# LANGUAGE OverloadedStrings #-}++module Distribution.Nixpkgs.Haskell.FromCabal.PostProcess ( postProcess ) where++import Control.Lens+import Data.List.Split+import Data.Set ( Set )+import qualified Data.Set as Set+import Data.Set.Lens+import Distribution.Nixpkgs.Haskell+import Distribution.Nixpkgs.Meta+import Distribution.Package+import Distribution.System+import Distribution.Text+import Distribution.Version+import Language.Nix++postProcess :: Derivation -> Derivation+postProcess deriv = foldr ($) (fixGtkBuilds deriv) [ f | (Dependency n vr, f) <- hooks, packageName deriv == n, packageVersion deriv `withinRange` vr ]++fixGtkBuilds :: Derivation -> Derivation+fixGtkBuilds drv = drv & dependencies . pkgconfig %~ Set.filter (not . collidesWithHaskellName)+                       & dependencies . system %~ Set.filter (not . collidesWithHaskellName)+                       & dependencies . tool %~ Set.filter (not . collidesWithHaskellName)+  where+    collidesWithHaskellName :: Binding -> Bool+    collidesWithHaskellName b = view localName b `Set.member` buildDeps++    myName :: Identifier+    myName = ident # n where PackageName n = packageName drv++    buildDeps :: Set Identifier+    buildDeps = Set.delete myName (setOf (dependencies . haskell . folded . localName) drv)++hooks :: [(Dependency, Derivation -> Derivation)]+hooks =+  [ ("Agda < 2.5", set (executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agdaPostInstall)+  , ("Agda >= 2.5", set (executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agda25PostInstall)+  , ("alex < 3.1.5",  set (testDepends . tool . contains (pkg "perl")) True)+  , ("alex",  set (executableDepends . tool . contains (bind "self.happy")) True)+  , ("bindings-GLFW", over (libraryDepends . system) (Set.union (Set.fromList [bind "pkgs.xorg.libXext", bind "pkgs.xorg.libXfixes"])))+  , ("bustle", set (libraryDepends . pkgconfig . contains "system-glib = pkgs.glib") True)+  , ("Cabal", set doCheck False) -- test suite doesn't work in Nix+  , ("cabal-helper", set doCheck False) -- https://github.com/DanielG/cabal-helper/issues/17+  , ("cabal-install", set phaseOverrides cabalInstallPostInstall)+  , ("darcs", set phaseOverrides darcsInstallPostInstall . set doCheck False)+  , ("dbus", set doCheck False) -- don't execute tests that try to access the network+  , ("dns", set testTarget "spec")      -- don't execute tests that try to access the network+  , ("eventstore", over (metaSection . platforms) (Set.filter (\(Platform arch _) -> arch == X86_64)))+  , ("freenect < 1.2.1", over configureFlags (Set.union (Set.fromList ["--extra-include-dirs=${pkgs.freenect}/include/libfreenect", "--extra-lib-dirs=${pkgs.freenect}/lib"])))+  , ("gf", set phaseOverrides gfPhaseOverrides . set doCheck False)+  , ("gi-cairo", giPhaseOverrides)      -- https://github.com/haskell-gi/haskell-gi/issues/36+  , ("gi-gio", giPhaseOverrides)        -- https://github.com/haskell-gi/haskell-gi/issues/36+  , ("gi-glib", giPhaseOverrides)       -- https://github.com/haskell-gi/haskell-gi/issues/36+  , ("gi-gobject", giPhaseOverrides)    -- https://github.com/haskell-gi/haskell-gi/issues/36+  , ("gi-pango", giPhaseOverrides)      -- https://github.com/haskell-gi/haskell-gi/issues/36+  , ("gio", set (libraryDepends . pkgconfig . contains "system-glib = pkgs.glib") True)+  , ("git", set doCheck False)          -- https://github.com/vincenthz/hit/issues/33+  , ("git-annex", gitAnnexHook)+  , ("github-backup", set (executableDepends . tool . contains (pkg "git")) True)+  , ("GlomeVec", set (libraryDepends . pkgconfig . contains (bind "self.llvmPackages.llvm")) True)+  , ("goatee-gtk", over (metaSection . platforms) (Set.filter (\(Platform _ os) -> os /= OSX)))+  , ("gtk3", gtk3Hook)+  , ("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 == 1.17.1", set doCheck False) -- test suite fails with ghc 8.0.1+  , ("hfsevents", over (metaSection . platforms) (Set.filter (\(Platform _ os) -> os == OSX)))+  , ("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/@'\";")+  , ("holy-project", set doCheck False)         -- attempts to access the network+  , ("hsignal < 0.2.7.4", set phaseOverrides "prePatch = \"rm -v Setup.lhs\";") -- https://github.com/amcphail/hsignal/issues/1+  , ("hslua", over (libraryDepends . each) (replace (pkg "lua") (pkg "lua5_1")))+  , ("http-client", set doCheck False)          -- attempts to access the network+  , ("http-client-openssl >= 0.2.0.1", set doCheck False) -- attempts to access the network+  , ("http-client-tls >= 0.2.2", set doCheck False) -- attempts to access the network+  , ("http-conduit", set doCheck False)         -- attempts to access the network+  , ("imagemagick", set (libraryDepends . pkgconfig . contains (pkg "imagemagick")) True) -- https://github.com/NixOS/cabal2nix/issues/136+  , ("include-file <= 0.1.0.2", set (libraryDepends . haskell . contains (bind "self.random")) True) -- https://github.com/Daniel-Diaz/include-file/issues/1+  , ("js-jquery", set doCheck False)            -- attempts to access the network+  , ("jsaddle", set (dependencies . haskell . contains (bind "self.ghcjs-base")) False)+  , ("libconfig", over (libraryDepends . system) (replace "config = null" (pkg "libconfig")))+  , ("liquid-fixpoint", set (executableDepends . system . contains (pkg "ocaml")) True . set (testDepends . system . contains (pkg "z3")) True)+  , ("liquidhaskell", set (testDepends . system . contains (pkg "z3")) True)+  , ("MFlow < 4.6", set (libraryDepends . tool . contains (bind "self.cpphs")) True)+  , ("mwc-random", set doCheck False)+  , ("mysql", set (libraryDepends . system . contains (pkg "mysql")) True)+  , ("network-attoparsec", set doCheck False) -- test suite requires network access+  , ("numeric-qq", set doCheck False) -- test suite doesn't finish even after 1+ days+  , ("pandoc", set jailbreak False) -- jailbreak-cabal break the build+  , ("pandoc >= 1.16.0.2", set doCheck False) -- https://github.com/jgm/pandoc/issues/2709 and https://github.com/fpco/stackage/issues/1332+  , ("pandoc-citeproc", set doCheck False) -- https://github.com/jgm/pandoc-citeproc/issues/172+  , ("readline", over (libraryDepends . system) (Set.union (pkgs ["readline", "ncurses"])))+  , ("rocksdb-haskell", set (metaSection . platforms) (Set.singleton (Platform X86_64 Linux)))+  , ("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+  , ("sharc-timbre", set (metaSection . broken) True) -- The build takes insanely long, i.e. >8 hours.+  , ("ssh", set doCheck False) -- test suite runs forever, probably can't deal with our lack of network access+  , ("stack", set phaseOverrides stackOverrides . set doCheck False)+  , ("stripe-http-streams", set doCheck False . set (metaSection . broken) False)+  , ("target", set (testDepends . system . contains (pkg "z3")) True)+  , ("terminfo", set (libraryDepends . system . contains (pkg "ncurses")) True)+  , ("text", set doCheck False)         -- break infinite recursion+  , ("thyme", set (libraryDepends . tool . contains (bind "self.cpphs")) True) -- required on Darwin+  , ("twilio", set doCheck False)         -- attempts to access the network+  , ("tz", set phaseOverrides "preConfigure = \"export TZDIR=${pkgs.tzdata}/share/zoneinfo\";")+  , ("websockets", set doCheck False)   -- https://github.com/jaspervdj/websockets/issues/104+  , ("Win32", over (metaSection . platforms) (Set.filter (\(Platform _ os) -> os == Windows)))+  , ("wxc", wxcHook)+  , ("wxcore", set (libraryDepends . pkgconfig . contains (pkg "wxGTK")) True)+  , ("X11", over (libraryDepends . system) (Set.union (Set.fromList $ map bind ["pkgs.xorg.libXinerama","pkgs.xorg.libXext","pkgs.xorg.libXrender"])))+  , ("xmonad", set phaseOverrides xmonadPostInstall)+  , ("zip-archive", over (testDepends . tool) (replace (bind "self.zip") (pkg "zip")))+  ]++pkg :: Identifier -> Binding+pkg i = binding # (i, path # ["pkgs",i])++pkgs :: [Identifier] -> Set Binding+pkgs = Set.fromList . map pkg++bind :: String -> Binding+bind s = binding # (i, path # is)+  where+    is = map (review ident) (splitOn "." s)+    i = last is++replace :: Binding -> Binding -> Set Binding -> Set Binding+replace old new bs = if old `Set.member` bs then Set.insert new (Set.delete old bs) else bs++-- TODO: I need to figure out how to conveniently replace a binding in a set.+gtk3Hook :: Derivation -> Derivation    -- https://github.com/NixOS/cabal2nix/issues/145+gtk3Hook = set (libraryDepends . pkgconfig . contains (pkg "gtk3")) True+         . over (libraryDepends . pkgconfig) (Set.filter (\b -> view localName b /= "gtk3"))++haddockHook :: Derivation -> Derivation+haddockHook = set doCheck False+            . set phaseOverrides "preCheck = \"unset GHC_PACKAGE_PATH\";"+            . over (dependencies . haskell) (Set.filter (\b -> view localName b /= "haddock-test"))+            . set (metaSection . broken) False++gitAnnexHook :: Derivation -> Derivation+gitAnnexHook = set phaseOverrides gitAnnexOverrides+             . over (executableDepends . system) (Set.union buildInputs)+             . over (metaSection . platforms) (Set.filter (\(Platform _ os) -> os /= OSX))+  where+    gitAnnexOverrides = unlines+      [ "preConfigure = \"export HOME=$TEMPDIR; patchShebangs .\";"+      , "postBuild = \"ln -sf dist/build/git-annex/git-annex git-annex\";"+      , "installPhase = \"make PREFIX=$out CABAL=./Setup BUILDER=./Setup install\";"+      , "checkPhase = \"./git-annex test\";"+      , "enableSharedExecutables = false;"+      ]+    buildInputs = pkgs ["git","rsync","gnupg","curl","wget","lsof","openssh","which","bup","perl"]++hfusePreConfigure :: String+hfusePreConfigure = unlines+  [ "preConfigure = ''"+  , "  sed -i -e \"s@  Extra-Lib-Dirs:         /usr/local/lib@  Extra-Lib-Dirs:         ${fuse}/lib@\" HFuse.cabal"+  , "'';"+  ]++gfPhaseOverrides :: String+gfPhaseOverrides = unlines+  [ "postPatch = ''"+  , "  sed -i \"s|\\\"-s\\\"|\\\"\\\"|\" ./Setup.hs"+    -- Disable silent compilation. Compiling takes long, it is best to see some+    -- output, otherwise it looks like the build step has stalled.+  , "  sed -i \"s|numJobs (bf bi)++||\" ./Setup.hs"+    -- Parallel compilation fails. Disable it.+  , "'';"+  , "preBuild = ''export LD_LIBRARY_PATH=`pwd`/dist/build:$LD_LIBRARY_PATH'';"+    -- The build step itself, after having built the library, needs to be able+    -- to find the library it just built in order to compile grammar files.+  ]++wxcHook :: Derivation -> Derivation+wxcHook drv = drv & libraryDepends . system %~ Set.union (Set.fromList [pkg "mesa", bind "pkgs.xorg.libX11"])+                  & libraryDepends . pkgconfig . contains (pkg "wxGTK") .~ True+                  & phaseOverrides .~ wxcPostInstall (packageVersion drv)+                  & runHaddock .~ False+  where+    wxcPostInstall :: Version -> String+    wxcPostInstall version = unlines+      [ "postInstall = \"cp -v dist/build/libwxc.so." ++ display version ++ " $out/lib/libwxc.so\";"+      , "postPatch = \"sed -i -e '/ldconfig inst_lib_dir/d' Setup.hs\";"+      ]++cabalInstallPostInstall :: String+cabalInstallPostInstall = unlines+  [ "postInstall = ''"+  , "  mkdir $out/etc"+  , "  mv bash-completion $out/etc/bash_completion.d"+  , "'';"+  ]++darcsInstallPostInstall :: String+darcsInstallPostInstall = unlines+  [ "postInstall = ''"+  , "  mkdir -p $out/etc/bash_completion.d"+  , "  mv contrib/darcs_completion $out/etc/bash_completion.d/darcs"+  , "'';"+  ]++xmonadPostInstall :: String+xmonadPostInstall = unlines+  [ "postInstall = ''"+  , "  shopt -s globstar"+  , "  mkdir -p $out/share/man/man1"+  , "  mv \"$out/\"**\"/man/\"*.1 $out/share/man/man1/"+  , "'';"+  ]++agdaPostInstall :: String+agdaPostInstall = unlines+  [ "postInstall = ''"+  , "  $out/bin/agda -c --no-main $(find $out/share -name Primitive.agda)"+  , "  $out/bin/agda-mode compile"+  , "'';"+  ]++agda25PostInstall :: String+agda25PostInstall = unlines+  [ "postInstall = ''"+  , "  files=(\"$out/share/\"*\"-ghc-\"*\"/Agda-\"*\"/lib/prim/Agda/\"{Primitive.agda,Builtin\"/\"*.agda})"+  -- Separate loops to avoid internal error+  , "  for f in \"''${files[@]}\" ; do"+  , "    $out/bin/agda $f"+  , "  done"+  , "  for f in \"''${files[@]}\" ; do"+  , "    $out/bin/agda -c --no-main $f"+  , "  done"+  , "  $out/bin/agda-mode compile"+  , "'';"+  ]++stackOverrides :: String+stackOverrides = unlines+  [ "preCheck = \"export HOME=$TMPDIR\";"+  , "postInstall = ''"+  , "  exe=$out/bin/stack"+  , "  mkdir -p $out/share/bash-completion/completions"+  , "  $exe --bash-completion-script $exe >$out/share/bash-completion/completions/stack"+  , "'';"+  ]++giPhaseOverrides :: Derivation -> Derivation+giPhaseOverrides+  = set phaseOverrides "preConfigure = \"export HASKELL_GI_GIR_SEARCH_PATH=${gobjectIntrospection.dev}/share/gir-1.0\";"+  . set (libraryDepends . pkgconfig . contains (pkg "gobjectIntrospection")) True++{-+postProcess' :: Derivation -> Derivation+postProcess' deriv@(MkDerivation {..})+  | pname == "alex" && version < Version [3,1] []+                                = deriv { buildTools = Set.insert "perl" buildTools }+  | pname == "alex" && version >= Version [3,1] []+                                = deriv { buildTools = Set.insert "perl" (Set.insert "happy" buildTools) }+  | pname == "apache-md5"       = deriv { testDepends = Set.delete "crypto" testDepends }+  | pname == "bits-extras"      = deriv { configureFlags = Set.insert "--ghc-option=-lgcc_s" configureFlags+                                        , extraLibs = Set.filter (/= "gcc_s") extraLibs+                                        }+  | pname == "Cabal"            = deriv { phaseOverrides = "preCheck = \"unset GHC_PACKAGE_PATH; export HOME=$NIX_BUILD_TOP\";" }+  | pname == "cabal-bounds"     = deriv { buildTools = Set.insert "cabal-install" buildTools }+  | pname == "editline"         = deriv { extraLibs = Set.insert "libedit" extraLibs }+  | pname == "ghc-heap-view"    = deriv { phaseOverrides = ghciPostInstall }+  | pname == "ghc-mod"          = deriv { phaseOverrides = ghcModPostInstall pname version, buildTools = Set.insert "emacs" buildTools }+  | pname == "ghc-parser"       = deriv { buildTools = Set.insert "cpphs" (Set.insert "happy" buildTools)+                                        , phaseOverrides = ghcParserPatchPhase }+  | pname == "ghc-vis"          = deriv { phaseOverrides = ghciPostInstall }+  | pname == "github-backup"    = deriv { buildTools = Set.insert "git" buildTools }+  | pname == "gloss-raster"     = deriv { extraLibs = Set.insert "llvm" extraLibs }+  | pname == "GLUT"             = deriv { extraLibs = Set.fromList ["glut","libSM","libICE","libXmu","libXi","mesa"] `Set.union` extraLibs }+  | pname == "gtkglext"         = deriv { pkgConfDeps = Set.insert "pangox_compat" pkgConfDeps }+  | pname == "gtk2hs-buildtools"= deriv { buildDepends = Set.insert "hashtables" buildDepends }+  | pname == "happy"            = deriv { buildTools = Set.insert "perl" buildTools }+  | pname == "haskeline"        = deriv { buildDepends = Set.insert "utf8-string" buildDepends }+  | pname == "haskell-src"      = deriv { buildTools = Set.insert "happy" buildTools }+  | pname == "haskell-src-meta" = deriv { buildDepends = Set.insert "uniplate" buildDepends }+  | pname == "hlibgit2"         = deriv { buildTools = Set.insert "git" buildTools }+  | pname == "HList"            = deriv { buildTools = Set.insert "diffutils" buildTools }+  | pname == "hmatrix"          = deriv { extraLibs = Set.insert "liblapack" (Set.insert "blas" (Set.filter (/= "lapack") extraLibs)) }+  | pname == "hmatrix-special"  = deriv { extraLibs = Set.insert "gsl" extraLibs }+  | pname == "idris"            = deriv { buildTools = Set.insert "happy" buildTools, extraLibs = Set.insert "gmp" (Set.insert "boehmgc" extraLibs) }+  | pname == "inline-c-cpp"     = deriv { testDepends = Set.delete "stdc++" testDepends }+  | pname == "language-c-quote" = deriv { buildTools = Set.insert "alex" (Set.insert "happy" buildTools) }+  | pname == "language-java"    = deriv { buildDepends = Set.insert "syb" buildDepends }+  | pname == "lhs2tex"          = deriv { extraLibs = Set.insert "texLive" extraLibs, phaseOverrides = lhs2texPostInstall }+  | pname == "libffi"           = deriv { extraLibs = Set.delete "ffi" extraLibs }+  | pname == "liquid-fixpoint"  = deriv { buildTools = Set.insert "z3" (Set.insert "ocaml" buildTools), configureFlags = Set.insert "-fbuild-external" configureFlags }+  | pname == "liquidhaskell"    = deriv { buildTools = Set.insert "z3" buildTools }+  | pname == "multiarg"         = deriv { buildDepends = Set.insert "utf8-string" buildDepends }+  | pname == "ncurses"          = deriv { phaseOverrides = ncursesPatchPhase }+  | pname == "Omega"            = deriv { testDepends = Set.delete "stdc++" testDepends }+  | pname == "OpenAL"           = deriv { extraLibs = Set.insert "openal" extraLibs }+  | pname == "OpenGL"           = deriv { extraLibs = Set.insert "mesa" (Set.insert "libX11" extraLibs) }+  | pname == "pandoc"           = deriv { buildDepends = Set.insert "alex" (Set.insert "happy" buildDepends) }+  | pname == "persistent"       = deriv { extraLibs = Set.insert "sqlite3" extraLibs }+  | pname == "purescript"       = deriv { buildTools = Set.insert "nodejs" buildTools }+  | pname == "repa-algorithms"  = deriv { extraLibs = Set.insert "llvm" extraLibs }+  | pname == "repa-examples"    = deriv { extraLibs = Set.insert "llvm" extraLibs }+  | pname == "SDL-image"        = deriv { extraLibs = Set.insert "SDL_image" extraLibs }+  | pname == "SDL-mixer"        = deriv { extraLibs = Set.insert "SDL_mixer" extraLibs }+  | pname == "SDL-ttf"          = deriv { extraLibs = Set.insert "SDL_ttf" extraLibs }+  | pname == "sloane"           = deriv { phaseOverrides = sloanePostInstall }+  | pname == "structured-haskell-mode" = deriv { buildTools = Set.insert "emacs" buildTools+                                               , phaseOverrides = structuredHaskellModePostInstall+                                               }+  | pname == "target"           = deriv { buildTools = Set.insert "z3" buildTools }+  | pname == "threadscope"      = deriv { configureFlags = Set.insert "--ghc-options=-rtsopts" configureFlags }+  | pname == "vacuum"           = deriv { extraLibs = Set.insert "ghc-paths" extraLibs }+  | pname == "wxcore"           = deriv { extraLibs = Set.fromList ["wxGTK","mesa","libX11"] `Set.union` extraLibs }+  | pname == "X11-xft"          = deriv { extraLibs = Set.fromList ["pkgconfig","freetype","fontconfig"] `Set.union` extraLibs+                                        , configureFlags = Set.insert "--extra-include-dirs=${freetype}/include/freetype2" configureFlags+                                        }+-- Unbreak packages during hackage2nix generation:++  | pname == "hnetcdf"          = deriv { testDepends = Set.delete "netcdf" testDepends }+  | pname == "SDL2-ttf"         = deriv { buildDepends = Set.delete "SDL2" buildDepends }+  | pname == "hzk"              = deriv { testDepends = Set.delete "zookeeper_mt" testDepends, buildTools = Set.insert "zookeeper_mt" buildTools }+  | pname == "z3"               = deriv { phaseOverrides = "preBuild = stdenv.lib.optionalString stdenv.isDarwin \"export DYLD_LIBRARY_PATH=${z3}/lib\";" }+  | otherwise                   = deriv++ghcModPostInstall :: String -> Version -> String+ghcModPostInstall pname version = unlines+  [ "configureFlags = \"--datasubdir=" ++ pname ++ "-" ++ display version ++ "\";"+  , "postInstall = ''"+  , "  cd $out/share/" ++ pname ++ "-" ++ display version+  , "  make"+  , "  rm Makefile"+  , "  cd .."+  , "  ensureDir \"$out/share/emacs\""+  , "  mv " ++ pname ++ "-" ++ display version ++ " emacs/site-lisp"+  , "'';"+  ]++ghciPostInstall :: String+ghciPostInstall = unlines+  [ "postInstall = ''"+  , "  ensureDir \"$out/share/ghci\""+  , "  ln -s \"$out/share/$pname-$version/ghci\" \"$out/share/ghci/$pname\""+  , "'';"+  ]+++lhs2texPostInstall :: String+lhs2texPostInstall = unlines+  [ "postInstall = ''"+  , "  mkdir -p \"$out/share/doc/$name\""+  , "  cp doc/Guide2.pdf $out/share/doc/$name"+  , "  mkdir -p \"$out/nix-support\""+  , "'';"+  ]++ncursesPatchPhase :: String+ncursesPatchPhase = "patchPhase = \"find . -type f -exec sed -i -e 's|ncursesw/||' {} \\\\;\";"+++structuredHaskellModePostInstall :: String+structuredHaskellModePostInstall = unlines+  [ "postInstall = ''"+  , "  emacs -L elisp --batch -f batch-byte-compile \"elisp/\"*.el"+  , "  install -d $out/share/emacs/site-lisp"+  , "  install \"elisp/\"*.el \"elisp/\"*.elc  $out/share/emacs/site-lisp"+  , "'';"+  ]++sloanePostInstall :: String+sloanePostInstall = unlines+  [ "postInstall = ''"+  , "  mkdir -p $out/share/man/man1"+  , "  cp sloane.1 $out/share/man/man1/"+  , "'';"+  ]++ghcParserPatchPhase :: String+ghcParserPatchPhase = unlines+  [ "patchPhase = ''"+  , "  substituteInPlace build-parser.sh --replace \"/bin/bash\" \"$SHELL\""+  , "'';"+  ]++-}
+ src/Distribution/Nixpkgs/Haskell/Hackage.hs view
@@ -0,0 +1,29 @@+module Distribution.Nixpkgs.Haskell.Hackage ( readHashedHackage, module Distribution.Hackage.DB ) where++import Data.ByteString.Lazy ( ByteString )+import Data.Digest.Pure.SHA ( sha256, showDigest )+import Distribution.Hackage.DB+import qualified Distribution.Hackage.DB.Parsed as Unparsed ( parsePackage )+import qualified Distribution.Hackage.DB.Unparsed as Unparsed++-- | A variant of 'readHackage' that adds the SHA256 digest of the+-- original Cabal file to the parsed 'GenericPackageDescription'. That+-- hash is required to build packages with an "edited" cabal file,+-- because Nix needs to download the edited file and patch it into the+-- original tarball.++readHashedHackage :: IO Hackage+readHashedHackage = fmap parseUnparsedHackage Unparsed.readHackage+  where+    parseUnparsedHackage :: Unparsed.Hackage -> Hackage+    parseUnparsedHackage = mapWithKey (mapWithKey . parsePackage)++    parsePackage :: String -> Version -> ByteString -> GenericPackageDescription+    parsePackage name version buf =+      let pkg = Unparsed.parsePackage name version buf+          hash = showDigest (sha256 buf)+      in+       pkg { packageDescription = (packageDescription pkg) {+                customFieldsPD = ("X-Cabal-File-Hash", hash) : customFieldsPD (packageDescription pkg)+                }+           }
+ src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Distribution.Nixpkgs.Haskell.OrphanInstances ( ) where++import Control.DeepSeq+import Data.Maybe+import Data.String+import qualified Data.Text as T+import Data.Yaml+import Distribution.Compiler+import Distribution.License+import Distribution.ModuleName hiding ( main, fromString )+import Distribution.Package+import Distribution.PackageDescription+import Distribution.System+import Distribution.Text+import Distribution.Version+import Language.Haskell.Extension++#if !MIN_VERSION_Cabal(1,23,0)+import GHC.Generics ( Generic )+deriving instance Generic (CondTree v c a)+deriving instance Generic (Condition a)+deriving instance Generic ConfVar+deriving instance Generic Flag+deriving instance Generic GenericPackageDescription+#else+instance NFData SetupBuildInfo+#endif++instance (NFData v, NFData c, NFData a) => NFData (CondTree v c a)+instance NFData Arch+instance NFData Benchmark+instance NFData BenchmarkInterface+instance NFData BenchmarkType+instance NFData BuildInfo+instance NFData BuildType+instance NFData CompilerFlavor+instance NFData ConfVar+instance NFData Dependency+instance NFData Executable+instance NFData Extension+instance NFData Flag+instance NFData FlagName+instance NFData GenericPackageDescription+instance NFData KnownExtension+instance NFData Language+instance NFData Library+instance NFData License+instance NFData ModuleName+instance NFData ModuleReexport+instance NFData ModuleRenaming+instance NFData OS+instance NFData PackageDescription+instance NFData RepoKind+instance NFData RepoType+instance NFData SourceRepo+instance NFData TestSuite+instance NFData TestSuiteInterface+instance NFData TestType+instance NFData VersionRange+instance NFData a => NFData (Condition a)+instance NFData Platform+instance NFData CompilerInfo+instance NFData CompilerId+instance NFData AbiTag++instance IsString PackageName where+  fromString = text2isString "PackageName"++instance IsString Version where+  fromString = text2isString "Version"++instance IsString PackageIdentifier where+  fromString = text2isString "PackageIdentifier"++instance IsString Dependency where+  fromString = text2isString "Dependency"++instance IsString CompilerId where+  fromString = text2isString "CompilerId"++instance IsString Platform where+  fromString "i686-linux" = Platform I386 Linux+  fromString "x86_64-linux" = Platform X86_64 Linux+  fromString "x86_64-darwin" = Platform X86_64 OSX+  fromString s = error ("fromString: " ++ show s ++ " is not a valid platform")++instance FromJSON Platform where+  parseJSON (String s) = pure (fromString (T.unpack s))+  parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid platform")++instance FromJSON PackageName where+  parseJSON (String s) = return (fromString (T.unpack s))+  parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Haskell package name")++instance FromJSON PackageIdentifier where+  parseJSON (String s) = return (fromString (T.unpack s))+  parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Haskell package identifier")++instance FromJSON Dependency where+  parseJSON (String s) = return (fromString (T.unpack s))+  parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Haskell Dependency")++instance FromJSON CompilerInfo where+  parseJSON (String s) = return (unknownCompilerInfo (fromString (T.unpack s)) NoAbiTag)+  parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Haskell compiler")++-- parsing tools++text2isString :: Text a => String -> String -> a+text2isString t s = fromMaybe (error ("fromString: " ++ show s ++ " is not a valid " ++ t)) (simpleParse s)
+ src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs view
@@ -0,0 +1,157 @@+module Distribution.Nixpkgs.Haskell.PackageSourceSpec+  ( Package(..), getPackage, sourceFromHackage+  ) where++import qualified Control.Exception as Exception+import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.Trans.Maybe+import qualified Data.ByteString.Lazy.Char8 as BS8+import Data.Digest.Pure.SHA ( sha256, showDigest )+import Data.List ( isSuffixOf, isPrefixOf )+import Data.Maybe+import Data.Version+import Distribution.Hackage.DB.Parsed+import Distribution.Nixpkgs.Fetch+import qualified Distribution.Nixpkgs.Haskell.Hackage as DB+import qualified Distribution.Package as Cabal+import Distribution.PackageDescription+import qualified Distribution.PackageDescription as Cabal+import Distribution.Text ( simpleParse )+import System.Directory ( doesDirectoryExist, doesFileExist, createDirectoryIfMissing, getHomeDirectory, getDirectoryContents )+import System.Exit ( exitFailure )+import System.FilePath ( (</>), (<.>) )+import System.IO ( hPutStrLn, stderr, hPutStr )++data Package = Package+  { pkgSource :: DerivationSource+  , pkgCabal :: Cabal.GenericPackageDescription+  }+  deriving (Show)++getPackage :: Maybe String -> Source -> IO Package+getPackage optHackageDB source = do+  (derivSource, pkgDesc) <- fetchOrFromDB optHackageDB source+  flip Package pkgDesc <$> maybe (sourceFromHackage (sourceHash source) $ showPackageIdentifier pkgDesc) return derivSource+++fetchOrFromDB :: Maybe String -> Source -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)+fetchOrFromDB optHackageDB src+  | "cabal://" `isPrefixOf` sourceUrl src = fmap ((,) Nothing) . fromDB optHackageDB . drop (length "cabal://") $ sourceUrl src+  | otherwise                             = do+    r <- fetch cabalFromPath src+    case r of+      Nothing ->+        hPutStrLn stderr "*** failed to fetch source. Does the URL exist?" >> exitFailure+      Just (derivSource, (externalSource, pkgDesc)) ->+        return (derivSource <$ guard externalSource, pkgDesc)++fromDB :: Maybe String -> String -> IO Cabal.GenericPackageDescription+fromDB optHackageDB pkg = do+  pkgDesc <- (lookupVersion <=< DB.lookup name) <$> maybe DB.readHashedHackage DB.readHackage' optHackageDB+  case pkgDesc of+    Just r -> return r+    Nothing -> hPutStrLn stderr "*** no such package in the cabal database (did you run cabal update?). " >> exitFailure+ where+  pkgId = fromMaybe (error ("invalid Haskell package id " ++ show pkg)) (simpleParse pkg)+  Cabal.PackageName name = Cabal.pkgName pkgId+  version = Cabal.pkgVersion pkgId++  lookupVersion :: DB.Map DB.Version Cabal.GenericPackageDescription -> Maybe Cabal.GenericPackageDescription+  lookupVersion+    | null (versionBranch version) = fmap snd . listToMaybe . reverse . DB.toAscList+    | otherwise                    = DB.lookup version+++readFileMay :: String -> IO (Maybe String)+readFileMay file = do+  e <- doesFileExist file+  if e+    then Just <$> readFile file+    else return Nothing++hashCachePath :: String -> IO String+hashCachePath pid = do+  home <- getHomeDirectory+  let cacheDir = home </> ".cache/cabal2nix"+  createDirectoryIfMissing True cacheDir+  return $ cacheDir </> pid <.> "sha256"++sourceFromHackage :: Hash -> String -> IO DerivationSource+sourceFromHackage optHash pkgId = do+  cacheFile <- hashCachePath pkgId+  cachedHash <-+    case optHash of+      Certain h -> return . Certain $ h+      Guess   h -> return . Guess $ h+      _         -> fmap (maybe UnknownHash Certain) . readFileMay $ cacheFile+  let url = "mirror://hackage/" ++ pkgId ++ ".tar.gz"++  -- Use the cached hash (either from cache file or given on cmdline via sha256 opt)+  -- if available, otherwise download from hackage to compute hash.+  case cachedHash of+    Guess hash -> return $ DerivationSource "url" url "" hash+    Certain hash ->+      -- We need to force the hash here. If we didn't do this, then when reading the+      -- hash from the cache file, the cache file will still be open for reading+      -- (because lazy io) when writeFile opens the file again for writing. By forcing+      -- the hash here, we ensure that the file is closed before opening it again.+      seq (length hash) $+      DerivationSource "url" url "" hash <$ writeFile cacheFile hash+    UnknownHash -> do+      maybeHash <- runMaybeT (derivHash . fst <$> fetchWith (False, "url", []) (Source url "" UnknownHash))+      case maybeHash of+        Just hash ->+          seq (length hash) $+          DerivationSource "url" url "" hash <$ writeFile cacheFile hash+        Nothing -> do+          hPutStr stderr $ unlines+            [ "*** cannot compute hash. (Not a hackage project?)"+            , " If your project is not on hackage, please supply the path to the root directory of"+            , " the project, not to the cabal file."+            , ""+            , " If your project is on hackage but you still want to specify the hash manually, you"+            , " can use the --sha256 option."+            ]+          exitFailure++showPackageIdentifier :: Cabal.GenericPackageDescription -> String+showPackageIdentifier pkgDesc = name ++ "-" ++ showVersion version where+  pkgId = Cabal.package . Cabal.packageDescription $ pkgDesc+  Cabal.PackageName name = Cabal.packageName pkgId+  version = Cabal.packageVersion pkgId++cabalFromPath :: FilePath -> MaybeT IO (Bool, Cabal.GenericPackageDescription)+cabalFromPath path = do+  d <- liftIO $ doesDirectoryExist path+  (,) d <$> if d+    then cabalFromDirectory  path+    else cabalFromFile False path++cabalFromDirectory :: FilePath -> MaybeT IO Cabal.GenericPackageDescription+cabalFromDirectory dir = do+  cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)+  case cabals of+    [cabalFile] -> cabalFromFile True cabalFile+    _       -> liftIO $ hPutStrLn stderr "*** found zero or more than one cabal file. Exiting." >> exitFailure++handleIO :: (Exception.IOException -> IO a) -> IO a -> IO a+handleIO = Exception.handle++cabalFromFile :: Bool -> FilePath -> MaybeT IO Cabal.GenericPackageDescription+cabalFromFile failHard file =+  -- readFile throws an error if it's used on binary files which contain sequences+  -- that do not represent valid characters. To catch that exception, we need to+  -- wrap the whole block in `catchIO`, because of lazy IO. The `case` will force+  -- the reading of the file, so we will always catch the expression here.+  MaybeT $ handleIO (\err -> Nothing <$ hPutStrLn stderr ("*** parsing cabal file: " ++ show err)) $ do+    buf <- BS8.readFile file+    let hash = showDigest (sha256 buf)+    case parsePackage' buf of+      Left msg    -> if failHard+                     then fail ("*** cannot parse " ++ show file ++ ": " ++ msg)+                     else return Nothing+      Right pkg -> do return $ Just $ pkg { packageDescription = (packageDescription pkg) {+                                               customFieldsPD = ("X-Cabal-File-Hash", hash) : customFieldsPD (packageDescription pkg)+                                            }+                                          }
− src/cabal2nix.hs
@@ -1,109 +0,0 @@-module Main ( main ) where--import Cabal2Nix.Generate ( cabal2nix )-import Cabal2Nix.Normalize ( normalize )-import Cabal2Nix.Package-import Cabal2Nix.Version-import Distribution.NixOS.Derivation.Cabal hiding ( version )-import Distribution.NixOS.Fetch--import Control.Exception ( bracket )-import Control.Monad ( when )-import Distribution.Text ( disp )-import System.Console.GetOpt ( OptDescr(..), ArgDescr(..), ArgOrder(..), usageInfo, getOpt )-import System.Environment ( getArgs )-import System.Exit ( exitFailure, exitSuccess )-import System.IO ( hPutStrLn, hFlush, stdout, stderr )--data Configuration = Configuration-  { optPrintHelp :: Bool-  , optPrintVersion :: Bool-  , optSha256 :: Maybe String-  , optMaintainer :: [String]-  , optPlatform :: [String]-  , optHaddock :: Bool-  , optDoCheck :: Bool-  , optJailbreak :: Bool-  , optRevision :: String-  , optHyperlinkSource :: Bool-  , optHackageDb :: Maybe FilePath-  }-  deriving (Show)--defaultConfiguration :: Configuration-defaultConfiguration = Configuration-  { optPrintHelp = False-  , optPrintVersion = False-  , optSha256 = Nothing-  , optMaintainer = []-  , optPlatform = []-  , optHaddock = True-  , optDoCheck = True-  , optJailbreak = False-  , optRevision = ""-  , optHyperlinkSource = True-  , optHackageDb = Nothing-  }--options :: [OptDescr (Configuration -> Configuration)]-options =-  [ Option "h" ["help"]       (NoArg (\o -> o { optPrintHelp = True }))                                  "show this help text"-  , Option "v" ["version"]    (NoArg (\o -> o { optPrintVersion = True }))                               "print version"-  , Option ""  ["hackage-db"] (ReqArg (\x o -> o { optHackageDb = Just x }) "FILEPATH")                  "path to the local hackage db in tar format"-  , Option ""  ["sha256"]     (ReqArg (\x o -> o { optSha256 = Just x }) "HASH")                         "sha256 hash of source tarball"-  , Option "m" ["maintainer"] (ReqArg (\x o -> o { optMaintainer = x : optMaintainer o }) "MAINTAINER")  "maintainer of this package (may be specified multiple times)"-  , Option "p" ["platform"]   (ReqArg (\x o -> o { optPlatform = x : optPlatform o }) "PLATFORM")        "supported build platforms (may be specified multiple times)"-  , Option ""  ["jailbreak"]  (NoArg (\o -> o { optJailbreak = True }))                                  "don't honor version restrictions on build inputs"-  , Option ""  ["no-haddock"] (NoArg (\o -> o { optHaddock = False }))                                   "don't run Haddock when building this package"-  , Option ""  ["no-check"]   (NoArg (\o -> o { optDoCheck = False }))                                   "don't run regression test suites of this package"-  , Option ""  ["rev"]        (ReqArg (\x o -> o { optRevision = x }) "REVISION")                        "revision, only used when fetching from VCS"-  , Option ""  ["no-hyperlink-source"] (NoArg (\o -> o { optHyperlinkSource = False }))                  "don't add pretty-printed source code to the documentation"-  ]--usage :: String-usage = usageInfo "Usage: cabal2nix [options] URI" options ++ unlines-        [ ""-        , "Recognized URI schemes:"-        , ""-        , "  cabal://pkgname-pkgversion     download the specified package from Hackage"-        , "  cabal://pkgname                download latest version of the specified package from Hackage"-        , "  file:///local/path             load the Cabal file from the local disk"-        , "  /local/path                    abbreviated version of file URI"-        , "  <git/svn/bzr/hg URL>           download the source from the specified repository"-        , ""-        , "If the URI refers to a cabal file, information for building the package will be retrieved from that file, but "-        , "hackage will be used as a source for the derivation."-        , "Otherwise, the supplied URI will be used to as the source for the derivation and the information is taken"-        , "from the cabal file at the root of the downloaded source."-        ]--cmdlineError :: String -> IO a-cmdlineError ""     = hPutStrLn stderr usage >> exitFailure-cmdlineError errMsg = hPutStrLn stderr errMsg >> cmdlineError ""--main :: IO ()-main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do-  args' <- getArgs-  (cfg,args) <- case getOpt Permute options args' of-                  (o,n,[]  ) -> return (foldl (flip ($)) defaultConfiguration o,n)-                  (_,_,errs) -> cmdlineError (concatMap ("*** "++) errs)--  when (optPrintHelp cfg) (putStr usage >> exitSuccess)-  when (optPrintVersion cfg) (putStrLn version >> exitSuccess)-  when (length args /= 1) (cmdlineError "*** exactly one url-to-cabal-file must be specified\n")--  pkg <- getPackage (optHackageDb cfg) $ Source (head args) (optRevision cfg) (optSha256 cfg)--  let deriv  = (cabal2nix $ cabal pkg) { src = source pkg-                                       , runHaddock = optHaddock cfg-                                       , jailbreak = optJailbreak cfg-                                       , hyperlinkSource = optHyperlinkSource cfg-                                       }-      deriv' = deriv { metaSection = (metaSection deriv)-                                     { maintainers = optMaintainer cfg-                                     , platforms   = optPlatform cfg-                                     }-                     , doCheck = doCheck deriv && optDoCheck cfg-                     }--  putStr (show (disp (normalize deriv')))
− src/hackage4nix.hs
@@ -1,260 +0,0 @@-module Main ( main ) where--import Cabal2Nix.Generate-import Cabal2Nix.Normalize-import Control.Exception ( bracket )-import Control.Monad.RWS-import Data.List-import qualified Data.Set as Set-import Data.Version-import qualified Distribution.Hackage.DB as DB-import Distribution.NixOS.Derivation.Cabal-import Distribution.Package-import Distribution.PackageDescription ( GenericPackageDescription() )-import Distribution.Text-import System.Console.GetOpt ( OptDescr(..), ArgDescr(..), ArgOrder(..), usageInfo, getOpt )-import System.Directory-import System.Environment-import System.Exit-import System.FilePath-import System.IO-import Text.Regex.Posix--data Pkg = Pkg Derivation FilePath Bool-  deriving (Show, Eq, Ord)--type PkgSet = Set.Set Pkg--data Configuration = Configuration-  { _msgDebug  :: String -> IO ()-  , _msgInfo   :: String -> IO ()-  , _hackageDb :: DB.Hackage-  , _force     :: Bool-  }--defaultConfiguration :: Configuration-defaultConfiguration = Configuration-  { _msgDebug  = hPutStrLn stderr-  , _msgInfo   = hPutStrLn stderr-  , _hackageDb = DB.empty-  , _force     = False-  }--type Hackage4Nix a = RWST Configuration () PkgSet IO a--io :: (MonadIO m) => IO a -> m a-io = liftIO--readDirectory :: FilePath -> IO [FilePath]-readDirectory dirpath = do-  entries <- getDirectoryContents dirpath-  return [ x | x <- entries, x /= ".", x /= ".." ]--msgDebug, msgInfo :: String -> Hackage4Nix ()-msgDebug msg = ask >>= \s -> io (_msgDebug s msg)-msgInfo msg = ask >>= \s -> io (_msgInfo s msg)--getCabalPackage :: String -> Version -> Hackage4Nix GenericPackageDescription-getCabalPackage name vers = do-  db <- asks _hackageDb-  case DB.lookup name db of-    Just db' -> case DB.lookup vers db' of-                  Just pkg -> return pkg-                  Nothing  -> fail ("hackage doesn't know about " ++ name ++ " version " ++ display vers)-    Nothing  -> fail ("hackage doesn't know about " ++ show name)--discoverNixFiles :: (FilePath -> Hackage4Nix ()) -> FilePath -> Hackage4Nix ()-discoverNixFiles yield dirOrFile = do-  isFile <- io (doesFileExist dirOrFile)-  case (isFile, takeExtension dirOrFile) of-    (True,".nix") -> yield dirOrFile-    (True,_)     -> return ()-    (False,_)    -> io (readDirectory dirOrFile) >>= mapM_ (discoverNixFiles yield . (dirOrFile </>))--regenerateDerivation :: Derivation -> String -> Bool-regenerateDerivation _ buf = not (buf =~ "(pre|post)Configure|(pre|post)Install|patchPhase|patches|broken|editedCabalFile")--parseNixFile :: FilePath -> String -> Hackage4Nix (Maybe Pkg)-parseNixFile path buf-  | not (buf =~ "cabal.mkDerivation")-               = msgDebug ("ignore non-cabal package " ++ path) >> return Nothing-  | any (`isSuffixOf`path) badPackagePaths-               = msgDebug ("ignore known bad package " ++ path) >> return Nothing-  | Just deriv <- parseDerivation buf-               = do forceReGen <- asks _force-                    let reGen = regenerateDerivation deriv buf-                    return (Just (Pkg deriv path (forceReGen || reGen)))-  | otherwise = msgInfo ("failed to parse file " ++ path) >> return Nothing--selectLatestVersions :: PkgSet -> PkgSet-selectLatestVersions = Set.fromList . nubBy f2 . sortBy f1 . Set.toList-  where-    f1 (Pkg deriv1 _ _) (Pkg deriv2 _ _)-      | pname deriv1 == pname deriv2     = compare (version deriv2) (version deriv1)-      | otherwise                        = compare (pname deriv1) (pname deriv2)-    f2 (Pkg deriv1 _ _) (Pkg deriv2 _ _) = pname deriv1 == pname deriv2--discoverUpdates :: String -> Version -> Hackage4Nix [Version]-discoverUpdates name vers = do-  db <- asks _hackageDb-  case DB.lookup name db of-    Just pkgs -> return (filter (>vers) (DB.keys pkgs))-    Nothing   -> fail ("discoverUpdates cannot find package " ++ show name ++ " on Hackage")--updateNixPkgs :: [FilePath] -> Hackage4Nix ()-updateNixPkgs paths = do-  -- Traverse the given directorcy structure and discover all available-  -- Haskell packages.-  forM_ paths $ \fileOrDir -> do-    msgDebug $ "scanning " ++ show fileOrDir-    flip discoverNixFiles fileOrDir $ \file -> do-      nix' <- io (readFile file) >>= parseNixFile file-      flip (maybe (return ())) nix' $ \nix ->-        modify (Set.insert nix)--  -- Re-generate all Haskell packages in-place (unless-  -- 'regenerateDerivation' decided that this particular package-  -- shouldn't be touched.-  latestVersions <- gets selectLatestVersions-  let latestVersionMap :: [(String,Version)]-      latestVersionMap = [ (pname deriv, version deriv) | Pkg deriv _ _ <- Set.toList latestVersions ]-  let isLatest :: Derivation -> Bool-      isLatest deriv = maybe False (version deriv ==) (lookup (pname deriv) latestVersionMap)-  get >>= \pkgset -> forM_ (Set.toList pkgset) $ \nix -> do-    let Pkg deriv path regenerate = nix-        maints = maintainers (metaSection deriv)-        plats  = platforms (metaSection deriv)-        hplats = if isLatest deriv then hydraPlatforms (metaSection deriv) else ["self.stdenv.lib.platforms.none"]--    when regenerate $ do-      msgDebug ("re-generate " ++ path)-      pkg <- getCabalPackage (pname deriv) (version deriv)-      let deriv'  = (cabal2nix pkg) { src = src deriv-                                    , runHaddock = runHaddock deriv-                                    , doCheck = doCheck deriv-                                    , jailbreak = jailbreak deriv-                                    , hyperlinkSource = hyperlinkSource deriv-                                    , enableSplitObjs = enableSplitObjs deriv-                                    }-          meta    = metaSection deriv'-          plats'  = if null plats then platforms meta else plats-          deriv'' = deriv' { metaSection = meta-                                           { maintainers    = maints-                                           , platforms      = plats'-                                           , hydraPlatforms = hplats-                                           }-                           }-      io $ writeFile path (show (disp (normalize deriv'')))--  -- Discover available updates and print the appropriate cabal2nix-  -- command line to the console for the user to execute at his/her-  -- discretion.-  updates' <- forM (Set.elems latestVersions) $ \pkg -> do-    let Pkg deriv _ _ = pkg-    updates <- discoverUpdates (pname deriv) (version deriv)-    return (pkg,updates)-  let updates = [ u | u@(_,_:_) <- updates' ]-  unless (null updates) $ do-    msgInfo "The following updates are available:"-    forM_ updates $ \(pkg,versions) -> do-      let Pkg deriv path regenerate = pkg-      msgInfo ""-      msgInfo $ display (packageId deriv) ++ ":"-      forM_ versions $ \newVersion -> do-        let deriv' = deriv { version = newVersion }-        msgInfo $ "  " ++ genCabal2NixCmdline (Pkg deriv' path regenerate)-  return ()--genCabal2NixCmdline :: Pkg -> String-genCabal2NixCmdline (Pkg deriv path _) = unwords $ ["cabal2nix"] ++ opts ++ ['>':path']-  where-    meta = metaSection deriv-    opts = [cabal] ++ maints' ++ plats' ++ hplats'-                   ++ (if jailbreak deriv then ["--jailbreak"] else [])-                   ++ (if runHaddock deriv then [] else ["--no-haddock"])-                   ++ (if doCheck deriv then [] else ["--no-check"])-    cabal = "cabal://" ++ display (packageId deriv)-    maints' = [ "--maintainer=" ++ normalizeMaintainer m | m <- maintainers meta ]-    plats'-      | ["self.ghc.meta.platforms"] == platforms meta = []-      | otherwise                                     = [ "--platform=" ++ p | p <- platforms meta ]-    hplats'-      | ["self.ghc.meta.platforms"] == platforms meta = []-      | otherwise                                     = [ "--hydra-platform=" ++ p | p <- hydraPlatforms meta ]-    path'-      | path =~ "/[0-9\\.]+\\.nix$" = replaceFileName path (display (version deriv) <.> "nix")-      | otherwise                   = path--normalizeMaintainer :: String -> String-normalizeMaintainer x-  | "self.stdenv.lib.maintainers." `isPrefixOf` x = drop 28 x-  | otherwise                                     = x--data CliOption = PrintHelp | Verbose | ForceRegen-  deriving (Eq)--main :: IO ()-main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do-  let options :: [OptDescr CliOption]-      options =-        [ Option "h" ["help"]     (NoArg PrintHelp)                 "show this help text"-        , Option "v" ["verbose"]  (NoArg Verbose)                   "enable noisy debug output"-        , Option ""  ["force"]    (NoArg ForceRegen)                "re-generate all files in place"-        ]--      usage :: String-      usage = usageInfo "Usage: hackage4nix [options] [dir-or-file ...]" options ++ unlines-              [ ""-              , "The purpose of 'hackage4nix' is to keep all Haskell packages in our"-              , "repository packages up-to-date. It scans a checked-out copy of"-              , "Nixpkgs for expressions that use 'cabal.mkDerivation', and"-              , "re-generates them in-place with cabal2nix."-              ]--      cmdlineError :: String -> IO a-      cmdlineError ""     = hPutStrLn stderr usage >> exitFailure-      cmdlineError errMsg = hPutStrLn stderr errMsg >> cmdlineError ""--  args' <- getArgs-  (opts,args) <- case getOpt Permute options args' of-     (o,n,[]  ) -> return (o,n)-     (_,_,errs) -> cmdlineError (concatMap (\e -> '*':'*':'*':' ':e) errs)--  when (PrintHelp `elem` opts) (cmdlineError "")--  hackage <- DB.readHackage-  let cfg = defaultConfiguration-            { _msgDebug  = if Verbose `elem` opts then _msgDebug defaultConfiguration else const (return ())-            , _hackageDb = hackage-            , _force     = ForceRegen `elem` opts-            }-  ((),_,()) <- runRWST (updateNixPkgs args) cfg Set.empty-  return ()----- Packages that cabal2nix cannot generate build expressions for.--badPackagePaths :: [FilePath]-badPackagePaths = [ -- These expression are not found on Hackage:-                    "haskell-platform/2009.2.0.2.nix", "haskell-platform/2010.1.0.0.nix"-                  , "haskell-platform/2010.2.0.0.nix", "haskell-platform/2011.2.0.0.nix"-                  , "haskell-platform/2011.2.0.1.nix", "haskell-platform/2011.4.0.0.nix"-                  , "haskell-platform/2012.2.0.0.nix", "haskell-platform/2012.4.0.0.nix"-                  , "haskell-platform/2013.2.0.0.nix", "compilers/flapjax/default.nix"-                  , "pkgs/games/uqm/3dovideo.nix",     "haskell/ghcjs-prim/default.nix"-                  , "system/journal-mailer/default.nix", "development/compilers/ghcjs/default.nix"-                    -- Our primitive parser cannot handle these files.-                  , "top-level/all-packages.nix", "top-level/haskell-packages.nix"-                    -- This build is way too complicated to maintain it automatically.-                  , "pkgs/development/compilers/pakcs/default.nix"-                  , "pkgs/development/libraries/haskell/hoogle/local.nix"-                    -- Not registered on Hackage.-                  , "pkgs/development/compilers/agda/stdlib.nix"-                  , "pkgs/development/compilers/cryptol/1.8.x.nix"-                  , "pkgs/development/compilers/cryptol/2.0.x.nix"-                  , "pkgs/development/compilers/jhc/default.nix"-                  , "pkgs/development/tools/haskell/cabal-delete/default.nix"-                  , "pkgs/tools/networking/sproxy-web/default.nix"-                  , "pkgs/tools/networking/sproxy/default.nix"-                  , "pkgs/applications/editors/yi/yi-custom.nix"-                  ]
− test/doc-test.hs
@@ -1,37 +0,0 @@-{--   Module      :  Main-   Copyright   :  (c) 2013 Peter Simons-   License     :  BSD3--   Maintainer  :  simons@cryp.to-   Stability   :  provisional-   Portability :  portable--   Cabal2nix doctest suite.--}--module Main ( main ) where--import Test.DocTest--main :: IO ()-main = do-  let libs = [ "dist/build/autogen/Paths_cabal2nix.hs"-             , "src/Cabal2Nix/License.hs"-             , "src/Cabal2Nix/CorePackages.hs"-             , "src/Cabal2Nix/Flags.hs"-             , "src/Cabal2Nix/Generate.hs"-             , "src/Cabal2Nix/Name.hs"-             , "src/Cabal2Nix/Normalize.hs"-             , "src/Cabal2Nix/Package.hs"-             , "src/Cabal2Nix/PostProcess.hs"-             , "src/Cabal2Nix/Version.hs"-             , "src/Distribution/NixOS/Derivation/Cabal.hs"-             , "src/Distribution/NixOS/Derivation/License.hs"-             , "src/Distribution/NixOS/Derivation/Meta.hs"-             , "src/Distribution/NixOS/Fetch.hs"-             , "src/Distribution/NixOS/PrettyPrinting.hs"-             , "src/Distribution/NixOS/Regex.hs"-             ]-  doctest $ "src/cabal2nix.hs" : libs-  doctest $ "src/hackage4nix.hs" : libs