- Preliminary support for svn repositories

- Support zip artifacts that are stored on the local filesystem
- Add option to package executables/CLI tools
This commit is contained in:
Sander van der Burg 2017-07-13 21:18:58 +02:00
parent 9231062ceb
commit 1ffe00522d
3 changed files with 102 additions and 28 deletions

View file

@ -28,6 +28,8 @@ Options:
--no-dev Do not install 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
a library or web application.
--no-copy-composer-env
Do not create a copy of the Nix expression that builds
composer packages
@ -54,6 +56,7 @@ $options = getopt("hv", array(
"prefer-dist",
"no-dev",
"name:",
"executable",
"no-copy-composer-env",
"help",
"version"
@ -115,21 +118,20 @@ if(array_key_exists("prefer-source", $options))
if(array_key_exists("prefer-dist", $options))
$preferredInstall = "dist";
if(array_key_exists("no-dev", $options))
$noDev = true;
else
$noDev = false;
$noDev = array_key_exists("no-dev", $options);
if(array_key_exists("name", $options))
$name = $options["name"];
else
$name = null;
$executable = array_key_exists("executable", $options);
/* Execute the generator */
try
{
Generator::generateNixExpressions($name, $preferredInstall, $noDev, $configFile, $lockFile, $outputFile, $compositionFile, $composerEnvFile, $noCopyComposerEnv);
Generator::generateNixExpressions($name, $executable, $preferredInstall, $noDev, $configFile, $lockFile, $outputFile, $compositionFile, $composerEnvFile, $noCopyComposerEnv);
}
catch(Exception $ex)
{

View file

@ -39,14 +39,14 @@ class Generator
}
}
private static function generatePackagesExpression($outputFile, $name, $preferredInstall, array $packages)
private static function generatePackagesExpression($outputFile, $name, $preferredInstall, array $packages, $executable)
{
$handle = fopen($outputFile, "w");
if($handle === false)
throw new Exception("Cannot write to: ".$outputFile);
fwrite($handle, "{composerEnv, fetchgit ? null}:\n\n");
fwrite($handle, "{composerEnv, fetchurl, fetchgit ? null, fetchhg ? null, fetchsvn ? null}:\n\n");
fwrite($handle, "let\n");
fwrite($handle, " dependencies = {\n");
@ -61,13 +61,29 @@ class Generator
break;
case "zip":
$hash = shell_exec('nix-prefetch-url "'.$sourceObj['url'].'"');
fwrite($handle, ' "'.$package["name"].'" = composerEnv.buildZipPackage {'."\n");
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n");
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
if($sourceObj["reference"] == "")
$reference = "";
else
$reference = "-".$sourceObj["reference"];
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").$reference.'";'."\n");
if(substr($sourceObj["url"], 0, 7) === "http://" || substr($sourceObj["url"], 0, 8) === "https://")
{
$hash = shell_exec('nix-prefetch-url "'.$sourceObj['url'].'"');
fwrite($handle, " src = fetchurl {\n");
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
fwrite($handle, " };\n");
}
else
fwrite($handle, " src = ".Generator::composeNixFilePath($sourceObj['url']).";\n");
fwrite($handle, " };\n");
break;
case "git":
$outputStr = shell_exec('nix-prefetch-git "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
@ -81,18 +97,29 @@ class Generator
fwrite($handle, ' sha256 = "'.$hash.'";'."\n");
fwrite($handle, " };\n");
break;
case "hg":
$outputStr = shell_exec('nix-prefetch-hg "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
$output = json_decode($outputStr, true);
$hash = $output["sha256"];
case "hg":
$hash = shell_exec('nix-prefetch-hg "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
fwrite($handle, ' "'.$package["name"].'" = fetchhg {'."\n");
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n");
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
fwrite($handle, ' rev = "'.$sourceObj["reference"].'";'."\n");
fwrite($handle, ' sha256 = "'.$hash.'";'."\n");
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
fwrite($handle, " };\n");
break;
case "svn":
$hash = shell_exec('nix-prefetch-svn "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
fwrite($handle, ' "'.$package["name"].'" = fetchsvn {'."\n");
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n");
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
fwrite($handle, ' rev = "'.$sourceObj["reference"].'";'."\n");
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
fwrite($handle, " };\n");
break;
default:
throw new Exception("Cannot convert dependency of type: ".$sourceObj["type"]);
}
@ -103,6 +130,7 @@ class Generator
fwrite($handle, "composerEnv.buildPackage {\n");
fwrite($handle, ' name = "'.$name.'";'."\n");
fwrite($handle, " src = ./.;\n");
fwrite($handle, " executable = ".($executable ? "true" : "false").";\n");
fwrite($handle, " inherit dependencies;\n");
fwrite($handle, "}\n");
@ -127,13 +155,13 @@ class Generator
fwrite($handle, "in\n");
fwrite($handle, "import ".Generator::composeNixFilePath($outputFile)." {\n");
fwrite($handle, " inherit composerEnv;\n");
fwrite($handle, " inherit (pkgs) fetchgit;\n");
fwrite($handle, " inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn;\n");
fwrite($handle, "}\n");
fclose($handle);
}
public static function generateNixExpressions($name, $preferredInstall, $noDev, $configFile, $lockFile, $outputFile, $compositionFile, $composerEnvFile, $noCopyComposerEnv)
public static function generateNixExpressions($name, $executable, $preferredInstall, $noDev, $configFile, $lockFile, $outputFile, $compositionFile, $composerEnvFile, $noCopyComposerEnv)
{
/* Open the composer.json file and decode it */
$composerJSONStr = file_get_contents($configFile);
@ -183,7 +211,7 @@ class Generator
$packages = array();
/* Generate packages expression */
Generator::generatePackagesExpression($outputFile, $name, $preferredInstall, $packages);
Generator::generatePackagesExpression($outputFile, $name, $preferredInstall, $packages, $executable);
/* Generate composition expression */
Generator::generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile);

View file

@ -36,12 +36,9 @@ rec {
};
};
buildZipPackage = { name, url, sha256 }:
buildZipPackage = { name, src }:
stdenv.mkDerivation {
inherit name;
src = fetchurl {
inherit url sha256;
};
inherit name src;
buildInputs = [ unzip ];
buildCommand = ''
unzip $src
@ -52,7 +49,7 @@ rec {
'';
};
buildPackage = { name, src, dependencies ? [], removeComposerArtifacts ? false }:
buildPackage = { name, src, dependencies ? [], executable ? false, removeComposerArtifacts ? false }:
let
reconstructInstalled = writeTextFile {
name = "reconstructinstalled.php";
@ -76,14 +73,55 @@ rec {
?>
'';
};
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))
{
mkdir("vendor/".$binDir);
foreach($config["bin"] as $bin)
symlink("../../".$bin, "vendor/".$binDir."/".basename($bin));
}
}
?>
'';
};
in
stdenv.mkDerivation {
inherit name src;
buildInputs = [ php composer ];
buildCommand = ''
cp -av $src $out
chmod -R u+w $out
cd $out
${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
@ -115,6 +153,12 @@ rec {
# Run the install step as a validation to confirm that everything works out as expected
composer install --optimize-autoloader
${stdenv.lib.optionalString executable ''
${constructBin} composer.json
ln -s $(pwd)/vendor/bin $out/bin
patchShebangs $out/bin
''}
${stdenv.lib.optionalString (removeComposerArtifacts) ''
# Remove composer stuff
rm composer.json composer.lock