Build against GHC 7.10.3 (#621)

... as requested by @jneira so that Dhall will continue to work as a
dependency of Eta, which is built using GHC 7.10.3

This adds CI support for testing the build against GHC 7.10.3 and also
fixes issues building against that GHC version that were caught in the process
This commit is contained in:
Gabriel Gonzalez 2018-10-05 20:51:18 -07:00 committed by GitHub
parent fedfa8e41e
commit f3a372c99a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 291 additions and 93 deletions

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
@ -5,6 +6,7 @@ module Main where
import Control.Monad (forM)
import Criterion.Main (defaultMain, bgroup, bench, whnf, nfIO)
import Data.Map (Map, foldrWithKey, singleton, unions)
import Data.Monoid ((<>))
import System.Directory
@ -16,6 +18,23 @@ import qualified Data.Text.IO as TIO
import qualified Dhall.Binary
import qualified Dhall.Parser as Dhall
#if MIN_VERSION_directory(1,2,3)
#else
import Control.Exception (bracket)
withCurrentDirectory :: FilePath -- ^ Directory to execute in
-> IO a -- ^ Action to be executed
-> IO a
withCurrentDirectory dir action =
bracket getCurrentDirectory setCurrentDirectory $ \ _ -> do
setCurrentDirectory dir
action
listDirectory :: FilePath -> IO [FilePath]
listDirectory path = filter f <$> getDirectoryContents path
where f filename = filename /= "." && filename /= ".."
#endif
type PreludeFiles = Map FilePath T.Text
loadPreludeFiles :: IO PreludeFiles

View File

@ -1,3 +1,5 @@
{ compiler ? "ghc843" }:
let
fetchNixpkgs = import ./nix/fetchNixpkgs.nix;
@ -20,56 +22,71 @@ let
in
pkgsNew.callPackage (import ./nix/dhall-sdist.nix src) { };
haskellPackages = pkgsOld.haskellPackages.override (old: {
overrides =
let
extension =
haskellPackagesNew: haskellPackagesOld: {
dhall =
pkgsNew.haskell.lib.overrideCabal
(pkgsNew.haskell.lib.doCoverage
(pkgsNew.haskell.lib.failOnAllWarnings
(haskellPackagesNew.callCabal2nix
"dhall"
pkgsNew.dhall-sdist
{ }
haskell = pkgsOld.haskell // {
packages = pkgsOld.haskell.packages // {
"${compiler}" = pkgsOld.haskell.packages."${compiler}".override (old: {
overrides =
let
failOnAllWarnings = drv:
# GHC 7.10.3 incorrectly detects non-exhaustive pattern
# matches
if compiler == "ghc7103"
then drv
else pkgsNew.haskell.lib.failOnAllWarnings drv;
extension =
haskellPackagesNew: haskellPackagesOld: {
dhall =
pkgsNew.haskell.lib.overrideCabal
(pkgsNew.haskell.lib.doCoverage
(failOnAllWarnings
(haskellPackagesNew.callCabal2nix
"dhall"
pkgsNew.dhall-sdist
{ }
)
)
)
)
)
(old: {
postInstall = (old.postInstall or "") + ''
${pkgsNew.coreutils}/bin/mkdir --parents $out/nix-support
${pkgsNew.coreutils}/bin/ln --symbolic $out/share/hpc/vanilla/html/dhall-* "$out/share/hpc/vanilla/html/dhall"
${pkgsNew.coreutils}/bin/echo "report coverage $out/share/hpc/vanilla/html/dhall/hpc_index.html" >> $out/nix-support/hydra-build-products
'';
}
);
(old: {
postInstall = (old.postInstall or "") + ''
${pkgsNew.coreutils}/bin/mkdir --parents $out/nix-support
${pkgsNew.coreutils}/bin/ln --symbolic $out/share/hpc/vanilla/html/dhall-* "$out/share/hpc/vanilla/html/dhall"
${pkgsNew.coreutils}/bin/echo "report coverage $out/share/hpc/vanilla/html/dhall/hpc_index.html" >> $out/nix-support/hydra-build-products
'';
}
);
prettyprinter =
pkgsNew.haskell.lib.dontCheck haskellPackagesOld.prettyprinter;
# https://github.com/well-typed/cborg/issues/172
serialise =
pkgsNew.haskell.lib.dontCheck
haskellPackagesOld.serialise;
serialise =
pkgsNew.haskell.lib.dontCheck haskellPackagesOld.serialise;
};
prettyprinter =
pkgsNew.haskell.lib.dontCheck
haskellPackagesOld.prettyprinter;
};
in
pkgsNew.lib.fold
pkgsNew.lib.composeExtensions
(old.overrides or (_: _: {}))
[ (pkgsNew.haskell.lib.packagesFromDirectory { directory = ./nix; })
in
pkgsNew.lib.fold
pkgsNew.lib.composeExtensions
(old.overrides or (_: _: {}))
[ (pkgsNew.haskell.lib.packagesFromDirectory { directory = ./nix; })
extension
];
}
);
extension
];
}
);
};
};
};
overlayDynamic = pkgsNew: pkgsOld: {
overlayCabal2nix = pkgsNew: pkgsOld: {
haskellPackages = pkgsOld.haskellPackages.override (old: {
overrides =
let
extension =
haskellPackagesNew: haskellPackagesOld: {
# `cabal2nix` requires a newer version of `hpack`
hpack =
haskellPackagesOld.hpack_0_29_6;
};
@ -82,6 +99,79 @@ let
);
};
overlayGHC7103 = pkgsNew: pkgsOld: {
haskell = pkgsOld.haskell // {
packages = pkgsOld.haskell.packages // {
"${compiler}" = pkgsOld.haskell.packages."${compiler}".override (old: {
overrides =
let
extension =
haskellPackagesNew: haskellPackagesOld: {
# Most of these fixes are due to certain dependencies being
# hidden behind a conditional compiler version directive, so
# they aren't included by default in the default Hackage
# package set (which was generated for `ghc-8.4.3`)
base-compat-batteries =
pkgsNew.haskell.lib.addBuildDepends
haskellPackagesOld.base-compat-batteries
[ haskellPackagesNew.bifunctors
haskellPackagesNew.fail
];
cborg =
pkgsNew.haskell.lib.addBuildDepends
haskellPackagesOld.cborg
[ haskellPackagesNew.fail
haskellPackagesNew.semigroups
];
dhall =
pkgsNew.haskell.lib.addBuildDepends
haskellPackagesOld.dhall
[ haskellPackagesNew.doctest
haskellPackagesNew.mockery
];
megaparsec =
pkgsNew.haskell.lib.addBuildDepend
haskellPackagesOld.megaparsec
haskellPackagesNew.fail;
generic-deriving =
pkgsNew.haskell.lib.dontCheck
haskellPackagesOld.generic-deriving;
prettyprinter =
pkgsNew.haskell.lib.addBuildDepend
haskellPackagesOld.prettyprinter
haskellPackagesNew.semigroups;
transformers-compat =
pkgsNew.haskell.lib.addBuildDepend
haskellPackagesOld.transformers-compat
haskellPackagesNew.generic-deriving;
# For some reason, `Cabal-1.22.5` does not respect the
# `buildable: False` directive for the executable section
# even when configured with `-f -cli`. Fixing this requires
# patching out the executable section of `wcwidth` in order
# to avoid pulling in some extra dependencies which cause a
# a dependency cycle.
wcwidth =
pkgsNew.haskell.lib.appendPatch
haskellPackagesOld.wcwidth ./nix/wcwidth.patch;
};
in
pkgsNew.lib.composeExtensions
(old.overrides or (_: _: {}))
extension;
}
);
};
};
};
nixpkgs = fetchNixpkgs {
rev = "1d4de0d552ae9aa66a5b8dee5fb0650a4372d148";
@ -92,7 +182,9 @@ let
pkgs = import nixpkgs {
config = {};
overlays = [ overlayShared overlayDynamic ];
overlays =
[ overlayShared overlayCabal2nix ]
++ (if compiler == "ghc7103" then [ overlayGHC7103 ] else []);
};
overlayStaticLinux = pkgsNew: pkgsOld: {
@ -115,12 +207,12 @@ let
useFixedCabal = drv: pkgsNew.haskell.lib.overrideCabal drv (old: {
setupHaskellDepends =
(old.setupHaskellDepends or []) ++ [
pkgsNew.haskellPackages.Cabal_patched
pkgsNew.haskell.packages."${compiler}".Cabal_patched
];
libraryHaskellDepends =
(old.libraryHaskellDepends or []) ++ [
pkgsNew.haskellPackages.Cabal_patched
pkgsNew.haskell.packages."${compiler}".Cabal_patched
];
}
);
@ -140,28 +232,30 @@ let
"--extra-lib-dirs=${pkgsNew.ncurses.override { enableStatic = true; }}/lib"
];
};
packages = pkgsOld.haskell.packages // {
"${compiler}" = pkgsOld.haskell.packages."${compiler}".override (old: {
overrides =
let
extension =
haskellPackagesNew: haskellPackagesOld: {
Cabal_patched =
haskellPackagesNew.callCabal2nix
"Cabal"
pkgsNew.Cabal_patched_Cabal_subdir
{ };
dhall = pkgsNew.haskell.lib.statify haskellPackagesOld.dhall;
};
in
pkgsNew.lib.composeExtensions
(old.overrides or (_: _: {}))
extension;
}
);
};
};
haskellPackages = pkgsOld.haskellPackages.override (old: {
overrides =
let
extension =
haskellPackagesNew: haskellPackagesOld: {
Cabal_patched =
pkgsNew.haskellPackages.callCabal2nix
"Cabal"
pkgsNew.Cabal_patched_Cabal_subdir
{ };
dhall = pkgsNew.haskell.lib.statify haskellPackagesOld.dhall;
};
in
pkgsNew.lib.composeExtensions
(old.overrides or (_: _: {}))
extension;
}
);
};
nixpkgsStaticLinux = fetchNixpkgs {
@ -190,7 +284,7 @@ in
tarball =
pkgsStaticLinux.releaseTools.binaryTarball rec {
src = pkgsStaticLinux.pkgsMusl.haskellPackages.dhall;
src = pkgsStaticLinux.pkgsMusl.haskell.packages."${compiler}".dhall;
installPhase = ''
releaseName=${src.name}
@ -198,17 +292,9 @@ in
'';
};
inherit (pkgs.haskellPackages) dhall;
inherit (pkgs.haskell.packages."${compiler}") dhall;
all = pkgs.releaseTools.aggregate
{ name = "dhall";
inherit (pkgs.releaseTools) aggregate;
constituents = [
dhall
tarball
pwd
];
};
shell = (pkgs.haskell.lib.doBenchmark pkgs.haskellPackages.dhall).env;
shell = (pkgs.haskell.lib.doBenchmark pkgs.haskell.packages."${compiler}".dhall).env;
}

