Initial commit
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					/composer.lock
 | 
				
			||||||
 | 
					/vendor
 | 
				
			||||||
							
								
								
									
										87
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
				
			|||||||
 | 
					PharLite: Easy PHAR generator
 | 
				
			||||||
 | 
					=============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make sure PHP can write PHARs in your `php.ini` before trying anything else.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`composer.json` options
 | 
				
			||||||
 | 
					-----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
 | 
					        "extra": {
 | 
				
			||||||
 | 
					            "phar": {
 | 
				
			||||||
 | 
					                "include": [ ... ],
 | 
				
			||||||
 | 
					                "exclude": [ ... ],
 | 
				
			||||||
 | 
					                "index": "web/index.php",
 | 
				
			||||||
 | 
					                "output": "pharname.phar",
 | 
				
			||||||
 | 
					                "strip": "none",
 | 
				
			||||||
 | 
					                "metadata": { ... },
 | 
				
			||||||
 | 
					                "preload": [ ... ],
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### `include` and `exclude`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Specify additional files or paths to include or exclude.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### `index`: Create a web phar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Specifying this option will automatically opt to create a web phar. The value should
 | 
				
			||||||
 | 
					point to a valid index file or router.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### `output`: Output filename
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Defines the output filename. Defaults to `output.phar`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### `strip`: Trim file sizes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Valid values are `none`, `all` or an array of patterns to match.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "strip": "all"              Strip all files
 | 
				
			||||||
 | 
					    "strip": "none"             Include everything as is (default)
 | 
				
			||||||
 | 
					    "strip": [ "src/*.php" ]    All *.php in src/ and subdirectories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Stripping will remove comments and whitepace in files, which makes them smaller
 | 
				
			||||||
 | 
					but can confuse code that dynamically parses f.ex. docblock comments for routing
 | 
				
			||||||
 | 
					info etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### `metadata`: Phar metadata
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Define additional metadata to write to the phar. The following keys are automatically
 | 
				
			||||||
 | 
					written:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Key                   | Type      | Description                           |
 | 
				
			||||||
 | 
					|:----------------------|:---------:|:-------------------------------------------
 | 
				
			||||||
 | 
					| `phar.generator`      | string    | The string `PharLite/x.y (PHP/x.y)`
 | 
				
			||||||
 | 
					| `phar.type`           | string    | One of `app`, `library` or `web`
 | 
				
			||||||
 | 
					| `package.name`        | string    | The composer package name
 | 
				
			||||||
 | 
					| `package.version`     | string    | The composer package version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### `preload`: Files to preload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined, this should be an array of files to include after `composer.json` in the
 | 
				
			||||||
 | 
					stub.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Building
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To build a phar from a composer project, just run `pharlite`. It will build one of
 | 
				
			||||||
 | 
					the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* **Library phar** - A single file containing a composer library, complete with
 | 
				
			||||||
 | 
					  autoloaders and all that magic.
 | 
				
			||||||
 | 
					* **Application phar** - An executable file containing an application and its
 | 
				
			||||||
 | 
					  dependencies.
 | 
				
			||||||
 | 
					* **Web phar** - A complete website in a single file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If more than one `bin` is defined in the `composer.json`, the first one will be
 | 
				
			||||||
 | 
					the default one, but all defined bins will be available by symlinking the phar
 | 
				
			||||||
 | 
					to the respective names.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "bin": [ "bin/foo", "bin/bar" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    output.phar, foo.phar, foo, hello.phar -> calls bin/foo
 | 
				
			||||||
 | 
					    bar.phar, bar -> calls bin/bar
 | 
				
			||||||
							
								
								
									
										83
									
								
								bin/pharlite
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										83
									
								
								bin/pharlite
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env php
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once __DIR__."/../vendor/autoload.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define("PHARLITE_VERSION", "0.1.x");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (posix_isatty(STDOUT)) {
 | 
				
			||||||
 | 
					  define("FMT_ERR", "\e[31;1m");
 | 
				
			||||||
 | 
					  define("FMT_WARN", "\e[33;1m");
 | 
				
			||||||
 | 
					  define("FMT_INFO", "\e[32m");
 | 
				
			||||||
 | 
					  define("FMT_AFTER", "\e[0m");
 | 
				
			||||||
 | 
					} else {
 | 
				
			||||||
 | 
					  define("FMT_ERR", "");
 | 
				
			||||||
 | 
					  define("FMT_WARN", "");
 | 
				
			||||||
 | 
					  define("FMT_INFO", "");
 | 
				
			||||||
 | 
					  define("FMT_AFTER", "");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function print_error($fmt, ...$arg) {
 | 
				
			||||||
 | 
					  fprintf(STDOUT, FMT_ERR.$fmt."ERROR: ".FMT_AFTER.PHP_EOL, ...$arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function print_warn($fmt, ...$arg) {
 | 
				
			||||||
 | 
					  fprintf(STDOUT, FMT_WARN.$fmt.FMT_AFTER.PHP_EOL, ...$arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function print_info($fmt, ...$arg) {
 | 
				
			||||||
 | 
					  fprintf(STDOUT, FMT_INFO.$fmt.FMT_AFTER.PHP_EOL, ...$arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function show_app_usage() {
 | 
				
			||||||
 | 
					  printf("usage\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function parse_opts() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $opts = getopt(
 | 
				
			||||||
 | 
					    "ho:d:i",
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      "help",
 | 
				
			||||||
 | 
					      "directory:",
 | 
				
			||||||
 | 
					      "dir:",
 | 
				
			||||||
 | 
					      "output:",
 | 
				
			||||||
 | 
					      "install"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $parsed = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  foreach ($opts as $option=>$value) {
 | 
				
			||||||
 | 
					    switch ($option) {
 | 
				
			||||||
 | 
					      case 'h':
 | 
				
			||||||
 | 
					      case 'help':
 | 
				
			||||||
 | 
					        show_app_usage();
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					      case 'd':
 | 
				
			||||||
 | 
					      case 'dir':
 | 
				
			||||||
 | 
					      case 'directory':
 | 
				
			||||||
 | 
					        $parsed['dir'] = $value;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'o':
 | 
				
			||||||
 | 
					      case 'output':
 | 
				
			||||||
 | 
					        $parsed['output'] = $value;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'i':
 | 
				
			||||||
 | 
					      case 'install':
 | 
				
			||||||
 | 
					        $parsed['install'] = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return $parsed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$opts = parse_opts();
 | 
				
			||||||
 | 
					if (false === parse_opts()) {
 | 
				
			||||||
 | 
					  exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$path = getcwd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$builder = new PharLite\Builder($path, $opts);
 | 
				
			||||||
 | 
					$builder->build();
 | 
				
			||||||
							
								
								
									
										13
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "autoload": {
 | 
				
			||||||
 | 
					    "psr-4": {
 | 
				
			||||||
 | 
					      "PharLite\\": "src/"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "require": {
 | 
				
			||||||
 | 
					    "symfony/finder": "^4.0"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "bin": [
 | 
				
			||||||
 | 
					    "bin/pharlite"
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										230
									
								
								src/Builder.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								src/Builder.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,230 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace PharLite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Builder
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const PHAR_TYPE_APP = "app";
 | 
				
			||||||
 | 
					    const PHAR_TYPE_WEB = "web";
 | 
				
			||||||
 | 
					    const PHAR_TYPE_LIB = "lib";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @var string */
 | 
				
			||||||
 | 
					    protected $path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $manifest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $composer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $output;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $pharType = self::PHAR_TYPE_LIB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $pharOpts = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $bins;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static $default_options = [
 | 
				
			||||||
 | 
					        'install' => false,
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct($path=null, array $opts=[])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$path) {
 | 
				
			||||||
 | 
					            $path = getcwd();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!file_exists($path."/composer.json")) {
 | 
				
			||||||
 | 
					            throw new \RuntimeException("Could not find a composer.json in {$path}");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->opts = array_merge(
 | 
				
			||||||
 | 
					            self::$default_options,
 | 
				
			||||||
 | 
					            $opts
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function readComposer()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        print_info("Parsing composer.json...");
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					        $json = file_get_contents("composer.json");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $composer = json_decode($json);      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isset($composer->bin) || !is_array($composer->bin)) {
 | 
				
			||||||
 | 
					            print_warn("No executable defined, building a library phar...");
 | 
				
			||||||
 | 
					        } elseif (count($composer->bin)>1) {
 | 
				
			||||||
 | 
					            print_info("More than one executable defined, using the first one as default");
 | 
				
			||||||
 | 
					            print_info(" → Using executable %s", $composer->bin[0]);
 | 
				
			||||||
 | 
					            $this->bins = $composer->bin;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            print_info(" → Using executable %s", $composer->bin[0]);
 | 
				
			||||||
 | 
					            $this->bins = $composer->bin;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isset($composer->extra) && isset($composer->extra->phar)) {
 | 
				
			||||||
 | 
					            print_info(" → Found extra phar configuration");
 | 
				
			||||||
 | 
					            $this->pharOpts = (array)$composer->extra->phar;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->index) {
 | 
				
			||||||
 | 
					            $this->pharType = self::PHAR_TYPE_WEB;
 | 
				
			||||||
 | 
					            $this->output = basename($this->index,".php").".phar";
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (isset($composer->bin) && is_array($composer->bin)) {
 | 
				
			||||||
 | 
					                $this->pharType = self::PHAR_TYPE_APP;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $this->output = "output.phar";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        print_info("Generating output %s", $this->output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->composer = $composer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					    private function installComposer()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        print_info("Installing dependencies...");
 | 
				
			||||||
 | 
					        passthru("composer install --no-interaction --optimize-autoloader");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function buildManifest()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        print_info("Creating manifest...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $manifest = new Manifest($this->path);
 | 
				
			||||||
 | 
					        // Always include the vendor directory
 | 
				
			||||||
 | 
					        print_info(" ← vendor/");
 | 
				
			||||||
 | 
					        $manifest->addDirectory("vendor");
 | 
				
			||||||
 | 
					        // Include everything from the autoload
 | 
				
			||||||
 | 
					        if (isset($this->composer->autoload)) {
 | 
				
			||||||
 | 
					            foreach ((array)$this->composer->autoload as $type=>$autoloaders) {
 | 
				
			||||||
 | 
					                if ($type == "files") {
 | 
				
			||||||
 | 
					                    foreach ($autoloaders as $file) {
 | 
				
			||||||
 | 
					                        print_info(" ← %s", $file);
 | 
				
			||||||
 | 
					                        $manifest->addFile($file);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                foreach ($autoloaders as $prefix=>$path) {
 | 
				
			||||||
 | 
					                    print_info(" ← %s", $path);
 | 
				
			||||||
 | 
					                    $manifest->addDirectory($path);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (array_key_exists('include', $this->pharOpts)) {
 | 
				
			||||||
 | 
					            foreach ((array)$this->pharOpts['include'] as $path) {
 | 
				
			||||||
 | 
					                print_info(" ← %s", $path);
 | 
				
			||||||
 | 
					                if (substr($path,-1,1)==DIRECTORY_SEPARATOR) {
 | 
				
			||||||
 | 
					                    $manifest->addDirectory($path);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $manifest->addFile($path);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->manifest = $manifest;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function generateBootstrap(\Phar $phar, $type, $index=null, array $bins=[])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        print_info("Generating bootstrap stub...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$index && count($bins)==0) {
 | 
				
			||||||
 | 
					            $indexFile = '<?php require_once __DIR__."/vendor/autoload.php";';
 | 
				
			||||||
 | 
					        } elseif (count($bins)>1) {
 | 
				
			||||||
 | 
					            $indexFile = '<?php $bin=basename($argv[0],".phar"); switch($bin) {';
 | 
				
			||||||
 | 
					            for ($n = 1; $n<count($bins); $n++) {
 | 
				
			||||||
 | 
					                $indexFile.= 'case '.var_export(basename($bins[$n]),true).': require_once __DIR__."/".'.var_export($bins[$n],true).'; break;';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $indexFile.= 'case '.var_export(basename($bins[0]),true).': default: require_once __DIR__."/".'.var_export($bins[0],true).'; break;';
 | 
				
			||||||
 | 
					            $indexFile.= '}';
 | 
				
			||||||
 | 
					            $index = "bootstrap.php";
 | 
				
			||||||
 | 
					            foreach ($bins as $bin) {
 | 
				
			||||||
 | 
					                $str = file_get_contents($bin);
 | 
				
			||||||
 | 
					                $str = $this->stripShebang($str);
 | 
				
			||||||
 | 
					                $phar->addFromString($bin, $str);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $indexFile = file_get_contents($index);
 | 
				
			||||||
 | 
					            $indexFile = $this->stripShebang($indexFile);
 | 
				
			||||||
 | 
					            $index = "bootstrap.php";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $stub = "#!/usr/bin/env php\n".$phar->createDefaultStub($index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $phar->addFromString($index, $indexFile);
 | 
				
			||||||
 | 
					        $phar->setStub($stub);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function stripShebang($str)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strpos($str, '#!') === 0) {
 | 
				
			||||||
 | 
					            if (strpos($str, '#!/usr/bin/env php') === 0) {
 | 
				
			||||||
 | 
					                $str = substr($str,strpos($str, "<?"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $str;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function writeMetadata(\Phar $phar, array $metadata=[])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $metadata = array_merge([            
 | 
				
			||||||
 | 
					            'phar.generator' => "PharLite/".PHARLITE_VERSION." (PHP/".PHP_VERSION.")",
 | 
				
			||||||
 | 
					            'phar.type' => $this->pharType,
 | 
				
			||||||
 | 
					            'package.name' => isset($this->composer->name)?$this->composer->name:null,
 | 
				
			||||||
 | 
					            'package.version' => isset($this->composer->version)?$this->composer->version:null,
 | 
				
			||||||
 | 
					        ], $metadata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        print_info("Writing metadata:\n%s", json_encode($metadata, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $phar->setMetadata($metadata);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function build()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->readComposer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->opts['install']) {
 | 
				
			||||||
 | 
					            $this->installComposer();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->buildManifest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        print_info("Adding files...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $phar = new \Phar($this->output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = count($this->manifest);
 | 
				
			||||||
 | 
					        $pcf = 100 / $total;
 | 
				
			||||||
 | 
					        $bw = 40;
 | 
				
			||||||
 | 
					        $pbf = $bw / $total;
 | 
				
			||||||
 | 
					        $index = 0;
 | 
				
			||||||
 | 
					        foreach ($this->manifest as $object) {
 | 
				
			||||||
 | 
					            // printf("  %s: %s\n", $object->getFilename(), $object->getLocalName());
 | 
				
			||||||
 | 
					            $object->addToPhar($phar);
 | 
				
			||||||
 | 
					            if (posix_isatty(STDOUT) && ($index++ % 25 == 0)) {
 | 
				
			||||||
 | 
					                $pc = $pcf * $index;
 | 
				
			||||||
 | 
					                $pb = round($pbf * $index);
 | 
				
			||||||
 | 
					                printf("\r[%s%s] %.1f%%", str_repeat("=",$pb), str_repeat(" ",$bw-$pb), $pc);
 | 
				
			||||||
 | 
					            }    
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (posix_isatty(STDOUT)) {
 | 
				
			||||||
 | 
					            printf("\r\e[2K");
 | 
				
			||||||
 | 
					        }    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        print_info("Added %d files!", $index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->generateBootstrap($phar, $this->pharType, $this->index, $this->bins);
 | 
				
			||||||
 | 
					        $this->writeMetadata($phar, (array)(array_key_exists('metadata',$this->pharOpts)?$this->pharOpts['metadata']:[]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        chmod($this->output, 0777);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								src/Manifest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/Manifest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace PharLite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Symfony\Component\Finder\Finder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Manifest implements \IteratorAggregate, \Countable
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /** @var string Root directory of the project being built */
 | 
				
			||||||
 | 
					    protected $root;
 | 
				
			||||||
 | 
					    /** @var ManifestObject[] The included objects */
 | 
				
			||||||
 | 
					    protected $objects = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct($root)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->root = $root;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function addDirectory($path, callable $filter=null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $path = rtrim($path, DIRECTORY_SEPARATOR);
 | 
				
			||||||
 | 
					        $obj = (new Finder)->files()->in($path);
 | 
				
			||||||
 | 
					        foreach ($obj as $o) {
 | 
				
			||||||
 | 
					            if (is_callable($filter) && (false === $filter($o))) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $path = $o->getPathname();
 | 
				
			||||||
 | 
					            $this->addFile($path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function addFile($file)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strpos($file, $this->root) === 0) {
 | 
				
			||||||
 | 
					            $local = substr($file, 0, strlen($this->root));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $local = $file;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->objects[] = new ManifestObject($file, $local);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getIterator()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return new \ArrayIterator($this->objects);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function count()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return count($this->objects);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								src/ManifestObject.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/ManifestObject.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace PharLite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class representing a single object to be added to a phar
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ManifestObject
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $filename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $localname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct($filename, $localname=null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->filename = $filename;
 | 
				
			||||||
 | 
					        $this->localname = $localname;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getFilename()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->filename;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getLocalName()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->localname;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function addToPhar(\Phar $phar)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $phar->addFile(
 | 
				
			||||||
 | 
					            $this->getFilename(), 
 | 
				
			||||||
 | 
					            $this->getLocalName()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function addFiltered(\Phar $phar, callable $filter)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $body = file_get_contents($this->filename);
 | 
				
			||||||
 | 
					        $body = call_user_func($filter, $body);
 | 
				
			||||||
 | 
					        $phar->addFromString($this->getLocalName(), $body);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user