git.iko.soy/typeable/cabal2nix
on 8810b21 help sign in
124 lines 5.0 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 cabal2nix <- findExecutable "cabal2nix" >>= maybe (fail "cannot find 'cabal2nix' in $PATH") return
33 testCases <- listDirectoryFilesBySuffix ".cabal" "test/golden-test-cases"
34 defaultMain $ testGroup "regression-tests"
35 [ testGroup "cabal2nix library" (map testLibrary testCases)
36 , testGroup "cabal2nix executable" (map (testExecutable cabal2nix) testCases)
37 ]
39testLibrary :: String -> TestTree
40testLibrary cabalFile = do
41 let nixFile = cabalFile `replaceExtension` "nix"
42 goldenFile = nixFile `addExtension` "golden"
44 cabal2nix :: GenericPackageDescription -> Derivation
45 cabal2nix gpd = fromGenericPackageDescription
46 (const True)
47 (\i -> Just (binding # (i, path # [i])))
48 (Platform X86_64 Linux)
49 (unknownCompilerInfo (CompilerId GHC (mkVersion [8,2])) NoAbiTag)
50 (configureCabalFlags (packageId gpd))
51 []
52 gpd
53 & src .~ DerivationSource
54 { derivKind = "url"
55 , derivUrl = "mirror://hackage/foo.tar.gz"
56 , derivRevision = ""
57 , derivHash = "deadbeef"
58 }
59 & extraFunctionArgs %~ Set.union (Set.singleton "inherit stdenv")
60 goldenVsFileDiff
61 nixFile
62 (\ref new -> ["diff", "-u", ref, new])
63 goldenFile
64 nixFile
65 (readGenericPackageDescription silent cabalFile >>= writeFileLn nixFile . prettyShow . cabal2nix)
67-- | TODO:
68--
69-- * Run cabal2nix in an empty environment. Currently, this fails because the
70-- tool uses $HOME to write cache files for SHA256 hashes. To fix this, use
71-- of the cache directory ought to be optional. Arguably, the whole notion
72-- of caching those hashes is a bit silly in the presense of format 01
73-- cabal-install tarballs which contain them already.
74--
75-- * If we cannot get along without $HOME, then we should at least set it to
76-- some temporary location that is empty.
77--
78-- * Run this test with different kinds of encodings.
81testExecutable :: FilePath -> FilePath -> TestTree
82testExecutable exe cabalFile = do
83 let nixFile = cabalFile `replaceExtension` "nix"
84 goldenFile = nixFile `addExtension` "golden"
85 goldenVsFileDiff
86 nixFile
87 (\ref new -> ["diff", "-u", ref, new])
88 goldenFile
89 nixFile
90 (callCommand (unwords ["env LANG=en_US.UTF-8", exe, "--sha256=deadbeef", "--compiler=ghc-8.2", "--", cabalFile, ">"++nixFile]))
92-------------------------------------------------------------------------------
93-- * Helper functions
94-------------------------------------------------------------------------------
96-- | Find all *files* in the given directory. This function does not recurse,
97-- nor does it include the special entries @'.'@ or @'..'@ in the result.
99listDirectoryFiles :: FilePath -> IO [FilePath]
100listDirectoryFiles dirPath = do
101 entries <- listDirectory dirPath
102 filterM doesFileExist (map (dirPath </>) entries)
104-- | Find all *files* in the given directory that end with the given suffix.
105-- This function does not recurse, nor does it include the special entries
106-- @'.'@ or @'..'@ in the result.
107--
108-- "Test.Tasty.Golden" offers 'findByExtension', which does something similar
109-- (and arguably more general) as those two functions, but unfortunately that
110-- function recurses through the directory hierarchy and in the process needs
111-- plenty of stack space. There might be a space leak in that code, I am not
112-- sure. Anyhow, since our test suite is supposed to run with 1K stack space,
113-- we prefer our own simpler code.
115listDirectoryFilesBySuffix :: String -> FilePath -> IO [FilePath]
116listDirectoryFilesBySuffix suff =
117 fmap (filter ((suff ==) . takeExtension)) . listDirectoryFiles
120-- | A variant of 'writeFile' that appends a newline to the end of the buffer
121-- before writing.
123writeFileLn :: FilePath -> String -> IO ()
124writeFileLn p buf = writeFile p (buf ++ "\n")