You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by mb...@apache.org on 2007/03/02 20:27:57 UTC

svn commit: r513901 - in /ant/core/trunk: ./ docs/manual/ docs/manual/CoreTasks/ src/main/org/apache/tools/ant/taskdefs/ src/tests/antunit/taskdefs/truncate/

Author: mbenson
Date: Fri Mar  2 11:27:56 2007
New Revision: 513901

URL: http://svn.apache.org/viewvc?view=rev&rev=513901
Log:
add truncate task

Added:
    ant/core/trunk/docs/manual/CoreTasks/truncate.html   (with props)
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Truncate.java   (with props)
    ant/core/trunk/src/tests/antunit/taskdefs/truncate/
    ant/core/trunk/src/tests/antunit/taskdefs/truncate/truncate-test.xml   (with props)
Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/docs/manual/coretasklist.html
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?view=diff&rev=513901&r1=513900&r2=513901
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Fri Mar  2 11:27:56 2007
@@ -83,6 +83,8 @@
 
 * Add a <last> resource collection, corresponding to <first>.
 
+* Add new <truncate> task.
+
 Changes from Ant 1.6.5 to Ant 1.7.0
 ===================================
 

Added: ant/core/trunk/docs/manual/CoreTasks/truncate.html
URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/truncate.html?view=auto&rev=513901
==============================================================================
--- ant/core/trunk/docs/manual/CoreTasks/truncate.html (added)
+++ ant/core/trunk/docs/manual/CoreTasks/truncate.html Fri Mar  2 11:27:56 2007
@@ -0,0 +1,106 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Truncate Task</title>
+</head>
+
+<body>
+
+<h2><a name="touch">Truncate</a></h2>
+<h3>Description</h3>
+
+<p>Set the length of one or more files, as the intermittently available
+<code>truncate</code> Unix utility/function. In addition to working with
+a single file, this Task can also work on
+<a href="../CoreTypes/resource.html">resources</a> and resource collections.
+<strong>Since Ant 1.7.1</strong>.
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">file</td>
+    <td valign="top">The name of the file.</td>
+    <td valign="top" align="center">Unless a nested resource collection element
+       has been specified.</td>
+  </tr>
+  <tr>
+    <td valign="top">length</td>
+    <td valign="top">Specifies the new file length to set. The following
+    suffixes are supported:
+    <ul>
+      <li>K : Kilobytes (1024 bytes)</li>
+      <li>M : Megabytes (1024 K)</li>
+      <li>G : Gigabytes (1024 M)</li>
+      <li>T : Terabytes (1024 G)</li>
+      <li>P : Petabytes (1024 T)</li>
+    </ul>
+</td>
+    <td valign="center" align="center" rowspan="2">One of these or neither.
+      Specifying neither is equivalent to length="0".
+    </td>
+  </tr>
+  <tr>
+    <td valign="top">adjust</td>
+    <td valign="top">Specifies the amount (and positive/negative direction)
+      by which to adjust file lengths.</td>
+  </tr>
+  <tr>
+    <td valign="top">create</td>
+    <td valign="top">Whether to create nonexistent files.</td>
+    <td valign="top" align="center">No, default <i>true</i>.</td>
+  </tr>
+  <tr>
+    <td valign="top">mkdirs</td>
+    <td valign="top">Whether to create nonexistent parent
+       directories when creating new files.</td>
+    <td valign="top" align="center">No, default <i>false</i>.</td>
+  </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>any resource collection</h4>
+
+<p>You can use any number of nested resource collection elements to
+define the resources for this task and refer to resources defined
+elsewhere.  <b>Note:</b> resources passed to this task are expected
+to be filesystem-based.</p>
+
+<h3>Examples</h3>
+
+<pre>  &lt;truncate file="foo" /&gt;</pre>
+<p>Sets the length of file <code>foo</code> to zero.</p>
+
+<pre>  &lt;truncate file="foo" length="1K" /&gt;</pre>
+<p>Sets the length of file <code>foo</code> to 1 kilobyte (1024 bytes).</p>
+
+<pre>  &lt;truncate file="foo" adjust="1K" /&gt;</pre>
+<p>Adjusts the length of file <code>foo</code> upward by 1 kilobyte.</p>
+
+<pre>  &lt;truncate file="foo" adjust="-1M" /&gt;</pre>
+<p>Adjusts the length of file <code>foo</code> downward by 1 megabyte.</p>
+
+</body>
+</html>

Propchange: ant/core/trunk/docs/manual/CoreTasks/truncate.html
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ant/core/trunk/docs/manual/coretasklist.html
URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/coretasklist.html?view=diff&rev=513901&r1=513900&r2=513901
==============================================================================
--- ant/core/trunk/docs/manual/coretasklist.html (original)
+++ ant/core/trunk/docs/manual/coretasklist.html Fri Mar  2 11:27:56 2007
@@ -113,6 +113,7 @@
 <a href="CoreTasks/taskdef.html">Taskdef</a><br/>
 <a href="CoreTasks/tempfile.html">Tempfile</a><br/>
 <a href="CoreTasks/touch.html">Touch</a><br/>
