on iko/ghcjs-patch-master help sign in
Add `getComponent` to project and package (#1060)
5c25ce9Hamish Mackenzie
@@ -80,9 +80,9 @@ dimension "Nixpkgs version" nixpkgsVersions (nixpkgsName: nixpkgs-pin:
80 } // pkgs.lib.optionalAttrs runTests {
80 } // pkgs.lib.optionalAttrs runTests {
81 inherit (build) tests tools maintainer-scripts maintainer-script-cache;
81 inherit (build) tests tools maintainer-scripts maintainer-script-cache;
82 } // pkgs.lib.optionalAttrs (ifdLevel >= 1) {
82 } // pkgs.lib.optionalAttrs (ifdLevel >= 1) {
83− iserv-proxy = pkgs.ghc-extra-packages."${compiler-nix-name}".iserv-proxy.components.exes.iserv-proxy;
83+ iserv-proxy = pkgs.ghc-extra-projects."${compiler-nix-name}".getComponent "iserv-proxy:exe:iserv-proxy";
84 } // pkgs.lib.optionalAttrs (ifdLevel >= 3) {
84 } // pkgs.lib.optionalAttrs (ifdLevel >= 3) {
85− hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; inherit compiler-nix-name; }).components.exes.hello;
85+ hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; inherit compiler-nix-name; }).getComponent "exe:hello";
86 });
86 });
87 }
87 }
88 //
88 //
@@ -102,10 +102,10 @@ dimension "Nixpkgs version" nixpkgsVersions (nixpkgsName: nixpkgs-pin:
102 inherit (build) tests;
102 inherit (build) tests;
103 }) // pkgs.lib.optionalAttrs (ifdLevel >= 2 && crossSystemName != "ghcjs") {
103 }) // pkgs.lib.optionalAttrs (ifdLevel >= 2 && crossSystemName != "ghcjs") {
104 # GHCJS builds its own template haskell runner.
104 # GHCJS builds its own template haskell runner.
105− remote-iserv = pkgs.ghc-extra-packages."${compiler-nix-name}".remote-iserv.components.exes.remote-iserv;
105+ remote-iserv = pkgs.ghc-extra-projects."${compiler-nix-name}".getComponent "remote-iserv:exe:remote-iserv";
106− iserv-proxy = pkgs.ghc-extra-packages."${compiler-nix-name}".iserv-proxy.components.exes.iserv-proxy;
106+ iserv-proxy = pkgs.ghc-extra-projects."${compiler-nix-name}".getComponent "iserv-proxy:exe:iserv-proxy";
107 } // pkgs.lib.optionalAttrs (ifdLevel >= 3) {
107 } // pkgs.lib.optionalAttrs (ifdLevel >= 3) {
108− hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; inherit compiler-nix-name; }).components.exes.hello;
108+ hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; inherit compiler-nix-name; }).getComponent "exe:hello";
109 })
109 })
110 ))
110 ))
111 )
111 )
compiler/ghcjs/ghcjs.nix+13−13
@@ -24,21 +24,21 @@ let
24 all-ghcjs = pkgs.buildPackages.symlinkJoin {
24 all-ghcjs = pkgs.buildPackages.symlinkJoin {
25 name = "ghcjs-${ghcjsVersion}-symlinked";
25 name = "ghcjs-${ghcjsVersion}-symlinked";
26 paths = [
26 paths = [
27− ghcjs.components.exes.ghcjs
27+ (ghcjs.getComponent "exe:ghcjs")
28− ghcjs.components.exes.ghcjs-pkg
28+ (ghcjs.getComponent "exe:ghcjs-pkg")
29− ghcjs.components.exes.ghcjs-boot
29+ (ghcjs.getComponent "exe:ghcjs-boot")
30− ghcjs.components.exes.ghcjs-dumparchive
30+ (ghcjs.getComponent "exe:ghcjs-dumparchive")
31 ] ++ (if isGhcjs88
31 ] ++ (if isGhcjs88
32 then [
32 then [
33− ghcjs.components.exes.haddock
33+ (ghcjs.getComponent "exe:haddock")
34− ghcjs.components.exes.private-ghcjs-run
34+ (ghcjs.getComponent "exe:private-ghcjs-run")
35− ghcjs.components.exes.private-ghcjs-unlit
35+ (ghcjs.getComponent "exe:private-ghcjs-unlit")
36− ghcjs.components.exes.private-ghcjs-hsc2hs
36+ (ghcjs.getComponent "exe:private-ghcjs-hsc2hs")
37 ]
37 ]
38 else [
38 else [
39− ghcjs.components.exes.haddock-ghcjs
39+ (ghcjs.getComponent "exe:haddock-ghcjs")
40− ghcjs.components.exes.hsc2hs-ghcjs
40+ (ghcjs.getComponent "exe:hsc2hs-ghcjs")
41− ghcjs.components.exes.ghcjs-run
41+ (ghcjs.getComponent "exe:ghcjs-run")
42 ]);
42 ]);
43 };
43 };
44 libexec = "libexec/${builtins.replaceStrings ["darwin" "i686"] ["osx" "i386"] pkgs.stdenv.buildPlatform.system}-${ghc.name}/ghcjs-${ghcVersion}";
44 libexec = "libexec/${builtins.replaceStrings ["darwin" "i686"] ["osx" "i386"] pkgs.stdenv.buildPlatform.system}-${ghc.name}/ghcjs-${ghcVersion}";
@@ -68,9 +68,9 @@ let
68 lndir ${all-ghcjs}/bin $out/bin
68 lndir ${all-ghcjs}/bin $out/bin
69 chmod -R +w $out/bin
69 chmod -R +w $out/bin
70 rm $out/bin/ghcjs-boot
70 rm $out/bin/ghcjs-boot
71− cp ${ghcjs.components.exes.ghcjs-boot}/bin/ghcjs-boot $out/bin
71+ cp ${ghcjs.getComponent "exe:ghcjs-boot"}/bin/ghcjs-boot $out/bin
72 rm $out/bin/haddock
72 rm $out/bin/haddock
73− cp ${ghcjs.components.exes.haddock}/bin/haddock $out/bin
73+ cp ${ghcjs.getComponent "exe:haddock"}/bin/haddock $out/bin
74
74
75 wrapProgram $out/bin/ghcjs --add-flags "-B$out/lib"
75 wrapProgram $out/bin/ghcjs --add-flags "-B$out/lib"
76 wrapProgram $out/bin/haddock --add-flags "-B$out/lib"
76 wrapProgram $out/bin/haddock --add-flags "-B$out/lib"
lib/call-cabal-project-to-nix.nix+45−10
@@ -44,6 +44,7 @@ in
44
44
45let
45let
46 forName = pkgs.lib.optionalString (name != null) (" for " + name);
46 forName = pkgs.lib.optionalString (name != null) (" for " + name);
47+ nameAndSuffix = suffix: if name == null then suffix else name + "-" + suffix;
47
48
48 ghc' =
49 ghc' =
49 if ghcOverride != null
50 if ghcOverride != null
@@ -378,7 +379,7 @@ let
378 else null;
379 else null;
379 } // pkgs.lib.optionalAttrs (checkMaterialization != null) {
380 } // pkgs.lib.optionalAttrs (checkMaterialization != null) {
380 inherit checkMaterialization;
381 inherit checkMaterialization;
381− }) (pkgs.evalPackages.runCommand (if name == null then "plan-to-nix-pkgs" else name + "-plan-to-nix-pkgs") {
382+ }) (pkgs.evalPackages.runCommand (nameAndSuffix "plan-to-nix-pkgs") {
382 nativeBuildInputs = [ nix-tools dummy-ghc dummy-ghc-pkg cabal-install pkgs.evalPackages.rsync ];
383 nativeBuildInputs = [ nix-tools dummy-ghc dummy-ghc-pkg cabal-install pkgs.evalPackages.rsync ];
383 # Needed or stack-to-nix will die on unicode inputs
384 # Needed or stack-to-nix will die on unicode inputs
384 LOCALE_ARCHIVE = pkgs.lib.optionalString (pkgs.evalPackages.stdenv.buildPlatform.libc == "glibc") "${pkgs.evalPackages.glibcLocales}/lib/locale/locale-archive";
385 LOCALE_ARCHIVE = pkgs.lib.optionalString (pkgs.evalPackages.stdenv.buildPlatform.libc == "glibc") "${pkgs.evalPackages.glibcLocales}/lib/locale/locale-archive";
@@ -386,10 +387,32 @@ let
386 meta.platforms = pkgs.lib.platforms.all;
387 meta.platforms = pkgs.lib.platforms.all;
387 preferLocalBuild = false;
388 preferLocalBuild = false;
388 outputs = [
389 outputs = [
389− "out" # The results of plan-to-nix
390+ "out" # The results of plan-to-nix
391+ # These two output will be present if in cabal configure failed.
392+ # They are used to provide passthru.json and passthru.freeze that
393+ # check first for cabal configure failure.
390− "json" # The `plan.json` file generated by cabal and used for `plan-to-nix` input
394+ "maybeJson" # The `plan.json` file generated by cabal and used for `plan-to-nix` input
391− "freeze" # The `cabal.project.freeze` file created by `cabal v2-freeze`
395+ "maybeFreeze" # The `cabal.project.freeze` file created by `cabal v2-freeze`
392 ];
396 ];
397+ passthru =
398+ let
399+ checkCabalConfigure = ''
400+ if [[ -f ${plan-nix}/cabal-configure.out ]]; then
401+ cat ${plan-nix}/cabal-configure.out
402+ exit 1
403+ fi
404+ '';
405+ in {
406+ # These check for cabal configure failure
407+ json = pkgs.evalPackages.runCommand (nameAndSuffix "plan-json") {} ''
408+ ${checkCabalConfigure}
409+ cp ${plan-nix.maybeJson} $out
410+ '';
411+ freeze = pkgs.evalPackages.runCommand (nameAndSuffix "plan-freeze") {} ''
412+ ${checkCabalConfigure}
413+ cp ${plan-nix.maybeFreeze} $out
414+ '';
415+ };
393 } ''
416 } ''
394 tmp=$(mktemp -d)
417 tmp=$(mktemp -d)
395 cd $tmp
418 cd $tmp
@@ -430,12 +453,14 @@ let
430 export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
453 export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
431 export GIT_SSL_CAINFO=${cacert}/etc/ssl/certs/ca-bundle.crt
454 export GIT_SSL_CAINFO=${cacert}/etc/ssl/certs/ca-bundle.crt
432
455
456+ mkdir -p $out
457+
433 # Using `cabal v2-freeze` will configure the project (since
458 # Using `cabal v2-freeze` will configure the project (since
434 # it is not configured yet), taking the existing `cabal.project.freeze`
459 # it is not configured yet), taking the existing `cabal.project.freeze`
435 # file into account. Then it "writes out a freeze file which
460 # file into account. Then it "writes out a freeze file which
436 # records all of the versions and flags that are picked" (from cabal docs).
461 # records all of the versions and flags that are picked" (from cabal docs).
437 echo "Using index-state ${index-state-found}"
462 echo "Using index-state ${index-state-found}"
438− HOME=${
463+ if(HOME=${
439 # This creates `.cabal` directory that is as it would have
464 # This creates `.cabal` directory that is as it would have
440 # been at the time `cached-index-state`. We may include
465 # been at the time `cached-index-state`. We may include
441 # some packages that will be excluded by `index-state-found`
466 # some packages that will be excluded by `index-state-found`
@@ -460,14 +485,12 @@ let
460 --enable-benchmarks \
485 --enable-benchmarks \
461 ${pkgs.lib.optionalString (ghc.targetPrefix == "js-unknown-ghcjs-")
486 ${pkgs.lib.optionalString (ghc.targetPrefix == "js-unknown-ghcjs-")
462 "--ghcjs --with-ghcjs=js-unknown-ghcjs-ghc --with-ghcjs-pkg=js-unknown-ghcjs-ghc-pkg"} \
487 "--ghcjs --with-ghcjs=js-unknown-ghcjs-ghc --with-ghcjs-pkg=js-unknown-ghcjs-ghc-pkg"} \
463− ${configureArgs}
488+ ${configureArgs} 2>&1 | tee -a cabal-configure.out); then
464
489
465− cp cabal.project.freeze $freeze
490+ cp cabal.project.freeze $maybeFreeze
466 # Not needed any more (we don't want it to wind up in the $out hash)
491 # Not needed any more (we don't want it to wind up in the $out hash)
467 rm cabal.project.freeze
492 rm cabal.project.freeze
468
493
469− mkdir -p $out
470−
471 # ensure we have all our .cabal files (also those generated from package.yaml) files.
494 # ensure we have all our .cabal files (also those generated from package.yaml) files.
472 # otherwise we'd need to be careful about putting the `cabal-generator = hpack` into
495 # otherwise we'd need to be careful about putting the `cabal-generator = hpack` into
473 # the nix expression. As we already called `hpack` on all `package.yaml` files we can
496 # the nix expression. As we already called `hpack` on all `package.yaml` files we can
@@ -489,7 +512,7 @@ let
489 (cd $out${subDir'} && plan-to-nix --full --plan-json $tmp${subDir'}/dist-newstyle/cache/plan.json -o .)
512 (cd $out${subDir'} && plan-to-nix --full --plan-json $tmp${subDir'}/dist-newstyle/cache/plan.json -o .)
490
513
491 # Make the plan.json file available in case we need to debug plan-to-nix
514 # Make the plan.json file available in case we need to debug plan-to-nix
492− cp $tmp${subDir'}/dist-newstyle/cache/plan.json $json
515+ cp $tmp${subDir'}/dist-newstyle/cache/plan.json $maybeJson
493
516
494 # Remove the non nix files ".project" ".cabal" "package.yaml" files
517 # Remove the non nix files ".project" ".cabal" "package.yaml" files
495 # as they should not be in the output hash (they may change slightly
518 # as they should not be in the output hash (they may change slightly
@@ -504,6 +527,18 @@ let
504
527
505 # move pkgs.nix to default.nix ensure we can just nix `import` the result.
528 # move pkgs.nix to default.nix ensure we can just nix `import` the result.
506 mv $out${subDir'}/pkgs.nix $out${subDir'}/default.nix
529 mv $out${subDir'}/pkgs.nix $out${subDir'}/default.nix
530+ else
531+ # When cabal configure fails copy the output that we captured above and
532+ # use `failed-cabal-configure.nix` to make a suitable derviation with.
533+ cp cabal-configure.out $out
534+ cp ${./failed-cabal-configure.nix} $out/default.nix
535+
536+ # These should only be used indirectly by `passthru.json` and `passthru.freeze`.
537+ # Those derivations will check for `cabal-configure.out` out first to see if
538+ # it is ok to use these files.
539+ echo "Cabal configure failed see $out/cabal-configure.out for details" > $maybeJson
540+ echo "Cabal configure failed see $out/cabal-configure.out for details" > $maybeFreeze
541+ fi
507 '');
542 '');
508in {
543in {
509 projectNix = plan-nix;
544 projectNix = plan-nix;
lib/default.nix+6
@@ -62,6 +62,12 @@ in {
62 benchmarks = "bench";
62 benchmarks = "bench";
63 };
63 };
64
64
65+ # For looking up the components attribute based on the cabal component type
66+ prefixComponent =
67+ lib.listToAttrs (
68+ lib.mapAttrsToList (value: name: { inherit name value; })
69+ componentPrefix);
70+
65 applyComponents = f: config:
71 applyComponents = f: config:
66 let
72 let
67 comps = config.components;
73 comps = config.components;
lib/failed-cabal-configure.nixnew file+9
@@ -0,0 +1,9 @@
1+let
2+ configurationError = ./cabal-configure.out;
3+in
4+ # Trace the error output to make sure the user has a chance to see it
5+ # (even if the choose not to build anything from the project)
6+ __trace ''
7+ ERROR: cabal configure failed with:
8+ ${__readFile configurationError}
9+ '' { inherit configurationError; }
overlays/bootstrap.nix+19−4
@@ -581,7 +581,7 @@ in {
581 cabal-install = final.evalPackages.haskell-nix.cabal-install-unchecked.${compiler-nix-name};
581 cabal-install = final.evalPackages.haskell-nix.cabal-install-unchecked.${compiler-nix-name};
582 nix-tools = final.evalPackages.haskell-nix.nix-tools-unchecked.${compiler-nix-name};
582 nix-tools = final.evalPackages.haskell-nix.nix-tools-unchecked.${compiler-nix-name};
583 materialized = ../materialized + "/${compiler-nix-name}/cabal-install";
583 materialized = ../materialized + "/${compiler-nix-name}/cabal-install";
584− } // args)).components.exes.cabal;
584+ } // args)).getComponent "exe:cabal";
585 nix-tools-set = { compiler-nix-name, ... }@args:
585 nix-tools-set = { compiler-nix-name, ... }@args:
586 let
586 let
587 project =
587 project =
@@ -617,7 +617,22 @@ in {
617 ];
617 ];
618 }];
618 }];
619 } // args);
619 } // args);
620− exes = project.nix-tools.components.exes // project.hpack.components.exes;
620+ exes =
621+ let
622+ package = project.getPackage "nix-tools";
623+ in (builtins.map (name: package.getComponent "exe:${name}") [
624+ "cabal-to-nix"
625+ "hashes-to-nix"
626+ "plan-to-nix"
627+ "hackage-to-nix"
628+ "lts-to-nix"
629+ "stack-to-nix"
630+ "truncate-index"
631+ "stack-repos"
632+ "cabal-name"
633+ ]) ++ [
634+ (project.getComponent "hpack:exe:hpack")
635+ ];
621 tools = [
636 tools = [
622 final.buildPackages.nix
637 final.buildPackages.nix
623 # Double buildPackages is intentional, see comment in lib/default.nix for details.
638 # Double buildPackages is intentional, see comment in lib/default.nix for details.
@@ -626,7 +641,7 @@ in {
626 in
641 in
627 final.symlinkJoin {
642 final.symlinkJoin {
628 name = "nix-tools";
643 name = "nix-tools";
629− paths = builtins.attrValues exes;
644+ paths = exes;
630 buildInputs = [ final.makeWrapper ];
645 buildInputs = [ final.makeWrapper ];
631 meta.platforms = final.lib.platforms.all;
646 meta.platforms = final.lib.platforms.all;
632 # We wrap the -to-nix executables with the executables from `tools` (e.g. nix-prefetch-git)
647 # We wrap the -to-nix executables with the executables from `tools` (e.g. nix-prefetch-git)
@@ -774,7 +789,7 @@ in {
774 version = "1.24.4";
789 version = "1.24.4";
775 inherit ghcOverride nix-tools cabal-install index-state;
790 inherit ghcOverride nix-tools cabal-install index-state;
776 materialized = ../materialized/bootstrap + "/${buildBootstrapper.compilerNixName}/hscolour";
791 materialized = ../materialized/bootstrap + "/${buildBootstrapper.compilerNixName}/hscolour";
777− } // args)).components.exes.HsColour;
792+ } // args)).getComponent "exe:HsColour";
778 hscolour = bootstrap.packages.hscolour-tool {};
793 hscolour = bootstrap.packages.hscolour-tool {};
779 hscolour-unchecked = bootstrap.packages.hscolour-tool { checkMaterialization = false; };
794 hscolour-unchecked = bootstrap.packages.hscolour-tool { checkMaterialization = false; };
780 };
795 };
overlays/haskell.nix+67−7
@@ -457,7 +457,7 @@ final: prev: {
457 hackage-package =
457 hackage-package =
458 { name, compiler-nix-name, ... }@args':
458 { name, compiler-nix-name, ... }@args':
459 let args = { caller = "hackage-package"; } // args';
459 let args = { caller = "hackage-package"; } // args';
460− in (hackage-project args).hsPkgs.${name};
460+ in (hackage-project args).getPackage name;
461 hackage-project =
461 hackage-project =
462 { name
462 { name
463 , compiler-nix-name
463 , compiler-nix-name
@@ -500,11 +500,19 @@ final: prev: {
500 let
500 let
501 args = { caller = "cabalProject'"; } // args';
501 args = { caller = "cabalProject'"; } // args';
502 callProjectResults = callCabalProjectToNix args;
502 callProjectResults = callCabalProjectToNix args;
503− in let pkg-set = mkCabalProjectPkgSet
504− { inherit compiler-nix-name;
505− plan-pkgs = importAndFilterProject {
503+ plan-pkgs = importAndFilterProject {
506− inherit (callProjectResults) projectNix sourceRepos src;
504+ inherit (callProjectResults) projectNix sourceRepos src;
505+ };
506+ pkg-set = if plan-pkgs ? configurationError
507+ then {
508+ inherit (plan-pkgs) configurationError;
509+ config = {
510+ compiler.nix-name = compiler-nix-name;
511+ hsPkgs = {};
507 };
512 };
513+ }
514+ else mkCabalProjectPkgSet
515+ { inherit compiler-nix-name plan-pkgs;
508 pkg-def-extras = args.pkg-def-extras or [];
516 pkg-def-extras = args.pkg-def-extras or [];
509 modules = (args.modules or [])
517 modules = (args.modules or [])
510 ++ final.lib.optional (args ? ghcOverride || args ? ghc)
518 ++ final.lib.optional (args ? ghcOverride || args ? ghc)
@@ -514,7 +522,7 @@ final: prev: {
514 extra-hackages = args.extra-hackages or [];
522 extra-hackages = args.extra-hackages or [];
515 };
523 };
516
524
517− project = addProjectAndPackageAttrs rec {
525+ project = addProjectAndPackageAttrs rec {
518 inherit (pkg-set.config) hsPkgs;
526 inherit (pkg-set.config) hsPkgs;
519 inherit pkg-set;
527 inherit pkg-set;
520 plan-nix = callProjectResults.projectNix;
528 plan-nix = callProjectResults.projectNix;
@@ -535,7 +543,7 @@ final: prev: {
535 final.lib.fix (project':
543 final.lib.fix (project':
536 let project = project' // { recurseForDerivations = false; };
544 let project = project' // { recurseForDerivations = false; };
537 in rawProject // rec {
545 in rawProject // rec {
538− hsPkgs = final.lib.mapAttrs (n: package':
546+ hsPkgs = final.lib.mapAttrs (packageName: package':
539 if package' == null
547 if package' == null
540 then null
548 then null
541 else
549 else
@@ -548,6 +556,16 @@ final: prev: {
548 ) package'.components;
556 ) package'.components;
549 inherit project;
557 inherit project;
550
558
559+ # Look up a component in the package based on ctype:name
560+ getComponent = componentName:
561+ let m = builtins.match "(lib|flib|exe|test|bench):([^:]*)" componentName;
562+ in
563+ assert final.lib.asserts.assertMsg (m != null)
564+ "Invalid package component name ${componentName}. Expected it to start with one of lib: flib: exe: test: or bench:";
565+ if builtins.elemAt m 0 == "lib" && builtins.elemAt m 1 == packageName
566+ then components.library
567+ else components.${haskellLib.prefixComponent.${builtins.elemAt m 0}}.${builtins.elemAt m 1};
568+
551 coverageReport = haskellLib.coverageReport (rec {
569 coverageReport = haskellLib.coverageReport (rec {
552 name = package.identifier.name + "-" + package.identifier.version;
570 name = package.identifier.name + "-" + package.identifier.version;
553 library = if components ? library then components.library else null;
571 library = if components ? library then components.library else null;
@@ -568,6 +586,48 @@ final: prev: {
568 rawProject.projectFunction pkgs.haskell-nix rawProject.projectArgs
586 rawProject.projectFunction pkgs.haskell-nix rawProject.projectArgs
569 ) final.pkgsCross) // { recurseForDerivations = false; };
587 ) final.pkgsCross) // { recurseForDerivations = false; };
570
588
589+ # Like `.hsPkgs.${packageName}` but when compined with `getComponent` any
590+ # cabal configure errors are defered until the components derivation builds.
591+ getPackage = packageName:
592+ if rawProject.pkg-set ? configurationError
593+ then
594+ # A minimal proxy for a package when cabal configure failed
595+ let package = {
596+ # Including the project so that things like:
597+ # (p.getPackage "hello").project.tool "hlint" "latest"
598+ # will still work even if "hello" failed to configure.
599+ inherit project;
600+
601+ # Defer configure time errors for the library component
602+ # (p.getPackage "hello").components.library
603+ components.library = package.getComponent "lib:${packageName}";
604+
605+ # This procide a derivation (even though the component may
606+ # not exist at all). The derivation will never build
607+ # and simple outputs the result of cabal configure.
608+ getComponent = componentName:
609+ final.evalPackages.runCommand "cabal-configure-error" {
610+ passthru = {
611+ inherit project package;
612+ };
613+ } ''
614+ cat ${rawProject.pkg-set.configurationError}
615+ echo Unable to find component ${packageName}:${componentName} \
616+ due to the above cabal configuration error
617+ exit 1
618+ '';
619+ };
620+ in package
621+ else project.hsPkgs.${packageName};
622+
623+ # Look a component in the project based on `pkg:ctype:name`
624+ getComponent = componentName:
625+ let m = builtins.match "([^:]*):(lib|flib|exe|test|bench):([^:]*)" componentName;
626+ in
627+ assert final.lib.asserts.assertMsg (m != null)
628+ "Invalid package component name ${componentName}. Expected package:ctype:component (where ctype is one of lib, flib, exe, test, or bench)";
629+ (getPackage (builtins.elemAt m 0)).getComponent "${builtins.elemAt m 1}:${builtins.elemAt m 2}";
630+
571 # Helper function that can be used to make a Nix Flake out of a project
631 # Helper function that can be used to make a Nix Flake out of a project
572 # by including a flake.nix. See docs/tutorials/getting-started-flakes.md
632 # by including a flake.nix. See docs/tutorials/getting-started-flakes.md
573 # for an example flake.nix file.
633 # for an example flake.nix file.
overlays/tools.nix+1−1
@@ -66,7 +66,7 @@ in { haskell-nix = prev.haskell-nix // {
66 { configureArgs = "--disable-benchmarks --disable-tests"; }
66 { configureArgs = "--disable-benchmarks --disable-tests"; }
67 // args
67 // args
68 // { name = final.haskell-nix.toolPackageName.${name} or name; }))
68 // { name = final.haskell-nix.toolPackageName.${name} or name; }))
69− .components.exes."${final.haskell-nix.packageToolName.${name} or name}";
69+ .getComponent "exe:${final.haskell-nix.packageToolName.${name} or name}";
70
70
71 tool = compiler-nix-name: name: versionOrArgs:
71 tool = compiler-nix-name: name: versionOrArgs:
72 let
72 let
scripts/check-compiler-materialization/default.nix+2−2
@@ -4,12 +4,12 @@
4let
4let
5 eval = (import ../../. {}).pkgs;
5 eval = (import ../../. {}).pkgs;
6 linux = (import ../../. { checkMaterialization = true; system = "x86_64-linux"; }).pkgs;
6 linux = (import ../../. { checkMaterialization = true; system = "x86_64-linux"; }).pkgs;
7− darwin = (import ../../. { checkMaterialization = true; system = "x86_64-darwin"; }).pkgs;
7+ darwin = (import ../../. { checkMaterialization = true; system = "x86_64-darwin"; }).pkgs-unstable;
8in eval.linkFarm "check-${compiler-nix-name}" [
8in eval.linkFarm "check-${compiler-nix-name}" [
9 # This set of derivations should be enough to ensure all the materialized files for a
9 # This set of derivations should be enough to ensure all the materialized files for a
10 # given GHC version are checked.
10 # given GHC version are checked.
11 { name = "linux-cabal-install"; path = linux.haskell-nix.cabal-install.${compiler-nix-name}; }
11 { name = "linux-cabal-install"; path = linux.haskell-nix.cabal-install.${compiler-nix-name}; }
12− # { name = "darwin-cabal-install"; path = darwin.haskell-nix.cabal-install.${compiler-nix-name}; }
12+ { name = "darwin-cabal-install"; path = darwin.haskell-nix.cabal-install.${compiler-nix-name}; }
13 { name = "linux-nix-tools"; path = linux.haskell-nix.nix-tools.${compiler-nix-name}; }
13 { name = "linux-nix-tools"; path = linux.haskell-nix.nix-tools.${compiler-nix-name}; }
14 { name = "linux"; path = linux.ghc-extra-projects.${compiler-nix-name}.plan-nix; }
14 { name = "linux"; path = linux.ghc-extra-projects.${compiler-nix-name}.plan-nix; }
15 # In some cased you may need comment out one or more of these if the GHC version needed cannot be built.
15 # In some cased you may need comment out one or more of these if the GHC version needed cannot be built.
test/cabal-simple-prof/default.nix+3−5
@@ -21,8 +21,6 @@ let
21 inherit modules;
21 inherit modules;
22 };
22 };
23
23
24− packages = project.hsPkgs;
25−
26in recurseIntoAttrs {
24in recurseIntoAttrs {
27 ifdInputs = {
25 ifdInputs = {
28 inherit (project) plan-nix;
26 inherit (project) plan-nix;
@@ -31,7 +29,7 @@ in recurseIntoAttrs {
31 name = "cabal-simple-prof-test";
29 name = "cabal-simple-prof-test";
32
30
33 buildCommand = ''
31 buildCommand = ''
34− exe="${packages.cabal-simple.components.exes.cabal-simple.exePath}"
32+ exe="${(project.getComponent "cabal-simple:exe:cabal-simple").exePath}"
35
33
36 size=$(command stat --format '%s' "$exe")
34 size=$(command stat --format '%s' "$exe")
37 printf "size of executable $exe is $size. \n" >& 2
35 printf "size of executable $exe is $size. \n" >& 2
@@ -41,7 +39,7 @@ in recurseIntoAttrs {
41 # Curiosity: cross compilers prodcing profiling with `+RTS -p -h` lead to the following cryptic message:
39 # Curiosity: cross compilers prodcing profiling with `+RTS -p -h` lead to the following cryptic message:
42 # cabal-simple: invalid heap profile option: -h*
40 # cabal-simple: invalid heap profile option: -h*
43 # Hence we pass `-hc`.
41 # Hence we pass `-hc`.
44− ${toString packages.cabal-simple.components.exes.cabal-simple.config.testWrapper} $exe +RTS -p -hc
42+ ${toString (project.getComponent "cabal-simple:exe:cabal-simple").config.testWrapper} $exe +RTS -p -hc
45
43
46 touch $out
44 touch $out
47 '';
45 '';
@@ -54,7 +52,7 @@ in recurseIntoAttrs {
54
52
55 passthru = {
53 passthru = {
56 # Used for debugging with nix repl
54 # Used for debugging with nix repl
57− inherit project packages;
55+ inherit project;
58 };
56 };
59 };
57 };
60}
58}
test/haskell-language-server/cabal.nix+1−1
@@ -5,5 +5,5 @@ in recurseIntoAttrs {
5 ifdInputs = {
5 ifdInputs = {
6 inherit (project) plan-nix;
6 inherit (project) plan-nix;
7 };
7 };
8− build = project.hsPkgs.haskell-language-server.components.exes.haskell-language-server;
8+ build = project.getComponent "haskell-language-server:exe:haskell-language-server";
9}
9}
test/index-state/default.nix+2−2
@@ -6,7 +6,7 @@ with lib;
6let
6let
7 # The hackage-security 0.6.0.1 was uploaded at 2020-04-06T20:54:35Z
7 # The hackage-security 0.6.0.1 was uploaded at 2020-04-06T20:54:35Z
8 # See https://hackage.haskell.org/package/hackage-security-0.6.0.1
8 # See https://hackage.haskell.org/package/hackage-security-0.6.0.1
9− version-used-at = index-state: (tool compiler-nix-name "cabal" {
9+ version-used-at = index-state: ((tool compiler-nix-name "cabal" {
10 version = "3.2.0.0";
10 version = "3.2.0.0";
11 inherit index-state;
11 inherit index-state;
12 cabalProject = ''
12 cabalProject = ''
@@ -15,7 +15,7 @@ let
15 package cabal-install
15 package cabal-install
16 flags: -native-dns
16 flags: -native-dns
17 '';
17 '';
18− }).project.hsPkgs.hackage-security.components.library.version;
18+ }).project.getPackage "hackage-security").components.library.version;
19 version-before = version-used-at "2020-04-06T20:54:34Z";
19 version-before = version-used-at "2020-04-06T20:54:34Z";
20 version-after = version-used-at "2020-04-06T20:54:35Z";
20 version-after = version-used-at "2020-04-06T20:54:35Z";
21
21
test/setup-deps/default.nix+2−3
@@ -15,7 +15,6 @@ let
15 { reinstallableLibGhc = true; } ];
15 { reinstallableLibGhc = true; } ];
16 };
16 };
17
17
18− packages = project.hsPkgs;
19 meta = {
18 meta = {
20 platforms = platforms.unix;
19 platforms = platforms.unix;
21 # Building reinstallable lib GHC is broken on 8.10, and we require lib ghc so this won't work with cross-compiling.
20 # Building reinstallable lib GHC is broken on 8.10, and we require lib ghc so this won't work with cross-compiling.
@@ -32,7 +31,7 @@ recurseIntoAttrs ({
32 name = "setup-deps-test";
31 name = "setup-deps-test";
33
32
34 buildCommand = ''
33 buildCommand = ''
35− exe="${packages.pkg.components.exes.pkg}/bin/pkg"
34+ exe="${project.getComponent "pkg:exe:pkg"}/bin/pkg"
36
35
37 printf "checking whether executable runs... " >& 2
36 printf "checking whether executable runs... " >& 2
38 $exe
37 $exe
@@ -43,7 +42,7 @@ recurseIntoAttrs ({
43 inherit meta;
42 inherit meta;
44 passthru = {
43 passthru = {
45 # Attributes used for debugging with nix repl
44 # Attributes used for debugging with nix repl
46− inherit project packages;
45+ inherit project;
47 };
46 };
48 };
47 };
49})
48})