haskell: support cross in generateOptparseApplicativeCompletions

Deprecate haskell.lib{,.compose}.generateOptparseApplicativeCompletion*
in favor of the newly added
haskell.packages.*.generateOptparseApplicativeCompletions (plural!)
which takes into account whether we are cross-compiling or not. If we
are, generating completions is disabled, since we can't execute software
built for a different platform.

The move is necessary, so we can receive the /same/ stdenv as the
package we are overriding in order to accurately check whether we can
execute produced binaries.

Resolves #174040.
Resolves #49648.
This commit is contained in:
sternenseemann 2022-09-09 20:33:20 +02:00
parent e7b47a72fe
commit ac1f1ad0e0
8 changed files with 107 additions and 50 deletions

View file

@ -550,6 +550,27 @@
module removed, due to lack of maintainers.
</para>
</listitem>
<listitem>
<para>
<literal>generateOptparseApplicativeCompletions</literal> and
<literal>generateOptparseApplicativeCompletion</literal> from
<literal>haskell.lib.compose</literal> (and
<literal>haskell.lib</literal>) have been deprecated in favor
of <literal>generateOptparseApplicativeCompletions</literal>
(plural!) as provided by the haskell package sets (so
<literal>haskellPackages.generateOptparseApplicativeCompletions</literal>
etc.). The latter allows for cross-compilation (by
automatically disabling generation of completion in the cross
case). For it to work properly you need to make sure that the
function comes from the same context as the package you are
trying to override, i.e. always use the same package set as
your package is coming from or even better use
<literal>self.generateOptparseApplicativeCompletions</literal>
if you are overriding a haskell package set. The old functions
are retained for backwards compatibility, but yield are
warning.
</para>
</listitem>
<listitem>
<para>
The <literal>services.graphite.api</literal> and

View file

@ -185,6 +185,15 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
- virtlyst package and `services.virtlyst` module removed, due to lack of maintainers.
- `generateOptparseApplicativeCompletions` and `generateOptparseApplicativeCompletion` from `haskell.lib.compose`
(and `haskell.lib`) have been deprecated in favor of `generateOptparseApplicativeCompletions` (plural!) as
provided by the haskell package sets (so `haskellPackages.generateOptparseApplicativeCompletions` etc.).
The latter allows for cross-compilation (by automatically disabling generation of completion in the cross case).
For it to work properly you need to make sure that the function comes from the same context as the package
you are trying to override, i.e. always use the same package set as your package is coming from or even
better use `self.generateOptparseApplicativeCompletions` if you are overriding a haskell package set.
The old functions are retained for backwards compatibility, but yield are warning.
- The `services.graphite.api` and `services.graphite.beacon` NixOS options, and
the `python3.pkgs.graphite_api`, `python3.pkgs.graphite_beacon` and
`python3.pkgs.influxgraph` packages, have been removed due to lack of upstream

View file

