ChmodTask.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <?php
  2. /*
  3. * $Id: ChmodTask.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/Task.php';
  22. include_once 'phing/types/FileSet.php';
  23. /**
  24. * Task that changes the permissions on a file/directory.
  25. *
  26. * @author Manuel Holtgrewe <grin@gmx.net>
  27. * @author Hans Lellelid <hans@xmpl.org>
  28. * @version $Revision: 905 $
  29. * @package phing.tasks.system
  30. */
  31. class ChmodTask extends Task {
  32. private $file;
  33. private $mode;
  34. private $filesets = array();
  35. private $filesystem;
  36. private $quiet = false;
  37. private $failonerror = true;
  38. private $verbose = true;
  39. /**
  40. * This flag means 'note errors to the output, but keep going'
  41. * @see setQuiet()
  42. */
  43. function setFailonerror($bool) {
  44. $this->failonerror = $bool;
  45. }
  46. /**
  47. * Set quiet mode, which suppresses warnings if chmod() fails.
  48. * @see setFailonerror()
  49. */
  50. function setQuiet($bool) {
  51. $this->quiet = $bool;
  52. if ($this->quiet) {
  53. $this->failonerror = false;
  54. }
  55. }
  56. /**
  57. * Set verbosity, which if set to false surpresses all but an overview
  58. * of what happened.
  59. */
  60. function setVerbose($bool) {
  61. $this->verbose = (bool)$bool;
  62. }
  63. /**
  64. * Sets a single source file to touch. If the file does not exist
  65. * an empty file will be created.
  66. */
  67. function setFile(PhingFile $file) {
  68. $this->file = $file;
  69. }
  70. function setMode($str) {
  71. $this->mode = $str;
  72. }
  73. /**
  74. * Nested creator, adds a set of files (nested fileset attribute).
  75. */
  76. function createFileSet() {
  77. $num = array_push($this->filesets, new FileSet());
  78. return $this->filesets[$num-1];
  79. }
  80. /**
  81. * Execute the touch operation.
  82. * @return void
  83. */
  84. function main() {
  85. // Check Parameters
  86. $this->checkParams();
  87. $this->chmod();
  88. }
  89. /**
  90. * Ensure that correct parameters were passed in.
  91. * @return void
  92. */
  93. private function checkParams() {
  94. if ($this->file === null && empty($this->filesets)) {
  95. throw new BuildException("Specify at least one source - a file or a fileset.");
  96. }
  97. if ($this->mode === null) {
  98. throw new BuildException("You have to specify an octal mode for chmod.");
  99. }
  100. // check for mode to be in the correct format
  101. if (!preg_match('/^([0-7]){3,4}$/', $this->mode)) {
  102. throw new BuildException("You have specified an invalid mode.");
  103. }
  104. }
  105. /**
  106. * Does the actual work.
  107. * @return void
  108. */
  109. private function chmod() {
  110. if (strlen($this->mode) === 4) {
  111. $mode = octdec($this->mode);
  112. } else {
  113. // we need to prepend the 0 before converting
  114. $mode = octdec("0". $this->mode);
  115. }
  116. // counters for non-verbose output
  117. $total_files = 0;
  118. $total_dirs = 0;
  119. // one file
  120. if ($this->file !== null) {
  121. $total_files = 1;
  122. $this->chmodFile($this->file, $mode);
  123. }
  124. // filesets
  125. foreach($this->filesets as $fs) {
  126. $ds = $fs->getDirectoryScanner($this->project);
  127. $fromDir = $fs->getDir($this->project);
  128. $srcFiles = $ds->getIncludedFiles();
  129. $srcDirs = $ds->getIncludedDirectories();
  130. $filecount = count($srcFiles);
  131. $total_files = $total_files + $filecount;
  132. for ($j = 0; $j < $filecount; $j++) {
  133. $this->chmodFile(new PhingFile($fromDir, $srcFiles[$j]), $mode);
  134. }
  135. $dircount = count($srcDirs);
  136. $total_dirs = $total_dirs + $dircount;
  137. for ($j = 0; $j < $dircount; $j++) {
  138. $this->chmodFile(new PhingFile($fromDir, $srcDirs[$j]), $mode);
  139. }
  140. }
  141. if (!$this->verbose) {
  142. $this->log('Total files changed to ' . vsprintf('%o', $mode) . ': ' . $total_files);
  143. $this->log('Total directories changed to ' . vsprintf('%o', $mode) . ': ' . $total_dirs);
  144. }
  145. }
  146. /**
  147. * Actually change the mode for the file.
  148. * @param PhingFile $file
  149. * @param int $mode
  150. */
  151. private function chmodFile(PhingFile $file, $mode) {
  152. if ( !$file->exists() ) {
  153. throw new BuildException("The file " . $file->__toString() . " does not exist");
  154. }
  155. try {
  156. $file->setMode($mode);
  157. if ($this->verbose) {
  158. $this->log("Changed file mode on '" . $file->__toString() ."' to " . vsprintf("%o", $mode));
  159. }
  160. } catch (Exception $e) {
  161. if($this->failonerror) {
  162. throw $e;
  163. } else {
  164. $this->log($e->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
  165. }
  166. }
  167. }
  168. }