diff --git a/default.nix b/default.nix index eefd8e7..f897f4e 100644 --- a/default.nix +++ b/default.nix @@ -68,22 +68,5 @@ EOF fi ''; - ofborg.php = pkgs.runCommand - "ofborg" - { - src = builtins.filterSource - (path: type: !( - (type == "symlink" && baseNameOf path == "result") - || (type == "directory" && baseNameOf path == ".git") - )) - ./php; - } - '' - cp -r $src ./ofborg - chmod -R u+w ./ofborg - cd ofborg - ls -la - cd .. - mv ofborg $out - ''; + ofborg.php = import ./php { inherit pkgs; }; } diff --git a/php/composer-env.nix b/php/composer-env.nix new file mode 100644 index 0000000..955a359 --- /dev/null +++ b/php/composer-env.nix @@ -0,0 +1,270 @@ +# This file originates from composer2nix + +{ stdenv, writeTextFile, fetchurl, php, unzip }: + +let + composer = stdenv.mkDerivation { + name = "composer-1.6.5"; + src = fetchurl { + url = https://github.com/composer/composer/releases/download/1.6.5/composer.phar; + sha256 = "07xkpg9y1dd4s33y3cbf7r5fphpgc39mpm066a8m9y4ffsf539f0"; + }; + buildInputs = [ php ]; + + # We must wrap the composer.phar because of the impure shebang. + # We cannot use patchShebangs because the executable verifies its own integrity and will detect that somebody has tampered with it. + + buildCommand = '' + # Copy phar file + mkdir -p $out/share/php + cp $src $out/share/php/composer.phar + chmod 755 $out/share/php/composer.phar + + # Create wrapper executable + mkdir -p $out/bin + cat > $out/bin/composer < + ''; + }; + + constructBin = writeTextFile { + name = "constructbin.php"; + executable = true; + text = '' + #! ${php}/bin/php + + ''; + }; + + bundleDependencies = dependencies: + stdenv.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 < vendor/composer/installed.json + + # Copy or symlink the provided dependencies + cd vendor + ${bundleDependencies packages} + ${stdenv.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 ${stdenv.lib.optionalString noDev "--no-dev"} + + # Run the install step as a validation to confirm that everything works out as expected + composer install --optimize-autoloader ${stdenv.lib.optionalString noDev "--no-dev"} + + ${stdenv.lib.optionalString executable '' + # Reconstruct the bin/ folder if we deploy an executable project + ${constructBin} composer.json + ln -s $(pwd)/vendor/bin $out/bin + ''} + + ${stdenv.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 = stdenv.lib.makeOverridable composer; + buildZipPackage = stdenv.lib.makeOverridable buildZipPackage; + buildPackage = stdenv.lib.makeOverridable buildPackage; +} diff --git a/php/composer.json b/php/composer.json index 3928836..31fa21f 100644 --- a/php/composer.json +++ b/php/composer.json @@ -1,5 +1,7 @@ { + "name": "ofborg-webhook", "require": { - "php-amqplib/php-amqplib": ">=2.6.1" + "php-amqplib/php-amqplib": ">=2.6.1", + "svanderburg/composer2nix": ">=0.0.3" } } diff --git a/php/composer.lock b/php/composer.lock index 351ea07..5c1994b 100644 --- a/php/composer.lock +++ b/php/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "f0b42ac9169509834501cb7aa271b580", + "content-hash": "81858eba648031903f09c76e5d8e23cd", "packages": [ { "name": "php-amqplib/php-amqplib", @@ -76,6 +76,89 @@ "rabbitmq" ], "time": "2018-02-11T19:28:00+00:00" + }, + { + "name": "svanderburg/composer2nix", + "version": "v0.0.3", + "source": { + "type": "git", + "url": "https://github.com/svanderburg/composer2nix.git", + "reference": "2fb157acaf0ecbe34436195c694637396f7258a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/svanderburg/composer2nix/zipball/2fb157acaf0ecbe34436195c694637396f7258a6", + "reference": "2fb157acaf0ecbe34436195c694637396f7258a6", + "shasum": "" + }, + "require": { + "svanderburg/pndp": "0.0.2" + }, + "require-dev": { + "phpdocumentor/phpdocumentor": "2.9.x" + }, + "bin": [ + "bin/composer2nix" + ], + "type": "library", + "autoload": { + "psr-4": { + "Composer2Nix\\": "src/Composer2Nix" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sander van der Burg", + "email": "svanderburg@gmail.com", + "homepage": "http://sandervanderburg.nl" + } + ], + "description": "Generate Nix expressions to build PHP composer packages", + "time": "2018-06-29T20:58:30+00:00" + }, + { + "name": "svanderburg/pndp", + "version": "v0.0.2", + "source": { + "type": "git", + "url": "https://github.com/svanderburg/pndp.git", + "reference": "4bfe9c4120c23354ab8dc295957dc3009a39bff0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/svanderburg/pndp/zipball/4bfe9c4120c23354ab8dc295957dc3009a39bff0", + "reference": "4bfe9c4120c23354ab8dc295957dc3009a39bff0", + "shasum": "" + }, + "require-dev": { + "phpdocumentor/phpdocumentor": "2.9.x" + }, + "bin": [ + "bin/pndp-build" + ], + "type": "library", + "autoload": { + "psr-4": { + "PNDP\\": "src/PNDP" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sander van der Burg", + "email": "svanderburg@gmail.com", + "homepage": "http://sandervanderburg.nl" + } + ], + "description": "PNDP: An internal DSL for Nix in PHP", + "time": "2017-10-22T12:43:22+00:00" } ], "packages-dev": [], diff --git a/php/default.nix b/php/default.nix new file mode 100644 index 0000000..d839f37 --- /dev/null +++ b/php/default.nix @@ -0,0 +1,13 @@ +{pkgs ? import { + inherit system; + }, system ? builtins.currentSystem, noDev ? false}: + +let + composerEnv = import ./composer-env.nix { + inherit (pkgs) stdenv writeTextFile fetchurl php unzip; + }; +in +import ./php-packages.nix { + inherit composerEnv noDev; + inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn; +} \ No newline at end of file diff --git a/php/php-packages.nix b/php/php-packages.nix new file mode 100644 index 0000000..94d0d43 --- /dev/null +++ b/php/php-packages.nix @@ -0,0 +1,45 @@ +{composerEnv, fetchurl, fetchgit ? null, fetchhg ? null, fetchsvn ? null, noDev ? false}: + +let + packages = { + "php-amqplib/php-amqplib" = { + targetDir = ""; + src = composerEnv.buildZipPackage { + name = "php-amqplib-php-amqplib-dfd3694a86f1a7394d3693485259d4074a6ec79b"; + src = fetchurl { + url = https://api.github.com/repos/php-amqplib/php-amqplib/zipball/dfd3694a86f1a7394d3693485259d4074a6ec79b; + sha256 = "1dlxgdnhy8xyx8xbp1glc7igksvsqyc3yaq76irhy09djij013ip"; + }; + }; + }; + "svanderburg/composer2nix" = { + targetDir = ""; + src = composerEnv.buildZipPackage { + name = "svanderburg-composer2nix-2fb157acaf0ecbe34436195c694637396f7258a6"; + src = fetchurl { + url = https://api.github.com/repos/svanderburg/composer2nix/zipball/2fb157acaf0ecbe34436195c694637396f7258a6; + sha256 = "01i3kxgx7pcmxafclp8ib08nib1xh6nvr5sbl6y38rw19xhnwa0m"; + }; + }; + }; + "svanderburg/pndp" = { + targetDir = ""; + src = composerEnv.buildZipPackage { + name = "svanderburg-pndp-4bfe9c4120c23354ab8dc295957dc3009a39bff0"; + src = fetchurl { + url = https://api.github.com/repos/svanderburg/pndp/zipball/4bfe9c4120c23354ab8dc295957dc3009a39bff0; + sha256 = "0n2vwpwshv16bhb7a6j95m664zh4lpfa7dqmcyhmn89nxpgvg91y"; + }; + }; + }; + }; + devPackages = {}; +in +composerEnv.buildPackage { + inherit packages devPackages noDev; + name = "ofborg-webhook"; + src = ./.; + executable = false; + symlinkDependencies = false; + meta = {}; +} \ No newline at end of file