Use PNDP for generating Nix expressions
This commit is contained in:
parent
b12373a127
commit
da4e2d914a
3 changed files with 154 additions and 76 deletions
|
@ -11,6 +11,10 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"require": {
|
||||||
|
"svanderburg/pndp": "0.0.1"
|
||||||
|
},
|
||||||
|
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": { "Composer2Nix\\": "src/Composer2Nix" }
|
"psr-4": { "Composer2Nix\\": "src/Composer2Nix" }
|
||||||
},
|
},
|
||||||
|
|
58
composer.lock
generated
Normal file
58
composer.lock
generated
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "47e170ac01f841e2b8ccd83d2ba65429",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "svanderburg/pndp",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/svanderburg/pndp.git",
|
||||||
|
"reference": "99b0904e0f2efb35b8f012892912e0d171e9c2da"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "path",
|
||||||
|
"url": "https://api.github.com/repos/svanderburg/pndp/zipball/99b0904e0f2efb35b8f012892912e0d171e9c2da",
|
||||||
|
"reference": "99b0904e0f2efb35b8f012892912e0d171e9c2da",
|
||||||
|
"shasum": null
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/pndp-build"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PNDP\\": "src/PNDP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Pkgs\\": "tests/Pkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Sander van der Burg",
|
||||||
|
"email": "svanderburg@gmail.com",
|
||||||
|
"homepage": "http://sandervanderburg.nl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PNDP: An internal DSL for Nix in PHP"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
|
@ -1,23 +1,21 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Composer2Nix;
|
namespace Composer2Nix;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixAttrReference;
|
||||||
|
use PNDP\AST\NixAttrSet;
|
||||||
|
use PNDP\AST\NixExpression;
|
||||||
|
use PNDP\AST\NixFile;
|
||||||
|
use PNDP\AST\NixFunction;
|
||||||
|
use PNDP\AST\NixFunInvocation;
|
||||||
|
use PNDP\AST\NixImport;
|
||||||
|
use PNDP\AST\NixInherit;
|
||||||
|
use PNDP\AST\NixLet;
|
||||||
|
use PNDP\AST\NixNoDefault;
|
||||||
|
use PNDP\AST\NixURL;
|
||||||
|
|
||||||
class Generator
|
class Generator
|
||||||
{
|
{
|
||||||
private static function composeNixFilePath($path)
|
|
||||||
{
|
|
||||||
// Prefix certain relative paths so that they are of the path type in the Nix expression language
|
|
||||||
if((strlen($path) > 0 && substr($path, 0, 1) === "/") || (strlen($path) > 1 && substr($path, 0, 2) === "./") || (strlen($path) > 2 && substr($path, 0, 3) === "../"))
|
|
||||||
$normalizedPath = $path;
|
|
||||||
else
|
|
||||||
$normalizedPath = "./".$path;
|
|
||||||
|
|
||||||
if(strpos($normalizedPath, ' ') === false)
|
|
||||||
return $normalizedPath; // Path names without spaces don't require any escaping
|
|
||||||
else
|
|
||||||
return '/. + "'.$normalizedPath.'"'; // Compose a path containing spaces
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function selectSourceObject($preferredInstall, $package)
|
private static function selectSourceObject($preferredInstall, $package)
|
||||||
{
|
{
|
||||||
if($preferredInstall === "source")
|
if($preferredInstall === "source")
|
||||||
|
@ -40,6 +38,14 @@ class Generator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function prefixRelativePath($target)
|
||||||
|
{
|
||||||
|
if(substr($target, 0, 1) == "/" || substr($target, 0, 2) == "./" || substr($target, 0, 3) == "../")
|
||||||
|
return $target;
|
||||||
|
else
|
||||||
|
return "./".$target;
|
||||||
|
}
|
||||||
|
|
||||||
private static function generatePackagesExpression($outputFile, $name, $preferredInstall, array $packages, $executable)
|
private static function generatePackagesExpression($outputFile, $name, $preferredInstall, array $packages, $executable)
|
||||||
{
|
{
|
||||||
$handle = fopen($outputFile, "w");
|
$handle = fopen($outputFile, "w");
|
||||||
|
@ -47,51 +53,46 @@ class Generator
|
||||||
if($handle === false)
|
if($handle === false)
|
||||||
throw new Exception("Cannot write to: ".$outputFile);
|
throw new Exception("Cannot write to: ".$outputFile);
|
||||||
|
|
||||||
fwrite($handle, "{composerEnv, fetchurl, fetchgit ? null, fetchhg ? null, fetchsvn ? null}:\n\n");
|
$dependencies = array();
|
||||||
fwrite($handle, "let\n");
|
|
||||||
fwrite($handle, " dependencies = {\n");
|
|
||||||
|
|
||||||
foreach($packages as $package)
|
foreach($packages as $package)
|
||||||
{
|
{
|
||||||
fwrite($handle, ' "'.$package["name"].'" = {'."\n");
|
$dependency = array();
|
||||||
|
|
||||||
if(array_key_exists("target-dir", $package))
|
if(array_key_exists("target-dir", $package))
|
||||||
$targetDir = $package["target-dir"];
|
$dependency["targetDir"] = $package["target-dir"];
|
||||||
else
|
else
|
||||||
$targetDir = "";
|
$dependency["targetDir"] = "";
|
||||||
|
|
||||||
fwrite($handle, ' targetDir = "'.$targetDir.'";'."\n");
|
|
||||||
|
|
||||||
$sourceObj = Generator::selectSourceObject($preferredInstall, $package);
|
$sourceObj = Generator::selectSourceObject($preferredInstall, $package);
|
||||||
|
|
||||||
switch($sourceObj["type"])
|
switch($sourceObj["type"])
|
||||||
{
|
{
|
||||||
case "path":
|
case "path":
|
||||||
fwrite($handle, ' src = '.Generator::composeNixFilePath($sourceObj['url']).";\n");
|
$dependency["src"] = new NixFile($sourceObj['url']);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "zip":
|
case "zip":
|
||||||
fwrite($handle, " src = composerEnv.buildZipPackage {\n");
|
|
||||||
|
|
||||||
if($sourceObj["reference"] == "")
|
if($sourceObj["reference"] == "")
|
||||||
$reference = "";
|
$reference = "";
|
||||||
else
|
else
|
||||||
$reference = "-".$sourceObj["reference"];
|
$reference = "-".$sourceObj["reference"];
|
||||||
|
|
||||||
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").$reference.'";'."\n");
|
|
||||||
|
|
||||||
if(substr($sourceObj["url"], 0, 7) === "http://" || substr($sourceObj["url"], 0, 8) === "https://")
|
if(substr($sourceObj["url"], 0, 7) === "http://" || substr($sourceObj["url"], 0, 8) === "https://")
|
||||||
{
|
{
|
||||||
$hash = shell_exec('nix-prefetch-url "'.$sourceObj['url'].'"');
|
$hash = shell_exec('nix-prefetch-url "'.$sourceObj['url'].'"');
|
||||||
fwrite($handle, " src = fetchurl {\n");
|
$src = new NixFunInvocation(new NixFile("fetchurl"), array(
|
||||||
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
|
"url" => new NixURL($sourceObj["url"]),
|
||||||
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
|
"sha256" => substr($hash, 0, -1)
|
||||||
fwrite($handle, " };\n");
|
));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fwrite($handle, " src = ".Generator::composeNixFilePath($sourceObj['url']).";\n");
|
$src = new NixFile($sourceObj['url']);
|
||||||
|
|
||||||
fwrite($handle, " };\n");
|
$dependency["src"] = new NixFunInvocation(new NixExpression("composerEnv.buildZipPackage", array(
|
||||||
|
"name" => strtr($package["name"], "/", "-").$reference,
|
||||||
|
"src" => $src
|
||||||
|
)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "git":
|
case "git":
|
||||||
|
@ -100,52 +101,58 @@ class Generator
|
||||||
$output = json_decode($outputStr, true);
|
$output = json_decode($outputStr, true);
|
||||||
$hash = $output["sha256"];
|
$hash = $output["sha256"];
|
||||||
|
|
||||||
fwrite($handle, " src = fetchgit {\n");
|
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchgit"), array(
|
||||||
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n");
|
"name" => strtr($package["name"], "/", "-").'-'.$sourceObj["reference"],
|
||||||
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
|
"url" => $sourceObj["url"],
|
||||||
fwrite($handle, ' rev = "'.$sourceObj["reference"].'";'."\n");
|
"rev" => $sourceObj["reference"],
|
||||||
fwrite($handle, ' sha256 = "'.$hash.'";'."\n");
|
"sha256" => $hash
|
||||||
fwrite($handle, " };\n");
|
));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "hg":
|
case "hg":
|
||||||
$hash = shell_exec('nix-prefetch-hg "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
$hash = shell_exec('nix-prefetch-hg "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
||||||
|
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchhg"), array(
|
||||||
fwrite($handle, " src = fetchhg {\n");
|
"name" => strtr($package["name"], "/", "-").'-'.$sourceObj["reference"],
|
||||||
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n");
|
"url" => $sourceObj["url"],
|
||||||
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
|
"rev" => $sourceObj["reference"],
|
||||||
fwrite($handle, ' rev = "'.$sourceObj["reference"].'";'."\n");
|
"sha256" => $hash
|
||||||
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
|
));
|
||||||
fwrite($handle, " };\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "svn":
|
case "svn":
|
||||||
$hash = shell_exec('nix-prefetch-svn "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
$hash = shell_exec('nix-prefetch-svn "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
||||||
|
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchsvn"), array(
|
||||||
fwrite($handle, " src = fetchsvn {\n");
|
"name" => strtr($package["name"], "/", "-").'-'.$sourceObj["reference"],
|
||||||
fwrite($handle, ' name = "'.strtr($package["name"], "/", "-").'-'.$sourceObj["reference"].'";'."\n");
|
"url" => $sourceObj["url"],
|
||||||
fwrite($handle, ' url = "'.$sourceObj["url"].'";'."\n");
|
"rev" => $sourceObj["reference"],
|
||||||
fwrite($handle, ' rev = "'.$sourceObj["reference"].'";'."\n");
|
"sha256" => $hash
|
||||||
fwrite($handle, ' sha256 = "'.substr($hash, 0, -1).'";'."\n");
|
));
|
||||||
fwrite($handle, " };\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Cannot convert dependency of type: ".$sourceObj["type"]);
|
throw new Exception("Cannot convert dependency of type: ".$sourceObj["type"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite($handle, " };\n");
|
$dependencies[$package["name"]] = $dependency;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite($handle, " };\n");
|
$expr = new NixFunction(array(
|
||||||
fwrite($handle, "in\n");
|
"composerEnv" => new NixNoDefault(),
|
||||||
fwrite($handle, "composerEnv.buildPackage {\n");
|
"fetchurl" => new NixNoDefault(),
|
||||||
fwrite($handle, ' name = "'.$name.'";'."\n");
|
"fetchgit" => null,
|
||||||
fwrite($handle, " src = ./.;\n");
|
"fetchhg" => null,
|
||||||
fwrite($handle, " executable = ".($executable ? "true" : "false").";\n");
|
"fetchsvn" => null
|
||||||
fwrite($handle, " inherit dependencies;\n");
|
), new NixLet(array(
|
||||||
fwrite($handle, "}\n");
|
"dependencies" => new NixAttrSet($dependencies)
|
||||||
|
), new NixFunInvocation(new NixExpression("composerEnv.buildPackage"), array(
|
||||||
|
"name" => $name,
|
||||||
|
"src" => new NixFile("./."),
|
||||||
|
"executable" => $executable,
|
||||||
|
"dependencies" => new NixInherit()
|
||||||
|
))));
|
||||||
|
|
||||||
|
$exprStr = NixGenerator::phpToNix($expr, true);
|
||||||
|
fwrite($handle, $exprStr);
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,20 +163,29 @@ class Generator
|
||||||
if($handle === false)
|
if($handle === false)
|
||||||
throw new Exception("Cannot write to: ".$compositionFile);
|
throw new Exception("Cannot write to: ".$compositionFile);
|
||||||
|
|
||||||
fwrite($handle, "{ pkgs ? import <nixpkgs> { inherit system; }\n");
|
$expr = new NixFunction(array(
|
||||||
fwrite($handle, ", system ? builtins.currentSystem\n");
|
"pkgs" => new NixFunInvocation(new NixImport(new NixExpression("<nixpkgs>")), array(
|
||||||
fwrite($handle, "}:\n\n");
|
"system" => new NixInherit()
|
||||||
|
)),
|
||||||
fwrite($handle, "let\n");
|
"system" => new NixAttrReference(new NixExpression("builtins"), new NixExpression("currentSystem"))
|
||||||
fwrite($handle, " composerEnv = import ".Generator::composeNixFilePath($composerEnvFile)." {\n");
|
), new NixLet(array(
|
||||||
fwrite($handle, " inherit (pkgs) stdenv writeTextFile fetchurl php unzip;\n");
|
"composerEnv" => new NixFunInvocation(new NixImport(new NixFile(Generator::prefixRelativePath($composerEnvFile))), array(
|
||||||
fwrite($handle, " };\n");
|
"stdenv" => new NixInherit("pkgs"),
|
||||||
fwrite($handle, "in\n");
|
"writeTextFile" => new NixInherit("pkgs"),
|
||||||
fwrite($handle, "import ".Generator::composeNixFilePath($outputFile)." {\n");
|
"fetchurl" => new NixInherit("pkgs"),
|
||||||
fwrite($handle, " inherit composerEnv;\n");
|
"php" => new NixInherit("pkgs"),
|
||||||
fwrite($handle, " inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn;\n");
|
"unzip" => new NixInherit("pkgs")
|
||||||
fwrite($handle, "}\n");
|
))
|
||||||
|
), new NixFunInvocation(new NixImport(new NixFile(Generator::prefixRelativePath($outputFile))), array(
|
||||||
|
"composerEnv" => new NixInherit(),
|
||||||
|
"fetchurl" => new NixInherit("pkgs"),
|
||||||
|
"fetchgit" => new NixInherit("pkgs"),
|
||||||
|
"fetchhg" => new NixInherit("pkgs"),
|
||||||
|
"fetchsvn" => new NixInherit("pkgs")
|
||||||
|
))));
|
||||||
|
|
||||||
|
$exprStr = NixGenerator::phpToNix($expr, true);
|
||||||
|
fwrite($handle, $exprStr);
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue