- Extended installed.json generation to include development packages

- Make build function overridable
- Document some overriding use-cases
This commit is contained in:
Sander van der Burg 2017-09-19 20:19:55 +02:00
parent f9829e8b9e
commit 930f8062c8
2 changed files with 92 additions and 12 deletions

View file

@ -15,7 +15,9 @@ Prerequisites
This package requires the following packages to be installed: This package requires the following packages to be installed:
* [Nix package manager](http://nixos.org/nix) * [Nix package manager](http://nixos.org/nix)
* The Nix prefetch scripts, e.g: `nix-env -f '<nixpkgs>' -iA nix-prefetch-scripts` * The Nix prefetch scripts. They can be installed from Nix packages by running:
$ nix-env -f '<nixpkgs>' -iA nix-prefetch-scripts
Consult the Nix documentation for the installation instructions. Consult the Nix documentation for the installation instructions.
@ -178,6 +180,73 @@ Advanced features
================= =================
`composer2nix` supports a number of less commonly used advanced features. `composer2nix` supports a number of less commonly used advanced features.
Running post installation instructions
--------------------------------------
For some packages, we may want to run additional command line instructions after
the packaging process completes, such as running unit tests.
By creating an override Nix expression (e.g. `override.nix`) that invokes the
generated build function and providing a `postInstall` hook, we can specify
additional command-line instructions to run:
```nix
{pkgs ? import <nixpkgs> {
inherit system;
}, system ? builtins.currentSystem}:
let
phpPackage = import ./default.nix {
inherit pkgs system;
};
in
phpPackage.override {
postInstall = ''
php vendor/bin/phpunit tests
'';
}
```
In the above code fragment, we invoke `phpunit` to run all our unit tests.
We can deploy the above package (and run the corresponding tests) with the
following command-line instruction:
$ nix-build override.nix
Adding unspecified dependencies
-------------------------------
Some packages may also require non-PHP package dependencies. Since these
dependencies are not specified in a composer configuration file, their
deployments may typically fail in a Nix builder environment, because they cannot
be implicitly found.
By overriding the generated package expression, we can supply these missing
dependencies ourselves:
```nix
{pkgs ? import <nixpkgs> {
inherit system;
}, system ? builtins.currentSystem}:
let
phpPackage = import ./default.nix {
inherit pkgs system;
};
in
phpPackage.override (oldAttrs: {
buildInputs = oldAttrs.buildInputs ++ [ pkgs.graphviz ];
postInstall = ''
php vendor/bin/phpdocumentor -d src -t out
'';
})
```
The above expression overrides the generated PHP package by supplying `graphviz`
as an extra dependency. This package is particularly useful when it is desired
to use `phpdocumentor` -- it uses `graphviz` to generate class diagrams. If this
tool is not present in the build environment, class diagrams will not be
generated.
Symlinking dependencies Symlinking dependencies
----------------------- -----------------------
By default, `composer2nix` makes copies of all packages that end up in the By default, `composer2nix` makes copies of all packages that end up in the

View file

@ -4,10 +4,10 @@
rec { rec {
composer = stdenv.mkDerivation { composer = stdenv.mkDerivation {
name = "composer-1.4.2"; name = "composer-1.5.2";
src = fetchurl { src = fetchurl {
url = https://github.com/composer/composer/releases/download/1.4.2/composer.phar; url = https://github.com/composer/composer/releases/download/1.5.2/composer.phar;
sha256 = "1x467ngxb976ba2r9kqba7jpvm95a0db8nwaa2z14zs7xv1la6bb"; sha256 = "07xkpg9y1dd4s33y3cbf7r5fphpgc39mpm066a8m9y4ffsf539f0";
}; };
buildInputs = [ php ]; buildInputs = [ php ];
@ -49,7 +49,7 @@ rec {
''; '';
}; };
buildPackage = { name, src, dependencies ? [], symlinkDependencies ? false, executable ? false, removeComposerArtifacts ? false }: buildPackage = { name, src, dependencies ? [], symlinkDependencies ? false, executable ? false, removeComposerArtifacts ? false, postInstall ? ""}@args:
let let
reconstructInstalled = writeTextFile { reconstructInstalled = writeTextFile {
name = "reconstructinstalled.php"; name = "reconstructinstalled.php";
@ -68,8 +68,17 @@ rec {
} }
else else
{ {
$config = json_decode($composerLockStr); $config = json_decode($composerLockStr, true);
$packagesStr = json_encode($config->packages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
if(array_key_exists("packages", $config))
$allPackages = $config["packages"];
else
$allPackages = array();
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); print($packagesStr);
} }
} }
@ -113,9 +122,8 @@ rec {
''; '';
}; };
in in
stdenv.mkDerivation { stdenv.lib.makeOverridable stdenv.mkDerivation (builtins.removeAttrs args [ "dependencies" ] // {
inherit name src; buildInputs = [ php composer ] ++ args.buildInputs or [];
buildInputs = [ php composer ];
buildCommand = '' buildCommand = ''
${if executable then '' ${if executable then ''
mkdir -p $out/share/php mkdir -p $out/share/php
@ -140,7 +148,7 @@ rec {
mkdir -p vendor/composer mkdir -p vendor/composer
${reconstructInstalled} composer.lock > vendor/composer/installed.json ${reconstructInstalled} composer.lock > vendor/composer/installed.json
# Symlink the provided dependencies # Copy or symlink the provided dependencies
cd vendor cd vendor
${stdenv.lib.concatMapStrings (dependencyName: ${stdenv.lib.concatMapStrings (dependencyName:
let let
@ -185,6 +193,9 @@ rec {
# Remove composer stuff # Remove composer stuff
rm -f composer.json composer.lock rm -f composer.json composer.lock
''} ''}
# Execute post install hook
runHook postInstall
''; '';
}; });
} }