summary refs log tree commit diff
diff options
context:
space:
mode:
authorJan Tojnar <jtojnar@gmail.com>2021-11-04 00:20:56 +0100
committerJan Tojnar <jtojnar@gmail.com>2021-11-14 23:05:48 +0100
commit968d18045263799811c2ff9e238214bd1f6a2329 (patch)
tree4dd996fd89b4d694bf68cf813d290ff4c20c7000
parentfe630fcb1fbaa1ca740ab27327c4d893a003a3b8 (diff)
downloadnixpkgs-968d18045263799811c2ff9e238214bd1f6a2329.tar
nixpkgs-968d18045263799811c2ff9e238214bd1f6a2329.tar.gz
nixpkgs-968d18045263799811c2ff9e238214bd1f6a2329.tar.bz2
nixpkgs-968d18045263799811c2ff9e238214bd1f6a2329.tar.lz
nixpkgs-968d18045263799811c2ff9e238214bd1f6a2329.tar.xz
nixpkgs-968d18045263799811c2ff9e238214bd1f6a2329.tar.zst
nixpkgs-968d18045263799811c2ff9e238214bd1f6a2329.zip
php: Implement overrideAttrs that composes with buildEnv/withExtensions
Hopefully.

Also add a couple of tests to check that.
-rw-r--r--pkgs/development/interpreters/php/generic.nix304
-rw-r--r--pkgs/test/default.nix2
-rw-r--r--pkgs/test/php/default.nix116
3 files changed, 287 insertions, 135 deletions
diff --git a/pkgs/development/interpreters/php/generic.nix b/pkgs/development/interpreters/php/generic.nix
index dbe01acb6df..7a1ee2a2eba 100644
--- a/pkgs/development/interpreters/php/generic.nix
+++ b/pkgs/development/interpreters/php/generic.nix
@@ -7,6 +7,7 @@ let
     , lib
     , stdenv
     , nixosTests
+    , tests
     , fetchurl
     , makeWrapper
     , symlinkJoin
@@ -31,6 +32,7 @@ let
     , sha256
     , extraPatches ? [ ]
     , packageOverrides ? (final: prev: { })
+    , phpAttrsOverrides ? (attrs: { })
 
       # Sapi flags
     , cgiSupport ? true
@@ -52,6 +54,16 @@ let
     }@args:
 
     let
+      # Compose two functions of the type expected by 'overrideAttrs'
+      # into one where changes made in the first are available to the second.
+      composeOverrides =
+        f: g: attrs:
+        let
+          fApplied = f attrs;
+          attrs' = attrs // fApplied;
+        in
+        fApplied // g attrs';
+
       # buildEnv wraps php to provide additional extensions and
       # configuration. Its usage is documented in
       # doc/languages-frameworks/php.section.md.
@@ -129,10 +141,20 @@ let
             passthru = php.passthru // {
               buildEnv = mkBuildEnv allArgs allExtensionFunctions;
               withExtensions = mkWithExtensions allArgs allExtensionFunctions;
