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 = '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 = '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); } } }