From bddd56a0af952378934c387864776f079c8c1478 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Tue, 21 May 2024 10:07:15 -0700 Subject: [PATCH] Add treefmt check --- flake.nix | 25 ++++++++++++++++----- nix/packages/allChecks.nix | 6 +++++ nix/packages/checks/haskell-project.nix | 25 +++++++++++++++++++++ nix/packages/checks/treefmt.nix | 22 ++++++++++++++++++ nix/packages/checksFrom.nix | 17 ++++++++++++++ nix/packages/ghciwatch.nix | 30 +++---------------------- nix/packages/mkCheck.nix | 25 +++++++++++++++++++++ 7 files changed, 117 insertions(+), 33 deletions(-) create mode 100644 nix/packages/allChecks.nix create mode 100644 nix/packages/checks/haskell-project.nix create mode 100644 nix/packages/checks/treefmt.nix create mode 100644 nix/packages/checksFrom.nix create mode 100644 nix/packages/mkCheck.nix diff --git a/flake.nix b/flake.nix index 1abcda3c..52011cd9 100644 --- a/flake.nix +++ b/flake.nix @@ -81,16 +81,23 @@ "ghc98" ]; in { + _pkgs = eachSystem (localSystem: makePkgs {inherit localSystem;}); + + localPkgs = eachSystem ( + localSystem: + self._pkgs.${localSystem}.callPackage ./nix/makePackages.nix {inherit inputs;} + ); + packages = eachSystem ( localSystem: let - pkgs = makePkgs {inherit localSystem;}; - inherit (pkgs) lib; - localPackages = pkgs.callPackage ./nix/makePackages.nix {inherit inputs;}; - ghciwatch = localPackages.ghciwatch.override { + inherit (nixpkgs) lib; + localPkgs = self.localPkgs.${localSystem}; + pkgs = self._pkgs.${localSystem}; + ghciwatch = localPkgs.ghciwatch.override { inherit ghcVersions; }; in - (lib.filterAttrs (name: value: lib.isDerivation value) localPackages) + (lib.filterAttrs (name: value: lib.isDerivation value) localPkgs) // { inherit ghciwatch; default = ghciwatch; @@ -120,7 +127,13 @@ }) ); - checks = eachSystem (system: self.packages.${system}.default.checks); + checks = eachSystem ( + system: + builtins.removeAttrs + self.localPkgs.${system}.allChecks + # CI and `nix flake check` complain that these are not derivations. + ["override" "overrideDerivation"] + ); devShells = eachSystem (system: { default = self.packages.${system}.default.devShell; diff --git a/nix/packages/allChecks.nix b/nix/packages/allChecks.nix new file mode 100644 index 00000000..2f3bd9e2 --- /dev/null +++ b/nix/packages/allChecks.nix @@ -0,0 +1,6 @@ +{ + ghciwatch, + checksFrom, + checks, +}: +(checksFrom ghciwatch) // checks diff --git a/nix/packages/checks/haskell-project.nix b/nix/packages/checks/haskell-project.nix new file mode 100644 index 00000000..f6700ef9 --- /dev/null +++ b/nix/packages/checks/haskell-project.nix @@ -0,0 +1,25 @@ +{ + mkCheck, + ghciwatch, +}: +mkCheck { + name = "haskell-project"; + sourceRoot = "source/tests/data/simple"; + nativeBuildInputs = ghciwatch.haskellInputs; + inherit (ghciwatch) GHC_VERSIONS; + + checkPhase = '' + # Need an empty `.cabal/config` or `cabal` errors trying to use the network. + mkdir "$TMPDIR/.cabal" + touch "$TMPDIR/.cabal/config" + export HOME="$TMPDIR" + + for VERSION in $GHC_VERSIONS; do + make test GHC="ghc-$VERSION" + done + ''; + + meta.description = '' + Check that the Haskell project used for integration tests compiles. + ''; +} diff --git a/nix/packages/checks/treefmt.nix b/nix/packages/checks/treefmt.nix new file mode 100644 index 00000000..cafd7a48 --- /dev/null +++ b/nix/packages/checks/treefmt.nix @@ -0,0 +1,22 @@ +{ + mkCheck, + treefmt, + alejandra, + craneLib, +}: +mkCheck { + name = "treefmt"; + nativeBuildInputs = [ + treefmt + alejandra + craneLib.rustfmt + ]; + + checkPhase = '' + treefmt --fail-on-change + ''; + + meta.description = '' + Check that treefmt runs without changes. + ''; +} diff --git a/nix/packages/checksFrom.nix b/nix/packages/checksFrom.nix new file mode 100644 index 00000000..9191bec9 --- /dev/null +++ b/nix/packages/checksFrom.nix @@ -0,0 +1,17 @@ +{lib}: let + name = drv: drv.pname or drv.name; +in + drv: + lib.mapAttrs' + (_name: check: let + drvName = name drv; + checkName = name check; + # If we have `ghciwatch.checks.ghciwatch-fmt` we want `ghciwatch-fmt`, + # not `ghciwatch-ghciwatch-fmt`. + newName = + if lib.hasPrefix drvName checkName + then checkName + else "${drvName}-${checkName}"; + in + lib.nameValuePair newName check) + drv.checks diff --git a/nix/packages/ghciwatch.nix b/nix/packages/ghciwatch.nix index 8afae79e..121cf461 100644 --- a/nix/packages/ghciwatch.nix +++ b/nix/packages/ghciwatch.nix @@ -28,7 +28,7 @@ then [ghc] else builtins.map (ghcVersion: haskell.compiler.${ghcVersion}) ghcVersions; - ghcBuildInputs = + haskellInputs = [ haskellPackages.cabal-install hpack @@ -136,7 +136,7 @@ ''; passthru = { - inherit GHC_VERSIONS checks devShell user-manual user-manual-tar-xz; + inherit GHC_VERSIONS haskellInputs checks devShell user-manual user-manual-tar-xz; }; }; @@ -225,7 +225,7 @@ testArgs = commonArgs // { - nativeBuildInputs = (commonArgs.nativeBuildInputs or []) ++ ghcBuildInputs; + nativeBuildInputs = (commonArgs.nativeBuildInputs or []) ++ haskellInputs; NEXTEST_PROFILE = "ci"; NEXTEST_HIDE_PROGRESS_BAR = "true"; @@ -263,30 +263,6 @@ cargo-nextest ]; }); - - # Check that the Haskell project used for integration tests is OK. - haskell-project-for-integration-tests = stdenv.mkDerivation { - name = "haskell-project-for-integration-tests"; - src = ../../tests/data/simple; - phases = ["unpackPhase" "buildPhase" "installPhase"]; - nativeBuildInputs = ghcBuildInputs; - inherit GHC_VERSIONS; - - buildPhase = '' - # Need an empty `.cabal/config` or `cabal` errors trying to use the network. - mkdir .cabal - touch .cabal/config - export HOME=$(pwd) - - for VERSION in $GHC_VERSIONS; do - make test GHC="ghc-$VERSION" - done - ''; - - installPhase = '' - touch $out - ''; - }; }; devShell = craneLib.devShell { diff --git a/nix/packages/mkCheck.nix b/nix/packages/mkCheck.nix new file mode 100644 index 00000000..5d89dee9 --- /dev/null +++ b/nix/packages/mkCheck.nix @@ -0,0 +1,25 @@ +{ + stdenv, + inputs, +}: { + name, + checkPhase, + ... +} @ args: let + cleanedArgs = builtins.removeAttrs args ["name" "checkPhase"]; +in + stdenv.mkDerivation ({ + name = "${name}-check"; + + src = inputs.self; + + phases = ["unpackPhase" "checkPhase" "installPhase"]; + + inherit checkPhase; + doCheck = true; + + installPhase = '' + touch $out + ''; + } + // cleanedArgs)