Initial commit of new codebase
This commit is contained in:
		
							
								
								
									
										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); }
 | 
			
		||||
		Reference in New Issue
	
	Block a user