+<a href="CoreTasks/truncate.html">Truncate</a><br/>
 <a href="CoreTasks/tstamp.html">TStamp</a><br/>
 <a href="CoreTasks/typedef.html">Typedef</a><br/>
 <a href="CoreTasks/unzip.html">Unjar</a><br/>

Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Truncate.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Truncate.java?view=auto&rev=513901
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Truncate.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Truncate.java Fri Mar  2 11:27:56 2007
@@ -0,0 +1,204 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Iterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Set the length of one or more files, as the intermittently available
+ * <code>truncate</code> Unix utility/function.
+ * @since Ant 1.7.1
+ */
+public class Truncate extends Task {
+
+    private static final Long ZERO = new Long(0L);
+
+    private static final String NO_CHILD = "No files specified.";
+
+    private static final String INVALID_LENGTH = "Cannot truncate to length ";
+
+    private static final String READ_WRITE = "rw";
+
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+    private static final byte[] FILL_BUFFER = new byte[1024];
+
+    private Path path;
+    private boolean create = true;
+    private boolean mkdirs = false;
+
+    private Long length;
+    private Long adjust;
+
+    /**
+     * Set a single target File.
+     * @param f the single File
+     */
+    public void setFile(File f) {
+        add(new FileResource(f));
+    }
+
+    /**
+     * Add a nested (filesystem-only) ResourceCollection.
+     * @param rc the ResourceCollection to add.
+     */
+    public void add(ResourceCollection rc) {
+        getPath().add(rc);
+    }
+
+    /**
+     * 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 void setAdjust(Long adjust) {
+        this.adjust = adjust;
+    }
+
+    /**
+     * Set the length to which files should be set.
+     * It is permissible to append K / M / G / T / P.
+     * @param adjust (positive) adjustment amount.
+     */
+    public void setLength(Long length) {
+        this.length = length;
+        if (length != null && length.longValue() < 0) {
+            throw new BuildException(INVALID_LENGTH + length);
+        }
+    }
+
+    /**
+     * Set whether to create nonexistent files.
+     * @param create boolean, default <code>true</code>.
+     */
+    public void setCreate(boolean create) {
+        this.create = create;
+    }
+
+    /**
+     * Set whether, when creating nonexistent files, nonexistent directories
+     * should also be created.
+     * @param mkdirs boolean, default <code>false</code>.
+     */
+    public void setMkdirs(boolean mkdirs) {
+        this.mkdirs = mkdirs;
+    }
+
+    /** {@inheritDoc}. */
+    public void execute() {
+        if (length != null && adjust != null) {
+            throw new BuildException(
+                    "length and adjust are mutually exclusive options");
+        }
+        if (length == null && adjust == null) {
+            length = ZERO;
+        }
+        if (path == null) {
+            throw new BuildException(NO_CHILD);
+        }
+        for (Iterator it = path.iterator(); it.hasNext();) {
+            File f = ((FileResource) it.next()).getFile();
+            if (shouldProcess(f)) {
+                process(f);
+            }
+        }
+    }
+
+    private boolean shouldProcess(File f) {
+        if (f.isFile()) {
+            return true;
+        }
+        if (!create) {
+            return false;
+        }
+        Exception exception = null;
+        try {
+            if (FILE_UTILS.createNewFile(f, mkdirs)) {
+                return true;
+            }
+        } catch (IOException e) {
+            exception = e;
+        }
+        String msg = "Unable to create " + f;
+        if (exception == null) {
+            log(msg, Project.MSG_WARN);
+            return false;
+        }
+        throw new BuildException(msg, exception);
+    }
+
+    private void process(File f) {
+        long len = f.length();
+        long newLength = length == null
+                ? len + adjust.longValue() : length.longValue();
+
+        if (len == newLength) {
+            //nothing to do!
+            return;
+        }
+        RandomAccessFile raf = null;
+        try {
+            raf = new RandomAccessFile(f, READ_WRITE);
+        } catch (Exception e) {
+            throw new BuildException("Could not open " + f + " for writing", e);
+        }
+        try {
+            if (newLength > len) {
+                long pos = len;
+                raf.seek(pos);
+                while (pos < newLength) {
+                    long writeCount = Math.min(FILL_BUFFER.length,
+                            newLength - pos);
+                    raf.write(FILL_BUFFER, 0, (int) writeCount);
+                    pos += writeCount;
+                }
+            } else {
+                raf.setLength(newLength);
+            }
+        } catch (IOException e) {
+            throw new BuildException("Exception working with " + raf, e);
+        } finally {
+            try {
+                raf.close();
+            } catch (IOException e) {
+                log("Caught " + e + " closing " + raf, Project.MSG_WARN);
+            }
+        }
+    }
+
+    private synchronized Path getPath() {
+        if (path == null) {
+            path = new Path(getProject());
+        }
+        return path;
+    }
+
+}

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Truncate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Truncate.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties?view=diff&rev=513901&r1=513900&r2=513901
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties Fri Mar  2 11:27:56 2007
@@ -71,6 +71,7 @@
 tempfile=org.apache.tools.ant.taskdefs.TempFile
 touch=org.apache.tools.ant.taskdefs.Touch
 tstamp=org.apache.tools.ant.taskdefs.Tstamp
