Skip to content

Commit b80204d

Browse files
NickSeagullclaude
andauthored
feat: Migrate CLI to haskell.nix Infrastructure for Enhanced Build Capabilities (#199)
* feat(cli): Organize event model into enterprise-grade structure Refactor the monolithic event model in Neo.hs into a proper layered architecture: - Domain layer: Types, Commands, Events, and Entity logic - ReadModels layer: Query-optimized views separated by concern - Maintain clean separation between write and read models This structure improves maintainability and scalability for enterprise applications. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * wip * wip * Enhances Nix development shell with HLS configuration Adds automatic hie.yaml generation for improved Haskell Language Server integration Configures direct cradle with proper package database paths and dependencies Includes informative shell hook messages for better developer experience Fixes source override path construction for nhcore dependency * fix build for cli-next * refactor(nix): extract common configuration into reusable module Creates shared configuration for GHC options and language extensions Consolidates project setup logic to reduce code duplication Streamlines cabal file generation with centralized formatting Improves maintainability across build and shell environments * format * move cli-next out of main repo * bump * bump * Migrate to haskell.nix for user projects 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix CLI parameter naming for remote SHA approach 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * add back a project * Revert "feat(cli): Use nix instead of file generation for builds (#191)" This reverts commit be27451. * docs: improve formatting and remove outdated migration files Enhances documentation readability by adding proper spacing around headers and sections Removes obsolete haskell.nix migration documentation and associated Nix configuration files that are no longer needed * necromancy * bump * fix old compilation * add module to iignore * bring back haskell.nix * bump * Moves static file embedding from File to Text module Relocates file embedding functionality to better align with its primary use case of generating text content at compile time Renames the quasi-quoter for clearer intent and adds UTF-8 decoding to handle text files properly Removes embedding feature from file I/O module to maintain separation of concerns between runtime file operations and compile-time content generation * Refactors Nix configuration to create reusable project template Extracts hardcoded project configuration into a generic function that accepts project name and source path as parameters Moves original project-specific configuration to a new wrapper file that uses the generic template Enables code reuse across multiple Haskell projects while maintaining the same build configuration * Adds nixfmt formatting and fixes trailing whitespace Enables nixfmt-rfc-style hook for consistent Nix code formatting Removes trailing whitespace from shell function definitions * compile * Refactors Haskell project function interface Changes function signature from positional arguments to named parameters using attribute set Improves code clarity and maintainability by making function calls more explicit and self-documenting * refactor(build): consolidate nix configuration and update templates Moves haskell-project.nix into cli directory and embeds it directly in templates Removes dependency on external nix files by inlining haskell.nix configuration Adds cabal.project template for improved dependency management Updates import formatting for consistency Simplifies build system by reducing file dependencies and improving portability * chore(cli-next): remove Nix build configuration Cleans up project by removing unused Haskell.nix build setup Adds file to gitignore to prevent future tracking * Generates cabal project file during build process Removes hardcoded cabal project configuration and adds dynamic generation through template system Improves build flexibility by allowing project-specific cabal configurations * Moves launcher to hidden directory Relocates executable source from app to .launcher folder Updates build configuration to use new launcher location Adds .launcher directory to gitignore Improves project organization by hiding build artifacts * Passes Nix expression directly to nix-build command Removes file-based Nix workflow by eliminating default.nix file creation and writing operations Passes Nix template directly as command line argument using -E flag instead of creating temporary file Streamlines build process and reduces filesystem operations * fix shell * feat(install): add binary cache support for faster builds Enhances installation script with configurable binary cache setup to reduce build times from hours to minutes Prompts user for permission before modifying system Nix configuration Safely handles existing cache configurations without duplicates Improves user experience with better feedback and troubleshooting guidance * fixes * Use main for now * bump version * typo * use correct path --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent cdb68ce commit b80204d

29 files changed

Lines changed: 530 additions & 345 deletions

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,13 @@ sandbox/*.nix
4141

4242
example.cabal
4343
result
44+
45+
.claude/settings.local.json
46+
47+
cli-next/default.nix
48+
49+
cli-next/cabal.project
50+
51+
cli-next/.launcher/
52+
53+
cli-next/neo-sandbox.cabal

.vscode/settings.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
"devenv",
1010
"dont",
1111
"foldl",
12+
"fourmolu",
1213
"fprint",
1314
"GADT",
15+
"haskellnix",
16+
"HIEYAML",
1417
"hlint",
1518
"Hspec",
16-
"Impredicative",
1719
"Inspectable",
1820
"Monoid",
1921
"Nanotime",
@@ -32,8 +34,7 @@
3234
"snoc",
3335
"testlib",
3436
"typeclasses",
35-
"Unagi",
36-
"Werror"
37+
"Unagi"
3738
],
3839
"nixEnvSelector.nixFile": "${workspaceFolder}/shell.nix",
3940
// Haskell

CLAUDE.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ NeoHaskell is a dialect of Haskell focused on newcomer-friendliness and producti
1313
## Development Setup
1414

1515
Required tools:
16+
1617
- Install [Nix](https://nixos.org/download/)
1718
- Run `nix-shell` to enter development environment
1819
- Run `cabal update && cabal build all` to build everything
@@ -22,23 +23,28 @@ The project uses VS Code with Haskell Language Server for development.
2223
## Build and Test Commands
2324

2425
### Core Commands
26+
2527
- `cabal build all` - Build all packages
2628
- `cabal test` - Run all tests
2729
- `cabal test nhcore-test` - Run core library tests only
2830
- `cabal test nhcli-test` - Run CLI tests only
2931
- `hlint .` - Run linter
3032

3133
### Documentation Tests
34+
3235
- `./scripts/run-doctest` - Run doctest (installs doctest if needed)
3336

3437
### Formatting
38+
3539
- Code auto-formats on save in VS Code using fourmolu
3640
- Configuration in `fourmolu.yaml` (2-space indent, 120 char limit)
3741

3842
## Architecture
3943

4044
### Core Library Structure
45+
4146
The core library (`nhcore`) provides NeoHaskell's standard library organized into:
47+
4248
- **Core modules**: Basic types (Text, Int, Array, Maybe, Result, etc.)
4349
- **System modules**: File, Directory, Path, Environment, Time, Subprocess
4450
- **Concurrency**: AsyncTask, Channel, Lock, ConcurrentVar
@@ -48,25 +54,30 @@ The core library (`nhcore`) provides NeoHaskell's standard library organized int
4854
- **Testing**: Comprehensive EventStore test suites with property-based testing
4955

5056
### CLI Tool
57+
5158
The CLI (`nhcli`) provides project management commands through the `neo` executable.
5259

5360
## NeoHaskell Code Style
5461

5562
NeoHaskell follows specific coding conventions (from `.cursor/rules/neohaskell-style.mdc`):
5663

5764
### Import Style
65+
5866
Always import types explicitly and modules qualified:
67+
5968
```haskell
6069
import Service.Event (Event(..))
6170
import Service.Event qualified as Event
6271
```
6372

6473
Use `Ghc` prefix for base library imports:
74+
6575
```haskell
6676
import Data.List qualified as GhcList
6777
```
6878

6979
### Code Structure
80+
7081
- No point-free style - always explicit function application
7182
- Prefer pipe operator `|>` over nested `$`
7283
- Use `do` blocks for intermediate bindings (even non-monadic), no `let..in` or `where`
@@ -77,6 +88,7 @@ import Data.List qualified as GhcList
7788
- Use `<TypeName>.yield` instead of `pure` or `return`
7889

7990
### Forbidden Patterns
91+
8092
- Never import Haskell ecosystem modules unless explicitly requested
8193
- Use nhcore modules instead of base/ecosystem equivalents
8294
- No `let..in` or `where` clauses
@@ -88,4 +100,4 @@ import Data.List qualified as GhcList
88100
- Adding new core modules: Add to `core/nhcore.cabal` exposed-modules
89101
- Adding CLI commands: Extend modules in `cli/src/Neo/`
90102
- Running specific tests: Use `cabal test <package-name>-test`
91-
- Code formatting: Automatic in VS Code, or `fourmolu --mode inplace **/*.hs`
103+
- Code formatting: Automatic in VS Code, or `fourmolu --mode inplace **/*.hs`

cli-next/README.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
1-
# Neo CLI - Next
1+
# TESTING STUFF
22

3-
This folder houses the new implementation of the `neo` CLI.
4-
5-
The idea is that it serves as a living integration test of NeoHaskell,
6-
so that the main features of the language are tested within the language
7-
main tool itself.
8-
9-
Once we get on parity with the current CLI, this will become the default
10-
implementation.

cli-next/neo.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
2-
"name": "neo",
3-
"version": "0.0.0",
4-
"description": "The NeoHaskell command line helper",
5-
"author": "Nikita Tchayka",
6-
"license": "Apache-2.0",
7-
"dependencies": {},
8-
"overrideNeohaskell": "file:///home/nick/Source/NeoHaskell"
9-
}
2+
"name": "neo-sandbox",
3+
"version": "0.0.1",
4+
"description": "Your project's description",
5+
"author": "Your Name",
6+
"license": "ISC",
7+
"dependencies": {
8+
}
9+
}

cli-next/src/Neo.hs

Lines changed: 0 additions & 10 deletions
This file was deleted.

cli-next/src/Neo/Model.hs

Lines changed: 0 additions & 7 deletions
This file was deleted.

cli-next/src/NeoSandbox.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module NeoSandbox where
2+
3+
import Core
4+
5+
6+
run :: Task Text Unit
7+
run = print "Hi"

cli/nhcli.cabal

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 3.4
22
name: nhcli
3-
version: 0.8.2
3+
version: 0.9.0
44
synopsis: Command Line Tool for NeoHaskell
55
description: NeoHaskell is a dialect of Haskell that is focused on newcomer-friendliness and productivity.
66
homepage: https://neohaskell.org
@@ -11,7 +11,7 @@ maintainer: nhlib@nickseagull.dev
1111
copyright:
1212
category: Development
1313
build-type: Simple
14-
-- extra-source-files:
14+
extra-source-files: ../nix/haskellnix.nix, ../nix/haskell-project.nix
1515

1616
common common_cfg
1717
ghc-options: -Wall
@@ -51,12 +51,17 @@ library
5151
exposed-modules:
5252
Neo,
5353
Neo.Build,
54+
Neo.Build.Templates.Cabal,
55+
Neo.Build.Templates.CabalProject,
56+
Neo.Build.Templates.Nix,
57+
Neo.Build.Templates.AppMain,
5458
Neo.Core,
5559
Neo.Core.ProjectConfiguration,
5660
Neo.New,
5761
Neo.New.Templates.NeoJson,
5862
Neo.New.Templates.MainModule,
5963
Neo.Run,
64+
Neo.Shell,
6065
-- other-modules:
6166
-- other-extensions:
6267
hs-source-dirs: src

cli/nix/haskell-project.nix

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{ pkgs }:
2+
3+
# Generic function to create a Haskell project template
4+
{ projectName, src }:
5+
let
6+
haskellNix = import (pkgs.fetchFromGitHub {
7+
owner = "input-output-hk";
8+
repo = "haskell.nix";
9+
rev = "4d493449406ec91db804511a6d15b6f076ba40e7";
10+
sha256 = "sha256-CHNMDgFfpTV5WkVhmMLf5d5qaLUjgeoziVgmgnhPGrI=";
11+
}) { inherit pkgs; };
12+
# Apply haskell.nix overlay
13+
pkgsWithOverlay = import haskellNix.sources.nixpkgs-unstable {
14+
overlays = [
15+
haskellNix.overlay
16+
(final: _prev: {
17+
"${projectName}Project" = final.haskell-nix.cabalProject {
18+
inherit src;
19+
compiler-nix-name = "ghc910";
20+
};
21+
})
22+
];
23+
inherit (haskellNix) config;
24+
};
25+
26+
flake = pkgsWithOverlay."${projectName}Project".flake { };
27+
28+
in flake.packages."${projectName}:exe:${projectName}"

0 commit comments

Comments
 (0)