Ejemplo n.º 1
0
 public function execute($pharFile = 'output.phar')
 {
     if (!extension_loaded('json')) {
         throw new RuntimeException('json extension is required.');
     }
     // $composerConfigFile is a SplFileInfo object since wuse ->isa('file')
     $composerConfigFile = $this->options->{'composer'} ?: 'composer.json';
     if (!file_exists($composerConfigFile)) {
         throw new Exception("composer config '{$composerConfigFile}' doesn't exist.");
     }
     $composerConfigFile = new SplFileInfo(realpath($composerConfigFile));
     $this->logger->debug("Found composer config at {$composerConfigFile}");
     // workingDir is a SplFileInfo object since we use ->isa('Dir')
     $workingDir = $this->options->{'working-dir'} ?: new SplFileInfo($composerConfigFile->getPath());
     if (!file_exists($workingDir)) {
         throw new Exception("working directory '{$workingDir}' doesn't exist.");
     }
     $this->logger->debug('Working directory: ' . $workingDir->getPathname());
     $vendorDirName = $this->options->vendor ?: 'vendor';
     $pharGenerator = new PharGenerator($this->logger, $this->options, $pharFile);
     $phar = $pharGenerator->getPhar();
     ini_set('phar.readonly', 0);
     $this->logger->info("Creating phar file {$pharFile}...");
     $phar->startBuffering();
     $stubs = new Block();
     if ($this->options->executable) {
         $this->logger->debug('Adding shell bang...');
         $stubs[] = '#!/usr/bin/env php';
     }
     // prepend open tag
     $stubs[] = '<?php';
     $this->logger->info('Setting up stub...');
     $stubs[] = "Phar::mapPhar('{$pharFile}');";
     // $workingDir = dirname(realpath($composerConfigFile));
     // Get class paths by ReflectionClass, they should be relative path.
     // However the class path might be in another directory because the
     // classes are loaded from vendor/autoload.php
     $classPaths = array(Utils::getClassPath('Universal\\ClassLoader\\ClassLoader'), Utils::getClassPath('Universal\\ClassLoader\\Psr0ClassLoader'), Utils::getClassPath('Universal\\ClassLoader\\Psr4ClassLoader'), Utils::getClassPath('Universal\\ClassLoader\\MapClassLoader'));
     // Generate class loader stub
     $this->logger->debug('Adding class loader files...');
     foreach ($classPaths as $classPath) {
         $phar->addFile($classPath, basename($classPath));
     }
     /*
             $classDir = dirname($classPaths[0]);
             $phar->buildFromIterator(
        new RecursiveIteratorIterator(new RecursiveDirectoryIterator($classDir)),
        $workingDir
             );
     */
     foreach ($classPaths as $classPath) {
         $this->logger->debug('Adding require statment for class loader: ' . basename($classPath));
         $stubs[] = new RequireStatement(new PharURI($pharFile, basename($classPath)));
     }
     if (!$this->options->{'no-classloader'}) {
         $this->logger->info('Generating classLoader stubs');
         $autoloadGenerator = new ComposerAutoloadGenerator($this->logger);
         $autoloadGenerator->setVendorDir('vendor');
         $autoloadGenerator->setWorkingDir($workingDir->getPathname());
         $autoloadGenerator->scanComposerJsonFiles($workingDir . DIRECTORY_SEPARATOR . $vendorDirName);
         $autoloads = $autoloadGenerator->traceAutoloadsWithComposerJson($composerConfigFile, $workingDir . DIRECTORY_SEPARATOR . $vendorDirName, true);
         foreach ($autoloads as $packageName => $config) {
             if (!isset($config['autoload'])) {
                 continue;
             }
             $autoload = $config['autoload'];
             if (!isset($config['root'])) {
                 $autoload = $autoloadGenerator->prependAutoloadPathPrefix($autoload, $vendorDirName . DIRECTORY_SEPARATOR . $packageName . DIRECTORY_SEPARATOR);
             }
             foreach ($autoload as $type => $map) {
                 foreach ($map as $mapPaths) {
                     $paths = (array) $mapPaths;
                     foreach ($paths as $path) {
                         $absolutePath = $workingDir . DIRECTORY_SEPARATOR . $path;
                         if (is_dir($absolutePath)) {
                             $this->logger->debug("Add files from directory {$absolutePath} under {$workingDir}");
                             $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($absolutePath, FilesystemIterator::SKIP_DOTS));
                             foreach ($it as $fileinfo) {
                                 $pathName = $fileinfo->getPathname();
                                 if (preg_match('/(\\.(?:git|svn|hg)|Tests|Test\\.php)/', $pathName)) {
                                     continue;
                                 }
                                 $localPath = str_replace($workingDir . DIRECTORY_SEPARATOR, '', $pathName);
                                 $this->logger->debug("Adding {$localPath}");
                                 $phar->addFile($pathName, $localPath);
                             }
                             /*
                             $builtFiles = $phar->buildFromIterator(
                                 new RecursiveIteratorIterator(
                                     new RecursiveDirectoryIterator($absolutePath, FilesystemIterator::SKIP_DOTS)
                                 ),
                                 $workingDir
                             );
                             */
                         } elseif (is_file($absolutePath)) {
                             $this->logger->debug("Add file {$absolutePath} under {$path}");
                             $phar->addFile($absolutePath, $path);
                         } else {
                             $this->logger->error("File '{$absolutePath}' is not found.");
                         }
                     }
                 }
             }
         }
         $classloaderStub = $autoloadGenerator->generate($composerConfigFile, $pharFile);
         $this->logger->debug('ClassLoader stub:');
         $this->logger->debug($classloaderStub);
         $stubs[] = $autoloadGenerator->generate($composerConfigFile, $pharFile);
     }
     if ($bootstraps = $this->options->bootstrap) {
         foreach ($bootstraps as $bootstrap) {
             $this->logger->info("Adding bootstrap: {$bootstrap}");
             $content = php_strip_whitespace($bootstrap);
             $content = preg_replace('{^#!/usr/bin/env\\s+php\\s*}', '', $content);
             $localPath = str_replace($workingDir->getPathname(), '', $bootstrap->getRealPath());
             $phar->addFromString($localPath, $content);
             $stubs[] = new RequireStatement(new PharURI($pharFile, $localPath));
         }
     }
     if ($this->options->{'app-bootstrap'}) {
         $app = $this->getApplication();
         $refObject = new ReflectionObject($app);
         $appClassName = $refObject->getName();
         $block = new Block();
         $block[] = new AssignStatement('$app', new NewObjectExpr($appClassName));
         $block[] = new MethodCallStatement('$app', 'run', array('$argv'));
         $stubs[] = $block;
     }
     $stubs[] = '__HALT_COMPILER();';
     $stubstr = $stubs->render();
     $this->logger->debug($stubstr);
     $phar->setStub($stubstr);
     // Add some extra files in phar's root
     if ($adds = $this->options->add) {
         foreach ($adds as $add) {
             $phar->buildFromIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($add)), $workingDir);
         }
     }
     $pharGenerator->generate();
     $this->logger->info('Done');
 }