generated from coulomb/repo-seed
Some checks failed
Build and Deploy / build-push-deploy (push) Has been cancelled
cabal-version: 2.2 does not support the pkg:sublibrary reference syntax. Bump to 3.0 which explicitly supports it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
334 lines
16 KiB
Nix
334 lines
16 KiB
Nix
{
|
|
inputs = {
|
|
ihp.url = "github:digitallyinduced/ihp/v1.5";
|
|
nixpkgs.follows = "ihp/nixpkgs";
|
|
nixpkgs-nixos.follows = "ihp/nixpkgs-nixos";
|
|
flake-parts.follows = "ihp/flake-parts";
|
|
devenv.follows = "ihp/devenv";
|
|
systems.follows = "ihp/systems";
|
|
devenv-root = {
|
|
url = "file+file:///dev/null";
|
|
flake = false;
|
|
};
|
|
};
|
|
|
|
outputs = inputs@{ self, nixpkgs, nixpkgs-nixos, ihp, flake-parts, systems, ... }:
|
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
|
|
|
systems = import systems;
|
|
imports = [ ihp.flakeModules.default ];
|
|
|
|
perSystem = { pkgs, config, lib, ... }: {
|
|
ihp = {
|
|
appName = "inter-hub";
|
|
enable = true;
|
|
projectPath = ./.;
|
|
packages = with pkgs; [
|
|
tailwindcss
|
|
];
|
|
haskellPackages = p: with p; [
|
|
# Haskell dependencies go here
|
|
p.ihp
|
|
base
|
|
wai
|
|
text
|
|
# ihp-mail # Email support: https://ihp.digitallyinduced.com/Guide/mail.html
|
|
# ihp-datasync # Real-time DataSync
|
|
# ihp-job-dashboard # Job dashboard UI
|
|
# ihp-typed-sql # Type-safe SQL queries
|
|
# ihp-pglistener # PostgreSQL LISTEN/NOTIFY
|
|
# Phase 5: Anthropic API calls
|
|
http-conduit
|
|
aeson
|
|
string-conversions
|
|
# Phase 9: External API, crypto, SDK generation
|
|
cryptohash-sha256
|
|
base16-bytestring
|
|
random-bytestring
|
|
yaml
|
|
network-uri
|
|
];
|
|
devHaskellPackages = p: with p; [
|
|
cabal-install
|
|
hlint
|
|
hspec
|
|
ihp-hspec
|
|
];
|
|
|
|
# Hoogle documentation server — disabled to save ~400 MB on constrained host
|
|
withHoogle = false;
|
|
|
|
# Disable relation type machinery for faster compilation
|
|
# relationSupport = false;
|
|
|
|
# Skip tests/haddock for specific packages to speed up builds
|
|
# dontCheckPackages = [ "my-package" ];
|
|
# doJailbreakPackages = [ "my-package" ];
|
|
# dontHaddockPackages = [ "my-package" ];
|
|
|
|
# Production build tuning
|
|
# optimizationLevel = "2"; # Default: "1", use "2" for more optimized production binaries
|
|
# rtsFlags = "-A96m -N"; # GHC runtime flags for compiled binaries
|
|
|
|
# Mount additional directories under /static/ in production builds
|
|
# static.extraDirs = {
|
|
# # Frontend = self.packages.${system}.frontend;
|
|
# };
|
|
# static.makeBundling = true; # Set false if not using Makefile for CSS/JS bundling
|
|
};
|
|
|
|
# OCI container image for Kubernetes deployment (Railiance01).
|
|
# Build: nix build .#docker
|
|
# Push: skopeo copy docker-archive:result docker://92.205.130.254:32166/coulomb/inter-hub:SHA
|
|
# Uses IHP's built-in unoptimized image; binary is /bin/RunProdServer.
|
|
packages.docker = config.packages.unoptimized-docker-image;
|
|
|
|
# Custom configuration that will start with `devenv up`
|
|
devenv.shells.default = {
|
|
# Start Mailhog on local development to catch outgoing emails
|
|
# services.mailhog.enable = true;
|
|
|
|
# PostgreSQL extensions
|
|
# services.postgres.extensions = extensions: [ extensions.postgis ];
|
|
|
|
# GHC 9.10.3 crash fix: Generated.Types imports 119 modules, exceeding
|
|
# the ~287 MB interface-file binary-deserialization limit.
|
|
#
|
|
# pkgs is built from `import nixpkgs { overlays = devenv.shells.default.overlays; }`.
|
|
# IHP adds ihp.overlays.default to this list, which sets
|
|
# pkgs.ghc = haskellPackages.override { overrides = ihpOverrides }.
|
|
# We extend pkgs.ghc with a mkDerivation override (lib.mkAfter ensures
|
|
# we run after IHP's overlay, so prev.ghc is already IHP's package set).
|
|
# 2-way split (60 entities) still crashes — TypesPart1.hi itself hits 287 MB.
|
|
# 4-way split (~30 entities, ~150 MB .hi each) stays safely under the limit.
|
|
# When pname == "inter-hub-models", postUnpack replaces the monolithic
|
|
# Types.hs → empty stub (not compiled); inter-hub-lib imports TypesPart1-8 directly.
|
|
overlays = lib.mkAfter [
|
|
(final: prev: {
|
|
ghc = prev.ghc.extend (hfinal: hprev: {
|
|
mkDerivation = args:
|
|
let drv = hprev.mkDerivation args;
|
|
in if (args.pname or "") == "inter-hub-models"
|
|
then drv.overrideAttrs (old: {
|
|
# GHC 9.10.3 crash: Data.Binary.Get.runGet at position 287686318.
|
|
# Invariant regardless of flags. Workaround: split the 476-module
|
|
# inter-hub-models into two Cabal library components so GHC runs
|
|
# two separate --make invocations instead of one giant one.
|
|
#
|
|
# models-inner (~63 modules): Generated.ActualTypes.* + Enums.
|
|
# Pure type definitions; no inter-hub-models deps.
|
|
# main library (~413 modules): entity ops + Include instances.
|
|
# Depends on models-inner.
|
|
#
|
|
# Long-term intent: explicit module boundaries reduce build cost,
|
|
# isolate changes, and make diagnostics cheaper across the board.
|
|
configureFlags = (old.configureFlags or []) ++ [
|
|
"--ghc-option=-O0"
|
|
"--ghc-option=-fomit-interface-pragmas"
|
|
];
|
|
postUnpack = (old.postUnpack or "") + ''
|
|
_cabal=$(ls "$sourceRoot"/*.cabal | head -1)
|
|
_pname=$(grep '^name:' "$_cabal" | awk '{print $2}')
|
|
|
|
# Classify exposed-modules into inner vs outer.
|
|
# Inner: Generated.ActualTypes.X (capital X) and Generated.Enums
|
|
# — these have zero inter-hub-models dependencies.
|
|
# Outer: everything else except Generated.Types (empty stub).
|
|
_inner=$(awk '
|
|
/^ exposed-modules:/{e=1;next}
|
|
e && /^ /{m=$1;
|
|
if (m~/^Generated\.ActualTypes\.[A-Z]/||m=="Generated.Enums")
|
|
print m;
|
|
next}
|
|
e{e=0}
|
|
' "$_cabal")
|
|
_outer=$(awk '
|
|
/^ exposed-modules:/{e=1;next}
|
|
e && /^ /{m=$1;
|
|
if (!(m~/^Generated\.ActualTypes\.[A-Z]/) &&
|
|
m!="Generated.Enums" && m!="Generated.Types")
|
|
print m;
|
|
next}
|
|
e{e=0}
|
|
' "$_cabal")
|
|
|
|
# Rewrite the cabal file with two library stanzas.
|
|
# Hard-coded deps/extensions match IHP default.nix template
|
|
# (pinned flake — these won't drift without a flake update).
|
|
cat > "$_cabal" <<CABAL_EOF
|
|
cabal-version: 3.0
|
|
name: $_pname
|
|
version: 0.1.0
|
|
build-type: Simple
|
|
|
|
library models-inner
|
|
default-language: GHC2021
|
|
hs-source-dirs: build
|
|
build-depends:
|
|
base
|
|
, ihp
|
|
, basic-prelude
|
|
, text
|
|
, bytestring
|
|
, time
|
|
, uuid
|
|
, aeson
|
|
, postgresql-simple
|
|
, deepseq
|
|
, data-default
|
|
, scientific
|
|
, string-conversions
|
|
, hasql
|
|
, hasql-dynamic-statements
|
|
, hasql-implicits
|
|
, hasql-mapping
|
|
, hasql-postgresql-types
|
|
, hasql-pool
|
|
, unordered-containers
|
|
, postgresql-types
|
|
exposed-modules:
|
|
$(echo "$_inner" | sed 's/^/ /')
|
|
default-extensions:
|
|
OverloadedStrings
|
|
NoImplicitPrelude
|
|
ImplicitParams
|
|
TypeSynonymInstances
|
|
FlexibleInstances
|
|
FlexibleContexts
|
|
InstanceSigs
|
|
MultiParamTypeClasses
|
|
TypeFamilies
|
|
DataKinds
|
|
TypeOperators
|
|
UndecidableInstances
|
|
ConstraintKinds
|
|
StandaloneDeriving
|
|
DuplicateRecordFields
|
|
OverloadedLabels
|
|
OverloadedRecordDot
|
|
ghc-options: -Wno-unused-imports -Wno-dodgy-imports -Wno-unused-matches
|
|
|
|
library
|
|
default-language: GHC2021
|
|
hs-source-dirs: build
|
|
build-depends:
|
|
$_pname:models-inner
|
|
, base
|
|
, ihp
|
|
, basic-prelude
|
|
, text
|
|
, bytestring
|
|
, time
|
|
, uuid
|
|
, aeson
|
|
, postgresql-simple
|
|
, deepseq
|
|
, data-default
|
|
, scientific
|
|
, string-conversions
|
|
, hasql
|
|
, hasql-dynamic-statements
|
|
, hasql-implicits
|
|
, hasql-mapping
|
|
, hasql-postgresql-types
|
|
, hasql-pool
|
|
, unordered-containers
|
|
, postgresql-types
|
|
exposed-modules:
|
|
$(echo "$_outer" | sed 's/^/ /')
|
|
default-extensions:
|
|
OverloadedStrings
|
|
NoImplicitPrelude
|
|
ImplicitParams
|
|
TypeSynonymInstances
|
|
FlexibleInstances
|
|
FlexibleContexts
|
|
InstanceSigs
|
|
MultiParamTypeClasses
|
|
TypeFamilies
|
|
DataKinds
|
|
TypeOperators
|
|
UndecidableInstances
|
|
ConstraintKinds
|
|
StandaloneDeriving
|
|
DuplicateRecordFields
|
|
OverloadedLabels
|
|
OverloadedRecordDot
|
|
ghc-options: -Wno-unused-imports -Wno-dodgy-imports -Wno-unused-matches
|
|
CABAL_EOF
|
|
|
|
# Stub out Generated.Types (kept as file for inter-hub-lib)
|
|
printf '%s\n' 'module Generated.Types () where' \
|
|
> "$sourceRoot/build/Generated/Types.hs"
|
|
'';
|
|
})
|
|
else if (args.pname or "") == "inter-hub-lib"
|
|
then drv.overrideAttrs (old: {
|
|
# Generated.Types is an empty stub in models — no re-export hub.
|
|
# Replace every bare `import Generated.Types` with direct imports
|
|
# of all 119 individual entity modules (read from the original
|
|
# Generated/Types.hs before it was replaced in models postUnpack —
|
|
# each package gets its own unpacked sourceRoot, so Types.hs is
|
|
# still intact here). Individual entity .hi files are ~9 MB each.
|
|
postUnpack = (old.postUnpack or "") + ''
|
|
_types="$sourceRoot/build/Generated/Types.hs"
|
|
_imp=$(mktemp)
|
|
awk '/^import Generated\./{print "import " $2}' "$_types" > "$_imp"
|
|
find "$sourceRoot" -name "*.hs" | while IFS= read -r _f; do
|
|
if grep -qE "^import Generated\.Types$" "$_f"; then
|
|
awk -v imp="$_imp" '
|
|
/^import Generated\.Types$/{
|
|
while ((getline ln < imp) > 0) print ln
|
|
close(imp)
|
|
next
|
|
}
|
|
{ print }' "$_f" > "$_f.new" && mv "$_f.new" "$_f"
|
|
fi
|
|
done
|
|
rm -f "$_imp"
|
|
'';
|
|
})
|
|
else drv;
|
|
});
|
|
})
|
|
];
|
|
|
|
# Resource limits for constrained host (2 CPU, ~3.8 GiB RAM).
|
|
# -A32m: smaller minor heap (reduces GC pressure).
|
|
# -M2g: hard heap ceiling (prevents OOM on large compiles).
|
|
# Note: -N1 is intentionally omitted — it requires -threaded and
|
|
# would break build-generated-code and similar tools.
|
|
# GHC parallel module compilation is capped via -j1 in .ghci.
|
|
env.GHCRTS = "-A32m -M2g";
|
|
|
|
# Custom processes that don't appear in https://devenv.sh/reference/options/
|
|
processes = {
|
|
tailwind.exec = "tailwindcss -c tailwind/tailwind.config.js -i ./tailwind/app.css -o static/app.css --watch=always";
|
|
};
|
|
};
|
|
};
|
|
|
|
# Adding the new NixOS configuration for "production"
|
|
# See https://ihp.digitallyinduced.com/Guide/deployment.html#deploying-with-deploytonixos for more info
|
|
# Used to deploy the IHP application
|
|
flake.nixosConfigurations."production" = import ./Config/nix/hosts/production/host.nix { inherit inputs; };
|
|
};
|
|
|
|
# The following configuration speeds up build times by using the devenv, cachix and digitallyinduced binary caches
|
|
# You can add your own cachix cache here to speed up builds. For that uncomment the following lines and replace `CHANGE-ME` with your cachix cache name
|
|
nixConfig = {
|
|
extra-substituters = [
|
|
"https://devenv.cachix.org"
|
|
"https://cachix.cachix.org"
|
|
"https://digitallyinduced.cachix.org"
|
|
# "https://CHANGE-ME.cachix.org"
|
|
];
|
|
extra-trusted-public-keys = [
|
|
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
|
|
"cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM="
|
|
"digitallyinduced.cachix.org-1:y+wQvrnxQ+PdEsCt91rmvv39qRCYzEgGQaldK26hCKE="
|
|
# "CHANGE-ME.cachix.org-1:CHANGE-ME-PUBLIC-KEY"
|
|
];
|
|
};
|
|
}
|