git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@705639 13f79535-47bb-0310-9956-ffa450edef68master
@@ -469,6 +469,10 @@ Other changes: | |||
behavior of Ant 1.7.0. | |||
Bugzilla Report 46010. | |||
* If the new remote attribute is set to true, <cvschangelog> can now | |||
work against a remote repository without any working copy. | |||
Bugzilla Report 27419. | |||
Changes from Ant 1.7.0 TO Ant 1.7.1 | |||
============================================= | |||
@@ -125,6 +125,13 @@ operation may fail when using such an incompatible client. | |||
included in the report.</td> | |||
<td align="center" valign="top">No</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">remote</td> | |||
<td valign="top">If set to true, works against the repository | |||
(using rlog) without a working copy. Default is | |||
false. <em>Since Ant 1.8.0</em></td> | |||
<td align="center" valign="top">No</td> | |||
</tr> | |||
</table> | |||
<h3>Parameters specified as nested elements</h3> | |||
@@ -22,8 +22,12 @@ import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.Enumeration; | |||
import java.util.Hashtable; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Locale; | |||
import java.util.TimeZone; | |||
import org.apache.tools.ant.taskdefs.AbstractCvsTask; | |||
import org.apache.tools.ant.util.CollectionUtils; | |||
/** | |||
* A class used to parse the output of the CVS log command. | |||
@@ -67,6 +71,30 @@ class ChangeLogParser { | |||
/** rcs entries */ | |||
private final Hashtable entries = new Hashtable(); | |||
private final boolean remote; | |||
private final String[] moduleNames; | |||
private final int[] moduleNameLengths; | |||
public ChangeLogParser() { | |||
this(false, "", CollectionUtils.EMPTY_LIST); | |||
} | |||
public ChangeLogParser(boolean remote, String packageName, List modules) { | |||
this.remote = remote; | |||
moduleNames = new String[modules.size() + (packageName == null ? 0 : 1)]; | |||
moduleNameLengths = new int[moduleNames.length]; | |||
int i = 0; | |||
if (packageName != null) { | |||
moduleNames[i] = packageName; | |||
moduleNameLengths[i++] = packageName.length(); | |||
} | |||
for (Iterator iter = modules.iterator(); iter.hasNext(); i++) { | |||
AbstractCvsTask.Module m = (AbstractCvsTask.Module) iter.next(); | |||
moduleNames[i] = m.getName(); | |||
moduleNameLengths[i] = moduleNames[i].length(); | |||
} | |||
} | |||
/** | |||
* Get a list of rcs entries as an array. | |||
* | |||
@@ -148,11 +176,29 @@ class ChangeLogParser { | |||
* @param line the line to process | |||
*/ | |||
private void processFile(final String line) { | |||
if (line.startsWith("Working file:")) { | |||
if (!remote && line.startsWith("Working file:")) { | |||
// CheckStyle:MagicNumber OFF | |||
file = line.substring(14, line.length()); | |||
// CheckStyle:MagicNumber ON | |||
status = GET_REVISION; | |||
} else if (remote && line.startsWith("RCS file:")) { | |||
// exclude the part of the RCS filename up to and | |||
// including the module name (and the path separator) | |||
int startOfFileName = 0; | |||
for (int i = 0; i < moduleNames.length; i++) { | |||
int index = line.indexOf(moduleNames[i]); | |||
if (index >= 0) { | |||
startOfFileName = index + moduleNameLengths[i] + 1; | |||
break; | |||
} | |||
} | |||
int endOfFileName = line.indexOf(",v"); | |||
if (endOfFileName == -1) { | |||
file = line.substring(startOfFileName); | |||
} else { | |||
file = line.substring(startOfFileName, endOfFileName); | |||
} | |||
status = GET_REVISION; | |||
} | |||
} | |||
@@ -95,6 +95,10 @@ public class ChangeLogTask extends AbstractCvsTask { | |||
/** The latest date at which to stop processing entries. */ | |||
private Date endDate; | |||
/** Determines whether log (false) or rlog (true) is used */ | |||
private boolean remote = false; | |||
/** | |||
* Filesets containing list of files against which the cvs log will be | |||
* performed. If empty then all files in the working directory will | |||
@@ -177,6 +181,15 @@ public class ChangeLogTask extends AbstractCvsTask { | |||
setStart(new Date(time)); | |||
} | |||
/** | |||
* Whether to use rlog against a remote repository instead of log | |||
* in a working copy's directory. | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public void setRemote(final boolean remote) { | |||
this.remote = remote; | |||
} | |||
/** | |||
* Adds a set of files about which cvs logs will be generated. | |||
@@ -210,6 +223,7 @@ public class ChangeLogTask extends AbstractCvsTask { | |||
userList.put(user.getUserID(), user.getDisplayname()); | |||
} | |||
if (!remote) { | |||
setCommand("log"); | |||
if (getTag() != null) { | |||
@@ -225,6 +239,17 @@ public class ChangeLogTask extends AbstractCvsTask { | |||
addCommandArgument("-S"); | |||
} | |||
} | |||
} else { | |||
// supply 'rlog' as argument instead of command | |||
setCommand(""); | |||
addCommandArgument("rlog"); | |||
// Do not print name/header if no revisions | |||
// selected. This is quicker: less output to parse. | |||
addCommandArgument("-S"); | |||
// Do not list tags. This is quicker: less output to | |||
// parse. | |||
addCommandArgument("-N"); | |||
} | |||
if (null != startDate) { | |||
final SimpleDateFormat outputDate = | |||
new SimpleDateFormat("yyyy-MM-dd"); | |||
@@ -253,7 +278,9 @@ public class ChangeLogTask extends AbstractCvsTask { | |||
} | |||
} | |||
final ChangeLogParser parser = new ChangeLogParser(); | |||
final ChangeLogParser parser = new ChangeLogParser(remote, | |||
getPackage(), | |||
getModules()); | |||
final RedirectingStreamHandler handler = | |||
new RedirectingStreamHandler(parser); | |||
@@ -17,12 +17,15 @@ | |||
*/ | |||
package org.apache.tools.ant.util; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.Vector; | |||
import java.util.Iterator; | |||
import java.util.Collections; | |||
import java.util.Dictionary; | |||
import java.util.Enumeration; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.NoSuchElementException; | |||
import java.util.Vector; | |||
// CheckStyle:HideUtilityClassConstructorCheck OFF - bc | |||
@@ -33,6 +36,12 @@ import java.util.NoSuchElementException; | |||
*/ | |||
public class CollectionUtils { | |||
/** | |||
* Collections.emptyList() is Java5+. | |||
*/ | |||
public static final List EMPTY_LIST = | |||
Collections.unmodifiableList(new ArrayList(0)); | |||
/** | |||
* Please use Vector.equals() or List.equals(). | |||
* @param v1 the first vector. | |||
@@ -38,6 +38,28 @@ | |||
<au:assertFileExists file="${output}/report.xml"/> | |||
</target> | |||
<target name="testRemoteChangelog"> | |||
<mkdir dir="${output}"/> | |||
<cvschangelog cvsroot="${cvsroot}" package="antmodule3" | |||
remote="true" | |||
destfile="${output}/report.xml"/> | |||
<au:assertFileExists file="${output}/report.xml"/> | |||
<au:assertResourceContains resource="${output}/report.xml" | |||
value="[yet another test.txt]"/> | |||
</target> | |||
<target name="testRemoteChangelogNestedModule"> | |||
<mkdir dir="${output}"/> | |||
<cvschangelog cvsroot="${cvsroot}" | |||
remote="true" | |||
destfile="${output}/report.xml"> | |||
<module name="antmodule3"/> | |||
</cvschangelog> | |||
<au:assertFileExists file="${output}/report.xml"/> | |||
<au:assertResourceContains resource="${output}/report.xml" | |||
value="[yet another test.txt]"/> | |||
</target> | |||
<target name="testCvsWithSpaceInModule"> | |||
<mkdir dir="${output}"/> | |||
<cvs cvsroot="${cvsroot}" dest="${output}"> | |||
@@ -20,3 +20,11 @@ O48f80394|stefan|/tmp/testoutput/*0|ant module 2||ant module 2 | |||
O48f80395|stefan|/tmp/testoutput/*0|antmodule1||antmodule1 | |||
O48f80ad6|stefan|/tmp/testoutput/*0|ant module 2||ant module 2 | |||
O48f80ad7|stefan|/tmp/testoutput/*0|antmodule1||antmodule1 | |||
O48f8a1d1|stefan|/tmp/testoutput/*0|ant module 2||ant module 2 | |||
O48f8a1d2|stefan|/tmp/testoutput/*0|antmodule1||antmodule1 | |||
O48f8a6a4|stefan|/tmp/testoutput/*0|ant module 2||ant module 2 | |||
O48f8a6a6|stefan|/tmp/testoutput/*0|antmodule1||antmodule1 | |||
O48f8a764|stefan|/tmp/testoutput/*0|ant module 2||ant module 2 | |||
O48f8a766|stefan|/tmp/testoutput/*0|antmodule1||antmodule1 | |||
O48f8abf0|stefan|/tmp/testoutput/*0|ant module 2||ant module 2 | |||
O48f8abf2|stefan|/tmp/testoutput/*0|antmodule1||antmodule1 |