From 7019678d8c64d5aa9a30c1df6de91c1a88504445 Mon Sep 17 00:00:00 2001 From: ACreed Date: Fri, 10 Feb 2023 07:19:45 +0530 Subject: [PATCH] Have `packages` option auto-detect single-package projects (#75) Co-authored-by: Ag Co-authored-by: Sridhar Ratnakumar --- CHANGELOG.md | 1 + example/flake.nix | 5 +---- flake-module.nix | 45 +++++++++++++++++++++++++++++++++++++++++++-- runtest.sh | 12 ++++++++++-- test/flake.nix | 4 ---- 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2610cbc..6fb6cc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - New features - #63: Add `config.haskellProjects.${name}.outputs` containing all flake outputs for that project. + - #49: The `packages` option now autodiscovers the top-level `.cabal` file as its default value. - API changes - #37: Group `buildTools` (renamed to `tools`), `hlsCheck` and `hlintCheck` under the `devShell` submodule option; and allow disabling them all using `devShell.enable = false;` (useful if you want haskell-flake to produce just the package outputs). - #64: Remove hlintCheck (use [treefmt-nix](https://github.com/numtide/treefmt-nix#flake-parts) instead) diff --git a/example/flake.nix b/example/flake.nix index 2a487c5..7b0ce38 100644 --- a/example/flake.nix +++ b/example/flake.nix @@ -10,10 +10,7 @@ imports = [ inputs.haskell-flake.flakeModule ]; perSystem = { self', pkgs, ... }: { haskellProjects.default = { - packages = { - # You can add more than one local package here. - example.root = ./.; # Assumes ./example.cabal - }; + # packages.example.root = ./.; # This value is detected based on .cabal files # overrides = self: super: { }; # devShell = { # enable = true; # Enabled by default diff --git a/flake-module.nix b/flake-module.nix index 08b49db..eb7ea8a 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -114,12 +114,53 @@ in description = '' Attrset of local packages in the project repository. - Autodetected by default by looking for `.cabal` files in sub-directories. + Autodiscovered by default by looking for `.cabal` files in + top-level or sub-directories. ''; default = + # We look for a single *.cabal in project root. Otherwise, + # look for multiple */*.cabal. Otherwise, error out. + # + # In future, we could just read `cabal.project`. See #76. + let + toplevel-cabal-paths = + lib.concatMapAttrs + (f: _: + if lib.strings.hasSuffix ".cabal" f + then { "${lib.strings.removeSuffix ''.cabal'' f}" = self; } + else { } + ) + (builtins.readDir self); + subdir-cabal-paths = lib.filesystem.haskellPathsInDir self; + errorNoDefault = msg: + lib.asserts.assertMsg false '' + A default value for `packages` cannot be auto-detected: + + ${msg} + You must manually specify the `packages` option. + ''; + cabal-paths = + if toplevel-cabal-paths != { } + then + let cabalNames = lib.attrNames toplevel-cabal-paths; + in if builtins.length cabalNames > 1 + then + errorNoDefault '' + More than one .cabal file found in project root: + + - ${lib.concatStringsSep ".cabal\n - " cabalNames}.cabal + '' + else + toplevel-cabal-paths + else if subdir-cabal-paths != { } + then + subdir-cabal-paths + else + errorNoDefault "No .cabal file found."; + in lib.mapAttrs (_: value: { root = value; }) - (lib.filesystem.haskellPathsInDir self); + cabal-paths; defaultText = lib.literalMD "autodiscovered by reading `self` files."; }; devShell = mkOption { diff --git a/runtest.sh b/runtest.sh index e064eea..8bc651c 100755 --- a/runtest.sh +++ b/runtest.sh @@ -13,9 +13,17 @@ else fi FLAKE=$(pwd) -cd ./test -# First, build the flake. +# A Nix bug causes incorrect self when in a sub-flake. +# https://github.com/NixOS/nix/issues/7263 +# Workaround: copy ./test somewhere outside of this Git repo. +TESTDIR=$(mktemp -d) +trap 'rm -fr "$TESTDIR"' EXIT +cp -r ./test/* "$TESTDIR" +cd "$TESTDIR" +pwd + +# First, build the flake logHeader "Testing nix build" nix build --override-input haskell-flake path:${FLAKE} # Run the devshell test script in a nix develop shell. diff --git a/test/flake.nix b/test/flake.nix index 64c6803..6768ad8 100644 --- a/test/flake.nix +++ b/test/flake.nix @@ -24,10 +24,6 @@ ]; perSystem = { self', pkgs, ... }: { haskellProjects.default = { - packages = { - # You can add more than one local package here. - haskell-flake-test.root = ./.; # Assumes ./haskell-flake-test.cabal - }; overrides = self: super: { # Custom library overrides (here, "foo" comes from a flake input) foo = self.callCabal2nix "foo" (inputs.haskell-multi-nix + /foo) { };