git.iko.soy/typeable/cabal2nix
on v2.15.1 help sign in
122 lines 5.2 kB history raw
1{-# LANGUAGE OverloadedStrings #-}
3module Main ( main ) where
5import Distribution.Nixpkgs.Fetch
6import Distribution.Nixpkgs.Haskell.Derivation
7import Distribution.Nixpkgs.Haskell.FromCabal
8import Distribution.Nixpkgs.Haskell.FromCabal.Flags
10import Control.Lens
11import Control.Monad
12import qualified Data.Set as Set
13import Distribution.Compiler
14import Distribution.Package
15import Distribution.PackageDescription
16import Distribution.PackageDescription.Parsec
17import Distribution.System
18import Distribution.Verbosity
19import Distribution.Version
20import Language.Nix
21import System.Directory
22import System.FilePath
23import System.Process
24import Test.Tasty
25import Test.Tasty.Golden
26import Text.PrettyPrint.HughesPJClass
28main :: IO ()
29main = do
30 -- TODO: Run this test with all kinds of setLocaleEncoding values to ensure we don't
31 -- depend on the system environment: https://github.com/NixOS/cabal2nix/issues/333.
32 --
33 -- TODO: Run this test without $HOME defined to ensure that we don't need that variable.
34 cabal2nix <- findExecutable "cabal2nix" >>= maybe (fail "cannot find 'cabal2nix' in $PATH") return
35 testCases <- listDirectoryFilesBySuffix ".cabal" "test/golden-test-cases"
36 defaultMain $ testGroup "regression-tests"
37 [ testGroup "cabal2nix library" (map testLibrary testCases)
38 , testGroup "cabal2nix executable" (map (testExecutable cabal2nix) testCases)
39 ]
41testLibrary :: String -> TestTree
42testLibrary cabalFile = do
43 let nixFile = cabalFile `replaceExtension` "nix"
44 goldenFile = nixFile `addExtension` "golden"
46 cabal2nix :: GenericPackageDescription -> Derivation
47 cabal2nix gpd = fromGenericPackageDescription
48 (const True)
49 (\i -> Just (binding # (i, path # [ident # "pkgs", i])))
50 (Platform X86_64 Linux)
51 (unknownCompilerInfo (CompilerId GHC (mkVersion [8,2])) NoAbiTag)
52 (configureCabalFlags (packageId gpd))
53 []
54 gpd
55 & src .~ DerivationSource
56 { derivKind = "url"
57 , derivUrl = "mirror://hackage/foo.tar.gz"
58 , derivRevision = ""
59 , derivHash = "deadbeef"
60 , derivSubmodule = Nothing
61 }
62 & extraFunctionArgs %~ Set.union (Set.singleton "inherit stdenv")
63 goldenVsFileDiff
64 nixFile
65 (\ref new -> ["diff", "-u", ref, new])
66 goldenFile
67 nixFile
68 (readGenericPackageDescription silent cabalFile >>= writeFileLn nixFile . prettyShow . cabal2nix)
70-- | TODO:
71--
72-- * Run cabal2nix in an empty environment. Currently, this fails because the
73-- tool uses $HOME to write cache files for SHA256 hashes. To fix this, use
74-- of the cache directory ought to be optional. Arguably, the whole notion
75-- of caching those hashes is a bit silly in the presence of format 01
76-- cabal-install tarballs which contain them already.
77--
78-- * If we cannot get along without $HOME, then we should at least set it to
79-- some temporary location that is empty.
80--
81-- * Run this test with different kinds of encodings.
82--
83-- * Run tests with a different target OS, like Darwin. The packages "iconv",
84-- "crypt-sha512", "gl" might be worthwhile for testing since their output
85-- differs on Darwin.
87testExecutable :: FilePath -> FilePath -> TestTree
88testExecutable exe cabalFile = do
89 let nixFile = cabalFile `replaceExtension` "nix"
90 goldenFile = nixFile `addExtension` "golden"
91 goldenVsFileDiff
92 nixFile
93 (\ref new -> ["diff", "-u", ref, new])
94 goldenFile
95 nixFile
96 (callCommand (unwords ["env LANG=en_US.UTF-8", exe, "--sha256=deadbeef", "--system=x86_64-linux", "--compiler=ghc-8.2", "--", cabalFile, ">"++nixFile]))
98-------------------------------------------------------------------------------
99-- * Helper functions
100-------------------------------------------------------------------------------
102-- | Find all *files* in the given directory that end with the given suffix.
103-- This function does not recurse, nor does it include the special entries
104-- @'.'@ or @'..'@ in the result.
105--
106-- "Test.Tasty.Golden" offers 'findByExtension', which does something similar
107-- (and arguably more general) as those two functions, but unfortunately that
108-- function recurses through the directory hierarchy and in the process needs
109-- plenty of stack space. There might be a space leak in that code, I am not
110-- sure. Anyhow, since our test suite is supposed to run with 1K stack space,
111-- we prefer our own simpler code.
113listDirectoryFilesBySuffix :: String -> FilePath -> IO [FilePath]
114listDirectoryFilesBySuffix suff dirPath = do
115 entries <- listDirectory dirPath
116 filterM doesFileExist [ dirPath </> e | e <- entries, takeExtension e == suff ]
118-- | A variant of 'writeFile' that appends a newline to the end of the buffer
119-- before writing.
121writeFileLn :: FilePath -> String -> IO ()
122writeFileLn p buf = writeFile p (buf ++ "\n")