diff --git a/flake.nix b/flake.nix
index 351c046211ce33ae3f6878e7c0c6910d7bebb331..b5d0dd6af56945105918d9119cd529bdbdbfb270 100644
--- a/flake.nix
+++ b/flake.nix
@@ -63,24 +63,7 @@
       checks = hslib.checks {};
       devShells = hslib.devShells {
         shellHook = ''
-          cat >cabal.project.local <<EOF
-          -- This file is auto-generated by the flake devShell's shellHook.  Do
-          -- not edit this file.  Make changes in flake.nix.
-          packages:
-            .
-            -- These aren't released on hackage yet so we have to get them
-            -- another way.  Here, we get them from the Nix store.
-            -- tahoe-chk
-            ${tahoe-chk}
-            -- tahoe-ssk
-            ${tahoe-ssk}
-            -- tahoe-capabilities
-            ${tahoe-capabilities}
-            -- tahoe-directory
-            ${tahoe-directory}
-            -- tahoe-great-black-swamp
-            ${tahoe-great-black-swamp}
-          EOF
+          nix run .#generate-cabal-project
         '';
         extraBuildInputs = pkgs:
           with pkgs; [
@@ -95,6 +78,35 @@
       };
       packages = hslib.packages {};
       apps.hlint = hslib.apps.hlint {};
+      apps.generate-cabal-project = {
+        type = "app";
+        program = "${
+          pkgs.writeShellApplication {
+            name = "generate-cabal-project";
+            text = ''
+              cat >cabal.project.local <<EOF
+              -- This file is auto-generated by the flake devShell's shellHook.  Do
+              -- not edit this file.  Make changes in flake.nix.
+              packages:
+                .
+                -- These aren't released on hackage yet so we have to get them
+                -- another way.  Here, we get them from the Nix store.
+                -- tahoe-chk
+                ${tahoe-chk}
+                -- tahoe-ssk
+                ${tahoe-ssk}
+                -- tahoe-capabilities
+                ${tahoe-capabilities}
+                -- tahoe-directory
+                ${tahoe-directory}
+                -- tahoe-great-black-swamp
+                ${tahoe-great-black-swamp}
+              EOF
+            '';
+          }
+        }/bin/generate-cabal-project";
+      };
+
       apps.entr-test = {
         type = "app";
         program = "${
@@ -130,6 +142,8 @@
             ];
 
             text = ''
+              nix run .#generate-cabal-project
+
               # Here we make zlib discoverable by pkg-config so cabal can find
               # headers and stuff.
               export PKG_CONFIG_PATH=${pkgs.lib.makeSearchPath "lib/pkgconfig" [pkgs.zlib.dev]}
@@ -138,9 +152,10 @@
               # solve our dependencies.
               cabal update hackage.haskell.org
 
-              # Configure with tests enable, build the tests (if necessary),
-              # and run the default test suite.
-              cabal run --enable-tests tests
+              # Run the default test suite.  The local cabal project file
+              # written above should have enabled tests so the build plan will
+              # support them.
+              cabal run tests
             '';
           }
         }/bin/cabal-build-and-test";