+truncate=org.apache.tools.ant.taskdefs.Truncate
 typedef=org.apache.tools.ant.taskdefs.Typedef
 unjar=org.apache.tools.ant.taskdefs.Expand
 untar=org.apache.tools.ant.taskdefs.Untar

Added: ant/core/trunk/src/tests/antunit/taskdefs/truncate/truncate-test.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/antunit/taskdefs/truncate/truncate-test.xml?view=auto&rev=513901
==============================================================================
--- ant/core/trunk/src/tests/antunit/taskdefs/truncate/truncate-test.xml (added)
+++ ant/core/trunk/src/tests/antunit/taskdefs/truncate/truncate-test.xml Fri Mar  2 11:27:56 2007
@@ -0,0 +1,128 @@
+<project name="truncate-test" default="default"
+         xmlns:au="antlib:org.apache.ant.antunit">
+
+  <target name="default">
+    <au:antunit>
+      <file file="${ant.file}" />
+    </au:antunit>
+  </target>
+
+  <target name="tearDown">
+    <delete file="foo" />
+    <delete file="bar" />
+    <delete dir="baz" />
+  </target>
+
+  <target name="test-basic">
+    <truncate file="foo" />
+    <au:assertTrue>
+      <length file="foo" length="0" />
+    </au:assertTrue>
+  </target>
+
+  <target name="test-explicit">
+    <truncate file="foo" length="1034" />
+    <au:assertTrue>
+      <length file="foo" length="1034" />
+    </au:assertTrue>
+  </target>
+
+  <target name="test-extend">
+    <truncate file="foo" length="5" />
+    <au:assertTrue>
+      <length file="foo" length="5" />
+    </au:assertTrue>
+    <truncate file="foo" adjust="5" />
+    <au:assertTrue>
+      <length file="foo" length="10" />
+    </au:assertTrue>
+  </target>
+
+  <target name="test-truncate">
+    <truncate file="foo" length="5" />
+    <au:assertTrue>
+      <length file="foo" length="5" />
+    </au:assertTrue>
+    <truncate file="foo" adjust="-5" />
+    <au:assertTrue>
+      <length file="foo" length="0" />
+    </au:assertTrue>
+  </target>
+
+  <target name="test-bigger">
+    <truncate file="foo" length="1K" />
+    <au:assertTrue>
+      <and>
+        <length file="foo" length="1K" />
+        <length file="foo" length="1024" />
+      </and>
+    </au:assertTrue>
+  </target>
+
+  <target name="truncate-bigger">
+    <truncate file="foo" length="3K" />
+    <au:assertTrue>
+      <length file="foo" length="3K" />
+    </au:assertTrue>
+    <truncate file="foo" adjust="-2K" />
+    <au:assertTrue>
+      <length file="foo" length="1K" />
+    </au:assertTrue>
+  </target>
+
+  <target name="test-no-create">
+    <au:assertFileDoesntExist file="foo" />
+    <truncate file="foo" create="false" length="0" />
+    <au:assertFileDoesntExist file="foo" />
+  </target>
+
+  <target name="test-mkdirs">
+    <au:assertFileDoesntExist file="baz" />
+    <truncate file="baz/foo" mkdirs="true" length="0" />
+    <au:assertTrue>
+      <length file="baz/foo" length="0" />
+    </au:assertTrue>
+  </target>
+
+  <target name="test-rc">
+    <truncate length="10">
+      <resources>
+        <file file="foo" />
+        <file file="bar" />
+      </resources>
+    </truncate>
+    <au:assertTrue>
+      <and>
+        <length file="foo" length="10" />
+        <length file="bar" length="10" />
+      </and>
+    </au:assertTrue>
+  </target>
+
+  <target name="test-bad-resource">
+    <au:expectfailure>
+      <truncate length="1P">
+        <string value="blah" />
+      </truncate>
+    </au:expectfailure>
+  </target>
+
+  <target name="test-invalid-attrs">
+    <au:expectfailure>
+      <truncate file="foo" length="0" adjust="0" />
+    </au:expectfailure>
+  </target>
+
+  <target name="test-bad-length">
+    <au:expectfailure>
+      <truncate file="foo" length="-1P" />
+    </au:expectfailure>
+  </target>
+
+  <target name="test-no-files">
+    <au:expectfailure>
+      <truncate length="0" />
+    </au:expectfailure>
+  </target>
+
+</project>

Propchange: ant/core/trunk/src/tests/antunit/taskdefs/truncate/truncate-test.xml
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org