View File

@ -179,11 +179,11 @@ Library
contravariant < 1.6 ,
cryptonite >= 0.23 && < 1.0 ,
Diff >= 0.2 && < 0.4 ,
directory >= 1.2.7.1 && < 1.4 ,
directory >= 1.2.2.0 && < 1.4 ,
exceptions >= 0.8.3 && < 0.11,
filepath >= 1.4 && < 1.5 ,
hashable < 1.3 ,
haskeline >= 0.7.3.0 && < 0.8 ,
haskeline >= 0.7.2.1 && < 0.8 ,
insert-ordered-containers >= 0.2.1.0 && < 0.3 ,
lens-family-core >= 1.0.0 && < 1.3 ,
megaparsec >= 7.0.0 && < 7.1 ,
@ -291,11 +291,16 @@ Test-Suite doctest
GHC-Options: -Wall
Build-Depends:
base ,
directory >= 1.2.2.0 && < 1.4 ,
directory ,
filepath < 1.5 ,
mockery < 0.4 ,
doctest >= 0.7.0 && < 0.17
Default-Language: Haskell2010
-- `doctest` doesn't work with `MIN_VERSION` macros before GHC 8
--
-- See: https://ghc.haskell.org/trac/ghc/ticket/10970
if impl(ghc < 8.0)
Buildable: False
Benchmark dhall-parser
Type: exitcode-stdio-1.0
@ -307,7 +312,7 @@ Benchmark dhall-parser
containers >= 0.5.0.0 && < 0.7,
criterion >= 1.1 && < 1.6,
dhall ,
directory >= 1.2.7.1 && < 1.4,
directory ,
serialise ,
text >= 0.11.1.0 && < 1.3
Default-Language: Haskell2010