@ -247,7 +247,7 @@ self: super: {
# 2020-06-05: HACK: does not pass own build suite - `dontCheck`
# 2022-06-17: Use hnix-store 0.5 until hnix 0.17
hnix = generateOptparseApplicativeCompletion "hnix" (dontCheck (
hnix = self.generateOptparseApplicativeCompletions [ "hnix" ] (dontCheck (
super.hnix.overrideScope (hself: hsuper: {
hnix-store-core = hself.hnix-store-core_0_5_0_0;
hnix-store-remote = hself.hnix-store-remote_0_5_0_0;
@ -719,7 +719,7 @@ self: super: {
# updated dependencies (haskeline and megaparsec) which can be
# removed when the next idris release (1.3.4 probably) comes
# around.
idris = generateOptparseApplicativeCompletion "idris"
idris = self.generateOptparseApplicativeCompletions [ "idris" ]
(doJailbreak (dontCheck super.idris));
# https://github.com/pontarius/pontarius-xmpp/issues/105
@ -998,14 +998,14 @@ self: super: {
servant-auth-server = doJailbreak super.servant-auth-server;
# Generate cli completions for dhall.
dhall = generateOptparseApplicativeCompletion "dhall" super.dhall;
dhall = self.generateOptparseApplicativeCompletions [ "dhall" ] super.dhall;
# For reasons that are not quire clear 'dhall-json' won't compile without 'tasty 1.4' due to its tests
# https://github.com/commercialhaskell/stackage/issues/5795
# This issue can be mitigated with 'dontCheck' which skips the tests and their compilation.
dhall-json = generateOptparseApplicativeCompletions ["dhall-to-json" "dhall-to-yaml"] (dontCheck super.dhall-json);
dhall-nix = generateOptparseApplicativeCompletion "dhall-to-nix" super.dhall-nix;
dhall-yaml = generateOptparseApplicativeCompletions ["dhall-to-yaml-ng" "yaml-to-dhall"] super.dhall-yaml;
dhall-nixpkgs = generateOptparseApplicativeCompletion "dhall-to-nixpkgs" super.dhall-nixpkgs;
dhall-json = self.generateOptparseApplicativeCompletions ["dhall-to-json" "dhall-to-yaml"] (dontCheck super.dhall-json);
dhall-nix = self.generateOptparseApplicativeCompletions [ "dhall-to-nix" ] super.dhall-nix;
dhall-yaml = self.generateOptparseApplicativeCompletions ["dhall-to-yaml-ng" "yaml-to-dhall"] super.dhall-yaml;
dhall-nixpkgs = self.generateOptparseApplicativeCompletions [ "dhall-to-nixpkgs" ] super.dhall-nixpkgs;
# https://github.com/haskell-hvr/netrc/pull/2#issuecomment-469526558
netrc = doJailbreak super.netrc;
@ -1014,7 +1014,7 @@ self: super: {
hgettext = doJailbreak super.hgettext;
stack =
generateOptparseApplicativeCompletion "stack"
self.generateOptparseApplicativeCompletions [ "stack" ]
# stack has a bunch of constraints in its .cabal file that don't seem to be necessary
(doJailbreak
(super.stack.overrideScope (self: super: {
@ -1067,7 +1067,7 @@ self: super: {
hoopl = dontCheck super.hoopl;
# Generate shell completion for spago
spago = generateOptparseApplicativeCompletion "spago" super.spago;
spago = self.generateOptparseApplicativeCompletions [ "spago" ] super.spago;
# 2020-06-05: HACK: Package can not pass test suite,
# Upstream Report: https://github.com/kcsongor/generic-lens/issues/83
@ -1505,7 +1505,7 @@ self: super: {
# PATH.
# - Patch can be removed on next package set bump
update-nix-fetchgit = let deps = [ pkgs.git pkgs.nix pkgs.nix-prefetch-git ];
in generateOptparseApplicativeCompletion "update-nix-fetchgit" (overrideCabal
in self.generateOptparseApplicativeCompletions [ "update-nix-fetchgit" ] (overrideCabal
(drv: {
buildTools = drv.buildTools or [ ] ++ [ pkgs.buildPackages.makeWrapper ];
postInstall = drv.postInstall or "" + ''
@ -1633,7 +1633,9 @@ self: super: {
http-media = doJailbreak super.http-media;
# 2022-03-19: strict upper bounds https://github.com/poscat0x04/hinit/issues/2
hinit = doJailbreak (generateOptparseApplicativeCompletion "hi" (super.hinit.override { haskeline = self.haskeline_0_8_2; }));
hinit = doJailbreak
(self.generateOptparseApplicativeCompletions [ "hi" ]
(super.hinit.override { haskeline = self.haskeline_0_8_2; }));
# 2022-03-19: Keeping jailbreak because of tons of strict bounds: https://github.com/snapframework/snap/issues/220
snap = doJailbreak super.snap;
@ -1676,7 +1678,7 @@ self: super: {
# waiting for aeson bump
servant-swagger-ui-core = doJailbreak super.servant-swagger-ui-core;
hercules-ci-agent = generateOptparseApplicativeCompletion "hercules-ci-agent" super.hercules-ci-agent;
hercules-ci-agent = self.generateOptparseApplicativeCompletions [ "hercules-ci-agent" ] super.hercules-ci-agent;
# Test suite doesn't compile with aeson 2.0
# https://github.com/hercules-ci/hercules-ci-agent/pull/387
@ -1687,7 +1689,7 @@ self: super: {
(overrideCabal (drv: { hydraPlatforms = super.hercules-ci-cli.meta.platforms; }))
# See hercules-ci-optparse-applicative in non-hackage-packages.nix.
(addBuildDepend super.hercules-ci-optparse-applicative)
(generateOptparseApplicativeCompletion "hci")
(self.generateOptparseApplicativeCompletions [ "hci" ])
];
pipes-aeson = appendPatches [
@ -2571,7 +2573,7 @@ in {
# likely be removed when purescript-0.14.6 is released.
doJailbreak
# Generate shell completions
(generateOptparseApplicativeCompletion "purs")
(self.generateOptparseApplicativeCompletions [ "purs" ])
];
purescript-cst = purescriptStOverride super.purescript-cst;

View file

@ -90,7 +90,7 @@ self: super: {
}) (doJailbreak super.language-haskell-extract);
# hnix 0.9.0 does not provide an executable for ghc < 8.10, so define completions here for now.
hnix = generateOptparseApplicativeCompletion "hnix"
hnix = self.generateOptparseApplicativeCompletions [ "hnix" ]
(overrideCabal (drv: {
# executable is allowed for ghc >= 8.10 and needs repline
executableHaskellDepends = drv.executableToolDepends or [] ++ [ self.repline ];

View file

@ -95,12 +95,12 @@ self: super: builtins.intersectAttrs super {
sfml-audio = appendConfigureFlag "--extra-include-dirs=${pkgs.openal}/include/AL" super.sfml-audio;
# avoid compiling twice by providing executable as a separate output (with small closure size)
niv = enableSeparateBinOutput (generateOptparseApplicativeCompletion "niv" super.niv);
niv = enableSeparateBinOutput (self.generateOptparseApplicativeCompletions [ "niv" ] super.niv);
ghcid = enableSeparateBinOutput super.ghcid;
ormolu = generateOptparseApplicativeCompletion "ormolu" (enableSeparateBinOutput super.ormolu);
ormolu = self.generateOptparseApplicativeCompletions [ "ormolu" ] (enableSeparateBinOutput super.ormolu);
# Generate shell completion.
cabal2nix = generateOptparseApplicativeCompletion "cabal2nix" super.cabal2nix;
cabal2nix = self.generateOptparseApplicativeCompletions [ "cabal2nix" ] super.cabal2nix;
arbtt = overrideCabal (drv: {
# The test suite needs the packages's executables in $PATH to succeed.
@ -814,7 +814,7 @@ self: super: builtins.intersectAttrs super {
install -D man/pnbackup.1 $out/share/man/man1/pnbackup.1
'' + (drv.postInstall or "");
})
(generateOptparseApplicativeCompletion "pnbackup" super.pinboard-notes-backup);
(self.generateOptparseApplicativeCompletions [ "pnbackup" ] super.pinboard-notes-backup);
# Pass the correct libarchive into the package.
streamly-archive = super.streamly-archive.override { archive = pkgs.libarchive; };
@ -875,7 +875,7 @@ self: super: builtins.intersectAttrs super {
}) super.tophat;
# Runtime dependencies and CLI completion
nvfetcher = generateOptparseApplicativeCompletion "nvfetcher" (overrideCabal
nvfetcher = self.generateOptparseApplicativeCompletions [ "nvfetcher" ] (overrideCabal
(drv: {
# test needs network
doCheck = false;
@ -889,7 +889,7 @@ self: super: builtins.intersectAttrs super {
rel8 = addTestToolDepend pkgs.postgresql super.rel8;
cachix = generateOptparseApplicativeCompletion "cachix" (super.cachix.override { nix = pkgs.nixVersions.nix_2_9; });
cachix = self.generateOptparseApplicativeCompletions [ "cachix" ] (super.cachix.override { nix = pkgs.nixVersions.nix_2_9; });
hercules-ci-agent = super.hercules-ci-agent.override { nix = pkgs.nixVersions.nix_2_9; };
hercules-ci-cnix-expr =
@ -917,7 +917,7 @@ self: super: builtins.intersectAttrs super {
# to arbitrary files in $HOME. This doesn't either not achieve anything
# or even fail, so we prevent it and install everything necessary ourselves.
# See also: https://hackage.haskell.org/package/cli-setup-0.2.1.4/docs/src/Distribution.CommandLine.html#setManpathGeneric
ats-format = generateOptparseApplicativeCompletion "atsfmt" (
ats-format = self.generateOptparseApplicativeCompletions [ "atsfmt" ] (
justStaticExecutables (
overrideCabal (drv: {
# use vanilla Setup.hs

View file

@ -418,23 +418,14 @@ rec {
builtins.listToAttrs (map toKeyVal haskellPaths);
addOptparseApplicativeCompletionScripts = exeName: pkg:
builtins.trace "addOptparseApplicativeCompletionScripts is deprecated in favor of generateOptparseApplicativeCompletion. Please change ${pkg.name} to use the latter or its plural form."
(generateOptparseApplicativeCompletion exeName pkg);
lib.warn "addOptparseApplicativeCompletionScripts is deprecated in favor of haskellPackages.generateOptparseApplicativeCompletions. Please change ${pkg.name} to use the latter and make sure it uses its matching haskell.packages set!"
(__generateOptparseApplicativeCompletion exeName pkg);
/*
Modify a Haskell package to add shell completion scripts for the
given executable produced by it. These completion scripts will be
picked up automatically if the resulting derivation is installed,
e.g. by `nix-env -i`.
Invocation:
generateOptparseApplicativeCompletion command pkg
command: name of an executable
pkg: Haskell package that builds the executables
INTERNAL function retained for backwards compatibility, use
haskell.packages.*.generateOptparseApplicativeCompletions instead!
*/
generateOptparseApplicativeCompletion = exeName: overrideCabal (drv: {
__generateOptparseApplicativeCompletion = exeName: overrideCabal (drv: {
postInstall = (drv.postInstall or "") + ''
bashCompDir="''${!outputBin}/share/bash-completion/completions"
zshCompDir="''${!outputBin}/share/zsh/vendor-completions"
@ -453,20 +444,22 @@ rec {
});
/*
Modify a Haskell package to add shell completion scripts for the
given executables produced by it. These completion scripts will be
picked up automatically if the resulting derivation is installed,
e.g. by `nix-env -i`.
Invocation:
generateOptparseApplicativeCompletions commands pkg
commands: name of an executable
pkg: Haskell package that builds the executables
Retained for backwards compatibility.
Use haskell.packages.*.generateOptparseApplicativeCompletions
which is cross aware instead.
*/
generateOptparseApplicativeCompletions = commands: pkg:
pkgs.lib.foldr generateOptparseApplicativeCompletion pkg commands;
lib.warnIf (lib.isInOldestRelease 2211) "haskellLib.generateOptparseApplicativeCompletions is deprecated in favor of haskellPackages.generateOptparseApplicativeCompletions. Please change ${pkg.name} to use the latter and make sure it uses its matching haskell.packages set!"
(pkgs.lib.foldr __generateOptparseApplicativeCompletion pkg commands);
/*
Retained for backwards compatibility.
Use haskell.packages.*.generateOptparseApplicativeCompletions
which is cross aware instead.
*/
generateOptparseApplicativeCompletion = command: pkg:
lib.warnIf (lib.isInOldestRelease 2211) "haskellLib.generateOptparseApplicativeCompletion is deprecated in favor of haskellPackages.generateOptparseApplicativeCompletions (plural!). Please change ${pkg.name} to use the latter and make sure it uses its matching haskell.packages set!"
(__generateOptparseApplicativeCompletion command pkg);
# Don't fail at configure time if there are multiple versions of the
# same package in the (recursive) dependencies of the package being

View file

@ -597,4 +597,34 @@ in package-set { inherit pkgs lib callPackage; } self // {
}
pkg;
/*
Modify a Haskell package to add shell completion scripts for the
given executables produced by it. These completion scripts will be
picked up automatically if the resulting derivation is installed,
e.g. by `nix-env -i`.
This depends on the `--*-completion` flag `optparse-applicative` provides
automatically. Since we need to invoke installed executables, completions
are not generated if we are cross-compiling.
commands: names of the executables built by the derivation
pkg: Haskell package that builds the executables
Example:
generateOptparseApplicativeCompletions [ "exec1" "exec2" ] pkg
Type: [str] -> drv -> drv
*/
generateOptparseApplicativeCompletions =
self.callPackage (
{ stdenv }:
commands:
pkg:
if stdenv.buildPlatform.canExecute stdenv.hostPlatform
then lib.foldr haskellLib.__generateOptparseApplicativeCompletion pkg commands
else pkg
) { };
}

View file

@ -3230,7 +3230,8 @@ with pkgs;
cue2pops = callPackage ../tools/cd-dvd/cue2pops { };
cabal2nix-unwrapped = haskell.lib.compose.justStaticExecutables (haskell.lib.compose.generateOptparseApplicativeCompletion "cabal2nix" haskellPackages.cabal2nix);
cabal2nix-unwrapped = haskell.lib.compose.justStaticExecutables
(haskellPackages.generateOptparseApplicativeCompletions [ "cabal2nix" ] haskellPackages.cabal2nix);
cabal2nix = symlinkJoin {
inherit (cabal2nix-unwrapped) name meta;
@ -9377,7 +9378,8 @@ with pkgs;
ngrep = callPackage ../tools/networking/ngrep { };
neuron-notes = haskell.lib.compose.justStaticExecutables (haskell.lib.compose.generateOptparseApplicativeCompletion "neuron" haskellPackages.neuron);
neuron-notes = haskell.lib.compose.justStaticExecutables
(haskellPackages.generateOptparseApplicativeCompletions [ "neuron" ] haskellPackages.neuron);
ngrok = callPackage ../tools/networking/ngrok { };