From e66636acb93b73af962a2ead16308c78f8bf5764 Mon Sep 17 00:00:00 2001 From: Sander van der Burg Date: Fri, 7 Jul 2017 22:51:59 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + LICENSE | 19 ++++ README.md | 40 +++++++++ bin/composer2nix.php | 132 ++++++++++++++++++++++++++++ composer.json | 19 ++++ src/Composer2Nix/Generator.php | 140 ++++++++++++++++++++++++++++++ src/Composer2Nix/composer-env.nix | 124 ++++++++++++++++++++++++++ 7 files changed, 475 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100755 bin/composer2nix.php create mode 100644 composer.json create mode 100644 src/Composer2Nix/Generator.php create mode 100644 src/Composer2Nix/composer-env.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48b8bf9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..938e480 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017 Sander van der Burg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..822aba8 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +composer2nix +============ +`composer2nix` is a tool that can be used to generate [Nix](http://nixos.org) +expressions for PHP [composer](https://getcomposer.org) packages. + +Nix integration makes it possible to use the Nix package manager (as opposed to +composer) to deploy PHP packages including all their required dependencies. + +In addition, generated Nix composer packages +support convenient integration of PHP applications with NixOS services, such as +NixOS' Apache HTTP service. + +Usage +===== +You need a project providing both a `composer.json` and a `composer.lock` +configuration file. + +Running the following command generates Nix expressions from the composer +configuration files: + + $ composer2nix + +The above command produces three expressions: `php-packages.nix` containing the +dependencies, `composer-env.nix` the build infrastructure and `default.nix` that +can be used to compose the package from its dependencies. + +Running the following command-line instruction deploys the package with Nix +including its dependencies: + + $ nix-build + +Limitations +=========== +Currently, the state of this tool is that it is just a proof on concept +implementation. As a result, it is lacking many features and probably buggy. +Most importantly, only the `zip` and `git` dependencies are supported. + +License +======= +The contents of this package is available under the [MIT license](http://opensource.org/licenses/MIT) diff --git a/bin/composer2nix.php b/bin/composer2nix.php new file mode 100755 index 0000000..bc0d36e --- /dev/null +++ b/bin/composer2nix.php @@ -0,0 +1,132 @@ +#!/usr/bin/env php +getMessage()."\n"); + exit(1); +} +?> diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..185ba53 --- /dev/null +++ b/composer.json @@ -0,0 +1,19 @@ +{ + "name": "svanderburg/composer2nix", + "description": "Generate Nix expressions to build PHP composer packages", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Sander van der Burg", + "email": "svanderburg@gmail.com", + "homepage": "http://sandervanderburg.nl" + } + ], + + "autoload": { + "psr-4": { "Composer2Nix\\": "src/Composer2Nix" } + }, + + "bin": [ "bin/composer2nix" ] +} diff --git a/src/Composer2Nix/Generator.php b/src/Composer2Nix/Generator.php new file mode 100644 index 0000000..e6377d9 --- /dev/null +++ b/src/Composer2Nix/Generator.php @@ -0,0 +1,140 @@ + 0 && substr($path, 0, 1) === "/") || (strlen($path) > 1 && substr($path, 0, 2) === "./")) + return $path; + else + return "./".$path; + } + + fwrite($handle, "{ pkgs ? import { inherit system; }\n"); + fwrite($handle, ", system ? builtins.currentSystem\n"); + fwrite($handle, "}:\n\n"); + + fwrite($handle, "let\n"); + fwrite($handle, " composerEnv = import ".composeNixFilePath($composerEnvFile)." {\n"); + fwrite($handle, " inherit (pkgs) stdenv writeTextFile fetchurl php unzip;\n"); + fwrite($handle, " };\n"); + fwrite($handle, "in\n"); + fwrite($handle, "import ".composeNixFilePath($outputFile)." {\n"); + fwrite($handle, " inherit composerEnv;\n"); + fwrite($handle, " inherit (pkgs) fetchgit;\n"); + fwrite($handle, "}\n"); + + fclose($handle); + + /* Copy composer-env.nix */ + + if(!$noCopyComposerEnv && !copy(dirname(__FILE__)."/composer-env.nix", $composerEnvFile)) + throw new Exception("Cannot copy node-env.nix!"); + } +} +?> diff --git a/src/Composer2Nix/composer-env.nix b/src/Composer2Nix/composer-env.nix new file mode 100644 index 0000000..fc6bda1 --- /dev/null +++ b/src/Composer2Nix/composer-env.nix @@ -0,0 +1,124 @@ +# This file originates from composer2nix + +{ stdenv, writeTextFile, fetchurl, php, unzip }: + +rec { + composer = stdenv.mkDerivation { + name = "composer-1.4.2"; + src = fetchurl { + url = https://github.com/composer/composer/releases/download/1.4.2/composer.phar; + sha256 = "1x467ngxb976ba2r9kqba7jpvm95a0db8nwaa2z14zs7xv1la6bb"; + }; + 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 <packages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + print($packagesStr); + } + ?> + ''; + }; + in + stdenv.mkDerivation { + inherit name src; + buildInputs = [ php composer ]; + buildCommand = '' + cp -av $src $out + chmod -R u+w $out + cd $out + + # Remove unwanted files + rm -f *.nix + + export HOME=$TMPDIR + + # Reconstruct the installed.json file from the lock file + mkdir -p vendor/composer + ${reconstructInstalled} composer.lock > vendor/composer/installed.json + + # Symlink the provided dependencies + cd vendor + ${stdenv.lib.concatMapStrings (dependencyName: + let + dependency = dependencies.${dependencyName}; + in + '' + vendorDir="$(dirname ${dependencyName})" + mkdir -p "$vendorDir" + ln -s "${dependency}" "$vendorDir/$(basename "${dependencyName}")" + '') (builtins.attrNames dependencies)} + 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 + + # Run the install step as a validation to confirm that everything works out as expected + composer install --optimize-autoloader + + ${stdenv.lib.optionalString (removeComposerArtifacts) '' + # Remove composer stuff + rm composer.json composer.lock + ''} + ''; + }; +}