- 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 --no-dev Do not install the development packages
--name Name of the generated package (defaults to the name --name Name of the generated package (defaults to the name
provided in the composer.json file) 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 --no-copy-composer-env
Do not create a copy of the Nix expression that builds Do not create a copy of the Nix expression that builds
composer packages composer packages
@ -54,6 +56,7 @@ $options = getopt("hv", array(
"prefer-dist", "prefer-dist",
"no-dev", "no-dev",
"name:", "name:",
"executable",
"no-copy-composer-env", "no-copy-composer-env",
"help", "help",
"version" "version"
@ -115,21 +118,20 @@ if(array_key_exists("prefer-source", $options))
if(array_key_exists("prefer-dist", $options)) if(array_key_exists("prefer-dist", $options))
$preferredInstall = "dist"; $preferredInstall = "dist";
if(array_key_exists("no-dev", $options)) $noDev = array_key_exists("no-dev", $options);
$noDev = true;
else
$noDev = false;
if(array_key_exists("name", $options)) if(array_key_exists("name", $options))
$name = $options["name"]; $name = $options["name"];
else else
$name = null; $name = null;
$executable = array_key_exists("executable", $options);
/* Execute the generator */ /* Execute the generator */
try 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) 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"); $handle = fopen($outputFile, "w");
if($handle === false) if($handle === false)
throw new Exception("Cannot write to: ".$outputFile); 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, "let\n");
fwrite($handle, " dependencies = {\n"); fwrite($handle, " dependencies = {\n");
@ -61,13 +61,29 @@ class Generator
break; break;
case "zip": case "zip":
$hash = shell_exec('nix-prefetch-url "'.$sourceObj['url'].'"');
fwrite($handle, ' "'.$package["name"].'" = composerEnv.buildZipPackage {'."\n"); fwrite($handle, ' "'.$package["name"].'" = composerEnv.buildZipPackage {'."\n");
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\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, ' url = "'.$sourceObj["url"].'";'."\n");
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n"); fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
fwrite($handle, " };\n"); fwrite($handle, " };\n");
}
else
fwrite($handle, " src = ".Generator::composeNixFilePath($sourceObj['url']).";\n");
fwrite($handle, " };\n");
break; break;
case "git": case "git":
$outputStr = shell_exec('nix-prefetch-git "'.$sourceObj['url'].'" '.$sourceObj["reference"]); $outputStr = shell_exec('nix-prefetch-git "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
@ -81,18 +97,29 @@ class Generator
fwrite($handle, ' sha256 = "'.$hash.'";'."\n"); fwrite($handle, ' sha256 = "'.$hash.'";'."\n");
fwrite($handle, " };\n"); fwrite($handle, " };\n");
break; break;
case "hg":
$outputStr = shell_exec('nix-prefetch-hg "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
$output = json_decode($outputStr, true); case "hg":
$hash = $output["sha256"]; $hash = shell_exec('nix-prefetch-hg "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
fwrite($handle, ' "'.$package["name"].'" = fetchhg {'."\n"); fwrite($handle, ' "'.$package["name"].'" = fetchhg {'."\n");
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n"); fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n");
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n"); fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
fwrite($handle, ' rev = "'.$sourceObj["reference"].'";'."\n"); fwrite($handle, ' rev = "'.$sourceObj["reference"].'";'."\n");
fwrite($handle, ' sha256 = "'.$hash.'";'."\n"); fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
fwrite($handle, " };\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: default:
throw new Exception("Cannot convert dependency of type: ".$sourceObj["type"]); throw new Exception("Cannot convert dependency of type: ".$sourceObj["type"]);
} }
@ -103,6 +130,7 @@ class Generator
fwrite($handle, "composerEnv.buildPackage {\n"); fwrite($handle, "composerEnv.buildPackage {\n");
fwrite($handle, ' name = "'.$name.'";'."\n"); fwrite($handle, ' name = "'.$name.'";'."\n");
fwrite($handle, " src = ./.;\n"); fwrite($handle, " src = ./.;\n");
fwrite($handle, " executable = ".($executable ? "true" : "false").";\n");
fwrite($handle, " inherit dependencies;\n"); fwrite($handle, " inherit dependencies;\n");
fwrite($handle, "}\n"); fwrite($handle, "}\n");
@ -127,13 +155,13 @@ class Generator
fwrite($handle, "in\n"); fwrite($handle, "in\n");
fwrite($handle, "import ".Generator::composeNixFilePath($outputFile)." {\n"); fwrite($handle, "import ".Generator::composeNixFilePath($outputFile)." {\n");
fwrite($handle, " inherit composerEnv;\n"); fwrite($handle, " inherit composerEnv;\n");
fwrite($handle, " inherit (pkgs) fetchgit;\n"); fwrite($handle, " inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn;\n");
fwrite($handle, "}\n"); fwrite($handle, "}\n");
fclose($handle); 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 */ /* Open the composer.json file and decode it */
$composerJSONStr = file_get_contents($configFile); $composerJSONStr = file_get_contents($configFile);
@ -183,7 +211,7 @@ class Generator
$packages = array(); $packages = array();
/* Generate packages expression */ /* Generate packages expression */
Generator::generatePackagesExpression($outputFile, $name, $preferredInstall, $packages); Generator::generatePackagesExpression($outputFile, $name, $preferredInstall, $packages, $executable);
/* Generate composition expression */ /* Generate composition expression */
Generator::generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile); Generator::generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile);

View file

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