Permalink
Browse files

- Added the attribute 'preservePermissions' to the CopyTask providing…

… target files/directories mode/permission preservation.

- Adjusted the task functionality with directory creation to utilize the 'mode' value, including permissions preservation feature.
- Adjusted the CopyTask documentation for addition of attribute documentation.
  • Loading branch information...
1 parent d8de393 commit 36e32f8dfd32f3822f85a9cbdfaab1161c984418 Utsav Handa committed Nov 9, 2012
View
@@ -30,6 +30,7 @@ Phing 2.x Development
- Christian Weiske
- Matthias Pigulla
- Lineke Kerckhoffs-Willems <lineke@phpassionate.com>
+ - Utsav Handa <handautsav@hotmail.com>
If you've done work on Phing and you are not listed here, please feel free
to add yourself.
@@ -38,33 +38,34 @@
*/
class CopyTask extends Task {
- protected $file = null; // the source file (from xml attribute)
- protected $destFile = null; // the destiantion file (from xml attribute)
- protected $destDir = null; // the destination dir (from xml attribute)
- protected $overwrite = false; // overwrite destination (from xml attribute)
- protected $preserveLMT = false; // sync timestamps (from xml attribute)
- protected $includeEmpty = true; // include empty dirs? (from XML)
- protected $flatten = false; // apply the FlattenMapper right way (from XML)
- protected $mapperElement = null;
-
- protected $fileCopyMap = array(); // asoc array containing mapped file names
- protected $dirCopyMap = array(); // asoc array containing mapped file names
- protected $completeDirMap= array(); // asoc array containing complete dir names
- protected $fileUtils = null; // a instance of fileutils
- protected $filesets = array(); // all fileset objects assigned to this task
- protected $filelists = array(); // all filelist objects assigned to this task
- protected $filterChains = array(); // all filterchains objects assigned to this task
-
- protected $verbosity = Project::MSG_VERBOSE;
+ protected $file = null; // the source file (from xml attribute)
+ protected $destFile = null; // the destiantion file (from xml attribute)
+ protected $destDir = null; // the destination dir (from xml attribute)
+ protected $overwrite = false; // overwrite destination (from xml attribute)
+ protected $preserveLMT = false; // sync timestamps (from xml attribute)
+ protected $preservePermissions = true; // sync permissions (from xml attribute)
+ protected $includeEmpty = true; // include empty dirs? (from XML)
+ protected $flatten = false; // apply the FlattenMapper right way (from XML)
+ protected $mapperElement = null;
+
+ protected $fileCopyMap = array(); // asoc array containing mapped file names
+ protected $dirCopyMap = array(); // asoc array containing mapped file names
+ protected $completeDirMap = array(); // asoc array containing complete dir names
+ protected $fileUtils = null; // a instance of fileutils
+ protected $filesets = array(); // all fileset objects assigned to this task
+ protected $filelists = array(); // all filelist objects assigned to this task
+ protected $filterChains = array(); // all filterchains objects assigned to this task
+
+ protected $verbosity = Project::MSG_VERBOSE;
- protected $mode = 0; // mode to create directories with
+ protected $mode = 0; // mode to create directories with
- protected $haltonerror = true; // stop build on errors
+ protected $haltonerror = true; // stop build on errors
/**
* Sets up this object internal stuff. i.e. the Fileutils instance and default mode
*
- * @return object The CopyTask instnace
+ * @return object The CopyTask instance
* @access public
*/
function __construct() {
@@ -118,6 +119,22 @@ function setPreserveLastModified($bool) {
}
/**
+ * Set the preserve permissions flag. IntrospectionHelper takes care of
+ * booleans in set* methods so we can assume that the right
+ * value (boolean primitive) is coming in here.
+ *
+ * @param boolean Preserve the timestamp on the destination file
+ * @return void
+ * @access public
+ */
+ function setPreservepermissions($bool) {
+ $this->preservePermissions = (boolean) $bool;
+ }
+ function setPreservemode($bool) {
+ $this->setPreservepermissions($bool);
+ }
+
+ /**
* Set the include empty dirs flag. IntrospectionHelper takes care of
* booleans in set* methods so we can assume that the right
* value (boolean primitive) is coming in here.
@@ -422,7 +439,15 @@ protected function doWork() {
$s = new PhingFile((string) $srcdir);
$d = new PhingFile((string) $destdir);
if (!$d->exists()) {
- if (!$d->mkdirs()) {
+
+ // Setting source directory permissions to target
+ // (On permissions preservation, the target directory permissions
+ // will be inherited from the source directory, otherwise the 'mode'
+ // will be used)
+ $dirMode = ($this->preservePermissions ? $s->getMode() : $this->mode);
+
+ // Directory creation with specific permission mode
+ if (!$d->mkdirs($dirMode)) {
$this->logError("Unable to create directory " . $d->__toString());
} else {
if ($this->preserveLMT) {
@@ -460,7 +485,7 @@ protected function doWork() {
$toSlot->setValue($toFile->getPath());
$toBasenameSlot->setValue($toFile->getName());
- $this->fileUtils->copyFile($fromFile, $toFile, $this->overwrite, $this->preserveLMT, $this->filterChains, $this->getProject(), $this->mode);
+ $this->fileUtils->copyFile($fromFile, $toFile, $this->overwrite, $this->preserveLMT, $this->filterChains, $this->getProject(), $this->mode, $this->preservePermissions);
$count++;
} catch (IOException $ioe) {
@@ -37,6 +37,25 @@
*/
class FileUtils {
+ /**
+ * Returns the default file/dir creation mask value
+ * (The mask value is prepared w.r.t the current user's file-creation mask value)
+ *
+ * @param boolean $dirmode Directory creation mask to select
+ * @param boolean $returnoctal Whether the return value is in octal representation
+ * @return String Creation Mask
+ */
+ public static function getDefaultFileCreationMask($dirmode = false, $returnoctal = false) {
+
+ // Preparing the creation mask base permission
+ $permission = ($dirmode === true) ? 0777 : 0666;
+
+ // Default mask information
+ $defaultmask = sprintf('%03o', ($permission & ($permission - (int) sprintf('%04o', umask()))));
+
+ return ($returnoctal ? octdec($defaultmask) : $defaultmask);
+ }
+
/**
* Returns a new Reader with filterchains applied. If filterchains are empty,
* simply returns passed reader.
@@ -72,7 +91,7 @@ public static function getChainedReader(Reader $in, &$filterChains, Project $pro
* @param integer $mode
* @return void
*/
- function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false, $preserveLastModified = true, &$filterChains = null, Project $project, $mode = 0755) {
+ function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false, $preserveLastModified = true, &$filterChains = null, Project $project, $mode = 0755, $preservePermissions = true) {
if ($overwrite || !$destFile->exists() || $destFile->lastModified() < $sourceFile->lastModified()) {
if ($destFile->exists() && $destFile->isFile()) {
@@ -82,7 +101,14 @@ function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false
// ensure that parent dir of dest file exists!
$parent = $destFile->getParentFile();
if ($parent !== null && !$parent->exists()) {
- $parent->mkdirs($mode);
+
+ // Setting source directory permissions to target
+ // (On permissions preservation, the target directory permissions
+ // will be inherited from the source directory, otherwise the 'mode'
+ // will be used)
+ $dirMode = ($preservePermissions ? $ssourceFile->getMode() : $mode);
+
+ $parent->mkdirs($dirMode);
}
if ((is_array($filterChains)) && (!empty($filterChains))) {
@@ -100,13 +126,22 @@ function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false
if ( $out !== null )
$out->close();
- $destFile->setMode($sourceFile->getMode());
+ // Set/Copy the permissions on the target
+ if ($preservePermissions === true) {
+ $destFile->setMode($sourceFile->getMode());
+ }
} else {
// simple copy (no filtering)
$sourceFile->copyTo($destFile);
+
+ // By default, PHP::Copy also copies the file permissions. Therefore,
+ // re-setting the mode with the "user file-creation mask" information.
+ if ($preservePermissions === false) {
+ $destFile->setMode( FileUtils::getDefaultFileCreationMask(false, true) );
+ }
}
-
+
if ($preserveLastModified) {
$destFile->setLastModified($sourceFile->lastModified());
}
@@ -610,6 +610,16 @@
<entry>No</entry>
</row>
<row>
+ <entry>preservemode or preservepermissions</entry>
+ <entry><literal role="type">Boolean</literal></entry>
+ <entry>If set to <literal>true</literal>, the new file (and directory) will have the same
+ permissions as the old one. The <literal>mode</literal> specified for directory creation
+ will be ignored, if this is set to <literal>true</literal>.
+ </entry>
+ <entry><literal>true</literal></entry>
+ <entry>No</entry>
+ </row>
+ <row>
<entry><literal>includeemptydirs</literal></entry>
<entry><literal role="type">Boolean</literal></entry>
<entry>If set to <literal>true</literal>, also empty directories are copied. </entry>

0 comments on commit 36e32f8

Please sign in to comment.