Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1# This expression takes a file like `hackage-packages.nix` and constructs 2# a full package set out of that. 3 4{ # package-set used for build tools (all of nixpkgs) 5 buildPackages 6 7, # A haskell package set for Setup.hs, compiler plugins, and similar 8 # build-time uses. 9 buildHaskellPackages 10 11, # package-set used for non-haskell dependencies (all of nixpkgs) 12 pkgs 13 14, # stdenv provides our build and host platforms 15 stdenv 16 17, # this module provides the list of known licenses and maintainers 18 lib 19 20 # needed for overrideCabal & packageSourceOverrides 21, haskellLib 22 23, # hashes for downloading Hackage packages 24 # This is either a directory or a .tar.gz containing the cabal files and 25 # hashes of Hackage as exemplified by this repository: 26 # https://github.com/commercialhaskell/all-cabal-hashes/tree/hackage 27 all-cabal-hashes 28 29, # compiler to use 30 ghc 31 32, # A function that takes `{ pkgs, lib, callPackage }` as the first arg and 33 # `self` as second, and returns a set of haskell packages 34 package-set 35 36, # The final, fully overridden package set usable with the nixpkgs fixpoint 37 # overriding functionality 38 extensible-self 39}: 40 41# return value: a function from self to the package set 42self: 43 44let 45 inherit (stdenv) buildPlatform hostPlatform; 46 47 inherit (lib) fix' extends makeOverridable; 48 inherit (haskellLib) overrideCabal; 49 50 mkDerivationImpl = pkgs.callPackage ./generic-builder.nix { 51 inherit stdenv; 52 nodejs = buildPackages.nodejs-slim; 53 inherit (self) buildHaskellPackages ghc ghcWithHoogle ghcWithPackages; 54 inherit (self.buildHaskellPackages) jailbreak-cabal; 55 hscolour = overrideCabal (drv: { 56 isLibrary = false; 57 doHaddock = false; 58 hyperlinkSource = false; # Avoid depending on hscolour for this build. 59 postFixup = "rm -rf $out/lib $out/share $out/nix-support"; 60 }) self.buildHaskellPackages.hscolour; 61 cpphs = overrideCabal (drv: { 62 isLibrary = false; 63 postFixup = "rm -rf $out/lib $out/share $out/nix-support"; 64 }) (self.cpphs.overrideScope (self: super: { 65 mkDerivation = drv: super.mkDerivation (drv // { 66 enableSharedExecutables = false; 67 enableSharedLibraries = false; 68 doHaddock = false; 69 useCpphs = false; 70 }); 71 })); 72 }; 73 74 mkDerivation = makeOverridable mkDerivationImpl; 75 76 # manualArgs are the arguments that were explicitly passed to `callPackage`, like: 77 # 78 # callPackage foo { bar = null; }; 79 # 80 # here `bar` is a manual argument. 81 callPackageWithScope = scope: fn: manualArgs: 82 let 83 # this code is copied from callPackage in lib/customisation.nix 84 # 85 # we cannot use `callPackage` here because we want to call `makeOverridable` 86 # on `drvScope` (we cannot add `overrideScope` after calling `callPackage` because then it is 87 # lost on `.override`) but determine the auto-args based on `drv` (the problem here 88 # is that nix has no way to "passthrough" args while preserving the reflection 89 # info that callPackage uses to determine the arguments). 90 drv = if lib.isFunction fn then fn else import fn; 91 auto = builtins.intersectAttrs (lib.functionArgs drv) scope; 92 93 # Converts a returned function to a functor attribute set if necessary 94 ensureAttrs = v: if builtins.isFunction v then { __functor = _: v; } else v; 95 96 # this wraps the `drv` function to add `scope` and `overrideScope` to the result. 97 drvScope = allArgs: ensureAttrs (drv allArgs) // { 98 inherit scope; 99 overrideScope = f: 100 let newScope = mkScope (fix' (extends f scope.__unfix__)); 101 # note that we have to be careful here: `allArgs` includes the auto-arguments that 102 # weren't manually specified. If we would just pass `allArgs` to the recursive call here, 103 # then we wouldn't look up any packages in the scope in the next interation, because it 104 # appears as if all arguments were already manually passed, so the scope change would do 105 # nothing. 106 in callPackageWithScope newScope drv manualArgs; 107 }; 108 in lib.makeOverridable drvScope (auto // manualArgs); 109 110 mkScope = scope: let 111 ps = pkgs.__splicedPackages; 112 scopeSpliced = pkgs.splicePackages { 113 pkgsBuildBuild = scope.buildHaskellPackages.buildHaskellPackages; 114 pkgsBuildHost = scope.buildHaskellPackages; 115 pkgsBuildTarget = {}; 116 pkgsHostHost = {}; 117 pkgsHostTarget = scope; 118 pkgsTargetTarget = {}; 119 } // { 120 # Don't splice these 121 inherit (scope) ghc buildHaskellPackages; 122 }; 123 in ps // ps.xorg // ps.gnome2 // { inherit stdenv; } // scopeSpliced; 124 defaultScope = mkScope self; 125 callPackage = drv: args: callPackageWithScope defaultScope drv args; 126 127 # Use cabal2nix to create a default.nix for the package sources found at 'src'. 128 haskellSrc2nix = { name, src, sha256 ? null, extraCabal2nixOptions ? "" }: 129 let 130 sha256Arg = if sha256 == null then "--sha256=" else ''--sha256="${sha256}"''; 131 in buildPackages.runCommand "cabal2nix-${name}" { 132 nativeBuildInputs = [ buildPackages.cabal2nix-unwrapped ]; 133 preferLocalBuild = true; 134 allowSubstitutes = false; 135 LANG = "en_US.UTF-8"; 136 LOCALE_ARCHIVE = pkgs.lib.optionalString (buildPlatform.libc == "glibc") "${buildPackages.glibcLocales}/lib/locale/locale-archive"; 137 } '' 138 export HOME="$TMP" 139 mkdir -p "$out" 140 cabal2nix --compiler=${self.ghc.haskellCompilerName} --system=${hostPlatform.config} ${sha256Arg} "${src}" ${extraCabal2nixOptions} > "$out/default.nix" 141 ''; 142 143 # Given a package name and version, e.g. name = "async", version = "2.2.4", 144 # gives its cabal file and hashes (JSON file) as discovered from the 145 # all-cabal-hashes value. If that's a directory, it will copy the relevant 146 # files to $out; if it's a tarball, it will extract and move them to $out. 147 all-cabal-hashes-component = name: version: buildPackages.runCommand "all-cabal-hashes-component-${name}-${version}" {} '' 148 mkdir -p $out 149 if [ -d ${all-cabal-hashes} ] 150 then 151 cp ${all-cabal-hashes}/${name}/${version}/${name}.json $out 152 cp ${all-cabal-hashes}/${name}/${version}/${name}.cabal $out 153 else 154 tar --wildcards -xzvf ${all-cabal-hashes} \*/${name}/${version}/${name}.{json,cabal} 155 mv */${name}/${version}/${name}.{json,cabal} $out 156 fi 157 ''; 158 159 hackage2nix = name: version: let component = all-cabal-hashes-component name version; in self.haskellSrc2nix { 160 name = "${name}-${version}"; 161 sha256 = ''$(sed -e 's/.*"SHA256":"//' -e 's/".*$//' "${component}/${name}.json")''; 162 src = "${component}/${name}.cabal"; 163 }; 164 165 # Adds a nix file derived from cabal2nix in the passthru of the derivation it 166 # produces. This is useful to debug callHackage / callCabal2nix by looking at 167 # the content of the nix file pointed by `cabal2nixDeriver`. 168 # However, it does not keep a reference to that file, which may be garbage 169 # collected, which may be an annoyance. 170 callPackageKeepDeriver = src: args: 171 overrideCabal (orig: { 172 passthru = orig.passthru or {} // { 173 # When using callCabal2nix or callHackage, it is often useful 174 # to debug a failure by inspecting the Nix expression 175 # generated by cabal2nix. This can be accessed via this 176 # cabal2nixDeriver field. 177 cabal2nixDeriver = src; 178 }; 179 }) (self.callPackage src args); 180 181in package-set { inherit pkgs lib callPackage; } self // { 182 183 inherit mkDerivation callPackage haskellSrc2nix hackage2nix buildHaskellPackages; 184 185 inherit (haskellLib) packageSourceOverrides; 186 187 # callHackage :: Text -> Text -> AttrSet -> HaskellPackage 188 # 189 # e.g., while overriding a package set: 190 # '... foo = self.callHackage "foo" "1.5.3" {}; ...' 191 callHackage = name: version: callPackageKeepDeriver (self.hackage2nix name version); 192 193 # callHackageDirect 194 # :: { pkg :: Text, ver :: Text, sha256 :: Text } 195 # -> AttrSet 196 # -> HaskellPackage 197 # 198 # This function does not depend on all-cabal-hashes and therefore will work 199 # for any version that has been released on hackage as opposed to only 200 # versions released before whatever version of all-cabal-hashes you happen 201 # to be currently using. 202 callHackageDirect = {pkg, ver, sha256}: 203 let pkgver = "${pkg}-${ver}"; 204 in self.callCabal2nix pkg (pkgs.fetchzip { 205 url = "mirror://hackage/${pkgver}/${pkgver}.tar.gz"; 206 inherit sha256; 207 }); 208 209 # Creates a Haskell package from a source package by calling cabal2nix on the source. 210 callCabal2nixWithOptions = name: src: extraCabal2nixOptions: args: 211 let 212 filter = path: type: 213 pkgs.lib.hasSuffix ".cabal" path || 214 baseNameOf path == "package.yaml"; 215 expr = self.haskellSrc2nix { 216 inherit name extraCabal2nixOptions; 217 src = if pkgs.lib.canCleanSource src 218 then pkgs.lib.cleanSourceWith { inherit src filter; } 219 else src; 220 }; 221 in overrideCabal (orig: { 222 inherit src; 223 }) (callPackageKeepDeriver expr args); 224 225 callCabal2nix = name: src: args: self.callCabal2nixWithOptions name src "" args; 226 227 # : { root : Path 228 # , name : Defaulted String 229 # , source-overrides : Defaulted (Either Path VersionNumber) 230 # , overrides : Defaulted (HaskellPackageOverrideSet) 231 # , modifier : Defaulted 232 # , returnShellEnv : Defaulted 233 # , withHoogle : Defaulted 234 # , cabal2nixOptions : Defaulted 235 # } -> NixShellAwareDerivation 236 # 237 # Given a path to a haskell package directory, an optional package name 238 # which defaults to the base name of the path, an optional set of source 239 # overrides as appropriate for the 'packageSourceOverrides' function, an 240 # optional set of arbitrary overrides, and an optional haskell package 241 # modifier, return a derivation appropriate for nix-build or nix-shell to 242 # build that package. 243 # 244 # If 'returnShellEnv' is true this returns a derivation which will give you 245 # an environment suitable for developing the listed packages with an 246 # incremental tool like cabal-install. 247 # 248 # If 'withHoogle' is true (the default if a shell environment is requested) 249 # then 'ghcWithHoogle' is used to generate the derivation (instead of 250 # 'ghcWithPackages'), see the documentation there for more information. 251 # 252 # 'cabal2nixOptions' can contain extra command line arguments to pass to 253 # 'cabal2nix' when generating the package derivation, for example setting 254 # a cabal flag with '--flag=myflag'. 255 developPackage = 256 { root 257 , name ? lib.optionalString (builtins.typeOf root == "path") (builtins.baseNameOf root) 258 , source-overrides ? {} 259 , overrides ? self: super: {} 260 , modifier ? drv: drv 261 , returnShellEnv ? pkgs.lib.inNixShell 262 , withHoogle ? returnShellEnv 263 , cabal2nixOptions ? "" }: 264 let drv = 265 (extensible-self.extend 266 (pkgs.lib.composeExtensions 267 (self.packageSourceOverrides source-overrides) 268 overrides)) 269 .callCabal2nixWithOptions name root cabal2nixOptions {}; 270 in if returnShellEnv 271 then (modifier drv).envFunc {inherit withHoogle;} 272 else modifier drv; 273 274 # This can be used to easily create a derivation containing GHC and the specified set of Haskell packages. 275 # 276 # Example: 277 # $ nix-shell -p 'haskellPackages.ghcWithPackages (hpkgs: [ hpkgs.mtl hpkgs.lens ])' 278 # $ ghci # in the nix-shell 279 # Prelude > import Control.Lens 280 # 281 # GHC is setup with a package database with all the specified Haskell packages. 282 # 283 # ghcWithPackages :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation 284 ghcWithPackages = buildHaskellPackages.callPackage ./with-packages-wrapper.nix { 285 haskellPackages = self; 286 }; 287 288 289 # Put 'hoogle' into the derivation's PATH with a database containing all 290 # the package's dependencies; run 'hoogle server --local' in a shell to 291 # host a search engine for the dependencies. 292 # 293 # Example usage: 294 # $ nix-shell -p 'haskellPackages.hoogleWithPackages (p: [ p.mtl p.lens ])' 295 # [nix-shell] $ hoogle server 296 # 297 # hoogleWithPackages :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation 298 # 299 # To reload the Hoogle server automatically on .cabal file changes try 300 # this: 301 # echo *.cabal | entr -r -- nix-shell --run 'hoogle server --local' 302 hoogleWithPackages = self.callPackage ./hoogle.nix { 303 haskellPackages = self; 304 }; 305 hoogleLocal = 306 { packages ? [] }: 307 lib.warn "hoogleLocal is deprecated, use hoogleWithPackages instead" ( 308 self.hoogleWithPackages (_: packages) 309 ); 310 # This is like a combination of ghcWithPackages and hoogleWithPackages. 311 # It provides a derivation containing both GHC and Hoogle with an index of 312 # the given Haskell package database. 313 # 314 # Example: 315 # $ nix-shell -p 'haskellPackages.ghcWithHoogle (hpkgs: [ hpkgs.conduit hpkgs.lens ])' 316 # 317 # ghcWithHoogle :: (HaskellPkgSet -> [ HaskellPkg ]) -> Derivation 318 ghcWithHoogle = self.ghcWithPackages.override { 319 withHoogle = true; 320 }; 321 322 # Returns a derivation whose environment contains a GHC with only 323 # the dependencies of packages listed in `packages`, not the 324 # packages themselves. Using nix-shell on this derivation will 325 # give you an environment suitable for developing the listed 326 # packages with an incremental tool like cabal-install. 327 # 328 # In addition to the "packages" arg and "withHoogle" arg, anything that 329 # can be passed into stdenv.mkDerivation can be included in the input attrset 330 # 331 # # default.nix 332 # with import <nixpkgs> {}; 333 # haskellPackages.extend (haskell.lib.compose.packageSourceOverrides { 334 # frontend = ./frontend; 335 # backend = ./backend; 336 # common = ./common; 337 # }) 338 # 339 # # shell.nix 340 # let pkgs = import <nixpkgs> {} in 341 # (import ./.).shellFor { 342 # packages = p: [p.frontend p.backend p.common]; 343 # withHoogle = true; 344 # buildInputs = [ pkgs.python pkgs.cabal-install ]; 345 # } 346 # 347 # -- cabal.project 348 # packages: 349 # frontend/ 350 # backend/ 351 # common/ 352 # 353 # bash$ nix-shell --run "cabal new-build all" 354 # bash$ nix-shell --run "python" 355 shellFor = 356 { # Packages to create this development shell for. These are usually 357 # your local packages. 358 packages 359 , # Whether or not to generate a Hoogle database for all the 360 # dependencies. 361 withHoogle ? false 362 , # Whether or not to include benchmark dependencies of your local 363 # packages. You should set this to true if you have benchmarks defined 364 # in your local packages that you want to be able to run with cabal benchmark 365 doBenchmark ? false 366 # An optional function that can modify the generic builder arguments 367 # for the fake package that shellFor uses to construct its environment. 368 # 369 # Example: 370 # let 371 # # elided... 372 # haskellPkgs = pkgs.haskell.packages.ghc884.override (hpArgs: { 373 # overrides = pkgs.lib.composeExtensions (hpArgs.overrides or (_: _: { })) ( 374 # _hfinal: hprev: { 375 # mkDerivation = args: hprev.mkDerivation ({ 376 # doCheck = false; 377 # doBenchmark = false; 378 # doHoogle = true; 379 # doHaddock = true; 380 # enableLibraryProfiling = false; 381 # enableExecutableProfiling = false; 382 # } // args); 383 # } 384 # ); 385 # }); 386 # in 387 # haskellPkgs.shellFor { 388 # packages = p: [ p.foo ]; 389 # genericBuilderArgsModifier = args: args // { doCheck = true; doBenchmark = true }; 390 # } 391 # 392 # This will disable tests and benchmarks for everything in "haskellPkgs" 393 # (which will invalidate the binary cache), and then re-enable them 394 # for the "shellFor" environment (ensuring that any test/benchmark 395 # dependencies for "foo" will be available within the nix-shell). 396 , genericBuilderArgsModifier ? (args: args) 397 398 # Extra dependencies, in the form of cabal2nix build attributes. 399 # 400 # An example use case is when you have Haskell scripts that use 401 # libraries that don't occur in your packages' dependencies. 402 # 403 # Example: 404 # 405 # extraDependencies = p: { 406 # libraryHaskellDepends = [ p.releaser ]; 407 # }; 408 , extraDependencies ? p: {} 409 , ... 410 } @ args: 411 let 412 # A list of the packages we want to build a development shell for. 413 # This is a list of Haskell package derivations. 414 selected = packages self; 415 416 # This is a list of attribute sets, where each attribute set 417 # corresponds to the build inputs of one of the packages input to shellFor. 418 # 419 # Each attribute has keys like buildDepends, executableHaskellDepends, 420 # testPkgconfigDepends, etc. The values for the keys of the attribute 421 # set are lists of dependencies. 422 # 423 # Example: 424 # cabalDepsForSelected 425 # => [ 426 # # This may be the attribute set corresponding to the `backend` 427 # # package in the example above. 428 # { buildDepends = [ gcc ... ]; 429 # libraryHaskellDepends = [ lens conduit ... ]; 430 # ... 431 # } 432 # # This may be the attribute set corresponding to the `common` 433 # # package in the example above. 434 # { testHaskellDepends = [ tasty hspec ... ]; 435 # libraryHaskellDepends = [ lens aeson ]; 436 # benchmarkHaskellDepends = [ criterion ... ]; 437 # ... 438 # } 439 # ... 440 # ] 441 cabalDepsForSelected = map (p: p.getCabalDeps) selected; 442 443 # A predicate that takes a derivation as input, and tests whether it is 444 # the same as any of the `selected` packages. 445 # 446 # Returns true if the input derivation is not in the list of `selected` 447 # packages. 448 # 449 # isNotSelected :: Derivation -> Bool 450 # 451 # Example: 452 # 453 # isNotSelected common [ frontend backend common ] 454 # => false 455 # 456 # isNotSelected lens [ frontend backend common ] 457 # => true 458 isNotSelected = input: pkgs.lib.all (p: input.outPath or null != p.outPath) selected; 459 460 # A function that takes a list of list of derivations, filters out all 461 # the `selected` packages from each list, and concats the results. 462 # 463 # zipperCombinedPkgs :: [[Derivation]] -> [Derivation] 464 # 465 # Example: 466 # zipperCombinedPkgs [ [ lens conduit ] [ aeson frontend ] ] 467 # => [ lens conduit aeson ] 468 # 469 # Note: The reason this isn't just the function `pkgs.lib.concat` is 470 # that we need to be careful to remove dependencies that are in the 471 # `selected` packages. 472 # 473 # For instance, in the above example, if `common` is a dependency of 474 # `backend`, then zipperCombinedPkgs needs to be careful to filter out 475 # `common`, because cabal will end up ignoring that built version, 476 # assuming new-style commands. 477 zipperCombinedPkgs = vals: 478 pkgs.lib.concatMap 479 (drvList: pkgs.lib.filter isNotSelected drvList) 480 vals; 481 482 # Zip `cabalDepsForSelected` into a single attribute list, combining 483 # the derivations in all the individual attributes. 484 # 485 # Example: 486 # packageInputs 487 # => # Assuming the value of cabalDepsForSelected is the same as 488 # # the example in cabalDepsForSelected: 489 # { buildDepends = [ gcc ... ]; 490 # libraryHaskellDepends = [ lens conduit aeson ... ]; 491 # testHaskellDepends = [ tasty hspec ... ]; 492 # benchmarkHaskellDepends = [ criterion ... ]; 493 # ... 494 # } 495 # 496 # See the Note in `zipperCombinedPkgs` for what gets filtered out from 497 # each of these dependency lists. 498 packageInputs = 499 pkgs.lib.zipAttrsWith (_name: zipperCombinedPkgs) (cabalDepsForSelected ++ [ (extraDependencies self) ]); 500 501 # A attribute set to pass to `haskellPackages.mkDerivation`. 502 # 503 # The important thing to note here is that all the fields from 504 # packageInputs are set correctly. 505 genericBuilderArgs = { 506 pname = 507 if pkgs.lib.length selected == 1 508 then (pkgs.lib.head selected).name 509 else "packages"; 510 version = "0"; 511 license = null; 512 } 513 // packageInputs 514 // pkgs.lib.optionalAttrs doBenchmark { 515 # `doBenchmark` needs to explicitly be set here because haskellPackages.mkDerivation defaults it to `false`. If the user wants benchmark dependencies included in their development shell, it has to be explicitly enabled here. 516 doBenchmark = true; 517 }; 518 519 # This is a pseudo Haskell package derivation that contains all the 520 # dependencies for the packages in `selected`. 521 # 522 # This is a derivation created with `haskellPackages.mkDerivation`. 523 # 524 # pkgWithCombinedDeps :: HaskellDerivation 525 pkgWithCombinedDeps = self.mkDerivation (genericBuilderArgsModifier genericBuilderArgs); 526 527 # The derivation returned from `envFunc` for `pkgWithCombinedDeps`. 528 # 529 # This is a derivation that can be run with `nix-shell`. It provides a 530 # GHC with a package database with all the dependencies of our 531 # `selected` packages. 532 # 533 # This is a derivation created with `stdenv.mkDerivation` (not 534 # `haskellPackages.mkDerivation`). 535 # 536 # pkgWithCombinedDepsDevDrv :: Derivation 537 pkgWithCombinedDepsDevDrv = pkgWithCombinedDeps.envFunc { inherit withHoogle; }; 538 539 mkDerivationArgs = builtins.removeAttrs args [ "genericBuilderArgsModifier" "packages" "withHoogle" "doBenchmark" "extraDependencies" ]; 540 541 in pkgWithCombinedDepsDevDrv.overrideAttrs (old: mkDerivationArgs // { 542 nativeBuildInputs = old.nativeBuildInputs ++ mkDerivationArgs.nativeBuildInputs or []; 543 buildInputs = old.buildInputs ++ mkDerivationArgs.buildInputs or []; 544 }); 545 546 ghc = ghc // { 547 withPackages = self.ghcWithPackages; 548 withHoogle = self.ghcWithHoogle; 549 }; 550 551 /* 552 Run `cabal sdist` on a source. 553 554 Unlike `haskell.lib.sdistTarball`, this does not require any dependencies 555 to be present, as it uses `cabal-install` instead of building `Setup.hs`. 556 This makes `cabalSdist` faster than `sdistTarball`. 557 */ 558 cabalSdist = { 559 src, 560 name ? if src?name then "${src.name}-sdist.tar.gz" else "source.tar.gz" 561 }: 562 pkgs.runCommandLocal name 563 { 564 inherit src; 565 nativeBuildInputs = [ 566 buildHaskellPackages.cabal-install 567 568 # TODO after https://github.com/haskell/cabal/issues/8352 569 # remove ghc 570 self.ghc 571 ]; 572 dontUnpack = false; 573 } '' 574 unpackPhase 575 cd "''${sourceRoot:-.}" 576 patchPhase 577 mkdir out 578 HOME=$PWD cabal sdist --output-directory out 579 mv out/*.tar.gz $out 580 ''; 581 582 /* 583 Like `haskell.lib.buildFromSdist`, but using `cabal sdist` instead of 584 building `./Setup`. 585 586 Unlike `haskell.lib.buildFromSdist`, this does not require any dependencies 587 to be present. This makes `buildFromCabalSdist` faster than `haskell.lib.buildFromSdist`. 588 */ 589 buildFromCabalSdist = pkg: 590 haskellLib.overrideSrc 591 { 592 src = self.cabalSdist { inherit (pkg) src; }; 593 version = pkg.version; 594 } 595 pkg; 596 597 /* 598 Modify a Haskell package to add shell completion scripts for the 599 given executables produced by it. These completion scripts will be 600 picked up automatically if the resulting derivation is installed, 601 e.g. by `nix-env -i`. 602 603 This depends on the `--*-completion` flag `optparse-applicative` provides 604 automatically. Since we need to invoke installed executables, completions 605 are not generated if we are cross-compiling. 606 607 commands: names of the executables built by the derivation 608 pkg: Haskell package that builds the executables 609 610 Example: 611 generateOptparseApplicativeCompletions [ "exec1" "exec2" ] pkg 612 613 Type: [str] -> drv -> drv 614 */ 615 generateOptparseApplicativeCompletions = 616 self.callPackage ( 617 { stdenv }: 618 619 commands: 620 pkg: 621 622 if stdenv.buildPlatform.canExecute stdenv.hostPlatform 623 then lib.foldr haskellLib.__generateOptparseApplicativeCompletion pkg commands 624 else pkg 625 ) { }; 626 627 }