TouchTask.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. /*
  3. * $Id: TouchTask.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/util/DirectoryScanner.php';
  23. include_once 'phing/types/FileSet.php';
  24. include_once 'phing/util/FileUtils.php';
  25. include_once 'phing/system/io/PhingFile.php';
  26. include_once 'phing/system/io/IOException.php';
  27. /**
  28. * Touch a file and/or fileset(s); corresponds to the Unix touch command.
  29. *
  30. * If the file to touch doesn't exist, an empty one is created.
  31. *
  32. * @version $Revision: 905 $
  33. * @package phing.tasks.system
  34. */
  35. class TouchTask extends Task {
  36. private $file;
  37. private $millis = -1;
  38. private $dateTime;
  39. private $filesets = array();
  40. private $fileUtils;
  41. function __construct() {
  42. $this->fileUtils = new FileUtils();
  43. }
  44. /**
  45. * Sets a single source file to touch. If the file does not exist
  46. * an empty file will be created.
  47. */
  48. function setFile(PhingFile $file) {
  49. $this->file = $file;
  50. }
  51. /**
  52. * the new modification time of the file
  53. * in milliseconds since midnight Jan 1 1970.
  54. * Optional, default=now
  55. */
  56. function setMillis($millis) {
  57. $this->millis = (int) $millis;
  58. }
  59. /**
  60. * the new modification time of the file
  61. * in the format MM/DD/YYYY HH:MM AM or PM;
  62. * Optional, default=now
  63. */
  64. function setDatetime($dateTime) {
  65. $this->dateTime = (string) $dateTime;
  66. }
  67. /**
  68. * Nested creator, adds a set of files (nested fileset attribute).
  69. * @return FileSet
  70. */
  71. function createFileSet() {
  72. $num = array_push($this->filesets, new FileSet());
  73. return $this->filesets[$num-1];
  74. }
  75. /**
  76. * Execute the touch operation.
  77. */
  78. function main() {
  79. $savedMillis = $this->millis;
  80. if ($this->file === null && count($this->filesets) === 0) {
  81. throw new BuildException("Specify at least one source - a file or a fileset.");
  82. }
  83. if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
  84. throw new BuildException("Use a fileset to touch directories.");
  85. }
  86. try { // try to touch file
  87. if ($this->dateTime !== null) {
  88. $this->setMillis(strtotime($this->dateTime));
  89. if ($this->millis < 0) {
  90. throw new BuildException("Date of {$this->dateTime} results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT).");
  91. }
  92. }
  93. $this->_touch();
  94. } catch (Exception $ex) {
  95. throw new BuildException("Error touch()ing file", $ex, $this->location);
  96. }
  97. $this->millis = $savedMillis;
  98. }
  99. /**
  100. * Does the actual work.
  101. */
  102. function _touch() {
  103. if ($this->file !== null) {
  104. if (!$this->file->exists()) {
  105. $this->log("Creating " . $this->file->__toString(), Project::MSG_INFO);
  106. try { // try to create file
  107. $this->file->createNewFile();
  108. } catch(IOException $ioe) {
  109. throw new BuildException("Error creating new file " . $this->file->__toString(), $ioe, $this->location);
  110. }
  111. }
  112. }
  113. $resetMillis = false;
  114. if ($this->millis < 0) {
  115. $resetMillis = true;
  116. $this->millis = Phing::currentTimeMillis();
  117. }
  118. if ($this->file !== null) {
  119. $this->touchFile($this->file);
  120. }
  121. // deal with the filesets
  122. foreach($this->filesets as $fs) {
  123. $ds = $fs->getDirectoryScanner($this->getProject());
  124. $fromDir = $fs->getDir($this->getProject());
  125. $srcFiles = $ds->getIncludedFiles();
  126. $srcDirs = $ds->getIncludedDirectories();
  127. for ($j=0,$_j=count($srcFiles); $j < $_j; $j++) {
  128. $this->touchFile(new PhingFile($fromDir, (string) $srcFiles[$j]));
  129. }
  130. for ($j=0,$_j=count($srcDirs); $j < $_j ; $j++) {
  131. $this->touchFile(new PhingFile($fromDir, (string) $srcDirs[$j]));
  132. }
  133. }
  134. if ($resetMillis) {
  135. $this->millis = -1;
  136. }
  137. }
  138. private function touchFile($file) {
  139. if ( !$file->canWrite() ) {
  140. throw new BuildException("Can not change modification date of read-only file " . $file->__toString());
  141. }
  142. $file->setLastModified($this->millis);
  143. }
  144. }