1# package descriptions in hackage will look like:
2# { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs }:
3# { flags = { flag1 = false; flags2 = true; ... };
4# package = { specVersion = "X.Y"; identifier = { name = "..."; version = "a.b.c.d"; };
5# license = "..."; copyright = "..."; maintainer = "..."; author = "...";
6# homepage = "..."; url = "..."; synopsis = "..."; description = "...";
7# buildType = "Simple"; # or Custom, Autoconf, ...
10# "..." = { depends = [ (hsPkgs.base) ... ]; };
11# exes = { "..." = { depends = ... };
12# "..." = { depends = ... }; };
13# tests = { "..." = { depends = ... }; ... };
16{ parentConfig, mod_args, listOfFilteringNulls, componentOptions, packageOptions }:
17{ lib, config, pkgs, haskellLib, ... }:
22# Work around issue that can cause _lots_ of files to be copied into the store.
23# See https://github.com/NixOS/nixpkgs/pull/64691
24let path = types.path // { check = x: types.path.check (x.origSrc or x); };
27 # This is how the Nix expressions generated by *-to-nix receive
28 # their flags argument.
29 config._module.args = mod_args // { flags = config.flags; };
31 options = (packageOptions parentConfig) // {
32 # TODO: Add descriptions to everything.
37 specVersion = mkOption {
41 identifier.name = mkOption {
45 identifier.version = mkOption {
53 copyright = mkOption {
57 maintainer = mkOption {
77 description = mkOption {
81 buildType = mkOption {
85 setup-depends = mkOption {
86 type = listOfFilteringNulls unspecified;
90 detailLevel = mkOption {
92 default = "MinimalDetails";
95 licenseFiles = mkOption {
96 type = listOfFilteringNulls unspecified;
105 dataFiles = mkOption {
106 type = listOfFilteringNulls unspecified;
110 extraSrcFiles = mkOption {
111 type = listOfFilteringNulls unspecified;
115 extraTmpFiles = mkOption {
116 type = listOfFilteringNulls unspecified;
120 extraDocFiles = mkOption {
121 type = listOfFilteringNulls unspecified;
125 cleanHpack = mkOption {
135 ghcOptions = mkOption {
142 componentType = submodule {
143 # add the shared componentOptions
144 options = (packageOptions config) // {
145 buildable = mkOption {
150 type = listOfFilteringNulls unspecified;
154 type = listOfFilteringNulls (nullOr package);
157 frameworks = mkOption {
158 type = listOfFilteringNulls package;
161 pkgconfig = mkOption {
162 type = listOf (listOfFilteringNulls package);
165 build-tools = mkOption {
166 type = listOfFilteringNulls unspecified;
170 type = listOfFilteringNulls unspecified;
173 asmSources = mkOption {
174 type = listOfFilteringNulls unspecified;
177 cmmSources = mkOption {
178 type = listOfFilteringNulls unspecified;
181 cSources = mkOption {
182 type = listOfFilteringNulls unspecified;
185 cxxSources = mkOption {
186 type = listOfFilteringNulls unspecified;
189 jsSources = mkOption {
190 type = listOfFilteringNulls unspecified;
193 hsSourceDirs = mkOption {
194 type = listOfFilteringNulls unspecified;
197 includeDirs = mkOption {
198 type = listOfFilteringNulls unspecified;
201 includes = mkOption {
202 type = listOfFilteringNulls unspecified;
205 mainPath = mkOption {
206 type = listOfFilteringNulls unspecified;
209 extraSrcFiles = mkOption {
210 type = listOfFilteringNulls unspecified;
213 platforms = mkOption {
214 type = nullOr (listOfFilteringNulls unspecified);
221 type = nullOr componentType;
226 doExactConfig = false;
227 # We have to set hsSourceDirs or cleanCabalComponent will
228 # include everything (and as a result all the components of
229 # the package will depend on eveything in the package).
230 # TODO find a better way
231 hsSourceDirs = ["setup-src"];
238 extraSrcFiles = [ "Setup.hs" "Setup.lhs" ];
243 type = nullOr componentType;
247 type = attrsOf componentType;
250 foreignlibs = mkOption {
251 type = attrsOf componentType;
255 type = attrsOf componentType;
259 type = attrsOf componentType;
262 benchmarks = mkOption {
263 type = attrsOf componentType;
267 type = componentType;
268 apply = all: all // {
269 # TODO: Should this check for the entire component
270 # definition to match, rather than just the identifier?
271 depends = builtins.filter (p: p.identifier != config.package.identifier) all.depends;
273 description = "The merged dependencies of all other components";
279 default = "${config.package.identifier.name}-${config.package.identifier.version}";
280 defaultText = "\${config.package.identifier.name}-\${config.package.identifier.version}";
287 type = either path package;
288 default = pkgs.fetchurl { url = "mirror://hackage/${config.name}.tar.gz"; inherit (config) sha256; };
289 defaultText = "pkgs.fetchurl { url = \"mirror://hackage/\${config.name}.tar.gz\"; inherit (config) sha256; };";
291 cabal-generator = mkOption {
295 revision = mkOption {
299 revisionSha256 = mkOption {
304 type = listOf (either unspecified path);
309 # This has one quirk. Manually setting options on the all component
310 # will be considered a conflict. This is almost always fine; most
311 # settings should be modified in either the package options, or an
312 # individual component's options. When this isn't sufficient,
313 # mkForce is a reasonable workaround.
315 # An alternative solution to mkForce for many of the options where
316 # this is relevant would be to switch from the bool type to
317 # something like an anyBool type, which would merge definitions by
318 # returning true if any is true.
319 config.components.all =
320 let allComps = haskellLib.getAllComponents config;
323 # Exclude attributes that are likely to have conflicting definitions
324 # (a common use case for `all` is in `shellFor` and it only has an
326 builtins.removeAttrs c ["preCheck" "postCheck" "keepSource"]
329 # If any one of the components needs us to keep the source
330 # then keep it for the `all` component
331 keepSource = lib.foldl' (x: comp: x || comp.keepSource) false allComps;
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list