From 8d4509e34d85501dca2eed1a2dfbd5c0611b0f5b Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Wed, 29 Jan 2020 00:44:11 +0100 Subject: [PATCH] haskell generic-builder: Fix package conf handling Previously the package conf files were handled without paying attention to the fact that it's pretty-printed output. One problem was discovered with GHC 8.8.1 on Darwin, where the dynamic-library-dirs first field seems to have increased in length, meaning while before it was dynamic-library-dirs: some-small-directory-name some-more-directories Now it is dynamic-library-dirs: some-larger-directory-name some-more-directories Which breaks the code installed for https://github.com/NixOS/nixpkgs/pull/25537, because that assumed the former format, resulting in the reoccurence of the bug in https://github.com/NixOS/nixpkgs/issues/22810, see https://github.com/Infinisil/all-hies/issues/43 This commit fixes this by "unprettyfying" the package conf files before processing them. Closes https://github.com/NixOS/nixpkgs/pull/78738. --- .../haskell-modules/generic-builder.nix | 56 ++++++++++++++++--- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/pkgs/development/haskell-modules/generic-builder.nix b/pkgs/development/haskell-modules/generic-builder.nix index c93fc5b7e451..513987dae7b3 100644 --- a/pkgs/development/haskell-modules/generic-builder.nix +++ b/pkgs/development/haskell-modules/generic-builder.nix @@ -132,6 +132,37 @@ let main = defaultMain ''; + # This awk expression transforms a package conf file like + # + # author: John Doe + # description: + # The purpose of this library is to do + # foo and bar among other things + # + # into a more easily processeable form: + # + # author: John Doe + # description: The purpose of this library is to do foo and bar among other things + unprettyConf = builtins.toFile "unpretty-cabal-conf.awk" '' + /^[^ ]+:/ { + # When the line starts with a new field, terminate the previous one with a newline + if (started == 1) print "" + # to strip leading spaces + $1=$1 + printf "%s", $0 + started=1 + } + + /^ +/ { + # to strip leading spaces + $1=$1 + printf " %s", $0 + } + + # Terminate the final field with a newline + END { print "" } + ''; + crossCabalFlags = [ "--with-ghc=${ghcCommand}" "--with-ghc-pkg=${ghc.targetPrefix}ghc-pkg" @@ -344,12 +375,22 @@ stdenv.mkDerivation ({ # libraries) from all the dependencies. local dynamicLinksDir="$out/lib/links" mkdir -p $dynamicLinksDir - for d in $(grep dynamic-library-dirs "$packageConfDir/"*|awk '{print $2}'|sort -u); do - ln -s "$d/"*.dylib $dynamicLinksDir + + # Unprettify all package conf files before reading/writing them + for d in "$packageConfDir/"*; do + # gawk -i inplace seems to strip the last newline + gawk -f ${unprettyConf} "$d" > tmp + mv tmp "$d" + done + + for d in $(grep '^dynamic-library-dirs:' "$packageConfDir"/* | cut -d' ' -f2- | tr ' ' '\n' | sort -u); do + for lib in "$d/"*.dylib; do + ln -s "$lib" "$dynamicLinksDir" + done done # Edit the local package DB to reference the links directory. for f in "$packageConfDir/"*.conf; do - sed -i "s,dynamic-library-dirs: .*,dynamic-library-dirs: $dynamicLinksDir," $f + sed -i "s,dynamic-library-dirs: .*,dynamic-library-dirs: $dynamicLinksDir," "$f" done '') + '' ${ghcCommand}-pkg --${packageDbFlag}="$packageConfDir" recache @@ -418,10 +459,6 @@ stdenv.mkDerivation ({ runHook postHaddock ''; - # The scary sed expression handles two cases in v2.5 Cabal's package configs: - # 1. 'id: short-name-0.0.1-9yvw8HF06tiAXuxm5U8KjO' - # 2. 'id:\n - # very-long-descriptive-useful-name-0.0.1-9yvw8HF06tiAXuxm5U8KjO' installPhase = '' runHook preInstall @@ -436,8 +473,9 @@ stdenv.mkDerivation ({ rmdir "$packageConfFile" fi for packageConfFile in "$packageConfDir/"*; do - local pkgId=$( ${gnused}/bin/sed -n -e ':a' -e '/^id:$/N; s/id:\n[ ]*\([^\n]*\).*$/\1/p; s/id:[ ]*\([^\n]*\)$/\1/p; ta' $packageConfFile ) - mv $packageConfFile $packageConfDir/$pkgId.conf + local pkgId=$(gawk -f ${unprettyConf} "$packageConfFile" \ + | grep '^id:' | cut -d' ' -f2) + mv "$packageConfFile" "$packageConfDir/$pkgId.conf" done # delete confdir if there are no libraries