php.buildComposerWithPlugin: init new builder

Changed files
+272 -2
pkgs
build-support
development
interpreters
top-level
+1
pkgs/build-support/php/builders/default.nix
···
{
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
pkgs/build-support/php/builders/v1/build-composer-with-plugin.nix
···
+
{
+
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
pkgs/build-support/php/builders/v1/hooks/composer-with-plugin-vendor-hook.sh
···
+
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
pkgs/build-support/php/builders/v1/hooks/default.nix
···
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
pkgs/development/interpreters/php/generic.nix
···
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" ];
+1 -1
pkgs/top-level/php-packages.nix
···
php = php.unwrapped;
};
-
inherit (builders.v1) buildComposerProject composerHooks mkComposerRepository;
+
inherit (builders.v1) buildComposerProject buildComposerWithPlugin composerHooks mkComposerRepository;
# Wrap mkDerivation to prepend pname with "php-" to make names consistent
# with how buildPecl does it and make the file easier to overview.