From 01d6cad27f6fe5e5adc521140913e65d35a10095 Mon Sep 17 00:00:00 2001 From: Gabriel Gonzalez Date: Sat, 20 Oct 2018 09:27:16 -0700 Subject: [PATCH] Update `README` and Nix logic (#650) Fixes https://github.com/dhall-lang/dhall-haskell/issues/645 Fixes https://github.com/dhall-lang/dhall-lang/issues/216 This updates the `README` with the following changes: * Points to the language-agnostic `README` in the `dhall-lang` repository * Retains only Haskell-specific sections of interest * Removes the embedded LICENSE now that GitHub auto-recognizes the project license (#644) * Changes the Quick Start instructions to use Nix * Adds instructions for project development using Nix The latter two points entailed refactors to the Nix logic to simplify the user experience: * `default.nix` was moved to `shared.nix` and replaced with a new `default.nix` that works out-of-the-box with `nix-build` * There is a new `nix/test-dhall.nix` which users can use to create a `nix-shell` with Dhall as a dependency --- README.md | 187 +++++++++------------------ default.nix | 301 +------------------------------------------ nix/test-dhall.nix | 1 + release.nix | 20 +-- shared.nix | 314 +++++++++++++++++++++++++++++++++++++++++++++ shell.nix | 2 +- 6 files changed, 386 insertions(+), 439 deletions(-) create mode 100644 nix/test-dhall.nix create mode 100644 shared.nix diff --git a/README.md b/README.md index 03fa4e6..a5a1a19 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,35 @@ # `dhall 1.18.0` -`dhall` is a total programming language specialized to configuration files +Dhall is a programmable configuration language that is not Turing-complete -## Features: +You can think of Dhall as: JSON + functions + types + imports -* Haskell integration - Dhall expressions can be marshalled into Haskell -* Total - Programs always terminate and will never hang -* Safe - Programs never crash or throw exceptions -* Distributed - Expressions can reference other expressions by URL or path -* Strong normalization - Every expression can be reduced to a normal form -* Statically typed - Configuration files can be validated ahead-of-time -* Strongly typed - No coercions, casts or subtyping -* Built-in data types - Includes lists, anonymous records and anonymous unions +You will probably want to read the language-agnostic README here: + +* [`dhall-lang` `README`](https://github.com/dhall-lang/dhall-lang/blob/master/README.md) + +This repository (and this `README`) focuses on the Haskell implementation of +Dhall + +## Motivation + +*"Why not configure my program using JSON or YAML?"* + +JSON or YAML are suitable for small configuration files, but larger +configuration files with complex schemas require programming language features +to reduce repetition. Otherwise, the repetitive configuration files become +error-prone and difficult to maintain/migrate. + +This post explains in more detail the motivation behind programmable +configuration files: + +* [Programmable configuration files](https://github.com/dhall-lang/dhall-lang/wiki/Programmable-configuration-files) + +*"Why not configure my program using Haskell code?"* + +You probably don't want to rebuild your program every time you make a +configuration change. Recompilation is slow and requires the GHC toolchain +to be installed anywhere you want to make configuration changes. ## Quick start @@ -55,8 +73,8 @@ $ cat ./bar ... you can interpret the Haskell program like this: ```bash -$ stack install dhall -$ stack runghc example.hs +$ nix-shell nix/test-dhall.nix +[nix-shell]$ runghc example.hs Example {foo = 1, bar = [3.0,4.0,5.0]} ``` @@ -69,7 +87,7 @@ List/head Double ./bar Optional Double -[3.0] : Optional Double +Some 3.0 ``` ... and you can reference remote expressions or functions by their URL, too: @@ -88,86 +106,37 @@ Now go read the [Dhall tutorial](https://hackage.haskell.org/package/dhall/docs/Dhall-Tutorial.html) to learn more -# Integrations +## Building this project -This section keeps track of what languages and file formats natively support the -Dhall configuration language: +Nix + Cabal is the recommended workflow for project development since continuous +integration uses Nix to build and test the project. Other development tools and +workflows are also supported on a best-effort basis. -Complete: +You can build the project using only Nix by running this command from the root +of the repository: -* [`dhall-haskell`](https://github.com/dhall-lang/dhall-haskell) - - Haskell integration (this package) -* [`dhall-nix`](https://github.com/dhall-lang/dhall-nix) - Nix integration -* [`dhall-json`](https://github.com/dhall-lang/dhall-json) - - JSON and YAML integration -* [`dhall-bash`](https://github.com/dhall-lang/dhall-bash) - Bash integration -* [`dhall-text`](https://github.com/dhall-lang/dhall-text) - Template engine +```bash +$ nix-build +``` -In progress: +More commonly, you will want to incrementally build the project using `cabal`. +You can either do so inside of a `nix-shell`: -* [`dhall-rs`](https://github.com/nanotech/dhall-rs) - Rust integration -* [`dhall-scala`](https://github.com/missingfaktor/dhall-scala) - Scala - integration +```bash +$ nix-shell +[nix-shell]$ cabal configure +[nix-shell]$ cabal build +[nix-shell]$ cabal test +``` -## Design philosophy +... or you can add `nix: True` to your `~/.cabal/config` file and then you can +run the same `cabal` commands without an explicit `nix-shell`: -Programming languages are all about design tradeoffs and the Dhall language uses -the following guiding principles (in order of descending priority) that help -navigate those tradeoffs: - -* Polish - - The language should delight users. Error messages should be fantastic, - execution should be snappy, documentation should be excellent, and - everything should "just work". - -* Simplicity - - When in doubt, cut it out. Every configuration language needs bindings to - multiple programming languages, and the more complex the configuration - language the more difficult to create new bindings. Let the host language - that you bind to compensate for any missing features from Dhall. - -* Beginner-friendliness - - Dhall needs to be a language that anybody can learn in a day and debug - with little to no assistance from others. Otherwise people can't recommend - Dhall to their team with confidence. - -* Robustness - - A configuration language needs to be rock solid. The last thing a person - wants to debug is their configuration file. The language should never hang - or crash. Ever. - -* Consistency - - There should only be one way to do something. Users should be able to - instantly discern whether or not something is possible within the Dhall - language or not. - -The `dhall` configuration language is also designed to negate many of the common -objections to programmable configuration files, such as: - -> "Config files shouldn't be Turing complete" - -Dhall is not Turing-complete. Evaluation always terminates, no exceptions - -> "Configuration languages become unreadable due to abstraction and indirection" - -Every Dhall configuration file can be reduced to a normal form which eliminates -all abstraction and indirection - -> "Users will go crazy with syntax and user-defined constructs" - -Dhall is a very minimal programming language. For example: you cannot even -compare strings for equality. The language also forbids many other common -operations in order to force users to keep things simple - -The biggest issue with using Dhall as a configuration language is that there are -currently only Haskell bindings. If you would like to contribute bindings to -another language then go for it, otherwise I will do my best to contribute them -as time permits. +```bash +$ cabal configure +$ cabal build +$ cabal test +``` ## Development status @@ -176,48 +145,8 @@ as time permits. The compiler is built upon a theoretically sound foundation, meaning that if there are no bugs then the language will never crash and will always halt. However, in practice the compiler needs to be battle-tested to weed out any -implementation bugs. +implementation bugs, so please open issues! 🙂 -The initial release of the language includes every feature that I intended to -add to the language. This means that the only new features that I will add from -this point onwards are those that users request. Even then, I may still push -back on feature requests in order to simplify porting Dhall bindings to -languages other than Haskell. +Read the following guide if you would like to contribute: -I would also like to create a formal language standard for Dhall to also help -with porting bindings to other host languages. If you would like to assist with -either standardizing the language or creating new bindings just let me know -through the issue tracker. - -## Name - -The language is named after a -[Dustman from the game Planescape: Torment](http://torment.wikia.com/wiki/Dhall) -who belongs to a faction obsessed with death (termination). - -## License (BSD 3-clause) - - Copyright (c) 2016 Gabriel Gonzalez - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Gabriel Gonzalez nor the names of other contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* [Contributing to Dhall](https://github.com/dhall-lang/dhall-lang/blob/master/.github/CONTRIBUTING.md) diff --git a/default.nix b/default.nix index c3661f8..6104172 100644 --- a/default.nix +++ b/default.nix @@ -1,300 +1 @@ -{ compiler ? "ghc843" }: - -let - fetchNixpkgs = import ./nix/fetchNixpkgs.nix; - - overlayShared = pkgsNew: pkgsOld: { - dhall-sdist = - let - predicate = path: type: - let - base = baseNameOf path; - - in - !( pkgsNew.lib.hasSuffix ".nix" base - || base == "dist" - || base == "result" - || base == ".git" - ); - - src = builtins.filterSource predicate ./.; - - in - pkgsNew.callPackage (import ./nix/dhall-sdist.nix src) { }; - - 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 - ''; - } - ); - - # https://github.com/well-typed/cborg/issues/172 - 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; }) - - extension - ]; - } - ); - }; - }; - }; - - 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; - }; - - in - pkgsNew.lib.composeExtensions - (old.overrides or (_: _: {})) - extension; - } - ); - }; - - 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"; - - sha256 = "09qx58dp1kbj7cpzp8ahbqfbbab1frb12sh1qng87rybcaz0dz01"; - - outputSha256 = "0xpqc1fhkvvv5dv1zmas2j1q27mi7j7dgyjcdh82mlgl1q63i660"; - }; - - pkgs = import nixpkgs { - config = {}; - overlays = - [ overlayShared overlayCabal2nix ] - ++ (if compiler == "ghc7103" then [ overlayGHC7103 ] else []); - }; - - overlayStaticLinux = pkgsNew: pkgsOld: { - cabal_patched_src = pkgsNew.fetchFromGitHub { - owner = "nh2"; - repo = "cabal"; - rev = "748f07b50724f2618798d200894f387020afc300"; - sha256 = "1k559m291f6spip50rly5z9rbxhfgzxvaz64cx4jqpxgfhbh2gfs"; - }; - - Cabal_patched_Cabal_subdir = pkgsNew.stdenv.mkDerivation { - name = "cabal-dedupe-src"; - buildCommand = '' - cp -rv ${pkgsNew.cabal_patched_src}/Cabal/ $out - ''; - }; - - haskell = pkgsOld.haskell // { - lib = pkgsOld.haskell.lib // { - useFixedCabal = drv: pkgsNew.haskell.lib.overrideCabal drv (old: { - setupHaskellDepends = - (old.setupHaskellDepends or []) ++ [ - pkgsNew.haskell.packages."${compiler}".Cabal_patched - ]; - - libraryHaskellDepends = - (old.libraryHaskellDepends or []) ++ [ - pkgsNew.haskell.packages."${compiler}".Cabal_patched - ]; - } - ); - - statify = drv: - pkgsNew.lib.foldl pkgsNew.haskell.lib.appendConfigureFlag - (pkgsNew.haskell.lib.disableLibraryProfiling - (pkgsNew.haskell.lib.disableSharedExecutables - (pkgsNew.haskell.lib.useFixedCabal - (pkgsNew.haskell.lib.justStaticExecutables drv) - ) - ) - ) - [ "--enable-executable-static" - "--extra-lib-dirs=${pkgsNew.gmp6.override { withStatic = true; }}/lib" - "--extra-lib-dirs=${pkgsNew.zlib.static}/lib" - "--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; - } - ); - }; - }; - }; - - nixpkgsStaticLinux = fetchNixpkgs { - owner = "nh2"; - - rev = "925aac04f4ca58aceb83beef18cb7dae0715421b"; - - sha256 = "0zkvqzzyf5c742zcl1sqc8009dr6fr1fblz53v8gfl63hzqwj0x4"; - - outputSha256 = "1zr8lscjl2a5cz61f0ibyx55a94v8yyp6sjzjl2gkqjrjbg99abx"; - }; - - pkgsStaticLinux = import nixpkgsStaticLinux { - config = {}; - overlays = [ overlayShared overlayStaticLinux ]; - system = "x86_64-linux"; - }; - - # Derivation that trivially depends on the current directory so that Hydra's - # pull request builder always posts a GitHub status on each revision - pwd = pkgs.runCommand "pwd" { here = ./.; } "touch $out"; - -in - rec { - inherit pwd; - - tarball = - pkgsStaticLinux.releaseTools.binaryTarball rec { - src = pkgsStaticLinux.pkgsMusl.haskell.packages."${compiler}".dhall; - - installPhase = '' - releaseName=${src.name} - ${pkgsStaticLinux.coreutils}/bin/install -D "$src/bin/dhall" "$TMPDIR/inst/bin/dhall" - ''; - }; - - inherit (pkgs.haskell.packages."${compiler}") dhall; - - inherit (pkgs.releaseTools) aggregate; - - shell = (pkgs.haskell.lib.doBenchmark pkgs.haskell.packages."${compiler}".dhall).env; - } +(import ./shared.nix {}).dhall diff --git a/nix/test-dhall.nix b/nix/test-dhall.nix new file mode 100644 index 0000000..4c8721e --- /dev/null +++ b/nix/test-dhall.nix @@ -0,0 +1 @@ +(import ../shared.nix {}).test-dhall diff --git a/release.nix b/release.nix index df0e319..73d4ef9 100644 --- a/release.nix +++ b/release.nix @@ -1,21 +1,23 @@ let - default_7_10_3 = import ./default.nix { compiler = "ghc7103"; }; + shared_7_10_3 = + import ./shared.nix { compiler = "ghc7103"; coverage = true; }; - default_8_4_3 = import ./default.nix { compiler = "ghc843"; }; + shared_8_4_3 = + import ./shared.nix { compiler = "ghc843"; coverage = true; }; in - { dhall = default_8_4_3.aggregate + { dhall = shared_8_4_3.aggregate { name = "dhall"; constituents = [ - default_7_10_3.dhall - default_8_4_3.dhall - default_8_4_3.tarball - default_8_4_3.pwd + shared_7_10_3.dhall + shared_8_4_3.dhall + shared_8_4_3.tarball + shared_8_4_3.pwd ]; }; - "coverage" = default_8_4_3.dhall; + "coverage" = shared_8_4_3.dhall; - inherit (default_8_4_3) tarball; + inherit (shared_8_4_3) tarball; } diff --git a/shared.nix b/shared.nix new file mode 100644 index 0000000..59bdcc1 --- /dev/null +++ b/shared.nix @@ -0,0 +1,314 @@ +{ compiler ? "ghc843", coverage ? false }: + +let + fetchNixpkgs = import ./nix/fetchNixpkgs.nix; + + overlayShared = pkgsNew: pkgsOld: { + dhall-sdist = + let + predicate = path: type: + let + base = baseNameOf path; + + in + !( pkgsNew.lib.hasSuffix ".nix" base + || base == "dist" + || base == "result" + || base == ".git" + ); + + src = builtins.filterSource predicate ./.; + + in + pkgsNew.callPackage (import ./nix/dhall-sdist.nix src) { }; + + haskell = pkgsOld.haskell // { + packages = pkgsOld.haskell.packages // { + "${compiler}" = pkgsOld.haskell.packages."${compiler}".override (old: { + overrides = + let + doCoverage = drv: + if coverage + then + pkgsNew.haskell.lib.overrideCabal + (pkgsNew.haskell.lib.doCoverage drv) + (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 + ''; + } + ) + else drv; + + 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 = + doCoverage + (failOnAllWarnings + (haskellPackagesNew.callCabal2nix + "dhall" + pkgsNew.dhall-sdist + { } + ) + ); + + # https://github.com/well-typed/cborg/issues/172 + 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; }) + + extension + ]; + } + ); + }; + }; + }; + + 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; + }; + + in + pkgsNew.lib.composeExtensions + (old.overrides or (_: _: {})) + extension; + } + ); + }; + + 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"; + + sha256 = "09qx58dp1kbj7cpzp8ahbqfbbab1frb12sh1qng87rybcaz0dz01"; + + outputSha256 = "0xpqc1fhkvvv5dv1zmas2j1q27mi7j7dgyjcdh82mlgl1q63i660"; + }; + + pkgs = import nixpkgs { + config = {}; + overlays = + [ overlayShared overlayCabal2nix ] + ++ (if compiler == "ghc7103" then [ overlayGHC7103 ] else []); + }; + + overlayStaticLinux = pkgsNew: pkgsOld: { + cabal_patched_src = pkgsNew.fetchFromGitHub { + owner = "nh2"; + repo = "cabal"; + rev = "748f07b50724f2618798d200894f387020afc300"; + sha256 = "1k559m291f6spip50rly5z9rbxhfgzxvaz64cx4jqpxgfhbh2gfs"; + }; + + Cabal_patched_Cabal_subdir = pkgsNew.stdenv.mkDerivation { + name = "cabal-dedupe-src"; + buildCommand = '' + cp -rv ${pkgsNew.cabal_patched_src}/Cabal/ $out + ''; + }; + + haskell = pkgsOld.haskell // { + lib = pkgsOld.haskell.lib // { + useFixedCabal = drv: pkgsNew.haskell.lib.overrideCabal drv (old: { + setupHaskellDepends = + (old.setupHaskellDepends or []) ++ [ + pkgsNew.haskell.packages."${compiler}".Cabal_patched + ]; + + libraryHaskellDepends = + (old.libraryHaskellDepends or []) ++ [ + pkgsNew.haskell.packages."${compiler}".Cabal_patched + ]; + } + ); + + statify = drv: + pkgsNew.lib.foldl pkgsNew.haskell.lib.appendConfigureFlag + (pkgsNew.haskell.lib.disableLibraryProfiling + (pkgsNew.haskell.lib.disableSharedExecutables + (pkgsNew.haskell.lib.useFixedCabal + (pkgsNew.haskell.lib.justStaticExecutables drv) + ) + ) + ) + [ "--enable-executable-static" + "--extra-lib-dirs=${pkgsNew.gmp6.override { withStatic = true; }}/lib" + "--extra-lib-dirs=${pkgsNew.zlib.static}/lib" + "--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; + } + ); + }; + }; + }; + + nixpkgsStaticLinux = fetchNixpkgs { + owner = "nh2"; + + rev = "925aac04f4ca58aceb83beef18cb7dae0715421b"; + + sha256 = "0zkvqzzyf5c742zcl1sqc8009dr6fr1fblz53v8gfl63hzqwj0x4"; + + outputSha256 = "1zr8lscjl2a5cz61f0ibyx55a94v8yyp6sjzjl2gkqjrjbg99abx"; + }; + + pkgsStaticLinux = import nixpkgsStaticLinux { + config = {}; + overlays = [ overlayShared overlayStaticLinux ]; + system = "x86_64-linux"; + }; + + # Derivation that trivially depends on the current directory so that Hydra's + # pull request builder always posts a GitHub status on each revision + pwd = pkgs.runCommand "pwd" { here = ./.; } "touch $out"; + +in + rec { + inherit pwd; + + tarball = + pkgsStaticLinux.releaseTools.binaryTarball rec { + src = pkgsStaticLinux.pkgsMusl.haskell.packages."${compiler}".dhall; + + installPhase = '' + releaseName=${src.name} + ${pkgsStaticLinux.coreutils}/bin/install -D "$src/bin/dhall" "$TMPDIR/inst/bin/dhall" + ''; + }; + + inherit (pkgs.haskell.packages."${compiler}") dhall; + + inherit (pkgs.releaseTools) aggregate; + + shell = (pkgs.haskell.lib.doBenchmark pkgs.haskell.packages."${compiler}".dhall).env; + + test-dhall = + pkgs.mkShell + { buildInputs = + [ (pkgs.haskell.packages."${compiler}".ghcWithPackages + (pkgs: [ pkgs.dhall ]) + ) + ]; + }; + } diff --git a/shell.nix b/shell.nix index 82fb296..107ec06 100644 --- a/shell.nix +++ b/shell.nix @@ -1 +1 @@ -(import ./default.nix {}).shell +(import ./shared.nix {}).shell