+              overrideAttrs =
+                f:
+                let
+                  newPhpAttrsOverrides = composeOverrides (filteredArgs.phpAttrsOverrides or (attrs: { })) f;
+                  php = generic (filteredArgs // { phpAttrsOverrides = newPhpAttrsOverrides; });
+                in
+                php.buildEnv { inherit extensions extraConfig; };
               phpIni = "${phpWithExtensions}/lib/php.ini";
               unwrapped = php;
               # Select the right php tests for the php version
-              tests = nixosTests."php${lib.strings.replaceStrings [ "." ] [ "" ] (lib.versions.majorMinor php.version)}";
+              tests = {
+                nixos = lib.recurseIntoAttrs nixosTests."php${lib.strings.replaceStrings [ "." ] [ "" ] (lib.versions.majorMinor php.version)}";
+                package = tests.php;
+              };
               inherit (php-packages) extensions buildPecl mkExtension;
               packages = php-packages.tools;
               meta = php.meta // {
@@ -163,139 +185,151 @@ let
       mkWithExtensions = prevArgs: prevExtensionFunctions: extensions:
         mkBuildEnv prevArgs prevExtensionFunctions { inherit extensions; };
     in
-    stdenv.mkDerivation {
-      pname = "php";
-
-      inherit version;
-
-      enableParallelBuilding = true;
-
-      nativeBuildInputs = [ autoconf automake bison flex libtool pkg-config re2c ]
-        ++ lib.optional stdenv.isDarwin xcbuild;
-
-      buildInputs =
-        # PCRE extension
-        [ pcre2 ]
-
-        # Enable sapis
-        ++ lib.optional pearSupport [ libxml2.dev ]
-
-        # Misc deps
-        ++ lib.optional apxs2Support apacheHttpd
-        ++ lib.optional argon2Support libargon2
-        ++ lib.optional systemdSupport systemd
-        ++ lib.optional valgrindSupport valgrind
-      ;
-
-      CXXFLAGS = lib.optionalString stdenv.cc.isClang "-std=c++11";
-
-      configureFlags =
-        # Disable all extensions
-        [ "--disable-all" ]
-
-        # PCRE
-        ++ lib.optionals (lib.versionAtLeast version "7.4") [ "--with-external-pcre=${pcre2.dev}" ]
-        ++ [ "PCRE_LIBDIR=${pcre2}" ]
-
-
-        # Enable sapis
-        ++ lib.optional (!cgiSupport) "--disable-cgi"
-        ++ lib.optional (!cliSupport) "--disable-cli"
-        ++ lib.optional fpmSupport "--enable-fpm"
-        ++ lib.optional pearSupport [ "--with-pear" "--enable-xml" "--with-libxml" ]
-        ++ lib.optionals (pearSupport && (lib.versionOlder version "7.4")) [
-          "--enable-libxml"
-          "--with-libxml-dir=${libxml2.dev}"
-        ]
-        ++ lib.optional pharSupport "--enable-phar"
-        ++ lib.optional (!phpdbgSupport) "--disable-phpdbg"
-
-
-        # Misc flags
-        ++ lib.optional apxs2Support "--with-apxs2=${apacheHttpd.dev}/bin/apxs"
-        ++ lib.optional argon2Support "--with-password-argon2=${libargon2}"
-        ++ lib.optional cgotoSupport "--enable-re2c-cgoto"
-        ++ lib.optional embedSupport "--enable-embed"
-        ++ lib.optional (!ipv6Support) "--disable-ipv6"
-        ++ lib.optional systemdSupport "--with-fpm-systemd"
-        ++ lib.optional valgrindSupport "--with-valgrind=${valgrind.dev}"
-        ++ lib.optional (ztsSupport && (lib.versionOlder version "8.0")) "--enable-maintainer-zts"
-        ++ lib.optional (ztsSupport && (lib.versionAtLeast version "8.0")) "--enable-zts"
-
-
-        # Sendmail
-        ++ [ "PROG_SENDMAIL=${system-sendmail}/bin/sendmail" ]
-      ;
-
-      hardeningDisable = [ "bindnow" ];
-
-      preConfigure =
-        # Don't record the configure flags since this causes unnecessary
-        # runtime dependencies
-        ''
-          for i in main/build-defs.h.in scripts/php-config.in; do
-            substituteInPlace $i \
-              --replace '@CONFIGURE_COMMAND@' '(omitted)' \
-              --replace '@CONFIGURE_OPTIONS@' "" \
-              --replace '@PHP_LDFLAGS@' ""
-          done
-
-          export EXTENSION_DIR=$out/lib/php/extensions
-        ''
-        # PKG_CONFIG need not be a relative path
-        + lib.optionalString (!lib.versionAtLeast version "7.4") ''
-          for i in $(find . -type f -name "*.m4"); do
-            substituteInPlace $i \
-              --replace 'test -x "$PKG_CONFIG"' 'type -P "$PKG_CONFIG" >/dev/null'
-          done
-        '' + ''
-          ./buildconf --copy --force
-
-          if test -f $src/genfiles; then
-            ./genfiles
-          fi
-        '' + lib.optionalString stdenv.isDarwin ''
-          substituteInPlace configure --replace "-lstdc++" "-lc++"
-        '';
-
-      postInstall = ''
-        test -d $out/etc || mkdir $out/etc
-        cp php.ini-production $out/etc/php.ini
-      '';
-
-      postFixup = ''
-        mkdir -p $dev/bin $dev/share/man/man1
-        mv $out/bin/phpize $out/bin/php-config $dev/bin/
-        mv $out/share/man/man1/phpize.1.gz \
-           $out/share/man/man1/php-config.1.gz \
-           $dev/share/man/man1/
-      '';
-
-      src = fetchurl {
-        url = "https://www.php.net/distributions/php-${version}.tar.bz2";
-        inherit sha256;
-      };
-
-      patches = [ ./fix-paths-php7.patch ] ++ extraPatches;
-
-      separateDebugInfo = true;
-
-      outputs = [ "out" "dev" ];
-
-      passthru = {
-        buildEnv = mkBuildEnv { } [ ];
-        withExtensions = mkWithExtensions { } [ ];
-        inherit ztsSupport;
-      };
-
-      meta = with lib; {
-        description = "An HTML-embedded scripting language";
-        homepage = "https://www.php.net/";
-        license = licenses.php301;
-        maintainers = teams.php.members;
-        platforms = platforms.all;
-        outputsToInstall = [ "out" "dev" ];
-      };
-    };
+    stdenv.mkDerivation (
+      let
+        attrs = {
+          pname = "php";
+
+          inherit version;
+
+          enableParallelBuilding = true;
+
+          nativeBuildInputs = [ autoconf automake bison flex libtool pkg-config re2c ]
+            ++ lib.optional stdenv.isDarwin xcbuild;
+
+          buildInputs =
+            # PCRE extension
+            [ pcre2 ]
+
+            # Enable sapis
+            ++ lib.optional pearSupport [ libxml2.dev ]
+
+            # Misc deps
+            ++ lib.optional apxs2Support apacheHttpd
+            ++ lib.optional argon2Support libargon2
+            ++ lib.optional systemdSupport systemd
+            ++ lib.optional valgrindSupport valgrind
+          ;
+
+          CXXFLAGS = lib.optionalString stdenv.cc.isClang "-std=c++11";
+
+          configureFlags =
+            # Disable all extensions
+            [ "--disable-all" ]
+
+            # PCRE
+            ++ lib.optionals (lib.versionAtLeast version "7.4") [ "--with-external-pcre=${pcre2.dev}" ]
+            ++ [ "PCRE_LIBDIR=${pcre2}" ]
+
+
+            # Enable sapis
+            ++ lib.optional (!cgiSupport) "--disable-cgi"
+            ++ lib.optional (!cliSupport) "--disable-cli"
+            ++ lib.optional fpmSupport "--enable-fpm"
+            ++ lib.optional pearSupport [ "--with-pear" "--enable-xml" "--with-libxml" ]
+            ++ lib.optionals (pearSupport && (lib.versionOlder version "7.4")) [
+              "--enable-libxml"
+              "--with-libxml-dir=${libxml2.dev}"
+            ]
+            ++ lib.optional pharSupport "--enable-phar"
+            ++ lib.optional (!phpdbgSupport) "--disable-phpdbg"
+
+
+            # Misc flags
+            ++ lib.optional apxs2Support "--with-apxs2=${apacheHttpd.dev}/bin/apxs"
+            ++ lib.optional argon2Support "--with-password-argon2=${libargon2}"
+            ++ lib.optional cgotoSupport "--enable-re2c-cgoto"
+            ++ lib.optional embedSupport "--enable-embed"
+            ++ lib.optional (!ipv6Support) "--disable-ipv6"
+            ++ lib.optional systemdSupport "--with-fpm-systemd"
+            ++ lib.optional valgrindSupport "--with-valgrind=${valgrind.dev}"
+            ++ lib.optional (ztsSupport && (lib.versionOlder version "8.0")) "--enable-maintainer-zts"
+            ++ lib.optional (ztsSupport && (lib.versionAtLeast version "8.0")) "--enable-zts"
+
+
+            # Sendmail
+            ++ [ "PROG_SENDMAIL=${system-sendmail}/bin/sendmail" ]
+          ;
+
+          hardeningDisable = [ "bindnow" ];
+
+          preConfigure =
+            # Don't record the configure flags since this causes unnecessary
+            # runtime dependencies
+            ''
+              for i in main/build-defs.h.in scripts/php-config.in; do
+                substituteInPlace $i \
+                  --replace '@CONFIGURE_COMMAND@' '(omitted)' \
+                  --replace '@CONFIGURE_OPTIONS@' "" \
+                  --replace '@PHP_LDFLAGS@' ""
+              done
+
+              export EXTENSION_DIR=$out/lib/php/extensions
+            ''
+            # PKG_CONFIG need not be a relative path
+            + lib.optionalString (!lib.versionAtLeast version "7.4") ''
+              for i in $(find . -type f -name "*.m4"); do
+                substituteInPlace $i \
+                  --replace 'test -x "$PKG_CONFIG"' 'type -P "$PKG_CONFIG" >/dev/null'
+              done
+            '' + ''
+              ./buildconf --copy --force
+
+              if test -f $src/genfiles; then
+                ./genfiles
+              fi
+            '' + lib.optionalString stdenv.isDarwin ''
+              substituteInPlace configure --replace "-lstdc++" "-lc++"
+            '';
+
+          postInstall = ''
+            test -d $out/etc || mkdir $out/etc
+            cp php.ini-production $out/etc/php.ini
+          '';
+
+          postFixup = ''
+            mkdir -p $dev/bin $dev/share/man/man1
+            mv $out/bin/phpize $out/bin/php-config $dev/bin/
+            mv $out/share/man/man1/phpize.1.gz \
+               $out/share/man/man1/php-config.1.gz \
+               $dev/share/man/man1/
+          '';
+
+          src = fetchurl {
+            url = "https://www.php.net/distributions/php-${version}.tar.bz2";
+            inherit sha256;
+          };
+
+          patches = [ ./fix-paths-php7.patch ] ++ extraPatches;
+
+          separateDebugInfo = true;
+
+          outputs = [ "out" "dev" ];
+
+          passthru = {
+            buildEnv = mkBuildEnv { } [ ];
+            withExtensions = mkWithExtensions { } [ ];
+            overrideAttrs =
+              f:
+              let
+                newPhpAttrsOverrides = composeOverrides phpAttrsOverrides f;
+                php = generic (args // { phpAttrsOverrides = newPhpAttrsOverrides; });
+              in
+              php;
+            inherit ztsSupport;
+          };
+
+          meta = with lib; {
+            description = "An HTML-embedded scripting language";
+            homepage = "https://www.php.net/";
+            license = licenses.php301;
+            maintainers = teams.php.members;
+            platforms = platforms.all;
+            outputsToInstall = [ "out" "dev" ];
+          };
+        };
+      in
+      attrs // phpAttrsOverrides attrs
+    );
 in
 generic
diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix
index 80d82e5bee0..ac4aebda5cd 100644
--- a/pkgs/test/default.nix
+++ b/pkgs/test/default.nix
@@ -37,6 +37,8 @@ with pkgs;
 
   cross = callPackage ./cross {};
 
+  php = recurseIntoAttrs (callPackages ./php {});
+
   rustCustomSysroot = callPackage ./rust-sysroot {};
   buildRustCrate = callPackage ../build-support/rust/build-rust-crate/test { };
   importCargoLock = callPackage ../build-support/rust/test/import-cargo-lock { };
diff --git a/pkgs/test/php/default.nix b/pkgs/test/php/default.nix
new file mode 100644
index 00000000000..3c6c8f61b6d
--- /dev/null
+++ b/pkgs/test/php/default.nix
@@ -0,0 +1,116 @@
+{ lib
+, php
+, runCommand
+}:
+
+let
+  runTest = name: body: runCommand name { } ''
+    testFailed=
+    checking() {
+      echo -n "Checking $1... " > /dev/stderr
+    }
+    ok() {
+      echo ok > /dev/stderr
+    }
+    nok() {
+      echo fail > /dev/stderr
+      testFailed=1
+    }
+
+    ${body}
+
+    if test -n "$testFailed"; then
+      exit 1
+    fi
+
+    touch $out
+  '';
+
+  check = cond: if cond then "ok" else "nok";
+in
+{
+  withExtensions-enables-previously-disabled-extensions = runTest "php-test-withExtensions-enables-previously-disabled-extensions" ''
+    php="${php}"
+
+    checking "that imagick is not present by default"
+    $php/bin/php -r 'exit(extension_loaded("imagick") ? 1 : 0);' && ok || nok
+
+    phpWithImagick="${php.withExtensions ({ all, ... }: [ all.imagick ])}"
+    checking "that imagick extension is present when enabled"
+    $phpWithImagick/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok
+  '';
+
+  overrideAttrs-preserves-enabled-extensions =
+    let
+      customPhp =
+        (php.withExtensions ({ all, ... }: [ all.imagick ])).overrideAttrs (attrs: {
+          postInstall = attrs.postInstall or "" + ''
+            touch "$out/oApee-was-here"
+          '';
+        });
+    in
+    runTest "php-test-overrideAttrs-preserves-enabled-extensions" ''
+      php="${customPhp}"
+      phpUnwrapped="${customPhp.unwrapped}"
+
+      checking "if overrides took hold"
+      test -f "$phpUnwrapped/oApee-was-here" && ok || nok
+
+      checking "if imagick extension is still present"
+      $php/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok
+
+      checking "if imagick extension is linked against the overridden PHP"
+      echo $php
+      $php/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok
+    '';
+
+  unwrapped-overrideAttrs-stacks =
+    let
+      customPhp =
+        lib.pipe php.unwrapped [
+          (pkg: pkg.overrideAttrs (attrs: {
+            postInstall = attrs.postInstall or "" + ''
+              touch "$out/oAs-first"
+            '';
+          }))
+
+          (pkg: pkg.overrideAttrs (attrs: {
+            postInstall = attrs.postInstall or "" + ''
+              touch "$out/oAs-second"
+            '';
+          }))
+        ];
+    in
+    runTest "php-test-unwrapped-overrideAttrs-stacks" ''
+      checking "if first override remained"
+      ${check (builtins.match ".*oAs-first.*" customPhp.postInstall != null)}
+
+      checking "if second override is there"
+      ${check (builtins.match ".*oAs-second.*" customPhp.postInstall != null)}
+    '';
+
+  wrapped-overrideAttrs-stacks =
+    let
+      customPhp =
+        lib.pipe php [
+          (pkg: pkg.overrideAttrs (attrs: {
+            postInstall = attrs.postInstall or "" + ''
+              touch "$out/oAs-first"
+            '';
+          }))
+
+          (pkg: pkg.overrideAttrs (attrs: {
+            postInstall = attrs.postInstall or "" + ''
+              touch "$out/oAs-second"
+            '';
+          }))
+        ];
+    in
+    runTest "php-test-wrapped-overrideAttrs-stacks" ''
+      checking "if first override remained"
+      ${check (builtins.match ".*oAs-first.*" customPhp.unwrapped.postInstall != null)}
+
+      checking "if second override is there"
+      ${check (builtins.match ".*oAs-second.*" customPhp.unwrapped.postInstall != null)}
+    '';
+}