Initial commit of new codebase
This commit is contained in:
commit
00ebb6ff95
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
vendor
|
||||
composer.lock
|
||||
makephar.phar
|
4
bin/makephar
Executable file
4
bin/makephar
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
require_once __DIR__."/../src/bootstrap.php";
|
22
composer.json
Normal file
22
composer.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "noccylabs/makephar",
|
||||
"description": "Build portable phar executables and libraries",
|
||||
"type": "application",
|
||||
"license": "GPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christopher Vagnetoft",
|
||||
"email": "cvagnetoft@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"noccylabs/sdl": "^2.0",
|
||||
"symfony/finder": "^3.2"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [ "src/global.php" ],
|
||||
"psr-0":{
|
||||
"": "src/"
|
||||
}
|
||||
}
|
||||
}
|
19
makephar.sdl
Normal file
19
makephar.sdl
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
phar "makephar.phar" {
|
||||
|
||||
// Set to true to build a library-only phar
|
||||
library false;
|
||||
|
||||
// Set to 1, 2 or 3 to compress, doesn't work for libraries
|
||||
compress false;
|
||||
|
||||
// Set stub
|
||||
stub "src/bootstrap.php";
|
||||
|
||||
// Select files/dirs to include
|
||||
include {
|
||||
dir "vendor";
|
||||
dir "src";
|
||||
}
|
||||
|
||||
}
|
65
src/MakePhar/Application.php
Normal file
65
src/MakePhar/Application.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace MakePhar;
|
||||
|
||||
class Application
|
||||
{
|
||||
|
||||
protected $config;
|
||||
|
||||
private function parseCommandLine()
|
||||
{
|
||||
$opts = "h";
|
||||
$long = [ 'help' ];
|
||||
|
||||
$parsed = getopt($opts, $long);
|
||||
$config = [
|
||||
'help' => false,
|
||||
'manifest' => getcwd()."/makephar.sdl",
|
||||
'output' => null,
|
||||
'compress' => false,
|
||||
];
|
||||
|
||||
foreach ($parsed as $k=>$v) switch ($k) {
|
||||
case 'h':
|
||||
case 'help':
|
||||
$config['help'] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->config = (object)$config;
|
||||
}
|
||||
|
||||
private function printHelp()
|
||||
{
|
||||
printf("Usage: makephar [opts]\n");
|
||||
printf("Options: -h,--help Show this help\n");
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->parseCommandLine();
|
||||
|
||||
if ($this->config->help) {
|
||||
$this->printHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->buildManifest();
|
||||
}
|
||||
|
||||
protected function buildManifest()
|
||||
{
|
||||
$manifests = Manifest::createFromFile($this->config->manifest);
|
||||
|
||||
foreach ($manifests as $manifest) {
|
||||
log_info("Building %s", $manifest->getOutput());
|
||||
$builder = new PharBuilder($manifest);
|
||||
$builder->prepare();
|
||||
$builder->build();
|
||||
$builder->finalize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
154
src/MakePhar/Manifest.php
Normal file
154
src/MakePhar/Manifest.php
Normal file
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace MakePhar;
|
||||
|
||||
use Sdl\Parser\SdlParser;
|
||||
use Sdl\SdlTag;
|
||||
|
||||
class Manifest
|
||||
{
|
||||
/** @var string Output filename */
|
||||
protected $output = null;
|
||||
/** @var int|null Mode to set on output filename */
|
||||
protected $chmod = null;
|
||||
/** @var string[] Included files and directories */
|
||||
protected $sources = [];
|
||||
/** @var bool If true, build a library instead of executable */
|
||||
protected $library = false;
|
||||
/** @var string|null The stub to call on */
|
||||
protected $stub = null;
|
||||
/** @var bool If true, the archive will be compressed */
|
||||
protected $compress = false;
|
||||
|
||||
/**
|
||||
* Read manifests from a makephar.sdl file and return all the build targets
|
||||
* defined in it.
|
||||
*
|
||||
* @return Manifest[] The parsed manifests
|
||||
*/
|
||||
public static function createFromFile($filename)
|
||||
{
|
||||
$root = SdlParser::parseFile($filename);
|
||||
$ret = [];
|
||||
foreach ($root->getChildren() as $child) {
|
||||
$mf = self::createFromSdlTag($child);
|
||||
$ret[] = $mf;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a manifest from a SdlTag
|
||||
*
|
||||
* @return Manifest The manifest
|
||||
*/
|
||||
public static function createFromSdlTag(SdlTag $tag)
|
||||
{
|
||||
$mf = new Manifest();
|
||||
|
||||
// Output
|
||||
$mf->setOutput($tag->getValue());
|
||||
|
||||
foreach ($tag->getChildren() as $child) switch ($child->getTagName()) {
|
||||
case 'library':
|
||||
$mf->setIsLibrary($child->getValue());
|
||||
break;
|
||||
case 'compress':
|
||||
$mf->setCompression($child->getValue());
|
||||
break;
|
||||
case 'stub':
|
||||
$mf->setStubFile($child->getValue());
|
||||
break;
|
||||
case 'include':
|
||||
foreach ($child->getChildren() as $inc) switch ($inc->getTagName()) {
|
||||
case 'dir':
|
||||
case 'file':
|
||||
$mf->addSource($inc->getTagName(),$inc->getValue(),$inc->getAttributeStrings());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $mf;
|
||||
}
|
||||
|
||||
|
||||
public function setOutput($output)
|
||||
{
|
||||
$this->output = $output;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
public function setIsLibrary($value)
|
||||
{
|
||||
$this->library = (bool)$value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsLibrary()
|
||||
{
|
||||
return $this->library;
|
||||
}
|
||||
|
||||
public function setStubFile($file)
|
||||
{
|
||||
$this->stub = $file;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStubFile()
|
||||
{
|
||||
return $this->stub;
|
||||
}
|
||||
|
||||
public function setCompression($value)
|
||||
{
|
||||
$this->compress = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCompression()
|
||||
{
|
||||
return $this->compress;
|
||||
}
|
||||
|
||||
public function addSource($type, $path, array $opts)
|
||||
{
|
||||
$this->sources[] = (object)[
|
||||
'type' => $type,
|
||||
'path' => $path,
|
||||
'opts' => (object)$opts,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSources()
|
||||
{
|
||||
return $this->sources;
|
||||
}
|
||||
|
||||
public function findSourceFiles()
|
||||
{
|
||||
$items = [];
|
||||
foreach ($this->sources as $source) {
|
||||
if ($source->type == 'dir') {
|
||||
$it = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source->path));
|
||||
foreach ($it as $item) {
|
||||
if ($item->isDir()) continue;
|
||||
$items[] = (object)['src'=>$item->getPathname(),'dest'=>null];
|
||||
}
|
||||
} elseif ($source->type == 'file') {
|
||||
$items[] = (object)['src'=>$source->path,'dest'=>null];
|
||||
} else {
|
||||
log_warn("Unsupported source type: %s", $source->type);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
77
src/MakePhar/PharBuilder.php
Normal file
77
src/MakePhar/PharBuilder.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace MakePhar;
|
||||
|
||||
class PharBuilder
|
||||
{
|
||||
|
||||
protected $manifest;
|
||||
|
||||
protected $files = [];
|
||||
|
||||
protected $phar;
|
||||
|
||||
public function __construct(Manifest $manifest)
|
||||
{
|
||||
$this->manifest = $manifest;
|
||||
}
|
||||
|
||||
public function prepare()
|
||||
{
|
||||
log_debug("Finding files to add...");
|
||||
$this->files = $this->manifest->findSourceFiles();
|
||||
log_debug("Found %d files", count($this->files));
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
// Create the phar
|
||||
$phar = new \Phar("/tmp/output.phar");
|
||||
|
||||
// Add files
|
||||
log_debug("Adding files to phar archive...");
|
||||
foreach ($this->files as $file) {
|
||||
$phar->addFile($file->dest?:$file->src, $file->src);
|
||||
}
|
||||
|
||||
// Create stub
|
||||
if ($this->manifest->getIsLibrary()) {
|
||||
log_debug("Creating library stub...");
|
||||
// Create library stub
|
||||
$stub = '<?php ';
|
||||
$stub.= 'if (basename(__FILE__)==basename($_SERVER["SCRIPT_FILENAME"])) { echo "Error: This is a library and can not be executed\n"; exit(1); }';
|
||||
$stub.= 'require_once __DIR__."/vendor/autoload.php";';
|
||||
$phar->addFromString("index.php", $stub);
|
||||
} else {
|
||||
log_debug("Creating application stub...");
|
||||
// Write application stub
|
||||
$stubfile = $this->manifest->getStubFile();
|
||||
$stub = '<?php require_once __DIR__."/'.ltrim($stubfile,'/').'";';
|
||||
$phar->addFromString("index.php", $stub);
|
||||
// Make the phar stub executable
|
||||
$mainstub = $phar->createDefaultStub("index.php");
|
||||
$mainstub = "#!/usr/bin/env php\n{$mainstub}";
|
||||
$phar->setStub($mainstub);
|
||||
}
|
||||
|
||||
// Close the phar
|
||||
$phar = null;
|
||||
}
|
||||
|
||||
public function finalize()
|
||||
{
|
||||
$output = $this->manifest->getOutput();
|
||||
|
||||
if (file_exists($output)) {
|
||||
unlink($output);
|
||||
}
|
||||
log_debug("Writing %s", $output);
|
||||
rename("/tmp/output.phar", $output);
|
||||
|
||||
if (!$this->manifest->getIsLibrary()) {
|
||||
chmod($output, 0777);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
6
src/bootstrap.php
Normal file
6
src/bootstrap.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__."/../vendor/autoload.php";
|
||||
|
||||
$app = new MakePhar\Application();
|
||||
$app->run();
|
11
src/global.php
Normal file
11
src/global.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class LogFuncs {
|
||||
public static function bind() {
|
||||
static $bound;
|
||||
if ($bound++) return;
|
||||
}
|
||||
}
|
||||
function log_info($fmt,...$arg) { printf("[info] {$fmt}\n", ...$arg); }
|
||||
function log_debug($fmt,...$arg) { printf("[debg] {$fmt}\n", ...$arg); }
|
||||
function log_warn($fmt,...$arg) { printf("[warn] {$fmt}\n", ...$arg); }
|
Loading…
Reference in New Issue
Block a user