12
nix/basement.nix Normal file
View File

@ -0,0 +1,12 @@
{ mkDerivation, base, ghc-prim, stdenv }:
mkDerivation {
pname = "basement";
version = "0.0.6";
sha256 = "9ca23b940006d8c6a7bc9c07c4ef1bf5ddb47ce82d384c5f341996e22cb95ff7";
revision = "1";
editedCabalFile = "0jlj6jy1fsh5xc3z1finjxsq838n3v7qz4zv344l37s1w9z8pwlf";
libraryHaskellDepends = [ base ghc-prim ];
homepage = "https://github.com/haskell-foundation/foundation";
description = "Foundation scrap box of array & string";
license = stdenv.lib.licenses.bsd3;
}

12
nix/foundation.nix Normal file
View File

@ -0,0 +1,12 @@
{ mkDerivation, base, basement, gauge, ghc-prim, stdenv }:
mkDerivation {
pname = "foundation";
version = "0.0.19";
sha256 = "b83bd852f1bc2f7a39fe02ce673580483cb3264ce10dd8768ee4dcf49a2b6f14";
libraryHaskellDepends = [ base basement ghc-prim ];
testHaskellDepends = [ base basement ];
benchmarkHaskellDepends = [ base basement gauge ];
homepage = "https://github.com/haskell-foundation/foundation";
description = "Alternative prelude with batteries and no dependencies";
license = stdenv.lib.licenses.bsd3;
}

