Add option that makes it possible to skip the deployment of development dependencies even if they are included in composer.lock
This commit is contained in:
parent
67805db37f
commit
4c20068b41
4 changed files with 104 additions and 57 deletions
40
README.md
40
README.md
|
@ -182,14 +182,43 @@ Advanced features
|
|||
=================
|
||||
`composer2nix` supports a number of less commonly used advanced features.
|
||||
|
||||
Disabling the deployment of development dependencies
|
||||
----------------------------------------------------
|
||||
By default `composer` (and as a result, also `composer2nix`) will include all
|
||||
development dependencies. However, in production environments you typically want
|
||||
to exclude them to reduce the amount of disk space consumed and the deployment
|
||||
times.
|
||||
|
||||
By overriding the expression (e.g. creating a file named: `override.nix`) and
|
||||
appending the `noDev = true;` parameter, we can disable development
|
||||
dependencies:
|
||||
|
||||
```nix
|
||||
{pkgs ? import <nixpkgs> {
|
||||
inherit system;
|
||||
}, system ? builtins.currentSystem}:
|
||||
|
||||
let
|
||||
phpPackage = import ./default.nix {
|
||||
inherit pkgs system;
|
||||
noDev = true; # Disable development dependencies
|
||||
};
|
||||
in
|
||||
phpPackage
|
||||
```
|
||||
|
||||
We can deploy the above package with the following command-line instruction:
|
||||
|
||||
$ nix-build override.nix
|
||||
|
||||
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:
|
||||
By creating an override Nix expression that invokes the generated build function
|
||||
and providing a `postInstall` hook, we can specify additional command-line
|
||||
instructions to run:
|
||||
|
||||
```nix
|
||||
{pkgs ? import <nixpkgs> {
|
||||
|
@ -210,11 +239,6 @@ phpPackage.override {
|
|||
|
||||
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
|
||||
|
|
|
@ -7,7 +7,8 @@ use Composer2Nix\Generator;
|
|||
|
||||
function displayHelp($command)
|
||||
{
|
||||
print("Usage: ".$command." [OPTION]\n\n");
|
||||
print("Usage: ".$command." [OPTION]\n");
|
||||
print(" or: ".$command." -p NAME [OPTION]\n\n");
|
||||
echo <<<EOT
|
||||
This executable can be used to generate Nix expressions from a composer.lock
|
||||
(and a composer.json) file so that a package and all its dependencies can be
|
||||
|
@ -18,7 +19,7 @@ Options:
|
|||
composer.json)
|
||||
--lock-file=FILE Path to the composer.lock file (defaults to:
|
||||
composer.lock)
|
||||
-p, --package Package to deploy as a command-line utility
|
||||
-p, --package=NAME Name of a package to deploy as a command-line utility
|
||||
--package-version Preferred version of the package to deploy (defaults
|
||||
to the latest version)
|
||||
--output=FILE Path to the Nix expression containing the generated
|
||||
|
@ -29,7 +30,8 @@ Options:
|
|||
packages (defaults to: composer-env.nix)
|
||||
--prefer-source Forces installation from package sources when possible
|
||||
--prefer-dist Forces installation from package dist
|
||||
--no-dev Do not install the development packages
|
||||
--no-dev Do not generate expressions for the development
|
||||
packages
|
||||
--name Name of the generated package (defaults to the name
|
||||
provided in the composer.json file)
|
||||
--executable Generate a Nix package for an executable as opposed to
|
||||
|
@ -103,7 +105,6 @@ if(array_key_exists("lock-file", $options))
|
|||
else
|
||||
$lockFile = "composer.lock";
|
||||
|
||||
|
||||
if(array_key_exists("output", $options))
|
||||
$outputFile = $options["output"];
|
||||
else
|
||||
|
@ -133,7 +134,7 @@ else
|
|||
|
||||
$noCopyComposerEnv = array_key_exists("no-copy-composer-env", $options);
|
||||
|
||||
$preferredInstall = "dist"; // TODO: consult composer.json's preferred-install property. defaults to: auto
|
||||
$preferredInstall = "dist";
|
||||
|
||||
if(array_key_exists("prefer-source", $options))
|
||||
$preferredInstall = "source";
|
||||
|
|
|
@ -46,13 +46,8 @@ class Generator
|
|||
return "./".$target;
|
||||
}
|
||||
|
||||
private static function generatePackagesExpression(array $config, $outputFile, $name, $preferredInstall, array $packages, $executable, $symlinkDependencies)
|
||||
private static function generatePackagesAttrSet(array $packages, $preferredInstall)
|
||||
{
|
||||
$handle = fopen($outputFile, "w");
|
||||
|
||||
if($handle === false)
|
||||
throw new Exception("Cannot write to: ".$outputFile);
|
||||
|
||||
$dependencies = array();
|
||||
|
||||
foreach($packages as $package)
|
||||
|
@ -136,6 +131,19 @@ class Generator
|
|||
$dependencies[$package["name"]] = $dependency;
|
||||
}
|
||||
|
||||
return new NixAttrSet($dependencies);
|
||||
}
|
||||
|
||||
private static function generatePackagesExpression(array $config, $outputFile, $name, $preferredInstall, array $packages, array $devPackages, $executable, $symlinkDependencies)
|
||||
{
|
||||
$handle = fopen($outputFile, "w");
|
||||
|
||||
if($handle === false)
|
||||
throw new Exception("Cannot write to: ".$outputFile);
|
||||
|
||||
$packagesAttrSet = Generator::generatePackagesAttrSet($packages, $preferredInstall);
|
||||
$devpackagesAttrSet = Generator::generatePackagesAttrSet($devPackages, $preferredInstall);
|
||||
|
||||
/* Compose meta properties */
|
||||
$meta = array();
|
||||
|
||||
|
@ -162,14 +170,18 @@ class Generator
|
|||
"fetchurl" => new NixNoDefault(),
|
||||
"fetchgit" => null,
|
||||
"fetchhg" => null,
|
||||
"fetchsvn" => null
|
||||
"fetchsvn" => null,
|
||||
"noDev" => false
|
||||
), new NixLet(array(
|
||||
"dependencies" => new NixAttrSet($dependencies)
|
||||
"packages" => $packagesAttrSet,
|
||||
"devPackages" => $devpackagesAttrSet
|
||||
), new NixFunInvocation(new NixExpression("composerEnv.buildPackage"), array(
|
||||
"name" => $name,
|
||||
"src" => new NixFile("./."),
|
||||
"executable" => $executable,
|
||||
"dependencies" => new NixInherit(),
|
||||
"packages" => new NixInherit(),
|
||||
"devPackages" => new NixInherit(),
|
||||
"noDev" => new NixInherit(),
|
||||
"symlinkDependencies" => $symlinkDependencies,
|
||||
"meta" => new NixAttrSet($meta)
|
||||
))));
|
||||
|
@ -190,7 +202,8 @@ class Generator
|
|||
"pkgs" => new NixFunInvocation(new NixImport(new NixExpression("<nixpkgs>")), array(
|
||||
"system" => new NixInherit()
|
||||
)),
|
||||
"system" => new NixAttrReference(new NixExpression("builtins"), new NixExpression("currentSystem"))
|
||||
"system" => new NixAttrReference(new NixExpression("builtins"), new NixExpression("currentSystem")),
|
||||
"noDev" => false
|
||||
), new NixLet(array(
|
||||
"composerEnv" => new NixFunInvocation(new NixImport(new NixFile(Generator::prefixRelativePath($composerEnvFile))), array(
|
||||
"stdenv" => new NixInherit("pkgs"),
|
||||
|
@ -201,6 +214,7 @@ class Generator
|
|||
))
|
||||
), new NixFunInvocation(new NixImport(new NixFile(Generator::prefixRelativePath($outputFile))), array(
|
||||
"composerEnv" => new NixInherit(),
|
||||
"noDev" => new NixInherit(),
|
||||
"fetchurl" => new NixInherit("pkgs"),
|
||||
"fetchgit" => new NixInherit("pkgs"),
|
||||
"fetchhg" => new NixInherit("pkgs"),
|
||||
|
@ -253,16 +267,18 @@ class Generator
|
|||
$packages = array();
|
||||
|
||||
if(!$noDev && array_key_exists("packages-dev", $lockConfig))
|
||||
{
|
||||
foreach($lockConfig["packages-dev"] as $identifier => $devPackage)
|
||||
$packages[$identifier] = $devPackage;
|
||||
}
|
||||
$devPackages = $lockConfig["packages-dev"];
|
||||
else
|
||||
$devPackages = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$packages = array();
|
||||
$devPackages = array();
|
||||
}
|
||||
|
||||
/* Generate packages expression */
|
||||
Generator::generatePackagesExpression($config, $outputFile, $name, $preferredInstall, $packages, $executable, $symlinkDependencies);
|
||||
Generator::generatePackagesExpression($config, $outputFile, $name, $preferredInstall, $packages, $devPackages, $executable, $symlinkDependencies);
|
||||
|
||||
/* Generate composition expression */
|
||||
Generator::generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile);
|
||||
|
|
|
@ -49,7 +49,7 @@ rec {
|
|||
'';
|
||||
};
|
||||
|
||||
buildPackage = { name, src, dependencies ? [], symlinkDependencies ? false, executable ? false, removeComposerArtifacts ? false, postInstall ? "", ...}@args:
|
||||
buildPackage = { name, src, packages ? {}, devPackages ? {}, symlinkDependencies ? false, executable ? false, removeComposerArtifacts ? false, postInstall ? "", noDev ? false, ...}@args:
|
||||
let
|
||||
reconstructInstalled = writeTextFile {
|
||||
name = "reconstructinstalled.php";
|
||||
|
@ -75,8 +75,10 @@ rec {
|
|||
else
|
||||
$allPackages = array();
|
||||
|
||||
${stdenv.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);
|
||||
|
@ -121,8 +123,33 @@ rec {
|
|||
?>
|
||||
'';
|
||||
};
|
||||
|
||||
bundleDependencies = dependencies:
|
||||
stdenv.lib.concatMapStrings (dependencyName:
|
||||
let
|
||||
dependency = dependencies.${dependencyName};
|
||||
in
|
||||
stdenv.lib.makeOverridable stdenv.mkDerivation (builtins.removeAttrs args [ "dependencies" ] // {
|
||||
''
|
||||
${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);
|
||||
in
|
||||
stdenv.lib.makeOverridable stdenv.mkDerivation (builtins.removeAttrs args [ "packages" "devPackages" ] // {
|
||||
buildInputs = [ php composer ] ++ args.buildInputs or [];
|
||||
buildCommand = ''
|
||||
${if executable then ''
|
||||
|
@ -150,38 +177,17 @@ rec {
|
|||
|
||||
# Copy or symlink the provided dependencies
|
||||
cd vendor
|
||||
${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)}
|
||||
${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
|
||||
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
|
||||
composer install --optimize-autoloader ${stdenv.lib.optionalString noDev "--no-dev"}
|
||||
|
||||
${stdenv.lib.optionalString executable ''
|
||||
${constructBin} composer.json
|
||||
|
|
Loading…
Reference in a new issue