-
-
Notifications
You must be signed in to change notification settings - Fork 11
Port NeoHaskell to haskell.nix Infrastructure #203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
022ef90
65c6752
4bc9a52
6b58a42
2ef8253
e97baed
6123594
6efa88b
c7f7cab
5d95459
1614e83
8c72256
5dd6bfa
58f8b22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| version: 2 | ||
| updates: | ||
| - package-ecosystem: github-actions | ||
| directory: / | ||
| schedule: | ||
| interval: weekly | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -28,33 +28,27 @@ jobs: | |||||||||||||||||||||||||
| run: brew install bash | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||
| - uses: cachix/install-nix-action@v27 | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - name: Build the project with Nix | ||||||||||||||||||||||||||
| run: nix-build | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - name: Cache Cabal | ||||||||||||||||||||||||||
| id: cache | ||||||||||||||||||||||||||
| uses: actions/cache@v4 | ||||||||||||||||||||||||||
| - uses: DeterminateSystems/determinate-nix-action@v3.8.6 | ||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||
| path: | | ||||||||||||||||||||||||||
| ~/.cabal | ||||||||||||||||||||||||||
| dist-newstyle | ||||||||||||||||||||||||||
| .devenv/profile | ||||||||||||||||||||||||||
| key: ${{ runner.os }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/*.lock') }}-1 # modify the key if the cache is not working as expected | ||||||||||||||||||||||||||
| extra-conf: | | ||||||||||||||||||||||||||
| extra-substituters = https://cache.iog.io | ||||||||||||||||||||||||||
| extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= | ||||||||||||||||||||||||||
|
Comment on lines
+34
to
+36
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Confirm extra-conf semantics; add a guard to prove caches are active. Using Apply this minimal check right after the Determinate Nix step: - uses: DeterminateSystems/determinate-nix-action@v3.8.6
with:
extra-conf: |
extra-substituters = https://cache.iog.io
extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=
+ - name: Verify Nix cache wiring
+ run: |
+ nix --version
+ nix show-config | sed -n 's/^substituters = //p; s/^trusted-public-keys = //p'
+ nix show-config | grep -q 'https://cache.iog.io' || { echo "cache.iog.io not in substituters"; exit 1; }
+ nix show-config | grep -q 'hydra.iohk.io:' || { echo "IOG key not in trusted-public-keys"; exit 1; }π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - name: Update Cabal Hackage list | ||||||||||||||||||||||||||
| # if: steps.cache.outputs.cache-hit != 'true' | ||||||||||||||||||||||||||
| run: nix-shell --run "cabal update" | ||||||||||||||||||||||||||
| - uses: DeterminateSystems/magic-nix-cache-action@v13 | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Comment on lines
+38
to
+39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion Also pin Magic Nix Cache to a commit SHA. Mitigate action supplyβchain risk by pinning to an exact commit, not a mutable tag. - - uses: DeterminateSystems/magic-nix-cache-action@v13
+ - uses: DeterminateSystems/magic-nix-cache-action@<commit-sha-of-v13>π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||
| - name: Build the project with Nix | ||||||||||||||||||||||||||
| run: nix-build | ||||||||||||||||||||||||||
|
Comment on lines
+40
to
+41
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Increase build log visibility for flakier investigations. Add -L to surface derivation logs in CI output. - - name: Build the project with Nix
- run: nix-build
+ - name: Build the project with Nix
+ run: nix-build -Lπ Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - name: Build the project with cabal | ||||||||||||||||||||||||||
| run: nix-shell --run "cabal build all" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - name: Run core tests | ||||||||||||||||||||||||||
| run: nix-shell --run "cabal test core" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - name: Run core doctests | ||||||||||||||||||||||||||
| run: nix-shell --run "run-doctests-verbose" | ||||||||||||||||||||||||||
| # Doctests are failing - See issue #204 | ||||||||||||||||||||||||||
| # - name: Run core doctests | ||||||||||||||||||||||||||
| # run: nix-shell --run "cabal repl --with-compiler=doctest --repl-options=--verbose core" | ||||||||||||||||||||||||||
|
Comment on lines
+49
to
+51
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Keep doctests running but non-blocking to avoid drift. Instead of commenting out, run them with continue-on-error so failures are visible but donβt gate merges while #204 is open. - # Doctests are failing - See issue #204
- # - name: Run core doctests
- # run: nix-shell --run "cabal repl --with-compiler=doctest --repl-options=--verbose core"
+ - name: Run core doctests (non-blocking) # See issue #204
+ continue-on-error: true
+ run: nix-shell --run "cabal repl --with-compiler=doctest --repl-options=--verbose core"π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - name: Run CLI tests | ||||||||||||||||||||||||||
| run: nix-shell --run "cabal test cli" | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |
| "Monoid", | ||
| "Nanotime", | ||
| "NEOHASKELL", | ||
| "nhcli", | ||
| "nhcore", | ||
| "nixfmt", | ||
| "nixpkgs", | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,28 +1,45 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { pkgs }: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Generic function to create a Haskell project template | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { projectName, src }: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { packages, mainPackageName, executableName }: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ Verification agent π§© Analysis chainParameterize the compiler to avoid silent breakage when haskell.nix moves; verify ghc910 availability Hard-coding Apply this diff to parameterize: -{ packages, mainPackageName, executableName }:
+{ packages, mainPackageName, executableName, compilerNixName ? "ghc910" }:And this one to use it: - compiler-nix-name = "ghc910";
+ compiler-nix-name = compilerNixName;To confirm the compiler alias is valid for your pin, run a quick web check: Also applies to: 19-20 π Web query: π‘ Result: For haskell.nix commit 4d493449406ec91db804511a6d15b6f076ba40e7, the accepted values for Key details:
Additional notes:
In summary, for haskell.nix at 4d493449406ec91db804511a6d15b6f076ba40e7, use Citations:
Parameterize Weβve confirmed that β’ In cli/nix/haskell-project.nix, change the function signature (around line 3): -{ packages, mainPackageName, executableName }:
+{ packages, mainPackageName, executableName, compilerNixName ? "ghc910" }:β’ Replace the hard-coded compiler name (around lines 19β20): - compiler-nix-name = "ghc910";
+ compiler-nix-name = compilerNixName;This makes the compiler choice configurable (defaulting to a verified, supported value) and guards against future compatibility issues. π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| haskellNix = import (pkgs.fetchFromGitHub { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| owner = "input-output-hk"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo = "haskell.nix"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rev = "4d493449406ec91db804511a6d15b6f076ba40e7"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sha256 = "sha256-CHNMDgFfpTV5WkVhmMLf5d5qaLUjgeoziVgmgnhPGrI="; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) { inherit pkgs; }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Apply haskell.nix overlay | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) { }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgsWithOverlay = import haskellNix.sources.nixpkgs-unstable { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| overlays = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| haskellNix.overlay | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (final: _prev: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "${projectName}Project" = final.haskell-nix.cabalProject { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inherit src; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compiler-nix-name = "ghc910"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (final: _prev: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| builtins.listToAttrs (builtins.map (packageName: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name = "${packageName}"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value = final.haskell-nix.cabalProject { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| src = packages.${packageName}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compiler-nix-name = "ghc910"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) (builtins.attrNames packages))) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quote hyphenated attribute 'haskell-nix' to avoid a parse error Attribute names with hyphens must be quoted in Nix. As written, Apply this diff: - value = final.haskell-nix.cabalProject {
+ value = final."haskell-nix".cabalProject {π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
11
to
22
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Name collisions in the overlay are possible; consider a namespaced project set. Injecting each package at the top level (pkgsWithOverlay.nhcli, pkgsWithOverlay.nhcore) risks collisions with existing attributes. Consider nesting under a single attribute (e.g., final.neohaskellPackages) and selecting from there. Apply: - (final: _prev:
- builtins.listToAttrs (builtins.map (packageName: {
- name = "${packageName}";
- value = final."haskell-nix".cabalProject {
- src = packages.${packageName};
- compiler-nix-name = compilerNixName;
- };
- }) (builtins.attrNames packages)))
+ (final: _prev:
+ {
+ neohaskellPackages =
+ builtins.listToAttrs (builtins.map (packageName: {
+ name = packageName;
+ value = final."haskell-nix".cabalProject {
+ src = packages.${packageName};
+ compiler-nix-name = compilerNixName;
+ };
+ }) (builtins.attrNames packages));
+ })And later: - pkg = builtins.getAttr mainPackageName pkgsWithOverlay;
+ pkg = builtins.getAttr mainPackageName pkgsWithOverlay.neohaskellPackages;π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inherit (haskellNix) config; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
11
to
24
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Lock imported nixpkgs system to match caller to prevent accidental cross-system evaluation. Pass system = pkgs.system when importing nixpkgs-unstable to ensure consistency with the outer pkgs. - pkgsWithOverlay = import haskellNix.sources.nixpkgs-unstable {
+ pkgsWithOverlay = import haskellNix.sources.nixpkgs-unstable {
+ system = pkgs.system;
overlays = [
haskellNix.overlay
(final: _prev:
builtins.listToAttrs (builtins.map (packageName: {
name = "${packageName}";
value = final."haskell-nix".cabalProject {
src = packages.${packageName};
compiler-nix-name = compilerNixName;
};
}) (builtins.attrNames packages)))
];
inherit (haskellNix) config;
};π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| flake = pkgsWithOverlay."${projectName}Project".flake { }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkg = pkgsWithOverlay."${mainPackageName}"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Prefer builtins.getAttr for dynamic attribute selection Using a string-literal selector here works, but Apply this diff: - pkg = pkgsWithOverlay."${mainPackageName}";
+ pkg = builtins.getAttr mainPackageName pkgsWithOverlay;π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| in flake.packages."${projectName}:exe:${projectName}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| in { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell = pkg.shellFor { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tools = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cabal = { }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hlint = { }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| haskell-language-server = { }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hspec-discover = { }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| buildInputs = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgs.nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgs.nixfmt-classic | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgs.nixpkgs-fmt | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgs.pkg-config | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgs.zlib | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package = (pkg.flake { }).packages."${executableName}"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+44
to
+45
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Fail early if executableName is wrong; add an assertion. Guard against typos by asserting the package key exists in the flake outputs. - package = (pkg.flake { }).packages."${executableName}";
+ package =
+ let
+ flakeOut = pkg.flake { };
+ pkgsOut = flakeOut.packages;
+ in
+ assert builtins.hasAttr executableName pkgsOut;
+ pkgsOut."${executableName}";π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,7 @@ run = do | |
| Command.CommandOptions | ||
| { name = "neo", | ||
| description = "NeoHaskell's console helper", | ||
| version = Just [Core.version|0.9.0|], | ||
| version = Just [Core.version|0.9.1|], | ||
| decoder = commandsParser | ||
|
Comment on lines
+52
to
53
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ Verification agent π§© Analysis chainVersion banner updated to 0.9.1 β approved. Consistent with cabal version bumps in this PR. Run this quick sweep to ensure no stale version references remain: π Script executed: #!/bin/bash
# Find old version references and version banners
rg -nP -C2 '\[Core\.version\|\d+\.\d+\.\d+\|]' --type=haskell
rg -nP '0\.9\.0' -g '!**/dist/**' -g '!**/result/**'Length of output: 570 Stale version references detectedβupdate to 0.9.1 before merging. The CLI banner in cli/src/Neo.hs is correctly bumped to 0.9.1, but the following outdated 0.9.0 pins remain: β’ website/package-lock.json:2318,9404 Command the update of these entries and regenerate the lock file. π€ Prompt for AI Agents |
||
| } | ||
| cmd <- Command.parseHandler parser | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -75,10 +75,12 @@ handle config = do | |||||||||||||||||||||||||||||||||||||||||||||||||
| File.writeText targetAppPath appMainFile | ||||||||||||||||||||||||||||||||||||||||||||||||||
| |> Task.mapError (\_ -> CustomError "Could not write app main file") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| -- FIXME: Create another thread that renders the output of the build via streaming. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- As right now there's no output at all | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let buildExpression :: Text = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| [fmt|{ pkgs ? import <nixpkgs> {} }: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ( (#{nixFile}) { inherit pkgs; } ).package|] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| completion <- | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Subprocess.openInherit "nix-build" (Array.fromLinkedList ["-E", nixFile]) rootFolder Subprocess.InheritBOTH | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Subprocess.openInherit "nix-build" (Array.fromLinkedList ["-E", buildExpression]) rootFolder Subprocess.InheritBOTH | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+78
to
+83
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ Verification agent π§© Analysis chainnix-build -E must evaluate to a derivation; donβt pass a lambda. Like nix-shell, nix-build -E expects a derivation or set of derivations, not a top-level lambda. The current expression begins with a lambda and will not build. Minimal fix using let/in: - let buildExpression :: Text =
- [fmt|{ pkgs ? import <nixpkgs> {} }:
- ( (#{nixFile}) { inherit pkgs; } ).package|]
+ let buildExpression :: Text =
+ [fmt|let pkgs = import <nixpkgs> {}; in
+ ( (#{nixFile}) { inherit pkgs; } ).package|]Alternative (clearer target selection): evaluate the set and select -A package: - completion <-
- Subprocess.openInherit "nix-build" (Array.fromLinkedList ["-E", buildExpression]) rootFolder Subprocess.InheritBOTH
+ let projectSetExpr :: Text =
+ [fmt|let pkgs = import <nixpkgs> {}; in
+ ( (#{nixFile}) { inherit pkgs; } )|]
+ completion <-
+ Subprocess.openInherit "nix-build" (Array.fromLinkedList ["-E", projectSetExpr, "-A", "package"]) rootFolder Subprocess.InheritBOTHAlso see my notes on pinning nixpkgs to avoid reliance on NIX_PATH. Run to double-check: π Script executed: #!/bin/bash
rg -n -C2 'nix-build' cli/src/Neo/Build.hsLength of output: 260 Enforce derivation evaluation for nix-build -E By my omniscient decree, Required changes in β’ Replace the lambda form of - let buildExpression :: Text =
- [fmt|{ pkgs ? import <nixpkgs> {} }:
- ( (#{nixFile}) { inherit pkgs; } ).package|]
+ let buildExpression :: Text =
+ [fmt|let pkgs = import <nixpkgs> {}; in
+ ( (#{nixFile}) { inherit pkgs; } ).package|]β’ Alternatively, select the attribute from the set and pass it via - completion <-
- Subprocess.openInherit "nix-build" (Array.fromLinkedList ["-E", buildExpression]) rootFolder Subprocess.InheritBOTH
+ let projectSetExpr :: Text =
+ [fmt|let pkgs = import <nixpkgs> {}; in
+ ( (#{nixFile}) { inherit pkgs; } )|]
+ completion <-
+ Subprocess.openInherit
+ "nix-build"
+ ( Array.fromLinkedList
+ [ "-E", projectSetExpr
+ , "-A", "package"
+ ]
+ )
+ rootFolder
+ Subprocess.InheritBOTHβ’ Pin your π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
| if completion.exitCode != 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| then errorOut completion.stderr | ||||||||||||||||||||||||||||||||||||||||||||||||||
| else print completion.stdout | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,8 +18,11 @@ let | |
| hp = (#{haskellProject}); | ||
|
|
||
| in (hp { inherit pkgs; }) { | ||
| projectName = "#{name}"; | ||
| src = ./.; | ||
| packages = { | ||
| "#{name}" = ./.; | ||
| }; | ||
| mainPackageName = "#{name}"; | ||
| executableName = "#{name}:exe:#{name}"; | ||
|
Comment on lines
+21
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ Verification agent π§© Analysis chainConfirm executableName matches the cabal executable stanza. Youβre selecting the build target by a fully-qualified executableName. Ensure this value matches the actual executable defined in the cabal file; otherwise nix-build will fail to resolve the attribute. If this template is used for arbitrary projects, consider deriving executableName from the generated Cabal template to avoid drift. [suggest_nitpick] π Script executed: #!/bin/bash
set -euo pipefail
echo "Cabal packages and executables detected:"
fd -t f --extension cabal -a | while read -r f; do
echo "--- $f"
rg -nP '^\s*name\s*:\s*(\S+)' "$f" || true
rg -nP '^\s*executable\s+(\S+)' -n "$f" || true
doneLength of output: 719 Fix Nix executableName to match Cabal executable The executableName = "#{name}:exe:#{name}";which expands to Please update in cli/src/Neo/Build/Templates/Nix.hs (lines 21-25):
To prevent this slipping out of sync in future, consider deriving π€ Prompt for AI Agents |
||
| } | ||
|
|
||
| |] | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -75,9 +75,10 @@ handle config = do | |||||||||||||||
| File.writeText targetAppPath appMainFile | ||||||||||||||||
| |> Task.mapError (\_ -> CustomError "Could not write app main file") | ||||||||||||||||
|
|
||||||||||||||||
| let shellExpression = | ||||||||||||||||
| let shellExpression :: Text = | ||||||||||||||||
| [fmt|{ pkgs ? import <nixpkgs> {} }: | ||||||||||||||||
| ( (#{nixFile}) { inherit pkgs; } ).env|] | ||||||||||||||||
| ( (#{nixFile}) { inherit pkgs; } ).shell|] | ||||||||||||||||
|
|
||||||||||||||||
|
Comment on lines
+78
to
+81
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ Verification agent π§© Analysis chainStop returning a lambda to nix-shell; emit a derivation (use let/in). nix-shell -E expects an expression that evaluates to a derivation or a shell env, not a top-level lambda. The current expression starts with a lambda and will not be evaluated as intended. Apply this fix to bind pkgs via let/in and return the shell directly: - let shellExpression :: Text =
- [fmt|{ pkgs ? import <nixpkgs> {} }:
- ( (#{nixFile}) { inherit pkgs; } ).shell|]
+ let shellExpression :: Text =
+ [fmt|let pkgs = import <nixpkgs> {}; in
+ ( (#{nixFile}) { inherit pkgs; } ).shell|]Follow-up: the direct import of assumes NIX_PATH is set. Either pin nixpkgs (preferred) or ensure CI sets NIX_PATH/-I. See my comments on default.nix/common.nix for a robust pin. Run this to confirm nix-shell evaluates to a derivation and not a lambda: π Script executed: #!/bin/bash
# Show what the expression evaluates to (should not be a lambda)
rg -n -C2 'shellExpression' cli/src/Neo/Shell.hsLength of output: 477 Stop returning a topβlevel lambda to nix-shell; emit a derivation nix-shell -E requires an expression that evaluates directly to a derivation or shell env, not a lambda. In - let shellExpression :: Text =
- [fmt|{ pkgs ? import <nixpkgs> {} }:
- ( (#{nixFile}) { inherit pkgs; } ).shell|]
+ let shellExpression :: Text =
+ [fmt|let pkgs = import <nixpkgs> {}; in
+ ( (#{nixFile}) { inherit pkgs; } ).shell|]Additionally, avoid relying on an externally set π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||
| completion <- | ||||||||||||||||
| Subprocess.openInherit "nix-shell" (Array.fromLinkedList ["-E", shellExpression]) rootFolder Subprocess.InheritBOTH | ||||||||||||||||
| if completion.exitCode != 0 | ||||||||||||||||
|
|
||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { pkgs ? import ./nix/nixpkgs.nix { } }: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Thread the compiler choice; do not hard-code what the cosmos may change. Expose a configurable compiler and pass it down to the project builder; default to a verified choice. Apply: -{ pkgs ? import ./nix/nixpkgs.nix { } }:
+{ pkgs ? import ./nix/nixpkgs.nix { }, compilerNixName ? "ghc910" }:
...
-in (hp {
+in (hp {
packages = {
"nhcore" = ./core;
"nhcli" = ./cli;
};
mainPackageName = "nhcli";
executableName = "nhcli:exe:neo";
-})
+ compilerNixName = compilerNixName;
+})Also applies to: 10-12 π€ Prompt for AI Agentsπ§Ή Nitpick (assertive) Eliminate the default pkgs import here to prevent accidental double-pinning. Since default.nix and shell.nix already pass a pinned pkgs, making pkgs mandatory here avoids mixing nixpkgs instances if someone imports common.nix directly. Apply: -{ pkgs ? import ./nix/nixpkgs.nix { }, compilerNixName ? "ghc910" }:
+{ pkgs, compilerNixName ? "ghc910" }:
π€ Prompt for AI Agents |
||
|
|
||
| let hp = import ./cli/nix/haskell-project.nix { inherit pkgs; }; | ||
| in (hp { | ||
| packages = { | ||
| "nhcore" = ./.; | ||
| "nhcli" = ./.; | ||
| }; | ||
|
|
||
| mainPackageName = "nhcli"; | ||
| executableName = "nhcli:exe:neo"; | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| import ./cli/default.nix | ||
| { pkgs ? import ./nix/nixpkgs.nix { } }: | ||
| ((import ./common.nix { inherit pkgs; }).package) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,10 @@ | ||
| # Pinned nixpkgs for NeoHaskell project | ||
| # Last updated: 2025-08-25 | ||
|
Comment on lines
+1
to
+2
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Reduce duplication; bind the revision once and derive the name. This avoids editing multiple spots when bumping nixpkgs. Apply: -import (builtins.fetchTarball {
- name = "nixpkgs-20075955";
- url = "https://github.com/nixos/nixpkgs/archive/20075955deac2583bb12f07151c2df830ef346b4.tar.gz";
+let
+ rev = "20075955deac2583bb12f07151c2df830ef346b4";
+in import (builtins.fetchTarball {
+ name = "nixpkgs-${rev}";
+ url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz";Also applies to: 5-6 π€ Prompt for AI Agents |
||
| # Commit from nixos-unstable branch (2025-08-19) | ||
| import (builtins.fetchTarball { | ||
| name = "nixpkgs-054144e5"; | ||
| url = | ||
| "https://github.com/nixos/nixpkgs/archive/054144e516ca1e3cf5706d5c3427d350eaa107af.tar.gz"; | ||
| sha256 = "0ixd2mc9kkmr8mz20ah2j7akgwllxsjv94ah895zgi9b9q1h25ka"; | ||
| name = "nixpkgs-20075955"; | ||
| url = "https://github.com/nixos/nixpkgs/archive/20075955deac2583bb12f07151c2df830ef346b4.tar.gz"; | ||
| # To get the sha256, run: | ||
| # nix-prefetch-url --unpack https://github.com/nixos/nixpkgs/archive/20075955deac2583bb12f07151c2df830ef346b4.tar.gz | ||
| sha256 = "1s3lxb33cwazlx72pygcbcc76bbgbhdil6q9bhqbzbjxj001zk0w"; | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,38 +45,51 @@ if [[ $REPLY =~ ^[Nn]$ ]]; then | |
| else | ||
| echo "π§ Adding binary cache configuration..." | ||
|
|
||
| # Create /etc/nix/nix.conf if it doesn't exist | ||
| if [ ! -f /etc/nix/nix.conf ]; then | ||
| echo "Creating /etc/nix/nix.conf..." | ||
| sudo mkdir -p /etc/nix | ||
| sudo touch /etc/nix/nix.conf | ||
| # Add binary cache configuration to custom config file | ||
| sudo mkdir -p /etc/nix | ||
| if [ ! -f /etc/nix/nix.custom.conf ]; then | ||
| echo "Creating /etc/nix/nix.custom.conf..." | ||
| sudo touch /etc/nix/nix.custom.conf | ||
| fi | ||
|
|
||
| # Check if the substituters line exists | ||
| if sudo grep -q "^extra-substituters" /etc/nix/nix.conf; then | ||
| # Add to existing line if not already present | ||
| if ! sudo grep -q "$BINARY_CACHE_SUBSTITUTERS" /etc/nix/nix.conf; then | ||
| escaped_substituters=$(printf '%s\n' "$BINARY_CACHE_SUBSTITUTERS" | sed 's/[[\.*^$()+?{|]/\\&/g') | ||
| sudo sed -i "/^extra-substituters/s/$/ $escaped_substituters/" /etc/nix/nix.conf | ||
| fi | ||
| else | ||
| # Add new line | ||
| echo "extra-substituters = $BINARY_CACHE_SUBSTITUTERS" | sudo tee -a /etc/nix/nix.conf > /dev/null | ||
| # Append our config if not already present | ||
| if ! sudo grep -q "$BINARY_CACHE_SUBSTITUTERS" /etc/nix/nix.custom.conf; then | ||
| echo "extra-substituters = $BINARY_CACHE_SUBSTITUTERS" | sudo tee -a /etc/nix/nix.custom.conf > /dev/null | ||
| fi | ||
| if ! sudo grep -q "$BINARY_CACHE_PUBLIC_KEYS" /etc/nix/nix.custom.conf; then | ||
| echo "extra-trusted-public-keys = $BINARY_CACHE_PUBLIC_KEYS" | sudo tee -a /etc/nix/nix.custom.conf > /dev/null | ||
| fi | ||
|
|
||
| # Check if the trusted-public-keys line exists | ||
| if sudo grep -q "^extra-trusted-public-keys" /etc/nix/nix.conf; then | ||
| # Add to existing line if not already present | ||
| if ! sudo grep -q "$BINARY_CACHE_PUBLIC_KEYS" /etc/nix/nix.conf; then | ||
| escaped_keys=$(printf '%s\n' "$BINARY_CACHE_PUBLIC_KEYS" | sed 's/[[\.*^$()+?{|]/\\&/g') | ||
| sudo sed -i "/^extra-trusted-public-keys/s/$/ $escaped_keys/" /etc/nix/nix.conf | ||
| echo "β Binary cache configuration added successfully!" | ||
|
|
||
| # Restart nix daemon to pick up new configuration | ||
| echo "π Restarting Nix daemon to apply configuration changes..." | ||
|
|
||
| # Detect platform and restart daemon accordingly | ||
| if [[ "$OSTYPE" == "darwin"* ]]; then | ||
| # macOS | ||
| if sudo launchctl kickstart -k system/org.nixos.nix-daemon 2>/dev/null; then | ||
| echo "β Nix daemon restarted successfully on macOS" | ||
| else | ||
| echo "β οΈ Failed to restart nix daemon on macOS - configuration will take effect on next restart" | ||
| fi | ||
| elif command -v systemctl &> /dev/null; then | ||
| # Linux with systemd (including WSL with systemd) | ||
| if sudo systemctl restart nix-daemon.service 2>/dev/null; then | ||
| echo "β Nix daemon restarted successfully" | ||
| else | ||
| echo "β οΈ Failed to restart nix daemon - configuration will take effect on next restart" | ||
| fi | ||
| else | ||
| # Add new line | ||
| echo "extra-trusted-public-keys = $BINARY_CACHE_PUBLIC_KEYS" | sudo tee -a /etc/nix/nix.conf > /dev/null | ||
| # WSL or Linux without systemd - try pkill approach | ||
| echo "π Attempting to restart nix daemon..." | ||
| if sudo pkill nix-daemon 2>/dev/null; then | ||
| echo "β Nix daemon stopped - it will restart automatically on next use" | ||
| else | ||
| echo "β οΈ Cannot automatically restart nix daemon on this system" | ||
| echo " Configuration will take effect when you restart your shell or reboot" | ||
| fi | ||
| fi | ||
|
Comment on lines
+76
to
92
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick (assertive) Add a fallback when systemctl restart fails. On some distros/WSL with systemd present but not fully functional, systemctl may exist yet fail. Fall back to pkill in that branch to avoid a no-op. Apply this refinement: @@
- elif command -v systemctl &> /dev/null; then
+ elif command -v systemctl &> /dev/null; then
# Linux with systemd (including WSL with systemd)
- if sudo systemctl restart nix-daemon.service 2>/dev/null; then
+ if sudo systemctl restart nix-daemon.service 2>/dev/null; then
echo "β
Nix daemon restarted successfully"
else
- echo "β οΈ Failed to restart nix daemon - configuration will take effect on next restart"
+ echo "β οΈ Failed to restart nix daemon via systemd - attempting manual stop so it auto-restarts"
+ if sudo pkill nix-daemon 2>/dev/null; then
+ echo "β
Nix daemon stopped - it will restart automatically on next use"
+ else
+ echo "β οΈ Cannot automatically restart nix daemon on this system"
+ echo " Configuration will take effect when you restart your shell or reboot"
+ fi
fiπ€ Prompt for AI Agents |
||
|
|
||
| echo "β Binary cache configuration added successfully!" | ||
| fi | ||
|
|
||
| echo "" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,58 +1 @@ | ||
| { pkgs ? import ./nix/nixpkgs.nix { }, }: | ||
| let | ||
| nix-pre-commit-hooks = import (builtins.fetchTarball | ||
| "https://github.com/cachix/git-hooks.nix/tarball/master"); | ||
| in let | ||
| pre-commit = { | ||
| # Configured with the module options defined in `modules/pre-commit.nix`: | ||
| pre-commit-check = nix-pre-commit-hooks.run { | ||
| src = ./.; | ||
| # If your hooks are intrusive, avoid running on each commit with a default_states like this: | ||
| # default_stages = ["manual" "pre-push"]; | ||
| hooks = { | ||
| fourmolu.enable = true; | ||
| nixfmt-classic.enable = true; | ||
| }; | ||
| }; | ||
| }; | ||
| in pkgs.mkShell rec { | ||
| buildInputs = [ | ||
| # Haskell dev tools | ||
| pkgs.ghc | ||
| pkgs.cabal-install | ||
| pkgs.haskell-language-server | ||
| pkgs.fourmolu | ||
| pkgs.hlint | ||
| pkgs.haskellPackages.zlib | ||
| pkgs.haskellPackages.hspec-discover | ||
| pkgs.haskellPackages.doctest | ||
|
|
||
| # Nix dev tools | ||
| pkgs.nil | ||
| pkgs.nixfmt-classic | ||
| pkgs.nixpkgs-fmt | ||
|
|
||
| # Website | ||
| pkgs.nodejs | ||
|
|
||
| # Required native libs | ||
| pkgs.pkg-config | ||
| pkgs.zlib | ||
| ] ++ pre-commit.pre-commit-check.enabledPackages; | ||
|
|
||
| shellHook = '' | ||
| unset TEMP TMP TEMPDIR TMPDIR # Required for nix-shell to work | ||
| ${pre-commit.pre-commit-check.shellHook} | ||
|
|
||
| run-doctests-verbose() { | ||
| cabal repl --with-compiler=doctest --repl-options=--verbose core | ||
| } | ||
|
|
||
| run-doctests() { | ||
| cabal repl --with-compiler=doctest core | ||
| } | ||
| ''; | ||
|
|
||
| # Required for cabal to find the location of zlib and other native libraries | ||
| LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; | ||
| } | ||
| { pkgs ? import ./nix/nixpkgs.nix { } }: ((import ./common.nix { inherit pkgs; }).shell) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π§Ή Nitpick (assertive)
Add a trailing newline to satisfy linters.
YAMLlint flags βno new line character at the end of file.β Add a newline to keep CI green and editors happy.
Apply:
π Committable suggestion
π§° Tools
πͺ YAMLlint (1.37.1)
[error] 6-6: no new line character at the end of file
(new-line-at-end-of-file)
π€ Prompt for AI Agents
π§Ή Nitpick (assertive)
Tame update noise with groups and metadata (still one ecosystem: github-actions).
Given the PRβs goal to standardize infra, group GH Actions updates to reduce PR churn and add metadata for routing.
Example:
version: 2 updates: - package-ecosystem: github-actions directory: / schedule: interval: weekly + groups: + gha-all: + patterns: + - "*" + reviewers: + - "neo-haskell/maintainers" + labels: + - "dependencies" + - "gha"π§° Tools
πͺ YAMLlint (1.37.1)
[error] 6-6: no new line character at the end of file
(new-line-at-end-of-file)
π€ Prompt for AI Agents