php-makephar/src/MakePhar/PharBuilder.php

154 lines
4.7 KiB
PHP

<?php
namespace MakePhar;
class PharBuilder
{
protected $tempFile;
protected $manifest;
protected $files = [];
protected $phar;
public function __construct(Manifest $manifest)
{
$this->manifest = $manifest;
}
/**
* Collect files and prepare to build the .phar
*
*/
public function prepare()
{
log_debug("Finding files to add...");
$this->files = $this->manifest->findSourceFiles();
log_debug("Found %d files", count($this->files));
$this->tempFile = "/tmp/".uniqid("phar").".phar";
}
/**
* Build the .phar archive
*
*/
public function build()
{
// Create the phar
$phar = new \Phar($this->tempFile);
// verbatim add
$verbatim = $this->manifest->getVerbatim();
if ($verbatim) {
log_debug("Note: Creating verbatim archive without minification");
}
// Add files
log_debug("Adding files to phar archive...");
$t = count($this->files); $i = 0; $lp = null;
$phar->startBuffering();
$size_tot = 0; $size_min = 0;
foreach ($this->files as $file) {
$i++;
$tp = dirname($file->dest);
if (($tp!=$lp) && (IS_TTY)) {
$lp=$tp;
printf("\r\e[K%d/%d %s", $i, $t, $tp);
}
$size_tot += filesize($file->src);
if (fnmatch("*.php",$file->src) && (!$file->verbatim)) {
$min = php_strip_whitespace($file->src);
$size_min += strlen($min);
$phar->addFromString($file->dest?:$file->src, $min);
} else {
$size_min += filesize($file->src);
$phar->addFile($file->src, $file->dest);
}
}
(IS_TTY) && printf("\r\e[K");
$phar->stopBuffering();
// Helper to format sizes
$formatSize = function ($s) {
$u = [ 'B', 'KB', 'MB', 'GB' ];
while (count($u)>1 && ($s > 1024)) { $s /= 1024; array_shift($u); }
return sprintf("%.2f%s", $s, array_shift($u));
};
// Format the status
$str_tot = $formatSize($size_tot);
if (!$verbatim) {
$str_min = $formatSize($size_min);
$str_rat = sprintf("%.2f%%", 100/$size_tot*$size_min);
log_debug("Size: %s, Minified: %s (%s)", $str_tot, $str_min, $str_rat);
} else {
log_debug("Size: %s", $str_tot);
}
// Create stub
if ($this->manifest->getIsLibrary()) {
log_debug("Creating library stub...");
// Create library stub
$stub = '<?php ';
$stub.= 'file_exists(__DIR__."/vendor/autoload.php") && require_once __DIR__."/vendor/autoload.php";';
foreach ($this->manifest->getProps() as $k=>$v) {
$stub.= sprintf('define(%s,%s);', var_export($k,true), var_export($v,true));
}
if (($stubfile = $this->manifest->getStubFile())) {
$stub.= 'require_once __DIR__."/'.ltrim($stubfile,'/').'";';
}
$phar->addFromString("index.php", $stub);
} else {
log_debug("Creating application stub...");
// Write application stub
$stubfile = $this->manifest->getStubFile();
$stub = '<?php ';
foreach ($this->manifest->getProps() as $k=>$v) {
$stub.= sprintf('define(%s,%s);', var_export($k,true), var_export($v,true));
}
$stub.= 'require_once __DIR__."/'.ltrim($stubfile,'/').'";';
$phar->addFromString("index.php", $stub);
// Make the phar stub executable
$mainstub = $phar->createDefaultStub("index.php");
$tmp = "/tmp/".uniqid("stub"); file_put_contents($tmp, $mainstub);
$mainstub = php_strip_whitespace($tmp);
unlink($tmp);
$mainstub = "#!/usr/bin/env php\n{$mainstub}";
$phar->setStub($mainstub);
}
// Write metadata
log_debug("Writing metadata...");
$md = $this->manifest->getMetadata();
foreach ($md as $key=>$value)
log_debug(" meta[{$key}] = {$value}");
$phar->setMetadata($md);
// Close the phar
$phar = null;
}
/**
* Move the built .phar into its target location.
*
*/
public function finalize()
{
$output = $this->manifest->getOutput();
if (file_exists($output)) {
unlink($output);
}
log_info("Writing %s", $output);
rename($this->tempFile, $output);
if (!$this->manifest->getIsLibrary()) {
chmod($output, 0777);
}
}
}