git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277591 13f79535-47bb-0310-9956-ffa450edef68master
@@ -158,14 +158,6 @@ | |||||
</or> | </or> | ||||
</selector> | </selector> | ||||
<!-- classes that should be present in Sun based JVMs, but not in | |||||
Kaffe for example --> | |||||
<selector id="needs.sun.tools"> | |||||
<or> | |||||
<filename name="${optional.package}/Javah*"/> | |||||
</or> | |||||
</selector> | |||||
<selector id="needs.sun.uue"> | <selector id="needs.sun.uue"> | ||||
<filename name="${ant.package}/taskdefs/email/UUMailer*"/> | <filename name="${ant.package}/taskdefs/email/UUMailer*"/> | ||||
</selector> | </selector> | ||||
@@ -647,7 +639,6 @@ | |||||
<selector refid="needs.jdk1.3+" unless="jdk1.3+"/> | <selector refid="needs.jdk1.3+" unless="jdk1.3+"/> | ||||
<selector refid="needs.jdk1.4+" unless="jdk1.4+"/> | <selector refid="needs.jdk1.4+" unless="jdk1.4+"/> | ||||
<selector refid="needs.jdk1.5+" unless="jdk1.5+"/> | <selector refid="needs.jdk1.5+" unless="jdk1.5+"/> | ||||
<selector refid="needs.sun.tools" unless="sun.tools.present"/> | |||||
<selector refid="needs.sun.uue" unless="sunuue.present"/> | <selector refid="needs.sun.uue" unless="sunuue.present"/> | ||||
<selector refid="needs.sun.b64" unless="base64.present"/> | <selector refid="needs.sun.b64" unless="base64.present"/> | ||||
@@ -1670,4 +1661,4 @@ | |||||
description="--> creates a minimum distribution in ./dist" | description="--> creates a minimum distribution in ./dist" | ||||
depends="dist-lite"/> | depends="dist-lite"/> | ||||
</project> | |||||
</project> |
@@ -35,6 +35,17 @@ | |||||
</sync> | </sync> | ||||
</target> | </target> | ||||
<target name="copyandremove-emptypreserve" depends="setup"> | |||||
<mkdir dir="${src}/a/b/c"/> | |||||
<touch file="${src}/a/b/c/d"/> | |||||
<mkdir dir="${dest}/e"/> | |||||
<touch file="${dest}/e/f"/> | |||||
<sync todir="${dest}"> | |||||
<fileset dir="${src}"/> | |||||
<preserveintarget/> | |||||
</sync> | |||||
</target> | |||||
<target name="emptycopy" depends="setup"> | <target name="emptycopy" depends="setup"> | ||||
<mkdir dir="${src}/a/b/c"/> | <mkdir dir="${src}/a/b/c"/> | ||||
<touch file="${src}/a/b/c/d"/> | <touch file="${src}/a/b/c/d"/> | ||||
@@ -69,9 +80,22 @@ | |||||
<touch file="${dest}/e/f"/> | <touch file="${dest}/e/f"/> | ||||
<sync todir="${dest}"> | <sync todir="${dest}"> | ||||
<fileset dir="${src}"/> | <fileset dir="${src}"/> | ||||
<deletefromtarget> | |||||
<exclude name="e/f"/> | |||||
</deletefromtarget> | |||||
<preserveintarget> | |||||
<include name="e/f"/> | |||||
</preserveintarget> | |||||
</sync> | |||||
</target> | |||||
<target name="copynoremove-selectors" depends="setup"> | |||||
<mkdir dir="${src}/a/b/c"/> | |||||
<touch file="${src}/a/b/c/d"/> | |||||
<mkdir dir="${dest}/e"/> | |||||
<touch file="${dest}/e/f"/> | |||||
<sync todir="${dest}"> | |||||
<fileset dir="${src}"/> | |||||
<preserveintarget> | |||||
<filename name="e/f"/> | |||||
</preserveintarget> | |||||
</sync> | </sync> | ||||
</target> | </target> | ||||
@@ -34,6 +34,9 @@ import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.types.AbstractFileSet; | import org.apache.tools.ant.types.AbstractFileSet; | ||||
import org.apache.tools.ant.types.FileSet; | import org.apache.tools.ant.types.FileSet; | ||||
import org.apache.tools.ant.types.PatternSet; | |||||
import org.apache.tools.ant.types.selectors.FileSelector; | |||||
import org.apache.tools.ant.types.selectors.NoneSelector; | |||||
/** | /** | ||||
* Synchronize a local target directory from the files defined | * Synchronize a local target directory from the files defined | ||||
@@ -163,8 +166,33 @@ public class Sync extends Task { | |||||
DirectoryScanner ds = null; | DirectoryScanner ds = null; | ||||
if (syncTarget != null) { | if (syncTarget != null) { | ||||
syncTarget.setTargetDir(toDir); | |||||
ds = syncTarget.getDirectoryScanner(getProject()); | |||||
FileSet fs = new FileSet(); | |||||
fs.setDir(toDir); | |||||
fs.setCaseSensitive(syncTarget.isCaseSensitive()); | |||||
fs.setFollowSymlinks(syncTarget.isFollowSymlinks()); | |||||
// preserveInTarget would find all files we want to keep, | |||||
// but we need to find all that we want to delete - so the | |||||
// meaning of all patterns and selectors must be inverted | |||||
PatternSet ps = syncTarget.mergePatterns(getProject()); | |||||
String[] excludes = ps.getExcludePatterns(getProject()); | |||||
fs.appendExcludes(ps.getIncludePatterns(getProject())); | |||||
fs.appendIncludes(ps.getExcludePatterns(getProject())); | |||||
fs.setDefaultexcludes(!syncTarget.getDefaultexcludes()); | |||||
// selectors are implicitly ANDed in DirectoryScanner. To | |||||
// revert their logic we wrap them into a <none> selector | |||||
// instead. | |||||
FileSelector[] s = syncTarget.getSelectors(getProject()); | |||||
if (s.length > 0) { | |||||
NoneSelector ns = new NoneSelector(); | |||||
for (int i = 0; i < s.length; i++) { | |||||
ns.appendSelector(s[i]); | |||||
} | |||||
fs.appendSelector(ns); | |||||
} | |||||
ds = fs.getDirectoryScanner(getProject()); | |||||
} else { | } else { | ||||
ds = new DirectoryScanner(); | ds = new DirectoryScanner(); | ||||
ds.setBasedir(toDir); | ds.setBasedir(toDir); | ||||
@@ -180,7 +208,7 @@ public class Sync extends Task { | |||||
++removedCount[1]; | ++removedCount[1]; | ||||
} | } | ||||
String[] dirs = ds.getIncludedDirectories(); | String[] dirs = ds.getIncludedDirectories(); | ||||
// ds returns the directories as it has visited them. | |||||
// ds returns the directories in lexicographic order. | |||||
// iterating through the array backwards means we are deleting | // iterating through the array backwards means we are deleting | ||||
// leaves before their parent nodes - thus making sure (well, | // leaves before their parent nodes - thus making sure (well, | ||||
// more likely) that the directories are empty when we try to | // more likely) that the directories are empty when we try to | ||||
@@ -306,13 +334,13 @@ public class Sync extends Task { | |||||
* are not present in any source directory. | * are not present in any source directory. | ||||
* | * | ||||
* <p>You must not invoke this method more than once.</p> | * <p>You must not invoke this method more than once.</p> | ||||
* @param s a deletefromtarget nested element | |||||
* @param s a preserveintarget nested element | |||||
* @since Ant 1.7 | * @since Ant 1.7 | ||||
*/ | */ | ||||
public void addDeleteFromTarget(SyncTarget s) { | |||||
public void addPreserveInTarget(SyncTarget s) { | |||||
if (syncTarget != null) { | if (syncTarget != null) { | ||||
throw new BuildException("you must not specify multiple " | throw new BuildException("you must not specify multiple " | ||||
+ "deletefromtaget elements."); | |||||
+ "preserveintarget elements."); | |||||
} | } | ||||
syncTarget = s; | syncTarget = s; | ||||
} | } | ||||
@@ -381,24 +409,19 @@ public class Sync extends Task { | |||||
*/ | */ | ||||
public SyncTarget() { | public SyncTarget() { | ||||
super(); | super(); | ||||
setDefaultexcludes(false); | |||||
} | } | ||||
/** | /** | ||||
* Override AbstractFileSet#setDir(File) to disallow | * Override AbstractFileSet#setDir(File) to disallow | ||||
* setting the directory. This is now set by #setTargetDir(File). | |||||
* setting the directory. | |||||
* @param dir ignored | * @param dir ignored | ||||
* @throws BuildException always | * @throws BuildException always | ||||
*/ | */ | ||||
public void setDir(File dir) throws BuildException { | public void setDir(File dir) throws BuildException { | ||||
throw new BuildException("synctarget doesn't support the dir " | |||||
throw new BuildException("preserveintarget doesn't support the dir " | |||||
+ "attribute"); | + "attribute"); | ||||
} | } | ||||
private void setTargetDir(File dir) throws BuildException { | |||||
super.setDir(dir); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Copyright 2002-2004 The Apache Software Foundation | |||||
* Copyright 2002-2005 The Apache Software Foundation | |||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
@@ -63,7 +63,7 @@ public abstract class AbstractFileSet extends DataType | |||||
private File dir; | private File dir; | ||||
private boolean useDefaultExcludes = true; | private boolean useDefaultExcludes = true; | ||||
private boolean isCaseSensitive = true; | |||||
private boolean caseSensitive = true; | |||||
private boolean followSymlinks = true; | private boolean followSymlinks = true; | ||||
/** | /** | ||||
@@ -84,7 +84,7 @@ public abstract class AbstractFileSet extends DataType | |||||
this.additionalPatterns = fileset.additionalPatterns; | this.additionalPatterns = fileset.additionalPatterns; | ||||
this.selectors = fileset.selectors; | this.selectors = fileset.selectors; | ||||
this.useDefaultExcludes = fileset.useDefaultExcludes; | this.useDefaultExcludes = fileset.useDefaultExcludes; | ||||
this.isCaseSensitive = fileset.isCaseSensitive; | |||||
this.caseSensitive = fileset.caseSensitive; | |||||
this.followSymlinks = fileset.followSymlinks; | this.followSymlinks = fileset.followSymlinks; | ||||
setProject(fileset.getProject()); | setProject(fileset.getProject()); | ||||
} | } | ||||
@@ -215,6 +215,24 @@ public abstract class AbstractFileSet extends DataType | |||||
defaultPatterns.setIncludes(includes); | defaultPatterns.setIncludes(includes); | ||||
} | } | ||||
/** | |||||
* Appends <code>includes</code> to the current list of include | |||||
* patterns. | |||||
* | |||||
* @param includes array containing the include patterns. | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public void appendIncludes(String[] includes) { | |||||
if (isReference()) { | |||||
throw tooManyAttributes(); | |||||
} | |||||
if (includes != null) { | |||||
for (int i = 0; i < includes.length; i++) { | |||||
defaultPatterns.createInclude().setName(includes[i]); | |||||
} | |||||
} | |||||
} | |||||
/** | /** | ||||
* Appends <code>excludes</code> to the current list of exclude | * Appends <code>excludes</code> to the current list of exclude | ||||
* patterns. | * patterns. | ||||
@@ -230,6 +248,24 @@ public abstract class AbstractFileSet extends DataType | |||||
defaultPatterns.setExcludes(excludes); | defaultPatterns.setExcludes(excludes); | ||||
} | } | ||||
/** | |||||
* Appends <code>excludes</code> to the current list of include | |||||
* patterns. | |||||
* | |||||
* @param excludes array containing the exclude patterns. | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public void appendExcludes(String[] excludes) { | |||||
if (isReference()) { | |||||
throw tooManyAttributes(); | |||||
} | |||||
if (excludes != null) { | |||||
for (int i = 0; i < excludes.length; i++) { | |||||
defaultPatterns.createExclude().setName(excludes[i]); | |||||
} | |||||
} | |||||
} | |||||
/** | /** | ||||
* Sets the <code>File</code> containing the includes patterns. | * Sets the <code>File</code> containing the includes patterns. | ||||
* | * | ||||
@@ -266,16 +302,38 @@ public abstract class AbstractFileSet extends DataType | |||||
this.useDefaultExcludes = useDefaultExcludes; | this.useDefaultExcludes = useDefaultExcludes; | ||||
} | } | ||||
/** | |||||
* Whether default exclusions should be used or not. | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public boolean getDefaultexcludes() { | |||||
return (isReference()) | |||||
? getRef(getProject()).getDefaultexcludes() : useDefaultExcludes; | |||||
} | |||||
/** | /** | ||||
* Sets case sensitivity of the file system. | * Sets case sensitivity of the file system. | ||||
* | * | ||||
* @param isCaseSensitive <code>boolean</code>. | * @param isCaseSensitive <code>boolean</code>. | ||||
*/ | */ | ||||
public void setCaseSensitive(boolean isCaseSensitive) { | |||||
public void setCaseSensitive(boolean caseSensitive) { | |||||
if (isReference()) { | if (isReference()) { | ||||
throw tooManyAttributes(); | throw tooManyAttributes(); | ||||
} | } | ||||
this.isCaseSensitive = isCaseSensitive; | |||||
this.caseSensitive = caseSensitive; | |||||
} | |||||
/** | |||||
* Find out if the fileset is case sensitive. | |||||
* | |||||
* @return <code>boolean</code> indicating whether the fileset is | |||||
* case sensitive. | |||||
* | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public boolean isCaseSensitive() { | |||||
return (isReference()) | |||||
? getRef(getProject()).isCaseSensitive() : caseSensitive; | |||||
} | } | ||||
/** | /** | ||||
@@ -365,16 +423,12 @@ public abstract class AbstractFileSet extends DataType | |||||
} | } | ||||
ds.setBasedir(dir); | ds.setBasedir(dir); | ||||
final int count = additionalPatterns.size(); | |||||
for (int i = 0; i < count; i++) { | |||||
Object o = additionalPatterns.elementAt(i); | |||||
defaultPatterns.append((PatternSet) o, p); | |||||
} | |||||
PatternSet ps = mergePatterns(p); | |||||
p.log(getDataTypeName() + ": Setup scanner in dir " + dir | p.log(getDataTypeName() + ": Setup scanner in dir " + dir | ||||
+ " with " + defaultPatterns, Project.MSG_DEBUG); | |||||
+ " with " + ps, Project.MSG_DEBUG); | |||||
ds.setIncludes(defaultPatterns.getIncludePatterns(p)); | |||||
ds.setExcludes(defaultPatterns.getExcludePatterns(p)); | |||||
ds.setIncludes(ps.getIncludePatterns(p)); | |||||
ds.setExcludes(ps.getExcludePatterns(p)); | |||||
if (ds instanceof SelectorScanner) { | if (ds instanceof SelectorScanner) { | ||||
SelectorScanner ss = (SelectorScanner) ds; | SelectorScanner ss = (SelectorScanner) ds; | ||||
ss.setSelectors(getSelectors(p)); | ss.setSelectors(getSelectors(p)); | ||||
@@ -382,7 +436,7 @@ public abstract class AbstractFileSet extends DataType | |||||
if (useDefaultExcludes) { | if (useDefaultExcludes) { | ||||
ds.addDefaultExcludes(); | ds.addDefaultExcludes(); | ||||
} | } | ||||
ds.setCaseSensitive(isCaseSensitive); | |||||
ds.setCaseSensitive(caseSensitive); | |||||
} | } | ||||
/** | /** | ||||
@@ -683,4 +737,44 @@ public abstract class AbstractFileSet extends DataType | |||||
} | } | ||||
} | } | ||||
/** | |||||
* @return the include patterns of the default pattern set and all | |||||
* nested patternsets. | |||||
* | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public String[] mergeIncludes(Project p) { | |||||
return mergePatterns(p).getIncludePatterns(p); | |||||
} | |||||
/** | |||||
* @return the exclude patterns of the default pattern set and all | |||||
* nested patternsets. | |||||
* | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public String[] mergeExcludes(Project p) { | |||||
return mergePatterns(p).getExcludePatterns(p); | |||||
} | |||||
/** | |||||
* @return the default patternset merged with the additional sets | |||||
* in a new PatternSet instance. | |||||
* | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public PatternSet mergePatterns(Project p) { | |||||
if (isReference()) { | |||||
return getRef(p).mergePatterns(p); | |||||
} | |||||
PatternSet ps = new PatternSet(); | |||||
ps.append(defaultPatterns, p); | |||||
final int count = additionalPatterns.size(); | |||||
for (int i = 0; i < count; i++) { | |||||
Object o = additionalPatterns.elementAt(i); | |||||
ps.append((PatternSet) o, p); | |||||
} | |||||
return ps; | |||||
} | |||||
} | } |
@@ -74,7 +74,7 @@ public class CommandlineJava implements Cloneable { | |||||
* Specialized Environment class for System properties | * Specialized Environment class for System properties | ||||
*/ | */ | ||||
public static class SysProperties extends Environment implements Cloneable { | public static class SysProperties extends Environment implements Cloneable { | ||||
private Properties sys = null; | |||||
Properties sys = null; | |||||
private Vector propertySets = new Vector(); | private Vector propertySets = new Vector(); | ||||
/** | /** | ||||
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Copyright 2002-2004 The Apache Software Foundation | |||||
* Copyright 2002-2005 The Apache Software Foundation | |||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
@@ -34,6 +34,16 @@ public class NotSelector extends NoneSelector { | |||||
public NotSelector() { | public NotSelector() { | ||||
} | } | ||||
/** | |||||
* Constructor that inverts the meaning of its argument. | |||||
* @param other the selector to invert | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public NotSelector(FileSelector other) { | |||||
this(); | |||||
appendSelector(other); | |||||
} | |||||
/** | /** | ||||
* @return a string representation of the selector | * @return a string representation of the selector | ||||
*/ | */ | ||||
@@ -28,6 +28,7 @@ import org.apache.tools.ant.Project; | |||||
/** | /** | ||||
* Special <CODE>PipedInputStream</CODE> that will not die | * Special <CODE>PipedInputStream</CODE> that will not die | ||||
* when the writing <CODE>Thread</CODE> is no longer alive. | * when the writing <CODE>Thread</CODE> is no longer alive. | ||||
* @since Ant 1.6.2 | |||||
*/ | */ | ||||
public class LeadPipeInputStream extends PipedInputStream { | public class LeadPipeInputStream extends PipedInputStream { | ||||
private ProjectComponent managingPc; | private ProjectComponent managingPc; | ||||
@@ -39,6 +40,16 @@ public class LeadPipeInputStream extends PipedInputStream { | |||||
super(); | super(); | ||||
} | } | ||||
/** | |||||
* Construct a new <CODE>LeadPipeInputStream</CODE> | |||||
* with the specified buffer size. | |||||
* @param size the size of the circular buffer. | |||||
*/ | |||||
public LeadPipeInputStream(int size) { | |||||
super(); | |||||
setBufferSize(size); | |||||
} | |||||
/** | /** | ||||
* Construct a new <CODE>LeadPipeInputStream</CODE> to pull | * Construct a new <CODE>LeadPipeInputStream</CODE> to pull | ||||
* from the specified <CODE>PipedOutputStream</CODE>. | * from the specified <CODE>PipedOutputStream</CODE>. | ||||
@@ -49,6 +60,18 @@ public class LeadPipeInputStream extends PipedInputStream { | |||||
super(src); | super(src); | ||||
} | } | ||||
/** | |||||
* Construct a new <CODE>LeadPipeInputStream</CODE> to pull | |||||
* from the specified <CODE>PipedOutputStream</CODE>, using a | |||||
* circular buffer of the specified size. | |||||
* @param src the <CODE>PipedOutputStream</CODE> source. | |||||
* @param size the size of the circular buffer. | |||||
*/ | |||||
public LeadPipeInputStream(PipedOutputStream src, int size) throws IOException { | |||||
super(src); | |||||
setBufferSize(size); | |||||
} | |||||
//inherit doc | //inherit doc | ||||
public synchronized int read() throws IOException { | public synchronized int read() throws IOException { | ||||
int result = -1; | int result = -1; | ||||
@@ -68,6 +91,28 @@ public class LeadPipeInputStream extends PipedInputStream { | |||||
return result; | return result; | ||||
} | } | ||||
/** | |||||
* Set the size of the buffer. | |||||
* @param size the new buffer size. Ignored if <= current size. | |||||
*/ | |||||
public synchronized void setBufferSize(int size) { | |||||
if (size > buffer.length) { | |||||
byte[] newBuffer = new byte[size]; | |||||
if (in >= 0) { | |||||
if (in > out) { | |||||
System.arraycopy(buffer, out, newBuffer, out, in - out); | |||||
} else { | |||||
int outlen = buffer.length - out; | |||||
System.arraycopy(buffer, out, newBuffer, 0, outlen); | |||||
System.arraycopy(buffer, 0, newBuffer, outlen, in); | |||||
in+= outlen; | |||||
out = 0; | |||||
} | |||||
} | |||||
buffer = newBuffer; | |||||
} | |||||
} | |||||
/** | /** | ||||
* Set a managing <CODE>Task</CODE> for | * Set a managing <CODE>Task</CODE> for | ||||
* this <CODE>LeadPipeInputStream</CODE>. | * this <CODE>LeadPipeInputStream</CODE>. | ||||
@@ -34,7 +34,7 @@ import junit.framework.TestSuite; | |||||
/** | /** | ||||
* Very limited test class for Project. Waiting to be extended. | * Very limited test class for Project. Waiting to be extended. | ||||
* | * | ||||
*/ | |||||
*/ | |||||
public class ProjectTest extends TestCase { | public class ProjectTest extends TestCase { | ||||
private Project p; | private Project p; | ||||
@@ -70,6 +70,17 @@ public class SyncTest extends BuildFileTest { | |||||
assertDebuglogContaining("Removed 1 dangling directory from"); | assertDebuglogContaining("Removed 1 dangling directory from"); | ||||
} | } | ||||
public void testCopyAndRemoveEmptyPreserve() { | |||||
executeTarget("copyandremove-emptypreserve"); | |||||
String d = getProject().getProperty("dest") + "/a/b/c/d"; | |||||
assertFileIsPresent(d); | |||||
String f = getProject().getProperty("dest") + "/e/f"; | |||||
assertFileIsNotPresent(f); | |||||
assertTrue(getFullLog().indexOf("Removing orphan file:") > -1); | |||||
assertDebuglogContaining("Removed 1 dangling file from"); | |||||
assertDebuglogContaining("Removed 1 dangling directory from"); | |||||
} | |||||
public void testEmptyDirCopyAndRemove() { | public void testEmptyDirCopyAndRemove() { | ||||
executeTarget("emptydircopyandremove"); | executeTarget("emptydircopyandremove"); | ||||
String d = getProject().getProperty("dest") + "/a/b/c/d"; | String d = getProject().getProperty("dest") + "/a/b/c/d"; | ||||
@@ -92,6 +103,15 @@ public class SyncTest extends BuildFileTest { | |||||
assertTrue(getFullLog().indexOf("Removing orphan file:") == -1); | assertTrue(getFullLog().indexOf("Removing orphan file:") == -1); | ||||
} | } | ||||
public void testCopyNoRemoveSelectors() { | |||||
executeTarget("copynoremove-selectors"); | |||||
String d = getProject().getProperty("dest") + "/a/b/c/d"; | |||||
assertFileIsPresent(d); | |||||
String f = getProject().getProperty("dest") + "/e/f"; | |||||
assertFileIsPresent(f); | |||||
assertTrue(getFullLog().indexOf("Removing orphan file:") == -1); | |||||
} | |||||
public void assertFileIsPresent(String f) { | public void assertFileIsPresent(String f) { | ||||
assertTrue("Expected file " + f, | assertTrue("Expected file " + f, | ||||
getProject().resolveFile(f).exists()); | getProject().resolveFile(f).exists()); | ||||