/src/Silexor/Compiler.php

https://github.com/benja-M-1/Silexor · PHP · 153 lines · 90 code · 24 blank · 39 comment · 5 complexity · 3d6c03ef908a5717bd92ef6fc516ab3a MD5 · raw file

  1. <?php
  2. /**
  3. * This file is part of the Silexor Project
  4. *
  5. * (c) Benjamin Grandfond <benjamin.grandfond@gmail.com>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. namespace Silexor;
  11. use Symfony\Component\Finder\Finder;
  12. /**
  13. * Compiler class
  14. *
  15. * Partly taken from Composer and Silex compiler class.
  16. * @see https://github.com/composer/composer/blob/master/src/Composer/Compiler.php
  17. * @see https://github.com/fabpot/Silex/blob/master/src/Silex/Compiler.php
  18. *
  19. * @author Benjamin Grandfond <benjaming@theodo.fr>
  20. */
  21. class Compiler
  22. {
  23. public function compile($pharFile = 'silexor.phar')
  24. {
  25. if (file_exists($pharFile)) {
  26. unlink($pharFile);
  27. }
  28. $phar = new \Phar($pharFile, 0, 'silexor.phar');
  29. $phar->setSignatureAlgorithm(\Phar::SHA1);
  30. $phar->startBuffering();
  31. // Add Symfttpd core files.
  32. $finder = new Finder();
  33. $finder->files()
  34. ->ignoreVCS(true)
  35. ->name('*.php')
  36. ->name('*.dist')
  37. ->in(__DIR__.'/..')
  38. ->notName('Compiler.php')
  39. ->exclude('Tests');
  40. foreach ($finder as $file) {
  41. $this->addFile($phar, $file, false);
  42. }
  43. // Add vendors
  44. $finder = new Finder();
  45. $finder->files()
  46. ->ignoreVCS(true)
  47. ->name('*.php')
  48. ->in(__DIR__.'/../../vendor/symfony')
  49. ->in(__DIR__.'/../../vendor/twig')
  50. ->exclude(__DIR__.'/../../vendor/twig/doc')
  51. ->exclude(__DIR__.'/../../vendor/twig/test');
  52. foreach ($finder as $file) {
  53. $this->addFile($phar, $file);
  54. }
  55. // Add Composer generated files.
  56. $this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/autoload.php'));
  57. $this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_namespaces.php'));
  58. $this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_classmap.php'));
  59. $this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/ClassLoader.php'));
  60. $this->addSymfttpdBin($phar);
  61. // Stubs
  62. $phar->setStub($this->getStub());
  63. $phar->stopBuffering();
  64. }
  65. private function addFile(\Phar $phar, $file, $strip = true)
  66. {
  67. $path = str_replace(dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR, '', $file->getRealPath());
  68. $content = file_get_contents($file);
  69. if ($strip) {
  70. $content = $this->stripWhitespace($content);
  71. }
  72. $phar->addFromString($path, $content);
  73. }
  74. private function addSymfttpdBin($phar)
  75. {
  76. $content = file_get_contents(__DIR__.'/../../bin/silexor');
  77. $content = preg_replace('{^#!/usr/bin/env php\s*}', '', $content);
  78. $phar->addFromString('bin/silexor', $content);
  79. }
  80. /**
  81. * Removes whitespace from a PHP source string while preserving line numbers.
  82. *
  83. * @param string $source A PHP string
  84. * @return string The PHP string with the whitespace removed
  85. */
  86. private function stripWhitespace($source)
  87. {
  88. if (!function_exists('token_get_all')) {
  89. return $source;
  90. }
  91. $output = '';
  92. foreach (token_get_all($source) as $token) {
  93. if (is_string($token)) {
  94. $output .= $token;
  95. } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
  96. $output .= str_repeat("\n", substr_count($token[1], "\n"));
  97. } elseif (T_WHITESPACE === $token[0]) {
  98. // reduce wide spaces
  99. $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
  100. // normalize newlines to \n
  101. $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
  102. // trim leading spaces
  103. $whitespace = preg_replace('{\n +}', "\n", $whitespace);
  104. $output .= $whitespace;
  105. } else {
  106. $output .= $token[1];
  107. }
  108. }
  109. return $output;
  110. }
  111. private function getStub()
  112. {
  113. return <<<'EOF'
  114. #!/usr/bin/env php
  115. <?php
  116. /**
  117. * This file is part of the Silexor Project
  118. *
  119. * (c) Benjamin Grandfond <benjamin.grandfond@gmail.com>
  120. *
  121. * This source file is subject to the MIT license that is bundled
  122. * with this source code in the file LICENSE.
  123. */
  124. Phar::mapPhar('silexor.phar');
  125. require 'phar://silexor.phar/bin/silexor';
  126. __HALT_COMPILER();
  127. EOF;
  128. }
  129. }