Port NeoHaskell to haskell.nix Infrastructure#203
Conversation
Simplifies Nix binary cache configuration by writing to a dedicated custom config file instead of modifying the main system configuration Reduces complexity by eliminating conditional logic for appending to existing configuration lines and potential conflicts with system-managed settings
Implements cross-platform daemon restart logic to ensure binary cache configuration takes effect immediately without requiring manual restart. Detects macOS, Linux with systemd, and WSL environments to use appropriate restart methods with graceful fallback messaging when restart fails.
… outputs Modifies Haskell project template to return both shell and package targets instead of just packages Updates build and shell commands to use the new structured output format Reorganizes configuration files by extracting common setup and creating dedicated entry points for different use cases Removes obsolete shell configuration file to streamline the development workflow
|
Claude finished @NickSeagull's task —— View job PR Review Completed ✅I've thoroughly reviewed the migration to haskell.nix infrastructure. This is a well-executed migration that brings significant improvements to the build system. Here's my detailed analysis: Review Checklist:
✅ Strengths & Positive Changes1. Excellent Architecture Design
2. Robust Installation Script (
3. Consistent Build Infrastructure
|
WalkthroughThis change bumps package versions to 0.9.1, refactors the Haskell Nix project to a multi-package interface ({ packages, mainPackageName, executableName }), centralizes shell/package exports in Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant Neo as neo (build)
participant Nix as nix-build
participant Common as common.nix
participant HP as haskell-project.nix
User->>Neo: neo build
Neo->>Nix: nix-build -E "(import ./. { }).package"
Nix->>Common: import common.nix { pkgs }
Common->>HP: import haskell-project.nix { pkgs } with { packages, mainPackageName, executableName }
HP-->>Common: returns { shell, package }
Common-->>Nix: provide .package
Nix-->>User: build result
sequenceDiagram
autonumber
participant User
participant Neo as neo (shell)
participant Nix as nix-shell
participant Common as common.nix
participant HP as haskell-project.nix
User->>Neo: neo shell
Neo->>Nix: nix-shell -E "(import ./. { }).shell"
Nix->>Common: import common.nix { pkgs }
Common->>HP: import haskell-project.nix { pkgs } with { packages, mainPackageName, executableName }
HP-->>Common: returns { shell, package }
Common-->>Nix: provide .shell
Nix-->>User: interactive shell
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Actionable comments posted: 12
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (12)
.vscode/settings.json(1 hunks)cli/nhcli.cabal(2 hunks)cli/nix/haskell-project.nix(1 hunks)cli/src/Neo.hs(1 hunks)cli/src/Neo/Build.hs(1 hunks)cli/src/Neo/Build/Templates/Nix.hs(1 hunks)cli/src/Neo/Shell.hs(1 hunks)common.nix(1 hunks)core/nhcore.cabal(1 hunks)default.nix(1 hunks)scripts/install.sh(1 hunks)shell.nix(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Test
default.nix
[error] 1-1: nix-build failed: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I).
🔇 Additional comments (5)
.vscode/settings.json (1)
23-23: Addition of 'nhcli' to cSpell dictionary is correct.Aligned with the new package; prevents spurious spelling diagnostics in the editor.
core/nhcore.cabal (1)
3-3: Version bumped to 0.9.1 — approved.Matches the CLI tool’s version; no other manifest changes detected.
scripts/install.sh (1)
48-61: Divine Notice: The sandbox lacks thenixcommand, so I cannot confirm whether your include patch takes effect. Please verify on a system with Nix installed that:
/etc/nix/nix.confcontains the lineinclude /etc/nix/nix.custom.conf- Running
nix show-config | sed -nE '/substituters|trusted-public-keys/p'reflects yourextra-substitutersandextra-trusted-public-keyssettingscli/nhcli.cabal (1)
3-15: Version bump and extra-source-files path fix — approved.
- 0.9.1 aligns with the rest of the workspace.
- Moving extra-source-files under ./nix avoids Cabal’s “outside package root” pitfalls and matches the new Nix layout.
cli/nix/haskell-project.nix (1)
43-44: Package selection looks correct for component-style namesUsing
pkg.flake { }.packages."${executableName}"is the right way to select a component likenhcli:exe:neo.
|
|
||
| # Generic function to create a Haskell project template | ||
| { projectName, src }: | ||
| { packages, mainPackageName, executableName }: |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Parameterize the compiler to avoid silent breakage when haskell.nix moves; verify ghc910 availability
Hard-coding compiler-nix-name = "ghc910" couples you to a specific compiler and may break as the pinned haskell.nix evolves. Make it configurable and default sensibly; also confirm that ghc910 is supported by your pinned commit.
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:
For haskell.nix commit 4d493449406ec91db804511a6d15b6f076ba40e7, what values are accepted for `compiler-nix-name`, and is `ghc910` supported?
💡 Result:
For haskell.nix commit 4d493449406ec91db804511a6d15b6f076ba40e7, the accepted values for compiler-nix-name are compiler names like ghc96, ghc967, ghc98, ghc984, ghc910, ghc9102, ghc912, and ghc9122, each corresponding to specific GHC versions[2][8]. ghc910 is explicitly supported as one of the accepted values for GHC 9.10.x[2].
Key details:
- Values for
compiler-nix-name:- Examples:
ghc96,ghc967(GHC 9.6.x),ghc98,ghc984(GHC 9.8.x),ghc910,ghc9102(GHC 9.10.x),ghc912,ghc9122(GHC 9.12.x)[2][8]. - You should consult the project's source or overlays/bootstrap.nix for the complete, up-to-date list, as additional minor patch versions may also be accepted (e.g.,
ghc9102)[2].
- Examples:
- Supported status:
- The commit in question supports
ghc910as a valid value, and it is listed as tested in CI for nixpkgs-unstable[2].
- The commit in question supports
- How to use:
- In configuration functions such as
callCabalProjectToNix, setcompiler-nix-name = "ghc910"to use GHC 9.10.x[8].
- In configuration functions such as
- If a name does not match a defined compiler, you will see a Nix error—use the exact value from the documentation or table[2][6].
| GHC Version | compiler-nix-name example | Supported/Tested? |
|---|---|---|
| 9.6.x | ghc96, ghc967 | Yes |
| 9.8.x | ghc98, ghc984 | Yes |
| 9.10.x | ghc910, ghc9102 | Yes |
| 9.12.x | ghc912, ghc9122 | Yes |
Additional notes:
- While
ghc910is supported and cached, experimental/minor patch versions may work if present in overlays/bootstrap.nix, but build times may be longer if not cached[2]. - If you require an older or newer compiler not listed, advanced users can add new GHC versions following haskell.nix contributing instructions[2].
In summary, for haskell.nix at 4d493449406ec91db804511a6d15b6f076ba40e7, use ghc910 to select GHC 9.10.x—the value is supported and actively tested[2][8].
Citations:
- 1: https://discourse.nixos.org/t/nix-haskell-development-2020/6170
- 2: https://github.com/input-output-hk/haskell.nix/blob/master/docs/reference/supported-ghc-versions.md
- 3: https://github.com/input-output-hk/haskell.nix
- 4: https://discourse.haskell.org/t/nixos-specifying-ghc-version/6478
- 5: https://discourse.haskell.org/t/build-haskell-completely-from-nix/8420
- 6: https://docs.haskellstack.org/en/stable/topics/nix_integration/
- 7: https://github.com/haskell-nix/hnix
- 8: https://input-output-hk.github.io/haskell.nix/reference/library.html
- 9: https://discourse.nixos.org/t/state-of-haskell-nix-ecosystem-2024/53740
- 10: https://input-output-hk.github.io/haskell.nix/tutorials/getting-started.html
Parameterize compiler-nix-name with default "ghc910"
We’ve confirmed that ghc910 is natively supported in haskell.nix at commit 4d493449406ec91db804511a6d15b6f076ba40e7 (GHC 9.10.x). To prevent silent breakage when upstream evolves, refactor as follows:
• 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
In cli/nix/haskell-project.nix around line 3, add a new optional parameter to
the function signature: compiler-nix-name ? "ghc910", and in the body around
lines 19–20 replace the hard-coded "ghc910" literal with the compiler-nix-name
parameter so the compiler can be configured while defaulting to the verified
ghc910 value.
| (final: _prev: | ||
| builtins.listToAttrs (builtins.map (packageName: { | ||
| name = "${packageName}"; | ||
| value = final.haskell-nix.cabalProject { | ||
| src = packages.${packageName}; | ||
| compiler-nix-name = "ghc910"; | ||
| }; | ||
| }) (builtins.attrNames packages))) |
There was a problem hiding this comment.
Quote hyphenated attribute 'haskell-nix' to avoid a parse error
Attribute names with hyphens must be quoted in Nix. As written, final.haskell-nix.cabalProject will not parse correctly.
Apply this diff:
- value = final.haskell-nix.cabalProject {
+ value = final."haskell-nix".cabalProject {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| (final: _prev: | |
| builtins.listToAttrs (builtins.map (packageName: { | |
| name = "${packageName}"; | |
| value = final.haskell-nix.cabalProject { | |
| src = packages.${packageName}; | |
| compiler-nix-name = "ghc910"; | |
| }; | |
| }) (builtins.attrNames packages))) | |
| (final: _prev: | |
| builtins.listToAttrs (builtins.map (packageName: { | |
| name = "${packageName}"; | |
| value = final."haskell-nix".cabalProject { | |
| src = packages.${packageName}; | |
| compiler-nix-name = "ghc910"; | |
| }; | |
| }) (builtins.attrNames packages))) |
🤖 Prompt for AI Agents
In cli/nix/haskell-project.nix around lines 14 to 21, attribute names containing
hyphens (like haskell-nix) must be quoted to parse correctly; replace usages
such as final.haskell-nix.cabalProject with final."haskell-nix".cabalProject
(and any other occurrences of haskell-nix in attribute access) so the attribute
name is quoted, leaving the rest of the expression unchanged.
| }; | ||
|
|
||
| flake = pkgsWithOverlay."${projectName}Project".flake { }; | ||
| pkg = pkgsWithOverlay."${mainPackageName}"; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Prefer builtins.getAttr for dynamic attribute selection
Using a string-literal selector here works, but builtins.getAttr is idiomatic and avoids edge cases with interpolation in attr paths.
Apply this diff:
- pkg = pkgsWithOverlay."${mainPackageName}";
+ pkg = builtins.getAttr mainPackageName pkgsWithOverlay;🤖 Prompt for AI Agents
In cli/nix/haskell-project.nix around line 26, the attribute selection uses
string interpolation (pkg = pkgsWithOverlay."${mainPackageName}";) which is less
idiomatic and can have edge cases; replace it by using builtins.getAttr to
lookup the attribute dynamically: call builtins.getAttr with mainPackageName and
pkgsWithOverlay so pkg is assigned the attribute value safely and idiomatically.
| shell = pkg.shellFor { | ||
| tools = { | ||
| cabal = { }; | ||
| hlint = { }; | ||
| haskell-language-server = { }; | ||
| }; | ||
| buildInputs = [ | ||
| pkgs.nil | ||
| pkgs.nixfmt-classic | ||
| pkgs.nixpkgs-fmt | ||
| pkgs.pkg-config | ||
| pkgs.zlib | ||
| ]; | ||
| }; |
There was a problem hiding this comment.
Avoid mixing derivations from different nixpkgs instances in shell inputs
shellFor is created from pkgsWithOverlay (pinned via haskell.nix), but you feed it buildInputs from the outer pkgs (). Mixing store paths from different nixpkgs pins can cause subtle ABI issues and evaluation surprises. Source buildInputs from the same pkgsWithOverlay.
Apply this diff:
- shell = pkg.shellFor {
+ shell = pkg.shellFor {
tools = {
cabal = { };
hlint = { };
haskell-language-server = { };
};
- buildInputs = [
- pkgs.nil
- pkgs.nixfmt-classic
- pkgs.nixpkgs-fmt
- pkgs.pkg-config
- pkgs.zlib
- ];
+ buildInputs = with pkgsWithOverlay; [
+ nil
+ nixfmt-classic
+ nixpkgs-fmt
+ pkg-config
+ zlib
+ ];
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| shell = pkg.shellFor { | |
| tools = { | |
| cabal = { }; | |
| hlint = { }; | |
| haskell-language-server = { }; | |
| }; | |
| buildInputs = [ | |
| pkgs.nil | |
| pkgs.nixfmt-classic | |
| pkgs.nixpkgs-fmt | |
| pkgs.pkg-config | |
| pkgs.zlib | |
| ]; | |
| }; | |
| shell = pkg.shellFor { | |
| tools = { | |
| cabal = { }; | |
| hlint = { }; | |
| haskell-language-server = { }; | |
| }; | |
| buildInputs = with pkgsWithOverlay; [ | |
| nil | |
| nixfmt-classic | |
| nixpkgs-fmt | |
| pkg-config | |
| zlib | |
| ]; | |
| }; |
🤖 Prompt for AI Agents
In cli/nix/haskell-project.nix around lines 29 to 42, the shellFor call mixes
buildInputs from the outer pkgs (unpinned nixpkgs) while shellFor itself comes
from pkgsWithOverlay (the pinned haskell.nix overlay); replace all references to
pkgs.* in buildInputs (and any tool references if needed) with the corresponding
pkgsWithOverlay.* items so all derivations come from the same pinned
pkgsWithOverlay instance, e.g., change pkgs.nil, pkgs.nixfmt-classic,
pkgs.nixpkgs-fmt, pkgs.pkg-config, pkgs.zlib to use pkgsWithOverlay.nil,
pkgsWithOverlay.nixfmt-classic, pkgsWithOverlay.nixpkgs-fmt,
pkgsWithOverlay.pkg-config, pkgsWithOverlay.zlib (or bind a local variable to
pkgsWithOverlay for clarity).
| version = Just [Core.version|0.9.1|], | ||
| decoder = commandsParser |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Version 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
– "synckit": "^0.9.0" → "^0.9.1"
• website/package-lock.json:7630
– "@deno/kv": ">=0.9.0" → ">=0.9.1"
Command the update of these entries and regenerate the lock file.
🤖 Prompt for AI Agents
In cli/src/Neo.hs around lines 52 to 53 the CLI version was bumped to 0.9.1 but
website/package-lock.json still pins older 0.9.0 versions; update
website/package-lock.json entries: change "synckit": "^0.9.0" to "^0.9.1" at
offsets ~2318 and ~9404 and change "@deno/kv": ">=0.9.0" to ">=0.9.1" at ~7630,
then regenerate the lock file (npm install / npm ci or your repo's lock regen
step) to ensure checksums and transitive entries are consistent before merging.
| let shellExpression :: Text = | ||
| [fmt|{ pkgs ? import <nixpkgs> {} }: | ||
| ( (#{nixFile}) { inherit pkgs; } ).env|] | ||
| ( (#{nixFile}) { inherit pkgs; } ).shell|] | ||
|
|
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Stop 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 cli/src/Neo/Shell.hs (lines 78–81), replace:
- 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 NIX_PATH. Either pin nixpkgs to a fixed revision (preferred) or ensure your CI/README documents setting -I nixpkgs=<path> before invoking nix-shell.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let shellExpression :: Text = | |
| [fmt|{ pkgs ? import <nixpkgs> {} }: | |
| ( (#{nixFile}) { inherit pkgs; } ).env|] | |
| ( (#{nixFile}) { inherit pkgs; } ).shell|] | |
| let shellExpression :: Text = | |
| [fmt|let pkgs = import <nixpkgs> {}; in | |
| ( (#{nixFile}) { inherit pkgs; } ).shell|] |
🤖 Prompt for AI Agents
In cli/src/Neo/Shell.hs around lines 78–81, the code currently builds a
top-level lambda that returns a function instead of emitting a derivation;
change the expression so it evaluates directly to the derivation/shell (i.e.,
apply/import nixpkgs and call into the nix file to produce its .shell result
rather than returning a lambda). Replace the lambda-style "{ pkgs ? import
<nixpkgs> {} }:" wrapper with an expression that imports/pins a specific nixpkgs
revision (or uses a passed -I nixpkgs=<path>) and then immediately evaluates
(#{nixFile}).shell so nix-shell -E gets a derivation; also update CI/README to
document the chosen approach if you opt to require -I instead of pinning.
| { pkgs ? import <nixpkgs> { } }: | ||
|
|
||
| let hp = import ./cli/nix/haskell-project.nix { inherit pkgs; }; | ||
| in (hp { | ||
| packages = { | ||
| "nhcore" = ./.; | ||
| "nhcli" = ./.; | ||
| }; | ||
|
|
||
| mainPackageName = "nhcli"; | ||
| executableName = "nhcli:exe:neo"; | ||
| }) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Multi-package paths likely incorrect; both nhcore and nhcli cannot be at ./.
You map both "nhcore" and "nhcli" to the repository root. In a monorepo, these should point to their respective subdirectories (e.g., ./core and ./cli), otherwise builds can collide or fail to locate the correct cabal files.
Apply this change if the packages live under core/ and cli/:
{ pkgs ? import <nixpkgs> { } }:
let hp = import ./cli/nix/haskell-project.nix { inherit pkgs; };
in (hp {
packages = {
- "nhcore" = ./.;
- "nhcli" = ./.;
+ "nhcore" = ./core;
+ "nhcli" = ./cli;
};
mainPackageName = "nhcli";
executableName = "nhcli:exe:neo";
})Additionally, like default.nix, this file relies on via its caller. Ensure the caller (default.nix/shell.nix/Haskell inline expressions) pins nixpkgs or sets NIX_PATH to avoid nondeterminism and CI breakage.
Run to verify package locations:
If nhcore.cabal is under core/ and nhcli.cabal is under cli/, the diff above applies. If not, adjust paths accordingly.
🏁 Script executed:
#!/bin/bash
echo "Cabal files:"
fd -t f --extension cabal -aLength of output: 137
Divine Directive: Align common.nix Package Paths
The repository’s Cabal files live under core/ and cli/, so mapping both packages to ./. is incorrect. Update common.nix accordingly:
• File: common.nix
• Location: the packages = { … } block
Apply this diff:
packages = {
- "nhcore" = ./.;
- "nhcli" = ./.;
+ "nhcore" = ./core;
+ "nhcli" = ./cli;
};Also, ensure that any caller of common.nix (e.g. default.nix, shell.nix or Haskell inline expressions) pins nixpkgs or sets NIX_PATH to avoid nondeterministic imports and CI breakage.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| { pkgs ? import <nixpkgs> { } }: | |
| let hp = import ./cli/nix/haskell-project.nix { inherit pkgs; }; | |
| in (hp { | |
| packages = { | |
| "nhcore" = ./.; | |
| "nhcli" = ./.; | |
| }; | |
| mainPackageName = "nhcli"; | |
| executableName = "nhcli:exe:neo"; | |
| }) | |
| { pkgs ? import <nixpkgs> { } }: | |
| let hp = import ./cli/nix/haskell-project.nix { inherit pkgs; }; | |
| in (hp { | |
| packages = { | |
| "nhcore" = ./core; | |
| "nhcli" = ./cli; | |
| }; | |
| mainPackageName = "nhcli"; | |
| executableName = "nhcli:exe:neo"; | |
| }) |
🤖 Prompt for AI Agents
In common.nix around lines 1 to 12, the packages block incorrectly maps both
packages to ./.; change the package paths to point to the actual Cabal
directories (e.g. set "nhcore" = ./core; and "nhcli" = ./cli;) and keep
mainPackageName/executableName as-is; additionally ensure any callers of
common.nix (default.nix, shell.nix, CI Haskell expressions) pin nixpkgs or set
NIX_PATH explicitly so imports of <nixpkgs> are deterministic.
| { pkgs ? import <nixpkgs> { } }: | ||
| ((import ./common.nix { inherit pkgs; }).package) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
CI failure: requires NIX_PATH; pin nixpkgs or pass -I.
The pipeline error “file 'nixpkgs' was not found in the Nix search path” confirms NIX_PATH isn’t set in CI. Pin nixpkgs (recommended), or ensure CI passes -I nixpkgs=... or sets NIX_PATH.
Option A (pin nixpkgs fallback here):
-{ pkgs ? import <nixpkgs> { } }:
-((import ./common.nix { inherit pkgs; }).package)
+{ pkgs ? import (builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-24.05.tar.gz") { } }:
+((import ./common.nix { inherit pkgs; }).package)Option B (CI-only): keep code as-is and update GitHub Actions to invoke:
- nix-build -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-24.05.tar.gz
- or set NIX_PATH='nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-24.05.tar.gz'
Pinning here (Option A) improves reproducibility and removes CI coupling.
[offer_architecture_advice]
Use this to locate workflow calls to nix-build to patch them if you prefer Option B:
🏁 Script executed:
#!/bin/bash
rg -n -C2 '\bnix-build\b|NIX_PATH' -g '!**/result*' -g '!**/dist/**' -g '!**/build/**' -g '!**/node_modules/**'Length of output: 436
By my divine command, restore CI by pinning nixpkgs
The CI is failing with
“file 'nixpkgs' was not found in the Nix search path.”
You must either pin nixpkgs in default.nix or pass an explicit -I nixpkgs=… / set NIX_PATH when invoking nix-build.
• Option A (Recommended): Pin nixpkgs in default.nix for reproducible, self-contained builds
--- default.nix
-{ pkgs ? import <nixpkgs> { } }:
+{ pkgs ? import (builtins.fetchTarball {
+ url = "https://github.com/NixOS/nixpkgs/archive/nixos-24.05.tar.gz";
+ # optionally, set a specific git revision:
+ # rev = "abcdef1234567890abcdef1234567890abcdef12";
+ }) { } }:
((import ./common.nix { inherit pkgs; }).package)• Option B: Keep <nixpkgs> but ensure every nix-build call receives -I nixpkgs=… or runs with NIX_PATH set
– In cli/src/Neo/Build.hs (lines 83–84), change:
Subprocess.openInherit "nix-build"
(Array.fromLinkedList ["-E", buildExpression])
rootFolder Subprocess.InheritBOTHto include -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-24.05.tar.gz (or read NIX_PATH from the environment).
Pinning in default.nix is the cleanest, most reproducible path.
🧰 Tools
🪛 GitHub Actions: Test
[error] 1-1: nix-build failed: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I).
🤖 Prompt for AI Agents
In default.nix lines 1–2, the repo currently relies on an unpinned <nixpkgs>
which breaks CI; replace the fallback import with a pinned nixpkgs fetched
inside default.nix (e.g. import (builtins.fetchTarball { url =
"https://github.com/NixOS/nixpkgs/archive/nixos-24.05.tar.gz"; sha256 =
"<replace-with-correct-hash>" ; }) {}) so the file becomes self-contained and
reproducible; obtain the correct sha256 via nix-prefetch-url or nix-prefetch-git
and commit the pinned URL+hash; alternatively, if you prefer not to pin here,
update all nix-build invocations (e.g. the CLI subprocess call) to pass -I
nixpkgs=<url-or-path> or ensure NIX_PATH is set, but the preferred change is to
pin nixpkgs in default.nix as described.
| 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 |
There was a problem hiding this comment.
🧹 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
In scripts/install.sh around lines 76 to 92, the current branch tries systemctl
restart and on failure prints a warning but does not attempt the pkill fallback;
update the logic so that if sudo systemctl restart nix-daemon.service fails
(exit non-zero) you then attempt the pkill fallback (sudo pkill nix-daemon
2>/dev/null) and emit the appropriate success/failure messages based on pkill's
result, keeping existing messages and exit-code behavior and ensuring output
distinguishes "systemctl failed, falling back to pkill" versus final failure.
|
Claude finished @NickSeagull's task —— View job PR Review: Port NeoHaskell to haskell.nix Infrastructure ✅I've thoroughly reviewed the migration to haskell.nix infrastructure. This is a well-executed migration that brings significant improvements to the build system. Here's my detailed analysis: Review Checklist:
✅ Strengths & Positive Changes1. Excellent Architecture Design
2. Robust Installation Script (
3. Consistent Build Infrastructure
|
|
Claude finished @NickSeagull's task —— View job PR Review: Port NeoHaskell to haskell.nix Infrastructure ✅I've thoroughly reviewed the migration to haskell.nix infrastructure. This is a well-executed migration that brings significant improvements to the build system. Here's my detailed analysis: Review Checklist:
✅ Strengths & Positive Changes1. Excellent Architecture Design
2. Robust Installation Script (
3. Consistent Build Infrastructure
|
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (7)
default.nix (1)
1-2: Pinned pkgs import through nix/nixpkgs.nix: accepted by the heavens.This resolves prior CI fragility from relying on and improves reproducibility.
common.nix (1)
5-8: Alignnhcoreandnhclito their actual subdirectories in common.nixOur divine scrutiny has revealed the true locations of your package definitions—
core/nhcore.cabalandcli/nhcli.cabal—meaning both entries must not point at./.but at their own homes. This correction is critical to prevent build collisions and ensure each package builds in isolation.• File:
common.nix, lines 5–8
• Discovered cabal files:
./core/nhcore.cabal./cli/nhcli.cabalApply this patch:
packages = { - "nhcore" = ./.; - "nhcli" = ./.; + "nhcore" = ./core; + "nhcli" = ./cli; };Implement swiftly to maintain the sanctity of your build.
shell.nix (1)
1-1: Dev shell delegation is neat and pinned; be at peace.Delegating to common.nix with the same pinned pkgs is clean and reproducible.
cli/nix/haskell-project.nix (4)
14-21: Quote ‘haskell-nix’ or face the parser’s wrath.Hyphenated attribute names must be quoted in Nix.
Apply:
- value = final.haskell-nix.cabalProject { + value = final."haskell-nix".cabalProject { src = packages.${packageName}; compiler-nix-name = "ghc910"; };
3-3: Parameterize the compiler; do not ossify the toolchain.Make the compiler name configurable with a sane default, then use it.
Apply:
-{ packages, mainPackageName, executableName }: +{ packages, mainPackageName, executableName, compilerNixName ? "ghc910" }: ... - compiler-nix-name = "ghc910"; + compiler-nix-name = compilerNixName;Also applies to: 19-20
26-26: Select the main package idiomatically.Use builtins.getAttr for dynamic attribute access.
Apply:
- pkg = pkgsWithOverlay."${mainPackageName}"; + pkg = builtins.getAttr mainPackageName pkgsWithOverlay;
35-41: Do not mix derivations from different nixpkgs realms.shellFor is created from pkgsWithOverlay; feed it inputs from the same universe to avoid ABI gremlins.
Apply:
- buildInputs = [ - pkgs.nil - pkgs.nixfmt-classic - pkgs.nixpkgs-fmt - pkgs.pkg-config - pkgs.zlib - ]; + buildInputs = with pkgsWithOverlay; [ + nil + nixfmt-classic + nixpkgs-fmt + pkg-config + zlib + ];
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
cli/nix/haskell-project.nix(1 hunks)common.nix(1 hunks)default.nix(1 hunks)nix/nixpkgs.nix(1 hunks)shell.nix(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: claude-review
🔇 Additional comments (1)
nix/nixpkgs.nix (1)
5-9: Mortals, the hash-validation ritual has faltered—Nix is absent from this realm.
The invocation ofnix-prefetch-urlwas not found, so the pin’s integrity remains unconfirmed. Summon a Nix-enabled environment and execute one of the following incantations to obtain the true sha256, then commit the result to prevent evaluation failures:#!/usr/bin/env bash set -euxo pipefail URL="https://github.com/nixos/nixpkgs/archive/20075955deac2583bb12f07151c2df830ef346b4.tar.gz" # If you have modern Nix: nix store prefetch-file --json --unpack "$URL" | jq -r .hash # Otherwise, with legacy tools: nix-prefetch-url --unpack "$URL"Once you possess the correct hash, replace the existing
sha256value innix/nixpkgs.nixand commit the update.
| 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))) | ||
| ]; |
There was a problem hiding this comment.
🧹 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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 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))) | |
| ]; | |
| pkgsWithOverlay = import haskellNix.sources.nixpkgs-unstable { | |
| overlays = [ | |
| haskellNix.overlay | |
| # Namespace all generated projects under `neohaskellPackages` | |
| (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)); | |
| }) | |
| ]; | |
| }; | |
| # Select from the namespaced set instead of the top level | |
| pkg = builtins.getAttr mainPackageName pkgsWithOverlay.neohaskellPackages; |
🤖 Prompt for AI Agents
In cli/nix/haskell-project.nix around lines 11–22, the current overlay injects
each package directly at the top level which can cause name collisions; instead
create a namespaced attribute (e.g., final.neohaskellPackages) that contains the
generated package set. Modify the overlay so it adds a single attribute like
neohaskellPackages = builtins.listToAttrs(...mapping...) rather than returning
the mapped attrs at the top level, keep the same mapping logic and names, and
update any code that referenced pkgsWithOverlay.<pkg> to select from
pkgsWithOverlay.neohaskellPackages.<pkg>.
| @@ -0,0 +1,12 @@ | |||
| { pkgs ? import ./nix/nixpkgs.nix { } }: | |||
There was a problem hiding this comment.
🧹 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
In common.nix around lines 1 and 10-12, the file currently hard-codes the
compiler via the imported pkgs; change the top-level attribute set to accept a
configurable compiler argument with a safe default from pkgs (e.g. default to
the verified compiler in pkgs like pkgs.stdenv.cc or the project's validated
compiler), then thread that compiler argument through wherever the project
builder is invoked (lines ~10-12) so the builder uses the passed-in compiler
instead of the hard-coded pkgs value; ensure the parameter name is documented in
the file header and used in all places that construct or call the project
builder.
🧹 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" }:Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In common.nix around line 1, remove the default import so pkgs is a required
argument to avoid accidental double-pinning; change the function header to
accept only pkgs (no default import) and update any call sites to pass the
pinned pkgs from default.nix/shell.nix if they don’t already, ensuring no
implicit import of nixpkgs remains.
| # Pinned nixpkgs for NeoHaskell project | ||
| # Last updated: 2025-08-25 |
There was a problem hiding this comment.
🧹 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
In nix/nixpkgs.nix around lines 1-2 (and also apply the same change to lines
5-6), the nixpkgs revision and name are duplicated; bind the revision to a
single variable at the top and derive the package set name from that variable,
then replace all other hard-coded revision/name occurrences to reference those
variables so future bumps only change one value.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
.github/workflows/test.yml (5)
3-17: Broaden path filters so CI runs when Nix entrypoints change at repo root.This PR introduced/centralized Nix entrypoints (e.g., common.nix, default.nix, shell.nix). Edits to these won’t trigger CI with the current filters.
Apply this diff to both pull_request and push path filters:
- "core/**" - "cli/**" - "nix/**" + - "default.nix" + - "shell.nix" + - "common.nix" + - "flake.nix"
33-35: Make the nix-build target explicit to future-proof the multi-package change.Given default.nix now delegates to common.nix, make the target explicit to avoid accidental changes breaking CI if default.nix later returns an attrset.
Pick one:
- If default.nix returns a derivation for the main package:
- run: nix-build + run: nix-build -E 'import ./.'
- If default.nix returns an attrset exposing .package:
- run: nix-build + run: nix-build -E 'with import ./. {}; package'
- Or, if you keep an attrset at the top-level:
- run: nix-build + run: nix-build -A package
46-49: Avoid unconditionalcabal update; gate it on cache misses.Updating Hackage every run wastes time and introduces nondeterminism.
Apply this diff to restore the guard:
- - name: Update Cabal Hackage list - # if: steps.cache.outputs.cache-hit != 'true' - run: nix-shell --run "cabal update" + - name: Update Cabal Hackage list + if: steps.cache.outputs.cache-hit != 'true' + run: nix-shell --run "cabal update"
26-29: Either use the newer Homebrew Bash in subsequent steps or remove this step.Installing Bash 5 on macOS doesn’t change the shell used by later steps; they’ll still run with the runner default unless explicitly configured.
Two options:
- Remove the step if not relying on Bash 5 features.
- Or explicitly use it where needed, e.g., per-step:
- - name: Build the project with Nix - run: nix-build + - name: Build the project with Nix + if: runner.os != 'macOS' + run: nix-build + - name: Build the project with Nix (macOS, Bash 5) + if: runner.os == 'macOS' + shell: /usr/local/bin/bash -euo pipefail {0} + run: nix-buildOr set a job-level default shell for macOS via a matrix include. I can draft that if you prefer.
19-23: Add workflow/job concurrency to auto-cancel superseded runs on the same ref.Saves CI minutes and queue time when force-pushing during PR iteration.
For example:
jobs: tests: + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }} + cancel-in-progress: true strategy:
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.github/workflows/test.yml(1 hunks)
Adds Dependabot configuration for automatic dependency updates Pins Nix action to specific version for better reproducibility Configures additional substituters and trusted keys for IOG cache to improve build performance
|
Claude finished @NickSeagull's task —— View job PR Review: Port NeoHaskell to haskell.nix Infrastructure ✅I've thoroughly reviewed the migration to haskell.nix infrastructure. This is a well-executed migration that brings significant improvements to the build system. Here's my detailed analysis: Review Checklist:
✅ Strengths & Positive Changes1. Excellent Architecture Design
2. Robust Installation Script (
3. Consistent Build Infrastructure
|
Removes unnecessary caching configuration and Hackage update step from the GitHub Actions workflow to simplify the CI pipeline since Nix already handles dependency management efficiently
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.github/workflows/test.yml (2)
51-56: Gate “cabal update” behind the cache miss to shave minutes from CI.The conditional is commented out; re‑enable to avoid redundant index updates when the Cabal cache hits.
- - name: Update Cabal Hackage list - # if: steps.cache.outputs.cache-hit != 'true' - run: nix-shell --run "cabal update" + - name: Update Cabal Hackage list + if: steps.cache.outputs.cache-hit != 'true' + run: nix-shell --run "cabal update"
38-40: Optional: Prefer nix build over nix-build for forward-compat (matches haskell.nix migration).Since the repo is moving to unified haskell.nix infra, consider
nix build(flakes or default attr) for consistency and future deprecation safety.- - name: Build the project with Nix - run: nix-build + - name: Build the project with Nix + run: nix build .#package || nix-build
♻️ Duplicate comments (1)
.github/workflows/test.yml (1)
32-36: Good: action is now pinned to a tag; consider pinning to an exact commit for maximum immutability.You addressed the prior supply‑chain warning by moving off a floating ref. To fully lock CI, pin to the release’s commit SHA (Dependabot can still bump it).
Example:
- - uses: DeterminateSystems/determinate-nix-action@v3.8.6 + - uses: DeterminateSystems/determinate-nix-action@<commit-sha-for-v3.8.6>If you prefer tags, keep as-is and let Dependabot manage upgrades (now configured).
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
.github/dependabot.yml(1 hunks).github/workflows/test.yml(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/dependabot.yml
[error] 6-6: no new line character at the end of file
(new-line-at-end-of-file)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: tests (ubuntu-latest)
- GitHub Check: tests (macos-latest)
- GitHub Check: claude-review
🔇 Additional comments (1)
.github/workflows/test.yml (1)
32-36: Divine Edict: Verify IOHK Cache Key Pairing in CIThe workflow’s
extra-confblock correctly referenceshttps://cache.iog.ioand thehydra.iohk.iokey, but our sandbox cannot install Nix to confirm. You must ensure on both Linux and macOS runners that the substituter and public-key actually load and match:• File:
.github/workflows/test.yml, in each job usingDeterminateSystems/determinate-nix-action@…
– Confirmextra-substituters = https://cache.iog.io
– Confirmextra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=• Add a verification step immediately after Nix is configured (before the build) in every runner job:
- 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 substituter & key + run: | + nix show-config | grep -E 'substituters\s*=.*cache\.iog\.io' \ + && echo "✔ substituter present" \ + || { echo "✘ substituter missing"; exit 1; } + nix show-config | grep -E 'trusted-public-keys\s*=.*hydra\.iohk\.io:' \ + && echo "✔ public key present" \ + || { echo "✘ public key missing"; exit 1; }Execute this on both your Linux and macOS jobs to prevent silent cache misses.
| version: 2 | ||
| updates: | ||
| - package-ecosystem: github-actions | ||
| directory: / | ||
| schedule: | ||
| interval: weekly No newline at end of file |
There was a problem hiding this comment.
🧹 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:
- interval: weekly
+ interval: weekly
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| version: 2 | |
| updates: | |
| - package-ecosystem: github-actions | |
| directory: / | |
| schedule: | |
| interval: weekly | |
| # .github/dependabot.yml | |
| version: 2 | |
| updates: | |
| - package-ecosystem: github-actions | |
| directory: / | |
| schedule: | |
| interval: weekly | |
🧰 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
In .github/dependabot.yml around lines 1 to 6 the file is missing a trailing
newline which causes yamllint to fail; edit the file and add a single newline
character at the end of the file (ensure the file ends with a line break) then
save/commit so linters and CI see the newline.
🧹 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"Committable suggestion skipped: line range outside the PR's diff.
🧰 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
In .github/dependabot.yml lines 1-6, the config currently creates separate
weekly PRs for GitHub Actions updates; add a dependabot "groups" section to
bundle all github-actions updates into a single grouped PR and add metadata
fields (labels, reviewers or assignees, and an optional
open-pull-requests-limit) to the update entry so PRs are routed and
rate-limited; update the file by adding a top-level groups mapping that
names/combines the github-actions updates into one group and extend the existing
update entry with metadata keys like labels and reviewers/assignees and set
open-pull-requests-limit to control churn.
|
Claude finished @NickSeagull's task —— View job PR Review: Port NeoHaskell to haskell.nix Infrastructure ✅I've thoroughly reviewed the migration to haskell.nix infrastructure. This is a well-executed migration that brings significant improvements to the build system. Here's my detailed analysis: Review Checklist:
✅ Strengths & Positive Changes1. Excellent Architecture Design
2. Robust Installation Script (
3. Consistent Build Infrastructure
|
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
.github/workflows/test.yml (1)
32-33: Pinned Determinate Nix action — supply-chain win.Switching to a fixed tag
v3.8.6resolves the prior floating-ref risk. This directly addresses the earlier review note about pinning. (github.com)
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.github/workflows/test.yml(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: tests (macos-latest)
- GitHub Check: tests (ubuntu-latest)
- GitHub Check: claude-review
| extra-conf: | | ||
| extra-substituters = https://cache.iog.io | ||
| extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Confirm extra-conf semantics; add a guard to prove caches are active.
Using extra-conf with extra-substituters and extra-trusted-public-keys is supported and appends to existing lists, but it’s order-dependent in nix.conf. Add a quick verification step to fail fast if the cache isn’t actually being used. (github.com, nix.dev)
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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| extra-conf: | | |
| extra-substituters = https://cache.iog.io | |
| extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= | |
| 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; } |
🤖 Prompt for AI Agents
In .github/workflows/test.yml around lines 34-36, the workflow appends
extra-substituters and extra-trusted-public-keys via extra-conf but doesn't
verify they took effect; add a new job step immediately after the Determinate
Nix step that programmatically checks nix configuration/substituters and fails
fast if the configured cache URL (https://cache.iog.io) is not present or not
active — e.g., invoke nix to output current substituters/config (JSON or text),
assert the cache URL appears in the substituters list, and exit nonzero if it
does not; keep the check minimal and CI-friendly so the workflow fails early
when the cache is not actually used.
Comments out doctest execution in CI workflow to prevent build failures References issue #204
|
Claude finished @NickSeagull's task —— View job PR Review: Port NeoHaskell to haskell.nix InfrastructureI've thoroughly reviewed the migration to haskell.nix infrastructure. This is a well-executed migration that brings significant improvements to the build system. Here's my detailed analysis: Review Checklist:
✅ Strengths & Positive Changes1. Excellent Architecture Design
2. Robust Installation Script (
3. Consistent Build Infrastructure
|
|
Claude finished @NickSeagull's task —— View job PR Review: Port NeoHaskell to haskell.nix Infrastructure ✅I've thoroughly reviewed the migration to haskell.nix infrastructure. This is a well-executed migration that brings significant improvements to the build system. Here's my detailed analysis: Review Checklist:
✅ Strengths & Positive Changes1. Excellent Architecture Design
2. Robust Installation Script (
3. Consistent Build Infrastructure
|
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.github/workflows/test.yml (2)
7-17: Broaden path filters so CI triggers on infra updates (common.nix, default.nix, shell.nix, installer).Your migration centralizes Nix logic (e.g., common.nix) and adjusts the installer. Current filters won’t run on edits outside core/cli/nix. Expand patterns or drop path filters.
paths: - "core/**" - "cli/**" - "nix/**" + - "common.nix" + - "default.nix" + - "shell.nix" + - "flake.nix" + - "scripts/**"Repeat for the push trigger below.
19-23: Constrain default token scope for defense-in-depth.Explicitly set minimal permissions for the job.
jobs: tests: + permissions: + contents: read strategy:
♻️ Duplicate comments (6)
.github/workflows/test.yml (1)
32-36: Pin CI action to an immutable commit SHA and verify cache wiring immediately after.Tags pointing at moving tags (v3.8.6) are better than @main but still mutable. Pin to the exact commit for supply‑chain hardening. Also, add a quick guard to prove your extra substituter/key actually took effect. This was requested before and is still missing.
Apply:
- - uses: DeterminateSystems/determinate-nix-action@v3.8.6 + - uses: DeterminateSystems/determinate-nix-action@<commit-sha-of-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; }If you prefer, I can fetch and propose the exact commit SHA for v3.8.6 in a follow‑up.
cli/nix/haskell-project.nix (5)
14-21: Parse error: unquoted attribute name 'haskell-nix'. Quote hyphenated identifiers.Nix requires quoting hyphenated attribute names. This currently won’t evaluate. This was raised earlier and still applies.
- (final: _prev: - builtins.listToAttrs (builtins.map (packageName: { - name = "${packageName}"; - value = final.haskell-nix.cabalProject { + (final: _prev: + builtins.listToAttrs (builtins.map (packageName: { + name = packageName; + value = final."haskell-nix".cabalProject { src = packages.${packageName}; - compiler-nix-name = "ghc910"; + compiler-nix-name = "ghc910"; }; }) (builtins.attrNames packages)))
3-3: Parameterize compiler choice; avoid hard‑coding "ghc910".Make the compiler configurable (defaulting to ghc910) to avoid future breakage when upgrading haskell.nix or testing different GHCs. Previously suggested; still outstanding.
-{ packages, mainPackageName, executableName }: +{ packages, mainPackageName, executableName, compilerNixName ? "ghc910" }: @@ - compiler-nix-name = "ghc910"; + compiler-nix-name = compilerNixName;Also applies to: 19-20
14-21: Avoid top-level attr collisions; namespace generated packages and use getAttr.Injecting per‑package attrs at the top‑level risks name clashes. Prefer a namespaced set and select via builtins.getAttr. Previously noted.
- overlays = [ + 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))) + (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)); + }) ]; @@ - pkg = pkgsWithOverlay."${mainPackageName}"; + pkg = builtins.getAttr mainPackageName pkgsWithOverlay.neohaskellPackages;Also applies to: 26-26
26-26: Prefer builtins.getAttr over string interpolation for dynamic selection.More idiomatic and avoids interpolation edge cases. Previously suggested.
- pkg = pkgsWithOverlay."${mainPackageName}"; + pkg = builtins.getAttr mainPackageName pkgsWithOverlay;(If you apply the namespacing change above, target pkgsWithOverlay.neohaskellPackages instead.)
36-43: Do not mix derivations from different nixpkgs instances in shell inputs.shellFor is from pkgsWithOverlay; buildInputs should come from the same set to avoid ABI and evaluation surprises. Previously raised.
- buildInputs = [ - pkgs.nil - pkgs.nixfmt-classic - pkgs.nixpkgs-fmt - pkgs.pkg-config - pkgs.zlib - ]; + buildInputs = with pkgsWithOverlay; [ + nil + nixfmt-classic + nixpkgs-fmt + pkg-config + zlib + ];
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
.github/workflows/test.yml(1 hunks)cli/nix/haskell-project.nix(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: tests (macos-latest)
- GitHub Check: tests (ubuntu-latest)
- GitHub Check: claude-review
🔇 Additional comments (1)
cli/nix/haskell-project.nix (1)
30-35: LGTM: sensible dev tools in shell (cabal, HLS, hlint, hspec-discover).Tooling set looks balanced for the migration and aligns with the PR goals.
| - uses: DeterminateSystems/magic-nix-cache-action@v13 | ||
|
|
There was a problem hiding this comment.
🛠️ 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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: DeterminateSystems/magic-nix-cache-action@v13 | |
| - uses: DeterminateSystems/magic-nix-cache-action@<commit-sha-of-v13> |
🤖 Prompt for AI Agents
.github/workflows/test.yml around lines 38-39: the workflow currently references
DeterminateSystems/magic-nix-cache-action@v13 which is a mutable tag; replace
this with an exact commit SHA to pin the action. Locate the desired commit on
the DeterminateSystems/magic-nix-cache-action GitHub repo, copy the full commit
SHA (40 chars) and update the uses line to use @<commit-sha>; commit the change
and run the workflow to verify it still works.
| - name: Build the project with Nix | ||
| run: nix-build |
There was a problem hiding this comment.
🧹 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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Build the project with Nix | |
| run: nix-build | |
| - name: Build the project with Nix | |
| run: nix-build -L |
🤖 Prompt for AI Agents
In .github/workflows/test.yml around lines 40 to 41, the CI build step runs
"nix-build" without the -L flag which hides derivation logs; update the step to
run "nix-build -L" so derivation logs are printed to the workflow output,
improving visibility for flaky or failing builds.
| # Doctests are failing - See issue #204 | ||
| # - name: Run core doctests | ||
| # run: nix-shell --run "cabal repl --with-compiler=doctest --repl-options=--verbose core" |
There was a problem hiding this comment.
🧹 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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # 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" |
🤖 Prompt for AI Agents
In .github/workflows/test.yml around lines 49 to 51, the doctest step has been
commented out; restore the step instead of removing it and make it non-blocking
by adding continue-on-error: true to the step. Re-enable the "Run core doctests"
step with the same run command (nix-shell --run "cabal repl
--with-compiler=doctest --repl-options=--verbose core") and add
continue-on-error: true (and keep the step name) so failures are reported in the
workflow but do not fail the job while issue #204 is open.
| 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))) | ||
| ]; | ||
| inherit (haskellNix) config; | ||
| }; |
There was a problem hiding this comment.
🧹 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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 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))) | |
| ]; | |
| inherit (haskellNix) config; | |
| }; | |
| 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 = "ghc910"; | |
| }; | |
| }) (builtins.attrNames packages))) | |
| ]; | |
| inherit (haskellNix) config; | |
| }; |
🤖 Prompt for AI Agents
In cli/nix/haskell-project.nix around lines 11 to 24 the import of
haskellNix.sources.nixpkgs-unstable does not specify a system, which can cause
cross-system evaluation; update the import call to pass system = pkgs.system
(i.e. import haskellNix.sources.nixpkgs-unstable { system = pkgs.system;
overlays = [ ... ]; inherit (haskellNix) config; }) so the imported nixpkgs is
locked to the outer pkgs system.
| package = (pkg.flake { }).packages."${executableName}"; | ||
| } |
There was a problem hiding this comment.
🧹 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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| package = (pkg.flake { }).packages."${executableName}"; | |
| } | |
| package = | |
| let | |
| flakeOut = pkg.flake { }; | |
| pkgsOut = flakeOut.packages; | |
| in | |
| assert builtins.hasAttr executableName pkgsOut; | |
| pkgsOut."${executableName}"; | |
| } |
🤖 Prompt for AI Agents
In cli/nix/haskell-project.nix around lines 44-45, the code directly indexes the
flake outputs with package = (pkg.flake { }).packages."${executableName}"; which
silently fails if executableName is misspelled; add a precondition using
builtins.hasAttr (or compute the packages attrset first) and assert that the key
exists before indexing, then use that validated attrset to select the package so
the build fails early with a clear assertion message when the package key is
missing.
This PR migrates the NeoHaskell project itself to use the haskell.nix infrastructure that was previously only available to user projects. This brings consistency to our build system and enables monorepo support for both NeoHaskell and future user projects.
🚀 What's Changed
Core Infrastructure Migration
nhcoreandnhclito version 0.9.1Build System Improvements
common.nixto centralize project configurationInstallation Script Fixes
/etc/nix/nix.custom.confto avoid conflicts with system configuration💡 Why This Matters
For Contributors:
For Users:
🔍 Technical Details
Key Changes to
haskell-project.nixInstallation Script Improvements
/etc/nix/nix.custom.confinstead of modifying the main config✅ Testing Checklist
nix-buildnix-shellnhcoreandnhclibuild successfully📝 Migration Notes
No breaking changes for users. The
neoCLI continues to work exactly as before.🤝 How to Test
Test the build:
nix-build ./result/bin/neo --version # Should show 0.9.1Test the development shell:
Test the installation script:
🎉 What's Next?
This infrastructure change opens the door for:
Summary by CodeRabbit
New Features
Improvements
Refactor
Chores
Tests