Unverified Commit bd92bef3 authored by Pol Dellaiera's avatar Pol Dellaiera
Browse files

php.buildComposerWithPlugin: init new builder

parent b258b44a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
{
  v1 = {
    buildComposerProject = callPackage ./v1/build-composer-project.nix { };
    buildComposerWithPlugin = callPackage ./v1/build-composer-with-plugin.nix { };
    mkComposerRepository = callPackage ./v1/build-composer-repository.nix { };
    composerHooks = callPackages ./v1/hooks { };
  };
+161 −0
Original line number Diff line number Diff line
{
  stdenvNoCC,
  writeText,
  lib,
  makeBinaryWrapper,
  php,
  cacert,
  nix-update-script,
}:

let
  composerJsonBuilder =
    pluginName: pluginVersion:
    writeText "composer.json" (
      builtins.toJSON {
        name = "nix/plugin";
        description = "Nix Composer plugin";
        license = "MIT";
        require = {
          "${pluginName}" = "${pluginVersion}";
        };
        config = {
          "allow-plugins" = {
            "${pluginName}" = true;
          };
        };
        repositories = [
          {
            type = "path";
            url = "./src";
            options = {
              versions = {
                "${pluginName}" = "${pluginVersion}";
              };
            };
          }
        ];
      }
    );

  buildComposerWithPluginOverride =
    finalAttrs: previousAttrs:

    let
      phpDrv = finalAttrs.php or php;
      composer = finalAttrs.composer or phpDrv.packages.composer;
    in
    {
      composerLock = previousAttrs.composerLock or null;
      composerNoDev = previousAttrs.composerNoDev or true;
      composerNoPlugins = previousAttrs.composerNoPlugins or true;
      composerNoScripts = previousAttrs.composerNoScripts or true;
      composerStrictValidation = previousAttrs.composerStrictValidation or true;
      composerGlobal = true;

      nativeBuildInputs = (previousAttrs.nativeBuildInputs or [ ]) ++ [
        composer
        phpDrv
        makeBinaryWrapper
      ];

      buildInputs = (previousAttrs.buildInputs or [ ]) ++ [ phpDrv ];

      patches = previousAttrs.patches or [ ];
      strictDeps = previousAttrs.strictDeps or true;

      # Should we keep these empty phases?
      configurePhase =
        previousAttrs.configurePhase or ''
          runHook preConfigure

          runHook postConfigure
        '';

      buildPhase =
        previousAttrs.buildPhase or ''
          runHook preBuild

          runHook postBuild
        '';

      doCheck = previousAttrs.doCheck or true;

      checkPhase =
        previousAttrs.checkPhase or ''
          runHook preCheck

          runHook postCheck
        '';

      installPhase =
        previousAttrs.installPhase or ''
            runHook preInstall

          makeWrapper ${lib.getExe composer} $out/bin/composer \
            --prefix COMPOSER_HOME : ${finalAttrs.vendor}

            runHook postInstall
        '';

      doInstallCheck = previousAttrs.doInstallCheck or false;
      installCheckPhase =
        previousAttrs.installCheckPhase or ''
          runHook preInstallCheck

          composer global show ${finalAttrs.pname}

          runHook postInstallCheck
        '';

      vendor = previousAttrs.vendor or stdenvNoCC.mkDerivation {
        pname = "${finalAttrs.pname}-vendor";
        pluginName = finalAttrs.pname;

        inherit (finalAttrs) version src;

        composerLock = previousAttrs.composerLock or null;
        composerNoDev = previousAttrs.composerNoDev or true;
        composerNoPlugins = previousAttrs.composerNoPlugins or true;
        composerNoScripts = previousAttrs.composerNoScripts or true;
        composerStrictValidation = previousAttrs.composerStrictValidation or true;
        composerGlobal = true;
        composerJson = composerJsonBuilder finalAttrs.pname finalAttrs.version;

        nativeBuildInputs = [
          cacert
          composer
          phpDrv.composerHooks.composerWithPluginVendorHook
        ];

        dontPatchShebangs = true;
        doCheck = true;
        doInstallCheck = true;

        env = {
          COMPOSER_CACHE_DIR = "/dev/null";
          COMPOSER_HTACCESS_PROTECT = "0";
        };

        outputHashMode = "recursive";
        outputHashAlgo = "sha256";
        outputHash = finalAttrs.vendorHash;
      };

      # Projects providing a lockfile from upstream can be automatically updated.
      passthru = previousAttrs.passthru or { } // {
        updateScript =
          previousAttrs.passthru.updateScript
            or (if finalAttrs.vendor.composerLock == null then nix-update-script { } else null);
      };

      env = {
        COMPOSER_CACHE_DIR = "/dev/null";
        COMPOSER_DISABLE_NETWORK = "1";
        COMPOSER_MIRROR_PATH_REPOS = "1";
      };

      meta = previousAttrs.meta or composer.meta;
    };
