Browse Source

<touch> to handle filelists. Forced me to add more tests for new and existing touch code, and in the process note that the granularity for unix filesystems is not 0 but 1000 milliseconds. oops.

PR: 23526
Submitted by:	gudnabrsam@yahoo.com


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275869 13f79535-47bb-0310-9956-ffa450edef68
master
Steve Loughran 21 years ago
parent
commit
5086d93694
5 changed files with 161 additions and 30 deletions
  1. +3
    -2
      docs/manual/CoreTasks/touch.html
  2. +26
    -0
      src/etc/testcases/taskdefs/touch.xml
  3. +41
    -26
      src/main/org/apache/tools/ant/taskdefs/Touch.java
  4. +5
    -1
      src/main/org/apache/tools/ant/util/FileUtils.java
  5. +86
    -1
      src/testcases/org/apache/tools/ant/taskdefs/TouchTest.java

+ 3
- 2
docs/manual/CoreTasks/touch.html View File

@@ -12,7 +12,8 @@
<p>Changes the modification time of a file and possibly creates it at <p>Changes the modification time of a file and possibly creates it at
the same time. In addition to working with a single file, this Task the same time. In addition to working with a single file, this Task
can also work a <a href="../CoreTypes/fileset.html">Fileset</a> (which can also work a <a href="../CoreTypes/fileset.html">Fileset</a> (which
also includes directories).</p>
also includes directories)
or a <a href="../CoreTypes/filelist.html">Filelist</a> (since Ant 1.6).</p>
<p>For JDK 1.1 only the creation of new files with a modification time <p>For JDK 1.1 only the creation of new files with a modification time
of now works, all other cases will emit a warning.</p> of now works, all other cases will emit a warning.</p>
<h3>Parameters</h3> <h3>Parameters</h3>
@@ -26,6 +27,7 @@ of now works, all other cases will emit a warning.</p>
<td valign="top">file</td> <td valign="top">file</td>
<td valign="top">the name of the file</td> <td valign="top">the name of the file</td>
<td valign="top" align="center">unless a nested fileset element <td valign="top" align="center">unless a nested fileset element
or a nested filelist element
has been specified.</td> has been specified.</td>
</tr> </tr>
<tr> <tr>
@@ -67,4 +69,3 @@ Reserved.</p>


</body> </body>
</html> </html>


+ 26
- 0
src/etc/testcases/taskdefs/touch.xml View File

@@ -12,4 +12,30 @@
<target name="seconds"> <target name="seconds">
<touch file="touchtest" datetime="2003/06/24 2:20:12 pm"/> <touch file="touchtest" datetime="2003/06/24 2:20:12 pm"/>
</target> </target>

<target name="testNow">
<touch file="touchtest" />
</target>
<target name="testMillis">
<touch file="touchtest" millis="1234567" />
</target>
<target name="test1970">
<touch file="touchtest" millis="0" />
</target>
<target name="testFilelist">
<touch millis="100000" >
<filelist dir="." files="touchtest"/>
</touch>
</target>

<target name="testFileset" depends="testNow">
<touch millis="200000" >
<fileset dir="." includes="touchtest"/>
</touch>
</target>

</project> </project>

+ 41
- 26
src/main/org/apache/tools/ant/taskdefs/Touch.java View File

@@ -65,11 +65,13 @@ import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task; import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.FileList;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JavaEnvUtils; import org.apache.tools.ant.util.JavaEnvUtils;


/** /**
* Touch a file and/or fileset(s); corresponds to the Unix touch command.
* Touch a file and/or fileset(s) and/or filelist(s);
* corresponds to the Unix touch command.
* *
* <p>If the file to touch doesn't exist, an empty one is * <p>If the file to touch doesn't exist, an empty one is
* created. </p> * created. </p>
@@ -91,6 +93,7 @@ public class Touch extends Task {
private long millis = -1; private long millis = -1;
private String dateTime; private String dateTime;
private Vector filesets = new Vector(); private Vector filesets = new Vector();
private Vector filelists = new Vector();
private FileUtils fileUtils; private FileUtils fileUtils;


public Touch() { public Touch() {
@@ -131,15 +134,22 @@ public class Touch extends Task {
filesets.addElement(set); filesets.addElement(set);
} }


/**
* Add a filelist to touch
*/
public void addFilelist(FileList list) {
filelists.addElement(list);
}

/** /**
* Execute the touch operation. * Execute the touch operation.
*/ */
public void execute() throws BuildException { public void execute() throws BuildException {
long savedMillis = millis; long savedMillis = millis;


if (file == null && filesets.size() == 0) {
if (file == null && filesets.size() == 0 && filelists.size() == 0) {
throw throw
new BuildException("Specify at least one source - a file or "
new BuildException("Specify at least one source - a file, filelist or "
+ "a fileset."); + "a fileset.");
} }


@@ -195,26 +205,9 @@ public class Touch extends Task {
} }


/** /**
* Does the actual work. Entry point for Untar and Expand as well.
* Does the actual work; assumes everything has been checked by now.
*/ */
protected void touch() throws BuildException { protected void touch() throws BuildException {
if (file != null) {
if (!file.exists()) {
log("Creating " + file, Project.MSG_INFO);
try {
fileUtils.createNewFile(file);
} catch (IOException ioe) {
throw new BuildException("Could not create " + file, ioe,
getLocation());
}
}
}

if (millis >= 0 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
log("modification time of files cannot be set in JDK 1.1",
Project.MSG_WARN);
return;
}


boolean resetMillis = false; boolean resetMillis = false;
if (millis < 0) { if (millis < 0) {
@@ -244,21 +237,43 @@ public class Touch extends Task {
} }
} }


// deal with the filelists
for (int i = 0; i < filelists.size(); i++) {
FileList fl = (FileList) filelists.elementAt(i);
File fromDir = fl.getDir(getProject());

String[] srcFiles = fl.getFiles(getProject());

for (int j = 0; j < srcFiles.length; j++) {
touch(new File(fromDir, srcFiles[j]));
}
}

if (resetMillis) { if (resetMillis) {
millis = -1; millis = -1;
} }
} }


/**
* touch a single file with the current timestamp (this.millis)
* @param file file to touch
* @throws BuildException
*/
protected void touch(File file) throws BuildException { protected void touch(File file) throws BuildException {
if (!file.exists()) {
log("Creating " + file, Project.MSG_INFO);
try {
fileUtils.createNewFile(file);
} catch (IOException ioe) {
throw new BuildException("Could not create " + file, ioe,
getLocation());
}
}

if (!file.canWrite()) { if (!file.canWrite()) {
throw new BuildException("Can not change modification date of " throw new BuildException("Can not change modification date of "
+ "read-only file " + file); + "read-only file " + file);
} }

if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
return;
}

fileUtils.setFileLastModified(file, millis); fileUtils.setFileLastModified(file, millis);
} }




+ 5
- 1
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -116,6 +116,10 @@ public class FileUtils {
*/ */
public static final long FAT_FILE_TIMESTAMP_GRANULARITY = 2000; public static final long FAT_FILE_TIMESTAMP_GRANULARITY = 2000;


/**
* the granularity of timestamps under Unix
*/
public static final long UNIX_FILE_TIMESTAMP_GRANULARITY = 1000;


// stolen from FilePathToURI of the Xerces-J team // stolen from FilePathToURI of the Xerces-J team
static { static {
@@ -1401,7 +1405,7 @@ public class FileUtils {
if (Os.isFamily("dos")) { if (Os.isFamily("dos")) {
return FAT_FILE_TIMESTAMP_GRANULARITY; return FAT_FILE_TIMESTAMP_GRANULARITY;
} else { } else {
return 0;
return UNIX_FILE_TIMESTAMP_GRANULARITY;
} }
} }
} }


+ 86
- 1
src/testcases/org/apache/tools/ant/taskdefs/TouchTest.java View File

@@ -55,9 +55,15 @@
package org.apache.tools.ant.taskdefs; package org.apache.tools.ant.taskdefs;


import org.apache.tools.ant.BuildFileTest; import org.apache.tools.ant.BuildFileTest;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.FileUtils;

import java.io.File;


public class TouchTest extends BuildFileTest { public class TouchTest extends BuildFileTest {


private static String touchfile="src/etc/testcases/taskdefs/touchtest";

public TouchTest(String name) { public TouchTest(String name) {
super(name); super(name);
} }
@@ -69,13 +75,23 @@ public class TouchTest extends BuildFileTest {
public void tearDown() { public void tearDown() {
executeTarget("cleanup"); executeTarget("cleanup");
} }

public long getTargetTime() {

File file = new File(touchfile);
if(!file.exists()) {
throw new BuildException("failed to touch file "+touchfile);
}
return file.lastModified();
}

/** /**
* No real test, simply checks whether the dateformat without * No real test, simply checks whether the dateformat without
* seconds is accepted - by erroring out otherwise. * seconds is accepted - by erroring out otherwise.
*/ */
public void testNoSeconds() { public void testNoSeconds() {
executeTarget("noSeconds"); executeTarget("noSeconds");
long time = getTargetTime();
} }


/** /**
@@ -84,5 +100,74 @@ public class TouchTest extends BuildFileTest {
*/ */
public void testSeconds() { public void testSeconds() {
executeTarget("seconds"); executeTarget("seconds");
long time=getTargetTime();
}
/**
* verify that the millis test sets things up
*/
public void testMillis() {
touchFile("testMillis", 1234567);
}

/**
* verify that the default value defaults to now
*/
public void testNow() {
long now=System.currentTimeMillis();
executeTarget("testNow");
long time = getTargetTime();
assertTimesNearlyMatch(time,now,5000);
}
/**
* verify that the millis test sets things up
*/
public void test1970() {
touchFile("test1970", 0);
}

/**
* test the file list
*/
public void testFilelist() {
touchFile("testFilelist", 100000);
}

/**
* test the file set
*/
public void testFileset() {
touchFile("testFileset", 200000);
}

/**
* run a target to touch the test file; verify the timestamp is as expected
* @param targetName
* @param timestamp
*/
private void touchFile(String targetName, long timestamp) {
executeTarget(targetName);
long time = getTargetTime();
assertTimesNearlyMatch(timestamp,time);
}

/**
* assert that two times are within the current FS granularity;
* @param timestamp
* @param time
*/
public void assertTimesNearlyMatch(long timestamp,long time) {
long granularity= FileUtils.newFileUtils().getFileTimestampGranularity();
assertTimesNearlyMatch(timestamp, time, granularity);
}

/**
* assert that two times are within a specified range
* @param timestamp
* @param time
* @param range
*/
private void assertTimesNearlyMatch(long timestamp, long time, long range) {
assertTrue("Time "+timestamp+" is not within "+range+" ms of "+time,
Math.abs(time-timestamp)<=range);
} }
} }

Loading…
Cancel
Save