de74c9e88c
Nixpkgs has dropped PHP 7.2. Updating to PHP 7.4 should be painless as our usage of PHP is very limited.
240 lines
7.4 KiB
Nix
240 lines
7.4 KiB
Nix
# This file originates from composer2nix
|
|
|
|
{ stdenv, lib, writeTextFile, fetchurl, php, unzip, phpPackages }:
|
|
|
|
let
|
|
inherit (phpPackages) composer;
|
|
buildZipPackage = { name, src }:
|
|
stdenv.mkDerivation {
|
|
inherit name src;
|
|
buildInputs = [ unzip ];
|
|
buildCommand = ''
|
|
unzip $src
|
|
baseDir=$(find . -type d -mindepth 1 -maxdepth 1)
|
|
cd $baseDir
|
|
mkdir -p $out
|
|
mv * $out
|
|
'';
|
|
};
|
|
|
|
buildPackage =
|
|
{ name
|
|
, src
|
|
, packages ? {}
|
|
, devPackages ? {}
|
|
, buildInputs ? []
|
|
, symlinkDependencies ? false
|
|
, executable ? false
|
|
, removeComposerArtifacts ? false
|
|
, postInstall ? ""
|
|
, noDev ? false
|
|
, composerExtraArgs ? ""
|
|
, unpackPhase ? "true"
|
|
, buildPhase ? "true"
|
|
, ...}@args:
|
|
|
|
let
|
|
reconstructInstalled = writeTextFile {
|
|
name = "reconstructinstalled.php";
|
|
executable = true;
|
|
text = ''
|
|
#! ${php}/bin/php
|
|
<?php
|
|
if(file_exists($argv[1]))
|
|
{
|
|
$composerLockStr = file_get_contents($argv[1]);
|
|
|
|
if($composerLockStr === false)
|
|
{
|
|
fwrite(STDERR, "Cannot open composer.lock contents\n");
|
|
exit(1);
|
|
}
|
|
else
|
|
{
|
|
$config = json_decode($composerLockStr, true);
|
|
|
|
if(array_key_exists("packages", $config))
|
|
$allPackages = $config["packages"];
|
|
else
|
|
$allPackages = array();
|
|
|
|
${lib.optionalString (!noDev) ''
|
|
if(array_key_exists("packages-dev", $config))
|
|
$allPackages = array_merge($allPackages, $config["packages-dev"]);
|
|
''}
|
|
|
|
$packagesStr = json_encode($allPackages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
print($packagesStr);
|
|
}
|
|
}
|
|
else
|
|
print("[]");
|
|
?>
|
|
'';
|
|
};
|
|
|
|
constructBin = writeTextFile {
|
|
name = "constructbin.php";
|
|
executable = true;
|
|
text = ''
|
|
#! ${php}/bin/php
|
|
<?php
|
|
$composerJSONStr = file_get_contents($argv[1]);
|
|
|
|
if($composerJSONStr === false)
|
|
{
|
|
fwrite(STDERR, "Cannot open composer.json contents\n");
|
|
exit(1);
|
|
}
|
|
else
|
|
{
|
|
$config = json_decode($composerJSONStr, true);
|
|
|
|
if(array_key_exists("bin-dir", $config))
|
|
$binDir = $config["bin-dir"];
|
|
else
|
|
$binDir = "bin";
|
|
|
|
if(array_key_exists("bin", $config))
|
|
{
|
|
if(!file_exists("vendor/".$binDir))
|
|
mkdir("vendor/".$binDir);
|
|
|
|
foreach($config["bin"] as $bin)
|
|
symlink("../../".$bin, "vendor/".$binDir."/".basename($bin));
|
|
}
|
|
}
|
|
?>
|
|
'';
|
|
};
|
|
|
|
bundleDependencies = dependencies:
|
|
lib.concatMapStrings (dependencyName:
|
|
let
|
|
dependency = dependencies.${dependencyName};
|
|
in
|
|
''
|
|
${if dependency.targetDir == "" then ''
|
|
vendorDir="$(dirname ${dependencyName})"
|
|
mkdir -p "$vendorDir"
|
|
${if symlinkDependencies then
|
|
''ln -s "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
|
|
else
|
|
''cp -av "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
|
|
}
|
|
'' else ''
|
|
namespaceDir="${dependencyName}/$(dirname "${dependency.targetDir}")"
|
|
mkdir -p "$namespaceDir"
|
|
${if symlinkDependencies then
|
|
''ln -s "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
|
|
else
|
|
''cp -av "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
|
|
}
|
|
''}
|
|
'') (builtins.attrNames dependencies);
|
|
|
|
extraArgs = removeAttrs args [ "name" "packages" "devPackages" "buildInputs" ];
|
|
in
|
|
stdenv.mkDerivation ({
|
|
name = "composer-${name}";
|
|
buildInputs = [ php composer ] ++ buildInputs;
|
|
|
|
inherit unpackPhase buildPhase;
|
|
|
|
installPhase = ''
|
|
${if executable then ''
|
|
mkdir -p $out/share/php
|
|
cp -av $src $out/share/php/$name
|
|
chmod -R u+w $out/share/php/$name
|
|
cd $out/share/php/$name
|
|
'' else ''
|
|
cp -av $src $out
|
|
chmod -R u+w $out
|
|
cd $out
|
|
''}
|
|
|
|
# Remove unwanted files
|
|
rm -f *.nix
|
|
|
|
export HOME=$TMPDIR
|
|
|
|
# Remove the provided vendor folder if it exists
|
|
rm -Rf vendor
|
|
|
|
# If there is no composer.lock file, compose a dummy file.
|
|
# Otherwise, composer attempts to download the package.json file from
|
|
# the registry which we do not want.
|
|
if [ ! -f composer.lock ]
|
|
then
|
|
cat > composer.lock <<EOF
|
|
{
|
|
"packages": []
|
|
}
|
|
EOF
|
|
fi
|
|
|
|
# Reconstruct the installed.json file from the lock file
|
|
mkdir -p vendor/composer
|
|
${php}/bin/php ${reconstructInstalled} composer.lock > vendor/composer/installed.json
|
|
|
|
# Copy or symlink the provided dependencies
|
|
cd vendor
|
|
${bundleDependencies packages}
|
|
${lib.optionalString (!noDev) (bundleDependencies devPackages)}
|
|
cd ..
|
|
|
|
# Reconstruct autoload scripts
|
|
# We use the optimize feature because Nix packages cannot change after they have been built
|
|
# Using the dynamic loader for a Nix package is useless since there is nothing to dynamically reload.
|
|
composer dump-autoload --optimize ${lib.optionalString noDev "--no-dev"} ${composerExtraArgs}
|
|
|
|
# Run the install step as a validation to confirm that everything works out as expected
|
|
composer install --optimize-autoloader ${lib.optionalString noDev "--no-dev"} ${composerExtraArgs}
|
|
|
|
${lib.optionalString executable ''
|
|
# Reconstruct the bin/ folder if we deploy an executable project
|
|
${php}/bin/php ${constructBin} composer.json
|
|
ln -s $(pwd)/vendor/bin $out/bin
|
|
''}
|
|
|
|
${lib.optionalString (!symlinkDependencies) ''
|
|
# Patch the shebangs if possible
|
|
if [ -d $(pwd)/vendor/bin ]
|
|
then
|
|
# Look for all executables in bin/
|
|
for i in $(pwd)/vendor/bin/*
|
|
do
|
|
# Look for their location
|
|
realFile=$(readlink -f "$i")
|
|
|
|
# Restore write permissions
|
|
chmod u+wx "$(dirname "$realFile")"
|
|
chmod u+w "$realFile"
|
|
|
|
# Patch shebang
|
|
sed -e "s|#!/usr/bin/php|#!${php}/bin/php|" \
|
|
-e "s|#!/usr/bin/env php|#!${php}/bin/php|" \
|
|
"$realFile" > tmp
|
|
mv tmp "$realFile"
|
|
chmod u+x "$realFile"
|
|
done
|
|
fi
|
|
''}
|
|
|
|
if [ "$removeComposerArtifacts" = "1" ]
|
|
then
|
|
# Remove composer stuff
|
|
rm -f composer.json composer.lock
|
|
fi
|
|
|
|
# Execute post install hook
|
|
runHook postInstall
|
|
'';
|
|
} // extraArgs);
|
|
in
|
|
{
|
|
composer = lib.makeOverridable composer;
|
|
buildZipPackage = lib.makeOverridable buildZipPackage;
|
|
buildPackage = lib.makeOverridable buildPackage;
|
|
}
|