9
nix/lens-family-core.nix Normal file
View File

@ -0,0 +1,9 @@
{ mkDerivation, base, containers, stdenv, transformers }:
mkDerivation {
pname = "lens-family-core";
version = "1.2.1";
sha256 = "95e3b9876a6cdcc6865bfad22e04af41430c7a9a6bc96e9a25a2a35a841d19a4";
libraryHaskellDepends = [ base containers transformers ];
description = "Haskell 98 Lens Families";
license = stdenv.lib.licenses.bsd3;
}

29
nix/wcwidth.patch Normal file
View File

@ -0,0 +1,29 @@
diff -Naur wcwidth-0.0.2.before/wcwidth.cabal wcwidth-0.0.2.after/wcwidth.cabal
--- wcwidth-0.0.2.before/wcwidth.cabal 2011-04-03 21:19:59.000000000 -0700
+++ wcwidth-0.0.2.after/wcwidth.cabal 2018-10-04 11:34:55.000000000 -0700
@@ -35,25 +35,3 @@
extensions : StandaloneDeriving
ForeignFunctionInterface
OverloadedStrings
-
-
-executable wcwidth-tools
- main-is : WCWidthTableaux.hs
- if flag(cli)
- buildable : True
- else
- buildable : False
- if flag(split-base)
- build-depends : base >= 4 && < 5
- else
- build-depends : base < 4
- build-depends : containers
- , bytestring
- , setlocale >= 0.0.3
- , utf8-string >= 0.3
- , attoparsec >= 0.8.5
- extensions : StandaloneDeriving
- ForeignFunctionInterface
- OverloadedStrings
-
-

View File

