Make the code structure more modular
This commit is contained in:
parent
4c20068b41
commit
adf0a9c460
11 changed files with 519 additions and 266 deletions
67
src/Composer2Nix/ComposerConfig.php
Normal file
67
src/Composer2Nix/ComposerConfig.php
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ComposerConfig
|
||||||
|
{
|
||||||
|
public $packageName;
|
||||||
|
|
||||||
|
public $packages;
|
||||||
|
|
||||||
|
public $devPackages;
|
||||||
|
|
||||||
|
public $values;
|
||||||
|
|
||||||
|
public function __construct($configFile, $lockFile, $packageName, $noDev)
|
||||||
|
{
|
||||||
|
/* Open the composer.json file and decode it */
|
||||||
|
$composerJSONStr = file_get_contents($configFile);
|
||||||
|
|
||||||
|
if($composerJSONStr === false)
|
||||||
|
throw new Exception("Cannot open contents of: ".$configFile);
|
||||||
|
|
||||||
|
$this->values = json_decode($composerJSONStr, true);
|
||||||
|
|
||||||
|
/* If no package name has been provided, attempt to use the name in the composer config file */
|
||||||
|
if($packageName === null)
|
||||||
|
{
|
||||||
|
if(array_key_exists("name", $this->values))
|
||||||
|
$packageName = $this->values["name"];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("Cannot determine a package name! Either add a name\n".
|
||||||
|
"property to the composer.json file or provide a --name parameter!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->packageName = strtr($packageName, "/", "-"); // replace / by - since / is not allowed in Nix package names
|
||||||
|
|
||||||
|
/* Open the lock file and decode it */
|
||||||
|
|
||||||
|
if(file_exists($lockFile))
|
||||||
|
{
|
||||||
|
$composerLockStr = file_get_contents($lockFile);
|
||||||
|
|
||||||
|
if($composerLockStr === false)
|
||||||
|
throw new Exception("Cannot open contents of: ".$lockFile);
|
||||||
|
|
||||||
|
$lockConfig = json_decode($composerLockStr, true);
|
||||||
|
|
||||||
|
if(array_key_exists("packages", $lockConfig))
|
||||||
|
$this->packages = $lockConfig["packages"];
|
||||||
|
else
|
||||||
|
$this->packages = array();
|
||||||
|
|
||||||
|
if(!$noDev && array_key_exists("packages-dev", $lockConfig))
|
||||||
|
$this->devPackages = $lockConfig["packages-dev"];
|
||||||
|
else
|
||||||
|
$this->devPackages = array();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->packages = array();
|
||||||
|
$this->devPackages = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
73
src/Composer2Nix/Dependencies/Dependency.php
Normal file
73
src/Composer2Nix/Dependencies/Dependency.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Dependencies;
|
||||||
|
use Composer2Nix\NixASTNode;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
abstract class Dependency extends NixASTNode
|
||||||
|
{
|
||||||
|
public $package;
|
||||||
|
|
||||||
|
protected $sourceObj;
|
||||||
|
|
||||||
|
protected function __construct(array $package, array $sourceObj)
|
||||||
|
{
|
||||||
|
$this->package = $package;
|
||||||
|
$this->sourceObj = $sourceObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function selectSourceObject($preferredInstall, array $package)
|
||||||
|
{
|
||||||
|
if($preferredInstall === "source")
|
||||||
|
{
|
||||||
|
if(array_key_exists("source", $package))
|
||||||
|
return $package["source"];
|
||||||
|
else if(array_key_exists("dist", $package))
|
||||||
|
return $package["dist"];
|
||||||
|
else
|
||||||
|
throw new Exception("Encountered a dangling package reference");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(array_key_exists("dist", $package))
|
||||||
|
return $package["dist"];
|
||||||
|
else if(array_key_exists("source", $package))
|
||||||
|
return $package["source"];
|
||||||
|
else
|
||||||
|
throw new Exception("Encountered a dangling package reference");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function constructDependency(array $package, $preferredInstall)
|
||||||
|
{
|
||||||
|
$sourceObj = Dependency::selectSourceObject($preferredInstall, $package);
|
||||||
|
|
||||||
|
switch($sourceObj["type"])
|
||||||
|
{
|
||||||
|
case "path":
|
||||||
|
return new PathDependency($package, $sourceObj);
|
||||||
|
case "zip":
|
||||||
|
return new ZipDependency($package, $sourceObj);
|
||||||
|
case "git":
|
||||||
|
return new GitDependency($package, $sourceObj);
|
||||||
|
case "hg":
|
||||||
|
return new HgDependency($package, $sourceObj);
|
||||||
|
case "svn":
|
||||||
|
return new SVNDependency($package, $sourceObj);
|
||||||
|
default:
|
||||||
|
throw new Exception("Cannot convert dependency of type: ".$sourceObj["type"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
$dependency = array();
|
||||||
|
|
||||||
|
if(array_key_exists("target-dir", $this->package))
|
||||||
|
$dependency["targetDir"] = $this->package["target-dir"];
|
||||||
|
else
|
||||||
|
$dependency["targetDir"] = "";
|
||||||
|
|
||||||
|
return $dependency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
38
src/Composer2Nix/Dependencies/GitDependency.php
Normal file
38
src/Composer2Nix/Dependencies/GitDependency.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Dependencies;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixExpression;
|
||||||
|
use PNDP\AST\NixFunInvocation;
|
||||||
|
|
||||||
|
class GitDependency extends Dependency
|
||||||
|
{
|
||||||
|
public function __construct(array $package, array $sourceObj)
|
||||||
|
{
|
||||||
|
parent::__construct($package, $sourceObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
$dependency = parent::toNixAST();
|
||||||
|
|
||||||
|
$outputStr = shell_exec('nix-prefetch-git "'.$this->sourceObj['url'].'" '.$this->sourceObj["reference"]);
|
||||||
|
|
||||||
|
if($outputStr === false)
|
||||||
|
throw new Exception("Error while invoking nix-prefetch-git");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$output = json_decode($outputStr, true);
|
||||||
|
$hash = $output["sha256"];
|
||||||
|
|
||||||
|
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchgit"), array(
|
||||||
|
"name" => strtr($this->package["name"], "/", "-").'-'.$this->sourceObj["reference"],
|
||||||
|
"url" => $this->sourceObj["url"],
|
||||||
|
"rev" => $this->sourceObj["reference"],
|
||||||
|
"sha256" => $hash
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dependency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
35
src/Composer2Nix/Dependencies/HgDependency.php
Normal file
35
src/Composer2Nix/Dependencies/HgDependency.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Dependencies;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixExpression;
|
||||||
|
use PNDP\AST\NixFunInvocation;
|
||||||
|
|
||||||
|
class HgDependency extends Dependency
|
||||||
|
{
|
||||||
|
public function __construct(array $package, array $sourceObj)
|
||||||
|
{
|
||||||
|
parent::__construct($package, $sourceObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
$dependency = parent::toNixAST();
|
||||||
|
|
||||||
|
$hash = shell_exec('nix-prefetch-hg "'.$this->sourceObj['url'].'" '.$this->sourceObj["reference"]);
|
||||||
|
|
||||||
|
if($hash === false)
|
||||||
|
throw new Exception("Error while invoking nix-prefetch-hg");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchhg"), array(
|
||||||
|
"name" => strtr($package["name"], "/", "-").'-'.$this->sourceObj["reference"],
|
||||||
|
"url" => $this->sourceObj["url"],
|
||||||
|
"rev" => $this->sourceObj["reference"],
|
||||||
|
"sha256" => $hash
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dependency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
20
src/Composer2Nix/Dependencies/PathDependency.php
Normal file
20
src/Composer2Nix/Dependencies/PathDependency.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Dependencies;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixFile;
|
||||||
|
|
||||||
|
class PathDependency extends Dependency
|
||||||
|
{
|
||||||
|
public function __construct(array $package, array $sourceObj)
|
||||||
|
{
|
||||||
|
parent::__construct($package, $sourceObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
$dependency = parent::toNixAST();
|
||||||
|
$dependency["src"] = new NixFile($sourceObj['url']);
|
||||||
|
return $dependency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
35
src/Composer2Nix/Dependencies/SVNDependency.php
Normal file
35
src/Composer2Nix/Dependencies/SVNDependency.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Dependencies;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixExpression;
|
||||||
|
use PNDP\AST\NixFunInvocation;
|
||||||
|
|
||||||
|
class SVNDependency extends Dependency
|
||||||
|
{
|
||||||
|
public function __construct(array $package, array $sourceObj)
|
||||||
|
{
|
||||||
|
parent::__construct($package, $sourceObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
$dependency = parent::toNixAST();
|
||||||
|
|
||||||
|
$hash = shell_exec('nix-prefetch-svn "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
||||||
|
|
||||||
|
if($hash === false)
|
||||||
|
throw new Exception("Error while invoking nix-prefetch-svn");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchsvn"), array(
|
||||||
|
"name" => strtr($package["name"], "/", "-").'-'.$sourceObj["reference"],
|
||||||
|
"url" => $sourceObj["url"],
|
||||||
|
"rev" => $sourceObj["reference"],
|
||||||
|
"sha256" => $hash
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dependency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
55
src/Composer2Nix/Dependencies/ZipDependency.php
Normal file
55
src/Composer2Nix/Dependencies/ZipDependency.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Dependencies;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixExpression;
|
||||||
|
use PNDP\AST\NixFile;
|
||||||
|
use PNDP\AST\NixFunInvocation;
|
||||||
|
use PNDP\AST\NixURL;
|
||||||
|
|
||||||
|
class ZipDependency extends Dependency
|
||||||
|
{
|
||||||
|
public function __construct(array $package, array $sourceObj)
|
||||||
|
{
|
||||||
|
parent::__construct($package, $sourceObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
$dependency = parent::toNixAST();
|
||||||
|
|
||||||
|
if($this->sourceObj["reference"] == "")
|
||||||
|
$reference = "";
|
||||||
|
else
|
||||||
|
$reference = "-".$this->sourceObj["reference"];
|
||||||
|
|
||||||
|
if(substr($this->sourceObj["url"], 0, 7) === "http://" || substr($this->sourceObj["url"], 0, 8) === "https://")
|
||||||
|
{
|
||||||
|
$hash = shell_exec('nix-prefetch-url "'.$this->sourceObj['url'].'"');
|
||||||
|
|
||||||
|
if($hash === null)
|
||||||
|
throw new Exception("Error while invoking nix-prefetch-url");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$src = new NixFunInvocation(new NixFile("fetchurl"), array(
|
||||||
|
"url" => new NixURL($this->sourceObj["url"]),
|
||||||
|
"sha256" => substr($hash, 0, -1)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$src = new NixFile($this->sourceObj['url']);
|
||||||
|
|
||||||
|
$dependency["src"] = new NixFunInvocation(new NixExpression("composerEnv.buildZipPackage"), array(
|
||||||
|
"name" => strtr($this->package["name"], "/", "-").$reference,
|
||||||
|
"src" => $src
|
||||||
|
));
|
||||||
|
|
||||||
|
return $dependency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixExpr($indentLevel, $format)
|
||||||
|
{
|
||||||
|
return NixGenerator::phpToIndentedNix($this->toNixAST(), $indentLevel, $format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
57
src/Composer2Nix/Expressions/CompositionExpression.php
Normal file
57
src/Composer2Nix/Expressions/CompositionExpression.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Expressions;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixAttrReference;
|
||||||
|
use PNDP\AST\NixExpression;
|
||||||
|
use PNDP\AST\NixFunction;
|
||||||
|
use PNDP\AST\NixFunInvocation;
|
||||||
|
use PNDP\AST\NixFile;
|
||||||
|
use PNDP\AST\NixImport;
|
||||||
|
use PNDP\AST\NixInherit;
|
||||||
|
use PNDP\AST\NixLet;
|
||||||
|
use PNDP\AST\NixObject;
|
||||||
|
use Composer2Nix\NixASTNode;
|
||||||
|
|
||||||
|
class CompositionExpression extends NixASTNode
|
||||||
|
{
|
||||||
|
public function __construct($outputFile, $composerEnvFile)
|
||||||
|
{
|
||||||
|
$this->outputFile = $outputFile;
|
||||||
|
$this->composerEnvFile = $composerEnvFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function prefixRelativePath($target)
|
||||||
|
{
|
||||||
|
if(substr($target, 0, 1) == "/" || substr($target, 0, 2) == "./" || substr($target, 0, 3) == "../")
|
||||||
|
return $target;
|
||||||
|
else
|
||||||
|
return "./".$target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
return new NixFunction(array(
|
||||||
|
"pkgs" => new NixFunInvocation(new NixImport(new NixExpression("<nixpkgs>")), array(
|
||||||
|
"system" => new NixInherit()
|
||||||
|
)),
|
||||||
|
"system" => new NixAttrReference(new NixExpression("builtins"), new NixExpression("currentSystem")),
|
||||||
|
"noDev" => false
|
||||||
|
), new NixLet(array(
|
||||||
|
"composerEnv" => new NixFunInvocation(new NixImport(new NixFile($this->prefixRelativePath($this->composerEnvFile))), array(
|
||||||
|
"stdenv" => new NixInherit("pkgs"),
|
||||||
|
"writeTextFile" => new NixInherit("pkgs"),
|
||||||
|
"fetchurl" => new NixInherit("pkgs"),
|
||||||
|
"php" => new NixInherit("pkgs"),
|
||||||
|
"unzip" => new NixInherit("pkgs")
|
||||||
|
))
|
||||||
|
), new NixFunInvocation(new NixImport(new NixFile($this->prefixRelativePath($this->outputFile))), array(
|
||||||
|
"composerEnv" => new NixInherit(),
|
||||||
|
"noDev" => new NixInherit(),
|
||||||
|
"fetchurl" => new NixInherit("pkgs"),
|
||||||
|
"fetchgit" => new NixInherit("pkgs"),
|
||||||
|
"fetchhg" => new NixInherit("pkgs"),
|
||||||
|
"fetchsvn" => new NixInherit("pkgs")
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
102
src/Composer2Nix/Expressions/PackagesExpression.php
Normal file
102
src/Composer2Nix/Expressions/PackagesExpression.php
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
<?php
|
||||||
|
namespace Composer2Nix\Expressions;
|
||||||
|
use Composer2Nix\ComposerConfig;
|
||||||
|
use Composer2Nix\Dependencies\Dependency;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixAttrSet;
|
||||||
|
use PNDP\AST\NixExpression;
|
||||||
|
use PNDP\AST\NixFile;
|
||||||
|
use PNDP\AST\NixFunction;
|
||||||
|
use PNDP\AST\NixFunInvocation;
|
||||||
|
use PNDP\AST\NixInherit;
|
||||||
|
use PNDP\AST\NixLet;
|
||||||
|
use PNDP\AST\NixNoDefault;
|
||||||
|
use PNDP\AST\NixObject;
|
||||||
|
use PNDP\AST\NixURL;
|
||||||
|
use Composer2Nix\NixASTNode;
|
||||||
|
|
||||||
|
class PackagesExpression extends NixASTNode
|
||||||
|
{
|
||||||
|
public $executable;
|
||||||
|
|
||||||
|
public $symlinkDependencies;
|
||||||
|
|
||||||
|
public $config;
|
||||||
|
|
||||||
|
public $preferredInstall;
|
||||||
|
|
||||||
|
public function __construct(ComposerConfig $config, $executable, $symlinkDependencies, $preferredInstall)
|
||||||
|
{
|
||||||
|
$this->executable = $executable;
|
||||||
|
$this->symlinkDependencies = $symlinkDependencies;
|
||||||
|
$this->config = $config;
|
||||||
|
$this->preferredInstall = $preferredInstall;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateDependenciesExpr(array $packages)
|
||||||
|
{
|
||||||
|
$dependencies = array();
|
||||||
|
|
||||||
|
foreach($packages as $package)
|
||||||
|
{
|
||||||
|
$dependency = Dependency::constructDependency($package, $this->preferredInstall);
|
||||||
|
$dependencies[$package["name"]] = $dependency;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NixAttrSet($dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generatePackageMetaDataExpr()
|
||||||
|
{
|
||||||
|
$meta = array();
|
||||||
|
|
||||||
|
if(array_key_exists("homepage", $this->config->values))
|
||||||
|
$meta["homepage"] = new NixURL($this->config->values["homepage"]);
|
||||||
|
|
||||||
|
if(array_key_exists("license", $this->config->values))
|
||||||
|
{
|
||||||
|
if(is_string($this->config->values["license"])) // If the license is a string, just take it
|
||||||
|
$meta["license"] = $this->config->values["license"];
|
||||||
|
else if(is_array($this->config->values["license"])) // If the license is an array, compose a comma , separated string from it
|
||||||
|
{
|
||||||
|
if(count($this->config->values["license"]) > 0)
|
||||||
|
$meta["license"] = $this->config->values["license"][0];
|
||||||
|
|
||||||
|
for($i = 1; $i < count($this->config->values["license"]); $i++)
|
||||||
|
$meta["license"] .= ", ".$this->config->values["license"][$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NixAttrSet($meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generatePackageBuild()
|
||||||
|
{
|
||||||
|
return new NixFunInvocation(new NixExpression("composerEnv.buildPackage"), array(
|
||||||
|
"name" => $this->config->packageName,
|
||||||
|
"src" => new NixFile("./."),
|
||||||
|
"executable" => $this->executable,
|
||||||
|
"packages" => new NixInherit(),
|
||||||
|
"devPackages" => new NixInherit(),
|
||||||
|
"noDev" => new NixInherit(),
|
||||||
|
"symlinkDependencies" => $this->symlinkDependencies,
|
||||||
|
"meta" => $this->generatePackageMetaDataExpr()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toNixAST()
|
||||||
|
{
|
||||||
|
return new NixFunction(array(
|
||||||
|
"composerEnv" => new NixNoDefault(),
|
||||||
|
"fetchurl" => new NixNoDefault(),
|
||||||
|
"fetchgit" => null,
|
||||||
|
"fetchhg" => null,
|
||||||
|
"fetchsvn" => null,
|
||||||
|
"noDev" => false
|
||||||
|
), new NixLet(array(
|
||||||
|
"packages" => $this->generateDependenciesExpr($this->config->packages),
|
||||||
|
"devPackages" => $this->generateDependenciesExpr($this->config->devPackages)
|
||||||
|
), $this->generatePackageBuild()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -2,290 +2,44 @@
|
||||||
namespace Composer2Nix;
|
namespace Composer2Nix;
|
||||||
use Exception;
|
use Exception;
|
||||||
use PNDP\NixGenerator;
|
use PNDP\NixGenerator;
|
||||||
use PNDP\AST\NixAttrReference;
|
use Composer2Nix\Expressions\CompositionExpression;
|
||||||
use PNDP\AST\NixAttrSet;
|
use Composer2Nix\Expressions\PackagesExpression;
|
||||||
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 selectSourceObject($preferredInstall, $package)
|
private static function writeExprToFile($filename, $expr)
|
||||||
{
|
{
|
||||||
if($preferredInstall === "source")
|
$handle = fopen($filename, "w");
|
||||||
{
|
|
||||||
if(array_key_exists("source", $package))
|
|
||||||
return $package["source"];
|
|
||||||
else if(array_key_exists("dist", $package))
|
|
||||||
return $package["dist"];
|
|
||||||
else
|
|
||||||
throw new Exception("Encountered a dangling package reference");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(array_key_exists("dist", $package))
|
|
||||||
return $package["dist"];
|
|
||||||
else if(array_key_exists("source", $package))
|
|
||||||
return $package["source"];
|
|
||||||
else
|
|
||||||
throw new Exception("Encountered a dangling package reference");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 generatePackagesAttrSet(array $packages, $preferredInstall)
|
|
||||||
{
|
|
||||||
$dependencies = array();
|
|
||||||
|
|
||||||
foreach($packages as $package)
|
|
||||||
{
|
|
||||||
$dependency = array();
|
|
||||||
|
|
||||||
if(array_key_exists("target-dir", $package))
|
|
||||||
$dependency["targetDir"] = $package["target-dir"];
|
|
||||||
else
|
|
||||||
$dependency["targetDir"] = "";
|
|
||||||
|
|
||||||
$sourceObj = Generator::selectSourceObject($preferredInstall, $package);
|
|
||||||
|
|
||||||
switch($sourceObj["type"])
|
|
||||||
{
|
|
||||||
case "path":
|
|
||||||
$dependency["src"] = new NixFile($sourceObj['url']);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "zip":
|
|
||||||
if($sourceObj["reference"] == "")
|
|
||||||
$reference = "";
|
|
||||||
else
|
|
||||||
$reference = "-".$sourceObj["reference"];
|
|
||||||
|
|
||||||
if(substr($sourceObj["url"], 0, 7) === "http://" || substr($sourceObj["url"], 0, 8) === "https://")
|
|
||||||
{
|
|
||||||
$hash = shell_exec('nix-prefetch-url "'.$sourceObj['url'].'"');
|
|
||||||
$src = new NixFunInvocation(new NixFile("fetchurl"), array(
|
|
||||||
"url" => new NixURL($sourceObj["url"]),
|
|
||||||
"sha256" => substr($hash, 0, -1)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$src = new NixFile($sourceObj['url']);
|
|
||||||
|
|
||||||
$dependency["src"] = new NixFunInvocation(new NixExpression("composerEnv.buildZipPackage"), array(
|
|
||||||
"name" => strtr($package["name"], "/", "-").$reference,
|
|
||||||
"src" => $src
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "git":
|
|
||||||
$outputStr = shell_exec('nix-prefetch-git "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
|
||||||
|
|
||||||
$output = json_decode($outputStr, true);
|
|
||||||
$hash = $output["sha256"];
|
|
||||||
|
|
||||||
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchgit"), array(
|
|
||||||
"name" => strtr($package["name"], "/", "-").'-'.$sourceObj["reference"],
|
|
||||||
"url" => $sourceObj["url"],
|
|
||||||
"rev" => $sourceObj["reference"],
|
|
||||||
"sha256" => $hash
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "hg":
|
|
||||||
$hash = shell_exec('nix-prefetch-hg "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
|
||||||
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchhg"), array(
|
|
||||||
"name" => strtr($package["name"], "/", "-").'-'.$sourceObj["reference"],
|
|
||||||
"url" => $sourceObj["url"],
|
|
||||||
"rev" => $sourceObj["reference"],
|
|
||||||
"sha256" => $hash
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "svn":
|
|
||||||
$hash = shell_exec('nix-prefetch-svn "'.$sourceObj['url'].'" '.$sourceObj["reference"]);
|
|
||||||
$dependency["src"] = new NixFunInvocation(new NixExpression("fetchsvn"), array(
|
|
||||||
"name" => strtr($package["name"], "/", "-").'-'.$sourceObj["reference"],
|
|
||||||
"url" => $sourceObj["url"],
|
|
||||||
"rev" => $sourceObj["reference"],
|
|
||||||
"sha256" => $hash
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Exception("Cannot convert dependency of type: ".$sourceObj["type"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$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)
|
if($handle === false)
|
||||||
throw new Exception("Cannot write to: ".$outputFile);
|
throw new Exception("Cannot write to: ".$filename);
|
||||||
|
|
||||||
$packagesAttrSet = Generator::generatePackagesAttrSet($packages, $preferredInstall);
|
fwrite($handle, NixGenerator::phpToNix($expr, true));
|
||||||
$devpackagesAttrSet = Generator::generatePackagesAttrSet($devPackages, $preferredInstall);
|
|
||||||
|
|
||||||
/* Compose meta properties */
|
|
||||||
$meta = array();
|
|
||||||
|
|
||||||
if(array_key_exists("homepage", $config))
|
|
||||||
$meta["homepage"] = $config["homepage"];
|
|
||||||
|
|
||||||
if(array_key_exists("license", $config))
|
|
||||||
{
|
|
||||||
if(is_string($config["license"]))
|
|
||||||
$meta["license"] = $config["license"];
|
|
||||||
else if(is_array($config["license"]))
|
|
||||||
{
|
|
||||||
if(count($config["license"]) > 0)
|
|
||||||
$meta["license"] = $config["license"][0];
|
|
||||||
|
|
||||||
for($i = 1; $i < count($config["license"]); $i++)
|
|
||||||
$meta["license"] .= ", ".$config["license"][$i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compose package function invocation */
|
|
||||||
$expr = new NixFunction(array(
|
|
||||||
"composerEnv" => new NixNoDefault(),
|
|
||||||
"fetchurl" => new NixNoDefault(),
|
|
||||||
"fetchgit" => null,
|
|
||||||
"fetchhg" => null,
|
|
||||||
"fetchsvn" => null,
|
|
||||||
"noDev" => false
|
|
||||||
), new NixLet(array(
|
|
||||||
"packages" => $packagesAttrSet,
|
|
||||||
"devPackages" => $devpackagesAttrSet
|
|
||||||
), new NixFunInvocation(new NixExpression("composerEnv.buildPackage"), array(
|
|
||||||
"name" => $name,
|
|
||||||
"src" => new NixFile("./."),
|
|
||||||
"executable" => $executable,
|
|
||||||
"packages" => new NixInherit(),
|
|
||||||
"devPackages" => new NixInherit(),
|
|
||||||
"noDev" => new NixInherit(),
|
|
||||||
"symlinkDependencies" => $symlinkDependencies,
|
|
||||||
"meta" => new NixAttrSet($meta)
|
|
||||||
))));
|
|
||||||
|
|
||||||
$exprStr = NixGenerator::phpToNix($expr, true);
|
|
||||||
fwrite($handle, $exprStr);
|
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function generatePackagesExpression($outputFile, ComposerConfig $config, $executable, $symlinkDependencies, $preferredInstall)
|
||||||
|
{
|
||||||
|
Generator::writeExprToFile($outputFile, new PackagesExpression($config, $executable, $symlinkDependencies, $preferredInstall));
|
||||||
|
}
|
||||||
|
|
||||||
private static function generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile)
|
private static function generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile)
|
||||||
{
|
{
|
||||||
$handle = fopen($compositionFile, "w");
|
Generator::writeExprToFile($compositionFile, new CompositionExpression($outputFile, $composerEnvFile));
|
||||||
|
}
|
||||||
|
|
||||||
if($handle === false)
|
private static function copyComposerEnv($composerEnvFile, $noCopyComposerEnv)
|
||||||
throw new Exception("Cannot write to: ".$compositionFile);
|
{
|
||||||
|
if(!$noCopyComposerEnv && !copy(dirname(__FILE__)."/composer-env.nix", $composerEnvFile))
|
||||||
$expr = new NixFunction(array(
|
throw new Exception("Cannot copy composer-env.nix to".$composerEnvFile);
|
||||||
"pkgs" => new NixFunInvocation(new NixImport(new NixExpression("<nixpkgs>")), array(
|
|
||||||
"system" => new NixInherit()
|
|
||||||
)),
|
|
||||||
"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"),
|
|
||||||
"writeTextFile" => new NixInherit("pkgs"),
|
|
||||||
"fetchurl" => new NixInherit("pkgs"),
|
|
||||||
"php" => new NixInherit("pkgs"),
|
|
||||||
"unzip" => new NixInherit("pkgs")
|
|
||||||
))
|
|
||||||
), 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"),
|
|
||||||
"fetchsvn" => new NixInherit("pkgs")
|
|
||||||
))));
|
|
||||||
|
|
||||||
$exprStr = NixGenerator::phpToNix($expr, true);
|
|
||||||
fwrite($handle, $exprStr);
|
|
||||||
fclose($handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function generateNixExpressions($name, $executable, $preferredInstall, $noDev, $configFile, $lockFile, $outputFile, $compositionFile, $composerEnvFile, $noCopyComposerEnv, $symlinkDependencies)
|
public static function generateNixExpressions($name, $executable, $preferredInstall, $noDev, $configFile, $lockFile, $outputFile, $compositionFile, $composerEnvFile, $noCopyComposerEnv, $symlinkDependencies)
|
||||||
{
|
{
|
||||||
/* Open the composer.json file and decode it */
|
$config = new ComposerConfig($configFile, $lockFile, $name, $noDev);
|
||||||
$composerJSONStr = file_get_contents($configFile);
|
Generator::generatePackagesExpression($outputFile, $config, $executable, $symlinkDependencies, $preferredInstall);
|
||||||
|
|
||||||
if($composerJSONStr === false)
|
|
||||||
throw new Exception("Cannot open contents of: ".$configFile);
|
|
||||||
|
|
||||||
$config = json_decode($composerJSONStr, true);
|
|
||||||
|
|
||||||
/* If no package name has been provided, attempt to use the name in the composer config file */
|
|
||||||
if($name === null)
|
|
||||||
{
|
|
||||||
if(array_key_exists("name", $config))
|
|
||||||
$name = $config["name"];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Cannot determine a package name! Either add a name\n".
|
|
||||||
"property to the composer.json file or provide a --name parameter!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = strtr($name, "/", "-"); // replace / by - since / is not allowed in Nix package names
|
|
||||||
|
|
||||||
/* Open the lock file and decode it */
|
|
||||||
|
|
||||||
if(file_exists($lockFile))
|
|
||||||
{
|
|
||||||
$composerLockStr = file_get_contents($lockFile);
|
|
||||||
|
|
||||||
if($composerLockStr === false)
|
|
||||||
throw new Exception("Cannot open contents of: ".$lockFile);
|
|
||||||
|
|
||||||
$lockConfig = json_decode($composerLockStr, true);
|
|
||||||
|
|
||||||
if(array_key_exists("packages", $lockConfig))
|
|
||||||
$packages = $lockConfig["packages"];
|
|
||||||
else
|
|
||||||
$packages = array();
|
|
||||||
|
|
||||||
if(!$noDev && array_key_exists("packages-dev", $lockConfig))
|
|
||||||
$devPackages = $lockConfig["packages-dev"];
|
|
||||||
else
|
|
||||||
$devPackages = array();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$packages = array();
|
|
||||||
$devPackages = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate packages expression */
|
|
||||||
Generator::generatePackagesExpression($config, $outputFile, $name, $preferredInstall, $packages, $devPackages, $executable, $symlinkDependencies);
|
|
||||||
|
|
||||||
/* Generate composition expression */
|
|
||||||
Generator::generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile);
|
Generator::generateCompositionExpression($compositionFile, $outputFile, $composerEnvFile);
|
||||||
|
Generator::copyComposerEnv($composerEnvFile, $noCopyComposerEnv);
|
||||||
/* Copy composer-env.nix */
|
|
||||||
if(!$noCopyComposerEnv && !copy(dirname(__FILE__)."/composer-env.nix", $composerEnvFile))
|
|
||||||
throw new Exception("Cannot copy composer-env.nix!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
17
src/Composer2Nix/NixASTNode.php
Normal file
17
src/Composer2Nix/NixASTNode.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
// TODO: move to PNDP
|
||||||
|
|
||||||
|
namespace Composer2Nix;
|
||||||
|
use PNDP\NixGenerator;
|
||||||
|
use PNDP\AST\NixObject;
|
||||||
|
|
||||||
|
abstract class NixASTNode extends NixObject
|
||||||
|
{
|
||||||
|
abstract public function toNixAST();
|
||||||
|
|
||||||
|
public function toNixExpr($indentLevel, $format)
|
||||||
|
{
|
||||||
|
return NixGenerator::phpToIndentedNix($this->toNixAST(), $indentLevel, $format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
Loading…
Reference in a new issue