PharPackageTask.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. /*
  3. * $Id: PharPackageTask.php 905 2010-10-05 16:28:03Z mrook $
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://phing.info>.
  20. */
  21. require_once 'phing/tasks/system/MatchingTask.php';
  22. require_once 'phing/tasks/ext/phar/IterableFileSet.php';
  23. require_once 'phing/tasks/ext/phar/PharMetadata.php';
  24. /**
  25. * Package task for {@link http://ru.php.net/manual/en/book.phar.php Phar technology}.
  26. *
  27. * @package phing.tasks.ext
  28. * @author Alexey Shockov <alexey@shockov.com>
  29. * @since 2.4.0
  30. */
  31. class PharPackageTask
  32. extends MatchingTask
  33. {
  34. /**
  35. * @var PhingFile
  36. */
  37. private $destinationFile;
  38. /**
  39. * @var int
  40. */
  41. private $compression = Phar::NONE;
  42. /**
  43. * Base directory, from where local package paths will be calculated.
  44. *
  45. * @var PhingFile
  46. */
  47. private $baseDirectory;
  48. /**
  49. * @var PhingFile
  50. */
  51. private $cliStubFile;
  52. /**
  53. * @var PhingFile
  54. */
  55. private $webStubFile;
  56. /**
  57. * @var string
  58. */
  59. private $stubPath;
  60. /**
  61. * @var int
  62. */
  63. private $signatureAlgorithm = Phar::SHA1;
  64. /**
  65. * @var array
  66. */
  67. private $filesets = array();
  68. /**
  69. * @var PharMetadata
  70. */
  71. private $metadata = null;
  72. /**
  73. * @var string
  74. */
  75. private $alias;
  76. /**
  77. * @return PharMetadata
  78. */
  79. public function createMetadata()
  80. {
  81. return ($this->metadata = new PharMetadata());
  82. }
  83. /**
  84. * @return FileSet
  85. */
  86. public function createFileSet()
  87. {
  88. $this->fileset = new IterableFileSet();
  89. $this->filesets[] = $this->fileset;
  90. return $this->fileset;
  91. }
  92. /**
  93. * @param string $algorithm
  94. */
  95. public function setSignature($algorithm)
  96. {
  97. /*
  98. * If we don't support passed algprithm, leave old one.
  99. */
  100. switch ($algorithm) {
  101. case 'md5':
  102. $this->signatureAlgorithm = Phar::MD5;
  103. break;
  104. case 'sha1':
  105. $this->signatureAlgorithm = Phar::SHA1;
  106. break;
  107. case 'sha256':
  108. $this->signatureAlgorithm = Phar::SHA256;
  109. break;
  110. case 'sha512':
  111. $this->signatureAlgorithm = Phar::SHA512;
  112. break;
  113. default:
  114. break;
  115. }
  116. }
  117. /**
  118. * @param string $compression
  119. */
  120. public function setCompression($compression)
  121. {
  122. /*
  123. * If we don't support passed compression, leave old one.
  124. */
  125. switch ($compression) {
  126. case 'gzip':
  127. $this->compression = Phar::GZ;
  128. break;
  129. case 'bzip2':
  130. $this->compression = Phar::BZ2;
  131. break;
  132. default:
  133. break;
  134. }
  135. }
  136. /**
  137. * @param PhingFile $destinationFile
  138. */
  139. public function setDestFile(PhingFile $destinationFile)
  140. {
  141. $this->destinationFile = $destinationFile;
  142. }
  143. /**
  144. * @param PhingFile $baseDirectory
  145. */
  146. public function setBaseDir(PhingFile $baseDirectory)
  147. {
  148. $this->baseDirectory = $baseDirectory;
  149. }
  150. /**
  151. * @param PhingFile $stubFile
  152. */
  153. public function setCliStub(PhingFile $stubFile)
  154. {
  155. $this->cliStubFile = $stubFile;
  156. }
  157. /**
  158. * @param PhingFile $stubFile
  159. */
  160. public function setWebStub(PhingFile $stubFile)
  161. {
  162. $this->webStubFile = $stubFile;
  163. }
  164. /**
  165. * @param string $stubPath
  166. */
  167. public function setStub($stubPath)
  168. {
  169. $this->stubPath = $stubPath;
  170. }
  171. /**
  172. * @param $alias
  173. */
  174. public function setAlias($alias)
  175. {
  176. $this->alias = $alias;
  177. }
  178. /**
  179. * @throws BuildException
  180. */
  181. public function main()
  182. {
  183. $this->checkPreconditions();
  184. try {
  185. $this->log(
  186. 'Building package: '.$this->destinationFile->__toString(),
  187. Project::MSG_INFO
  188. );
  189. /*
  190. * Delete old package, if exists.
  191. */
  192. if ($this->destinationFile->exists()) {
  193. /*
  194. * TODO Check operation for errors...
  195. */
  196. $this->destinationFile->delete();
  197. }
  198. $phar = $this->buildPhar();
  199. $phar->startBuffering();
  200. $baseDirectory = realpath($this->baseDirectory->getPath());
  201. foreach ($this->filesets as $fileset) {
  202. foreach ($fileset as $realFileName) {
  203. /*
  204. * Calculate local file name.
  205. */
  206. $localFileName = $realFileName;
  207. if (0 === strpos($realFileName, $baseDirectory)) {
  208. $localFileName = substr(
  209. $realFileName,
  210. strlen($baseDirectory)
  211. );
  212. }
  213. $this->log(
  214. 'Adding '.$realFileName.' as '.$localFileName.' to package',
  215. Project::MSG_VERBOSE
  216. );
  217. $phar->addFile($realFileName, $localFileName);
  218. }
  219. }
  220. $phar->stopBuffering();
  221. /*
  222. * File compression, if needed.
  223. */
  224. if (Phar::NONE != $this->compression) {
  225. $phar->compressFiles($this->compression);
  226. }
  227. } catch (Exception $e) {
  228. throw new BuildException(
  229. 'Problem creating package: '.$e->getMessage(),
  230. $e,
  231. $this->getLocation()
  232. );
  233. }
  234. }
  235. /**
  236. * @throws BuildException
  237. */
  238. private function checkPreconditions()
  239. {
  240. if (is_null($this->destinationFile)) {
  241. throw new BuildException("destfile attribute must be set!", $this->getLocation());
  242. }
  243. if ($this->destinationFile->exists() && $this->destinationFile->isDirectory()) {
  244. throw new BuildException("destfile is a directory!", $this->getLocation());
  245. }
  246. if (!$this->destinationFile->canWrite()) {
  247. throw new BuildException("Can not write to the specified destfile!", $this->getLocation());
  248. }
  249. if (!is_null($this->baseDirectory)) {
  250. if (!$this->baseDirectory->exists()) {
  251. throw new BuildException("basedir does not exist!", $this->getLocation());
  252. }
  253. }
  254. if (is_null($this->metadata)) {
  255. throw new BuildException("metadata element must be set", $this->getLocation());
  256. }
  257. }
  258. /**
  259. * Build and configure Phar object.
  260. *
  261. * @return Phar
  262. */
  263. private function buildPhar()
  264. {
  265. $phar = new Phar($this->destinationFile);
  266. $phar->setSignatureAlgorithm($this->signatureAlgorithm);
  267. if (isset($this->stubPath)) {
  268. $phar->setStub(file_get_contents($this->stubPath));
  269. } else {
  270. $phar->setDefaultStub(
  271. $this->cliStubFile,
  272. $this->webStubFile
  273. );
  274. }
  275. if ($metadata = $this->metadata->toArray()) {
  276. $phar->setMetadata($metadata);
  277. }
  278. if(!empty($this->alias)){
  279. $phar->setAlias($this->alias);
  280. }
  281. return $phar;
  282. }
  283. }