@ -1,10 +1,21 @@
let
default = (import ./default.nix);
default_7_10_3 = import ./default.nix { compiler = "ghc7103"; };
default_8_4_3 = import ./default.nix { compiler = "ghc843"; };
in
{ dhall = default.all;
{ dhall = default_8_4_3.aggregate
{ name = "dhall";
inherit (default) tarball;
constituents = [
default_7_10_3.dhall
default_8_4_3.dhall
default_8_4_3.tarball
default_8_4_3.pwd
];
};
coverage = default.dhall;
"coverage" = default_8_4_3.dhall;
inherit (default_8_4_3) tarball;
}

View File

@ -1 +1 @@
(import ./default.nix).shell
(import ./default.nix {}).shell

View File

@ -129,7 +129,6 @@ module Dhall.Import (
import Control.Applicative (Alternative(..))
import Codec.CBOR.Term (Term)
import Control.Applicative (empty)
import Control.Exception (Exception, SomeException, throwIO, toException)
import Control.Monad (guard)
import Control.Monad.Catch (throwM, MonadCatch(catch), catches, Handler(..))
@ -470,7 +469,7 @@ exprFromImport here@(Import {..}) = do
result <- Maybe.runMaybeT $ do
Just expectedHash <- return hash
cacheFile <- getCacheFile expectedHash
True <- liftIO (Directory.doesPathExist cacheFile)
True <- liftIO (Directory.doesFileExist cacheFile)
bytesStrict <- liftIO (Data.ByteString.readFile cacheFile)
@ -564,7 +563,7 @@ getCacheFile hash = do
liftIO (Directory.setPermissions directory private)
cacheDirectory <- liftIO $ Directory.getXdgDirectory Directory.XdgCache ""
cacheDirectory <- getCacheDirectory
assertDirectory cacheDirectory
@ -576,6 +575,23 @@ getCacheFile hash = do
return cacheFile
getCacheDirectory :: MonadIO io => io FilePath
#if MIN_VERSION_directory(1,2,3)
getCacheDirectory = liftIO (Directory.getXdgDirectory Directory.XdgCache "")
#else
getCacheDirectory = liftIO $ do
maybeXDGCacheHome <- System.Environment.lookupEnv "XDG_CACHE_HOME"
case maybeXDGCacheHome of
Nothing -> do
homeDirectory <- Directory.getHomeDirectory
return (homeDirectory </> ".cache")
Just xdgCacheHome -> do
return xdgCacheHome
#endif
exprFromUncachedImport :: Import -> StateT (Status IO) IO (Expr Src Import)
exprFromUncachedImport (Import {..}) = do
let ImportHashed {..} = importHashed

View File

@ -1,7 +1,6 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Regression where
@ -52,7 +51,7 @@ data Foo = Foo Integer Bool | Bar Bool Bool Bool | Baz Integer Integer
unnamedFields :: TestTree
unnamedFields = Test.Tasty.HUnit.testCase "Unnamed Fields" (do
let ty = Dhall.auto @Foo
let ty = Dhall.auto :: Dhall.Type Foo
Test.Tasty.HUnit.assertEqual "Good type" (Dhall.expected ty) (Dhall.Core.Union (
Data.HashMap.Strict.InsOrd.fromList [
("Bar",Dhall.Core.Record (Data.HashMap.Strict.InsOrd.fromList [
@ -62,14 +61,14 @@ unnamedFields = Test.Tasty.HUnit.testCase "Unnamed Fields" (do
,("Foo",Dhall.Core.Record (Data.HashMap.Strict.InsOrd.fromList [
("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool)]))]))
let inj = Dhall.inject @Foo
let inj = Dhall.inject :: Dhall.InputType Foo
Test.Tasty.HUnit.assertEqual "Good Inject" (Dhall.declared inj) (Dhall.expected ty)
let tu_ty = Dhall.auto @(Integer, Bool)
let tu_ty = Dhall.auto :: Dhall.Type (Integer, Bool)
Test.Tasty.HUnit.assertEqual "Auto Tuple" (Dhall.expected tu_ty) (Dhall.Core.Record (
Data.HashMap.Strict.InsOrd.fromList [ ("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool) ]))
let tu_in = Dhall.inject @(Integer, Bool)
let tu_in = Dhall.inject :: Dhall.InputType (Integer, Bool)
Test.Tasty.HUnit.assertEqual "Inj. Tuple" (Dhall.declared tu_in) (Dhall.expected tu_ty)
return () )