Skip to content

Commit

Permalink
Added Truncate Task (#611)
Browse files Browse the repository at this point in the history
  • Loading branch information
siad007 authored and mrook committed Nov 9, 2016
1 parent 4964219 commit 9a80878
Show file tree
Hide file tree
Showing 6 changed files with 431 additions and 0 deletions.
1 change: 1 addition & 0 deletions classes/phing/tasks/defaults.properties
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ sleep=phing.tasks.system.SleepTask
taskdef=phing.tasks.system.TaskdefTask
tempfile=phing.tasks.system.TempFile
touch=phing.tasks.system.TouchTask
truncate=phing.tasks.system.TruncateTask
tstamp=phing.tasks.system.TstampTask
typedef=phing.tasks.system.TypedefTask
uptodate=phing.tasks.system.UpToDateTask
Expand Down
173 changes: 173 additions & 0 deletions classes/phing/tasks/system/TruncateTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php
/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/Task.php';
include_once 'phing/system/io/PhingFile.php';
include_once 'phing/BuildException.php';

/**
* @author Siad Ardroumli <siad.ardroumli@gmail.com>
* @package phing.tasks.system
*/
class TruncateTask extends Task
{
private $create = true;
private $mkdirs = false;

private $length;
private $adjust;
private $file;

/**
* Set a single target File.
* @param PhingFile|string $f the single File
* @throws \IOException
* @throws \NullPointerException
*/
public function setFile($f)
{
if (is_string($f)) {
$f = new PhingFile($f);
}
$this->file = $f;
}

/**
* Set the amount by which files' lengths should be adjusted.
* It is permissible to append K / M / G / T / P.
* @param $adjust (positive or negative) adjustment amount.
*/
public function setAdjust($adjust)
{
$this->adjust = $adjust;
}

/**
* Set the length to which files should be set.
* It is permissible to append K / M / G / T / P.
* @param $length (positive) adjustment amount.
*
* @throws \BuildException
*/
public function setLength($length)
{
$this->length = $length;
if ($this->length !== null && $this->length < 0) {
throw new BuildException('Cannot truncate to length ' . $this->length);
}
}

/**
* Set whether to create nonexistent files.
* @param boolean $create default <code>true</code>.
*/
public function setCreate($create)
{
$this->create = $create;
}

/**
* Set whether, when creating nonexistent files, nonexistent directories
* should also be created.
* @param boolean $mkdirs default <code>false</code>.
*/
public function setMkdirs($mkdirs)
{
$this->mkdirs = $mkdirs;
}

/**
* {@inheritDoc}.
* @throws \BuildException
*/
public function main()
{
if ($this->length !== null && $this->adjust !== null) {
throw new BuildException(
'length and adjust are mutually exclusive options'
);
}
if ($this->length === null && $this->adjust === null) {
$this->length = 0;
}
if ($this->file === null) {
throw new BuildException('No files specified.');
}

if ($this->shouldProcess($this->file)) {
$this->process($this->file);
}
}

/**
* @param PhingFile $f
* @return bool
* @throws \BuildException
*/
private function shouldProcess(PhingFile $f)
{
if ($f->isFile()) {
return true;
}
if (!$this->create) {
return false;
}
$exception = null;
try {
/** @var PhingFile $parent */
$parent = $f->getParentFile();
if ($this->mkdirs && !$parent->exists()) {
$parent->mkdirs();
}

if ($f->createNewFile()) {
return true;
}
} catch (IOException $e) {
$exception = $e;
}
$msg = "Unable to create " . $f;
if ($exception === null) {
$this->log($msg, Project::MSG_WARN);
return false;
}
throw new BuildException($msg, $exception);
}

private function process(PhingFile $f)
{
$len = $f->length();
$newLength = $this->length === null
? $len + $this->adjust
: $this->length;

if ($len === $newLength) {
//nothing to do!
return;
}

$splFile = new SplFileObject($f->getPath(), 'a+');

if (!$splFile->ftruncate((int) $newLength)) {
throw new BuildException("Exception working with " . (string)$splFile);
}

$splFile->rewind();
clearstatcache();
}
}
68 changes: 68 additions & 0 deletions docs/docbook5/en/source/appendixes/coretasks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4054,6 +4054,74 @@ file defines a task in the format: name=path.to.Task -->
</itemizedlist>
</sect2>
</sect1>
<sect1 role="taskdef" xml:id="TruncateTask">
<title>TruncateTask </title>
<para>Set the length of one file, as the intermittently available
truncate Unix utility/function.</para>

<table>
<title>Attributes</title>
<tgroup cols="5">
<colspec colname="name" colnum="1" colwidth="1.5*"/>
<colspec colname="type" colnum="2" colwidth="0.8*"/>
<colspec colname="description" colnum="3" colwidth="3.5*"/>
<colspec colname="default" colnum="4" colwidth="0.8*"/>
<colspec colname="required" colnum="5" colwidth="1.2*"/>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>Description</entry>
<entry>Default</entry>
<entry>Required</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>file</literal></entry>
<entry><literal role="type">String</literal></entry>
<entry>The name of the file.</entry>
<entry>n/a</entry>
<entry>Yes</entry>
</row>
<row>
<entry><literal>length</literal></entry>
<entry><literal role="type">Integer</literal></entry>
<entry>Specifies the new file length (in bytes) to set.</entry>
<entry>n/a</entry>
<entry>No</entry>
</row>
<row>
<entry><literal>adjust</literal></entry>
<entry><literal role="type">Integer</literal></entry>
<entry>Specifies the number of bytes (and positive/negative
direction) by which to adjust file lengths.</entry>
<entry>n/a</entry>
<entry>No</entry>
</row>
<row>
<entry><literal>create</literal></entry>
<entry><literal role="type">Boolean</literal></entry>
<entry>Whether to create nonexistent files.</entry>
<entry><literal>true</literal></entry>
<entry>No</entry>
</row>
<row>
<entry><literal>mkdirs</literal></entry>
<entry><literal role="type">Boolean</literal></entry>
<entry>Whether to create nonexistent parent directories
when creating new files.</entry>
<entry><literal>false</literal></entry>
<entry>No</entry>
</row>
</tbody>
</tgroup>
</table>
<sect2>
<title>Examples</title>
<programlisting language="xml">&lt;truncate file="foo" /></programlisting>
</sect2>
</sect1>
<sect1 role="trycatch" xml:id="TryCatchTask">
<title>TryCatchTask</title>
<para>This task is a wrapper task that lets you run tasks(s) when another set of tasks fails,
Expand Down
25 changes: 25 additions & 0 deletions etc/phing-grammar.rng
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@
<ref name="taskdef"/>
<ref name="tempfile"/>
<ref name="touch"/>
<ref name="truncate"/>
<ref name="trycatch"/>
<ref name="tstamp"/>
<ref name="typedef"/>
Expand Down Expand Up @@ -1702,6 +1703,30 @@
</element>
</define>

<define name="truncate">
<element name="truncate">
<interleave>
<attribute name="file"/>
<optional>
<attribute name="adjust"/>
</optional>
<optional>
<attribute name="length"/>
</optional>
<optional>
<attribute name="create" a:defaultValue="true">
<data type="boolean"/>
</attribute>
</optional>
<optional>
<attribute name="mkdirs" a:defaultValue="false">
<data type="boolean"/>
</attribute>
</optional>
</interleave>
</element>
</define>

<define name="trycatch">
<element name="trycatch">
<interleave>
Expand Down
Loading

0 comments on commit 9a80878

Please sign in to comment.