-
Notifications
You must be signed in to change notification settings - Fork 2
/
flake.nix
199 lines (162 loc) · 7.88 KB
/
flake.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
{
inputs.flakes.url = "github:deemp/flakes";
outputs = inputs: inputs.flakes.makeFlake {
inputs = {
inherit (inputs.flakes.all)
haskell-tools codium drv-tools devshell
flakes-tools nixpkgs formatter workflows lima;
};
perSystem = { inputs, system }:
let
# We're going to make some dev tools for our Haskell package
# The NixOS wiki has more info - https://nixos.wiki/wiki/Haskell
# --- Imports ---
pkgs = inputs.nixpkgs.legacyPackages.${system};
inherit (inputs.codium.lib.${system}) extensions extensionsCommon settingsNix settingsCommonNix writeSettingsJSON mkCodium;
inherit (inputs.devshell.lib.${system}) mkCommands mkRunCommands mkShell;
inherit (inputs.drv-tools.lib.${system}) withAttrs withMan withDescription mkShellApp man;
inherit (inputs.flakes-tools.lib.${system}) mkFlakesTools;
inherit (inputs.haskell-tools.lib.${system}) toolsGHC;
inherit (inputs.workflows.lib.${system}) writeWorkflow nixCI;
inherit (inputs) lima;
# --- Parameters ---
# The desired GHC version
ghcVersion = "948";
# The name of a package
packageName = "nix-managed";
# The libraries that the package needs during a build
packageLibraryDependencies = [ pkgs.lzma ];
# The packages that provide the binaries that our package uses at runtime
packageRuntimeDependencies = [ pkgs.hello ];
# --- Override ---
# We need to prepare an attrset of Haskell packages and include our packages into it,
# so we define an override - https://nixos.wiki/wiki/Haskell#Overrides.
# We'll supply the necessary dependencies to our packages.
# Sometimes, we need to fix the broken packages - https://gutier.io/post/development-fixing-broken-haskell-packages-nixpkgs/.
# For doing that, we use several helper functions.
# Overriding the packages may trigger multiple rebuilds,
# so we override as few packages as possible.
inherit (pkgs.haskell.lib)
# doJailbreak - remove package bounds from build-depends of a package
doJailbreak
# dontCheck - skip tests
dontCheck
# override deps of a package
overrideCabal
;
# Here's our override
# Haskell overrides are described here: https://nixos.org/manual/nixpkgs/unstable/#haskell
override = {
overrides = self: super: {
lzma = dontCheck (doJailbreak super.lzma);
"${packageName}" = overrideCabal
(super.callCabal2nix packageName ./. { })
(x: {
# See what can be overriden - https://github.com/NixOS/nixpkgs/blob/0ba44a03f620806a2558a699dba143e6cf9858db/pkgs/development/haskell-modules/generic-builder.nix#L13
# And the explanation of the deps - https://nixos.org/manual/nixpkgs/unstable/#haskell-derivation-deps
# Dependencies of the our package library
# New deps go before the existing deps and override them
librarySystemDepends = packageLibraryDependencies ++ (x.librarySystemDepends or [ ]);
# Dependencies of our package executables
executableSystemDepends = packageLibraryDependencies ++ (x.executableSystemDepends or [ ]);
# Here's how we can add a package built from sources
# Later, we may use this package in `.cabal` in a test-suite
# We should use `cabal v1-*` commands with it - https://github.com/NixOS/nixpkgs/issues/130556#issuecomment-1114239002
# `lima` lets you write a `README.hs` and convert it to `README.md` - https://hackage.haskell.org/package/lima
# Uncomment `lima` to use it
testHaskellDepends = [
# (super.callCabal2nix "lima" lima.outPath { })
] ++ (x.testHaskellDepends or [ ]);
});
};
};
# --- Haskell tools ---
# We call a helper function that will give us tools for Haskell
inherit (toolsGHC {
version = ghcVersion;
inherit override;
# Programs that will be available to cabal at development time
# and to a Haskell program at runtime
runtimeDependencies = packageRuntimeDependencies;
# If we work on multiple packages, we need to supply all of them
# so that their dependencies can be correctrly filtered.
# Suppose we develop packages A and B, where B is in dependencies of A.
# GHC will be given dependencies of both A and B.
# However, we don't want B to be in the list of dependencies of GHC
# because build of GHC may fail due to errors in B.
packages = ps: [ ps.${packageName} ];
})
hls cabal fourmolu implicit-hie justStaticExecutable
ghcid callCabal2nix haskellPackages hpack ghc;
# --- Tools ---
# We list the tools that we'd like to use
tools = [
ghcid
hpack
implicit-hie
fourmolu
cabal
# `cabal` already has a `ghc` on its `PATH`,
# so you may remove `ghc` from this list.
# Then, you can access `ghc` like `cabal exec -- ghc --version`.
# However, sometimes, HLS wants a GHC.
# In this case, write it before `HLS` - see https://github.com/NixOS/nixpkgs/issues/225895
ghc
hls
];
# --- Packages ---
packages = {
# --- Haskell package ---
# This is a static executable with given runtime dependencies.
# In this case, its name is the same as the package name.
default = justStaticExecutable {
package = haskellPackages.${packageName};
runtimeDependencies = packageRuntimeDependencies;
description = "A Haskell `hello-world` script";
};
# --- IDE ---
# We compose `VSCodium` with extensions
codium = mkCodium { extensions = extensionsCommon // { inherit (extensions) haskell; }; };
# a script to write `.vscode/settings.json`
writeSettings = writeSettingsJSON (settingsCommonNix // { inherit (settingsNix) haskell; });
# --- Flakes ---
# Scripts that can be used in CI
inherit (mkFlakesTools { dirs = [ "." ]; root = ./.; }) updateLocks pushToCachix saveFlakes format;
# --- GH Actions
# A script to write GitHub Actions workflow file into `.github/ci.yaml`
writeWorkflows = writeWorkflow "ci" (nixCI { jobArgs.doPushToCachix = true; });
};
# --- Devshells ---
devShells = {
default = mkShell {
packages = tools;
# sometimes necessary for programs that work with files
bash.extra = "export LANG=C.utf8";
commands =
mkCommands "tools" tools
++ mkRunCommands "packages" { inherit (packages) default; }
++ mkRunCommands "ide" { "codium ." = packages.codium; inherit (packages) writeSettings; }
++ mkRunCommands "infra" { inherit (packages) writeWorkflows updateLocks pushToCachix saveFlakes format; }
;
};
};
in
{
inherit packages devShells;
formatter = inputs.formatter.${system};
ghcVersions = pkgs.lib.attrsets.mapAttrsToList (name: _: pkgs.lib.strings.removePrefix "ghc" name) pkgs.haskell.compiler;
};
};
nixConfig = {
extra-substituters = [
"https://nix-community.cachix.org"
"https://cache.iog.io"
"https://deemp.cachix.org"
];
extra-trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
"deemp.cachix.org-1:9shDxyR2ANqEPQEEYDL/xIOnoPwxHot21L5fiZnFL18="
];
};
}