in
args: (stdenvNoCC.mkDerivation args).overrideAttrs buildComposerWithPluginOverride
+93 −0
Original line number Diff line number Diff line
declare composerLock
declare version
declare composerNoDev
declare composerNoPlugins
declare composerNoScripts
declare composerStrictValidation

preConfigureHooks+=(composerWithPluginConfigureHook)
preBuildHooks+=(composerWithPluginBuildHook)
preCheckHooks+=(composerWithPluginCheckHook)
preInstallHooks+=(composerWithPluginInstallHook)
preInstallCheckHooks+=(composerWithPluginInstallCheckHook)

source @phpScriptUtils@

composerWithPluginConfigureHook() {
    echo "Executing composerWithPluginConfigureHook"

    mkdir -p $out

    export COMPOSER_HOME=$out

    if [[ -e "$composerLock" ]]; then
        cp $composerLock $out/composer.lock
    fi

    cp $composerJson $out/composer.json
    cp -ar $src $out/src

    if [[ ! -f "$out/composer.lock" ]]; then
        setComposeRootVersion

        composer \
            global \
            --no-install \
            --no-interaction \
            --no-progress \
            ${composerNoDev:+--no-dev} \
            ${composerNoPlugins:+--no-plugins} \
            ${composerNoScripts:+--no-scripts} \
            update

        echo
        echo -e "\e[31mERROR: No composer.lock found\e[0m"
        echo
        echo -e '\e[31mNo composer.lock file found, consider adding one to your repository to ensure reproducible builds.\e[0m'
        echo -e "\e[31mIn the meantime, a composer.lock file has been generated for you in $out/composer.lock\e[0m"
        echo
        echo -e '\e[31mTo fix the issue:\e[0m'
        echo -e "\e[31m1. Copy the composer.lock file from $out/composer.lock to the project's source:\e[0m"
        echo -e "\e[31m  cp $out/composer.lock <path>\e[0m"
        echo -e '\e[31m2. Add the composerLock attribute, pointing to the copied composer.lock file:\e[0m'
        echo -e '\e[31m  composerLock = ./composer.lock;\e[0m'
        echo

        exit 1
    fi

    echo "Finished composerWithPluginConfigureHook"
}

composerWithPluginBuildHook() {
    echo "Executing composerWithPluginBuildHook"

    echo "Finished composerWithPluginBuildHook"
}

composerWithPluginCheckHook() {
    echo "Executing composerWithPluginCheckHook"

    checkComposerValidate

    echo "Finished composerWithPluginCheckHook"
}

composerWithPluginInstallHook() {
    echo "Executing composerWithPluginInstallHook"

    composer \
        global \
        --no-interaction \
        --no-progress \
        ${composerNoDev:+--no-dev} \
        ${composerNoPlugins:+--no-plugins} \
        ${composerNoScripts:+--no-scripts} \
        install

    echo "Finished composerWithPluginInstallHook"
}

composerWithPluginInstallCheckHook() {
    composer global show $pluginName
}
+15 −0
Original line number Diff line number Diff line
@@ -42,4 +42,19 @@ in
      phpScriptUtils = lib.getExe php-script-utils;
    };
  } ./composer-install-hook.sh;

  composerWithPluginVendorHook = makeSetupHook {
    name = "composer-with-plugin-vendor-hook.sh";
    propagatedBuildInputs = [
      jq
      moreutils
      cacert
    ];
    substitutions = {
      # Specify the stdenv's `diff` by abspath to ensure that the user's build
      # inputs do not cause us to find the wrong `diff`.
      cmp = "${lib.getBin buildPackages.diffutils}/bin/cmp";
      phpScriptUtils = lib.getExe php-script-utils;
    };
  } ./composer-with-plugin-vendor-hook.sh;
}
+1 −1
Original line number Diff line number Diff line
@@ -164,7 +164,7 @@ let
                nixos = lib.recurseIntoAttrs nixosTests."php${lib.strings.replaceStrings [ "." ] [ "" ] (lib.versions.majorMinor php.version)}";
                package = tests.php;
              };
              inherit (php-packages) extensions buildPecl mkComposerRepository buildComposerProject composerHooks mkExtension;
              inherit (php-packages) extensions buildPecl mkComposerRepository buildComposerProject buildComposerWithPlugin composerHooks mkExtension;
              packages = php-packages.tools;
              meta = php.meta // {
                outputsToInstall = [ "out" ];
Loading