Index: xdocs/properties.xml =================================================================== --- xdocs/properties.xml (revision 168155) +++ xdocs/properties.xml (working copy) @@ -42,15 +42,49 @@ + maven.changelog.type + Yes + + Indicates what the change log is based on. + This is used by the "changelog" goal. + Possible values are: range (meaning a date range), + date (meaning an absolute date), + or tag (meaning a tag). + The default value is range. + + + maven.changelog.range Yes Specifies the range to use when generating the change log. - This is used by the "changelog" goal. The default value is + This is used by the "changelog" goal if the maven.changelog.type + property is "range". The default value is 30 days. + maven.changelog.date + No (if type==date) + + Specifies an absolute date to use when generating the change log. + This is used by the "changelog" goal if the maven.changelog.type + property is "date". The log will contain changes made after this date. + The date format is that specified by maven.changelog.dateformat if + present; otherwise, the format is yyyy-MM-dd. + + + + maven.changelog.tag + No (if type==tag) + + Specifies the range to use when generating the change log. + This is used by the "changelog" goal if the maven.changelog.type + property is "tag". The log will contain changes made after this + tag. Currently, this is supported for CVS only. + + + maven.changelog.factory Yes @@ -87,7 +121,7 @@ maven.changelog.dateformat Yes - The date format in input stream. It's only used by Starteam changelog. + The date format in input stream. It's only used by Starteam changelog and/or when specifying an absolute date. Index: src/test/org/apache/maven/cvslib/CvsChangeLogGeneratorTest.java =================================================================== --- src/test/org/apache/maven/cvslib/CvsChangeLogGeneratorTest.java (revision 168155) +++ src/test/org/apache/maven/cvslib/CvsChangeLogGeneratorTest.java (working copy) @@ -18,15 +18,22 @@ */ +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + +import junit.framework.TestCase; + +import org.apache.maven.changelog.ChangeLog; import org.apache.maven.util.EnhancedStringTokenizer; import org.apache.maven.util.RepositoryUtils; import org.apache.tools.ant.types.Commandline; -import junit.framework.TestCase; - /** * @author Ben Walding - * @version $Id: CvsChangeLogGeneratorTest.java,v 1.11 2004/09/24 10:47:03 brett Exp $ + * @version $Id$ */ class ExposeGenerator extends CvsChangeLogGenerator { @@ -39,61 +46,115 @@ /** * @author Ben Walding - * @version $Id: CvsChangeLogGeneratorTest.java,v 1.11 2004/09/24 10:47:03 brett Exp $ + * @version $Id$ */ public class CvsChangeLogGeneratorTest extends TestCase { class Test { + Map map; String conn; String args; Class throwable; - public Test(String conn, String args, Class throwable) + public Test(String params, String conn, String args, Class throwable) { + this.map = null; this.conn = conn; this.args = args; this.throwable = throwable; + + if (params != null) + { + map = new HashMap(); + StringTokenizer tokens = new StringTokenizer(params, "|"); + while (tokens.hasMoreTokens()) + { + String name = tokens.nextToken(); + assertTrue("params must have an even number of values.", tokens.hasMoreTokens()); + String value = tokens.nextToken(); + map.put(name, value); + } + } } } + static SimpleDateFormat standardFormat = new SimpleDateFormat("yyyy-MM-dd"); + static String now = standardFormat.format(new Date(System.currentTimeMillis() + (long) 1 * 24 * 60 * 60 * 1000)); + static String range30 = standardFormat.format(new Date(System.currentTimeMillis() - (long) 30 * 24 * 60 * 60 * 1000)); + static String range10 = standardFormat.format(new Date(System.currentTimeMillis() - (long) 10 * 24 * 60 * 60 * 1000)); + Test[] tests = { - new Test(null, "", NullPointerException.class), - new Test("asd:asd", "", IllegalArgumentException.class), + new Test(null, null, "", NullPointerException.class), + new Test(null, "asd:asd", "", IllegalArgumentException.class), new Test( + null, "scm:csvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", "", IllegalArgumentException.class), new Test( + null, "scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", "cvs|-d|:pserver:anoncvs@cvs.apache.org:/home/cvspublic|log", null), new Test( + null, "scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven:anoncvs", "", IllegalArgumentException.class), new Test( + null, "scm|cvs|pserver|anoncvs@cvs.apache.org|D:\\home\\cvspublic|maven", "cvs|-d|:pserver:anoncvs@cvs.apache.org:D:\\home\\cvspublic|log", null), new Test( + null, "scm|cvs|pserver|anoncvs@cvs.apache.org|D:/home/cvspublic|maven", "cvs|-d|:pserver:anoncvs@cvs.apache.org:D:/home/cvspublic|log", null), new Test( + null, "scm:cvs:lserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", "cvs|-d|anoncvs@cvs.apache.org:/home/cvspublic|log", null) , new Test( + null, "scm|cvs|local|local|D:/home/cvspublic|maven", "cvs|-d|D:/home/cvspublic|log", null), new Test( + null, "scm:cvs:extssh:someuser@cvs.apache.org:/home/cvs:maven", "cvs|-d|:extssh:someuser@cvs.apache.org:/home/cvs|log", - null)}; + null), + new Test( + "type|range|range|30", + "scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", + "cvs|-d|:pserver:anoncvs@cvs.apache.org:/home/cvspublic|log|-d " + range30 + "<" + now, + null), + new Test( + "type|range|range|10", + "scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", + "cvs|-d|:pserver:anoncvs@cvs.apache.org:/home/cvspublic|log|-d " + range10 + "<" + now, + null), + new Test( + "type|date|date|2004-04-01", + "scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", + "cvs|-d|:pserver:anoncvs@cvs.apache.org:/home/cvspublic|log|-d 2004-04-01<" + now, + null), + new Test( + "type|date|date|1996-06-12", + "scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", + "cvs|-d|:pserver:anoncvs@cvs.apache.org:/home/cvspublic|log|-d 1996-06-12<" + now, + null), + new Test( + "type|tag|tag|my_tag_name", + "scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven", + "cvs|-d|:pserver:anoncvs@cvs.apache.org:/home/cvspublic|log|-rmy_tag_name::", + null), + }; public void testParse() throws Throwable { @@ -101,36 +162,49 @@ { Test t = tests[i]; - testParse(t); + testParse(t, i); } } - public void testParse(Test test) throws Throwable + public void testParse(Test test, int index) throws Throwable { String[] expected = RepositoryUtils.tokenizerToArray(new EnhancedStringTokenizer(test.args, "|")); ExposeGenerator eg = new ExposeGenerator(); try { - - eg.setConnection(test.conn); + ChangeLog changelog = new ChangeLog(); + if (test.map != null) + { + changelog.setType((String)test.map.get("type")); + changelog.setRange((String)test.map.get("range")); + changelog.setDate((String)test.map.get("date")); + changelog.setTag((String)test.map.get("tag")); + changelog.setDateFormat((String)test.map.get("dateformat")); + } + else + { + changelog.setType("range"); + } + changelog.setRepositoryConnection(test.conn); + eg.init(changelog); Commandline cl = eg.getScmLogCommand(); String[] clArgs = cl.getCommandline(); if (test.throwable == null) { - assertEquals("clArgs.length", expected.length, clArgs.length); + assertEquals("index " + index + ": clArgs.length", expected.length, clArgs.length); for (int i = 0; i < expected.length; i++) { - assertEquals("clArgs[" + i + "]", expected[i], clArgs[i]); + assertEquals("index " + index + ": clArgs[" + i + "]", expected[i], clArgs[i]); } } else { - fail("Failed to throw :" + test.throwable.getName()); + fail("index " + index + ": Failed to throw :" + test.throwable.getName()); } } - catch (Throwable t) + catch (Exception t) { if (test.throwable != null && test.throwable.isAssignableFrom(t.getClass())) { @@ -138,7 +212,7 @@ } else { - throw new RuntimeException("Caught unexpected exception \"" + t.getLocalizedMessage() + "\" testing " + test.conn); + throw new RuntimeException("Caught unexpected exception \"" + t.getLocalizedMessage() + "\" testing " + test.conn + " (index " + index + ")", t); } } Index: src/main/org/apache/maven/cvslib/CvsChangeLogGenerator.java =================================================================== --- src/main/org/apache/maven/cvslib/CvsChangeLogGenerator.java (revision 168155) +++ src/main/org/apache/maven/cvslib/CvsChangeLogGenerator.java (working copy) @@ -178,6 +178,10 @@ { command.createArgument().setValue(dateRange); } + else if (tag != null) + { + command.createArgument().setValue(tag); + } return command; } @@ -195,6 +199,14 @@ SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd"); return "-d " + outputDate.format(before) + "<" + outputDate.format(to); } + + /** + * @see AbstractChangeLogGenerator#getScmTagArgument(String) + */ + protected String getScmTagArgument(String tag) + { + return "-r" + tag + "::"; + } /** * Handle ChangeLogParser IOExceptions. Index: src/main/org/apache/maven/starteamlib/StarteamChangeLogGenerator.java =================================================================== --- src/main/org/apache/maven/starteamlib/StarteamChangeLogGenerator.java (revision 168155) +++ src/main/org/apache/maven/starteamlib/StarteamChangeLogGenerator.java (working copy) @@ -32,7 +32,7 @@ * interface. * * @author Emmanuel Venisse - * @version $Id: StarteamChangeLogGenerator.java,v 1.4 2004/03/02 15:00:18 evenisse Exp $ + * @version $Id$ */ class StarteamChangeLogGenerator extends AbstractChangeLogGenerator { @@ -79,6 +79,14 @@ return ""; } + /** + * @see AbstractChangeLogGenerator#getScmTagArgument(String) + */ + protected String getScmTagArgument(String tag) + { + throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Starteam."); + } + /** * Handle ChangeLogParser IOExceptions. * Index: src/main/org/apache/maven/changelog/AbstractChangeLogGenerator.java =================================================================== --- src/main/org/apache/maven/changelog/AbstractChangeLogGenerator.java (revision 168155) +++ src/main/org/apache/maven/changelog/AbstractChangeLogGenerator.java (working copy) @@ -22,6 +22,8 @@ import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; @@ -47,7 +49,7 @@ * @author Peter Donald * @author Pete Kazmier * @version - * $Id: AbstractChangeLogGenerator.java,v 1.5 2004/03/02 15:00:17 evenisse Exp $ + * $Id$ */ public abstract class AbstractChangeLogGenerator implements ChangeLogGenerator, ExecuteStreamHandler { @@ -70,11 +72,17 @@ /** The connection string from the project */ private String connection; + + /** The log type (range, date, or tag). */ + protected String type; /** - * The date range. + * The date range command line argument. */ protected String dateRange; + + /** The tag command line argument. */ + protected String tag; /** * The collection of ChangeLogEntry's returned from clParser. @@ -105,15 +113,28 @@ changeLogExecutor = changeLog; base = changeLogExecutor.getBasedir(); - - // This lets the user 'not' set a limit on the log command. We - // need this cuz Subversion doesn't currently support date - // commands on web-based repositories, so it would be nice to - // let the user still use the changelog plugin. - if (changeLogExecutor.getRange() != null && changeLogExecutor.getRange().length() != 0) + + type = changeLogExecutor.getType(); + + if (type.equalsIgnoreCase("tag")) { - setDateRange(changeLogExecutor.getRange()); + tag = getScmTagArgument(changeLogExecutor.getTag()); } + else if (type.equalsIgnoreCase("date")) + { + setDateRangeFromAbsoluteDate(changeLogExecutor.getDate()); + } + else // type == "range" (the default) + { + // This lets the user 'not' set a limit on the log command. We + // need this cuz Subversion doesn't currently support date + // commands on web-based repositories, so it would be nice to + // let the user still use the changelog plugin. + if (changeLogExecutor.getRange() != null && changeLogExecutor.getRange().length() != 0) + { + setDateRange(changeLogExecutor.getRange()); + } + } setConnection(changeLogExecutor.getRepositoryConnection()); } @@ -134,7 +155,31 @@ dateRange = getScmDateArgument(before, to); } + + /** + * Set the dateRange member based on an absolute date. + * + * @param startDate The start date for the range. + */ + protected void setDateRangeFromAbsoluteDate(String startDate) + { + String dateFormat = changeLogExecutor.getDateFormat(); + SimpleDateFormat format = dateFormat == null ? new SimpleDateFormat("yyyy-MM-dd") : new SimpleDateFormat(dateFormat); + + Date before; + try + { + before = format.parse(startDate); + } + catch (ParseException ex) + { + throw new IllegalArgumentException("Unable to parse start date " + startDate + ": " + ex.getLocalizedMessage()); + } + Date to = new Date(System.currentTimeMillis() + (long) 1 * 24 * 60 * 60 * 1000); + dateRange = getScmDateArgument(before, to); + } + /** * Execute scm client driving the given parser. * @@ -228,6 +273,16 @@ */ protected abstract String getScmDateArgument(Date before, Date to); + /** + * Construct the command-line argument that is passed to the scm + * client to specify the appropriate tag. + * + * @param tag The tag name. + * @return A string that can be used to specify a tag to a scm + * system. + */ + protected abstract String getScmTagArgument(String tag); + /** * Stop the process - currently unimplemented */ Index: src/main/org/apache/maven/changelog/ChangeLog.java =================================================================== --- src/main/org/apache/maven/changelog/ChangeLog.java (revision 168155) +++ src/main/org/apache/maven/changelog/ChangeLog.java (working copy) @@ -54,10 +54,19 @@ */ public class ChangeLog { + /** Used to specify whether to build the log from a range, absolute date, or tag. */ + private String type; + /** * Used to specify the range of log entries to retrieve. */ private String range; + + /** Used to specify the absolute date to start log entries from. */ + private String date; + + /** Used to specify the tag to start log entries from. */ + private String tag; /** * Used to specify the date format of log entries to retrieve. @@ -118,8 +127,30 @@ } /** + * Set the type of log to generate (range, date, or tag). + * + * @param type one of "range", "date", or "tag". + */ + public void setType(String type) + { + this.type = type; + } + + /** + * Get the type of log to generate (range, date, or tag). + * + * @return the basis for the log. + */ + public String getType() + { + return type; + } + + + /** * Set the range of log entries to process; the interpretation of this * parameter depends on the generator. + * This is only used if the type is "range". * * @param range the range of log entries. */ @@ -138,6 +169,52 @@ { return range; } + + + /** + * Set the date to start the log from. + * This is only used if the type is "date". + * The format is that given by the dateFormat property, if present. Otherwise, the format is "yyyy-MM-dd". + * + * @param date the date to use. + */ + public void setDate(String date) + { + this.date = date; + } + + /** + * Get the date to start the log from. + * + * @return the start date. + */ + public String getDate() + { + return date; + } + + + /** + * Set the tag to start the log from. + * This is only used if the type is "tag". + * + * @param tag the tag to use. + */ + public void setTag(String tag) + { + this.tag = tag; + } + + /** + * Get the tag to start the log from. + * + * @return the tag. + */ + public String getTag() + { + return tag; + } + /** * Set the date format of log entries to process; the Index: src/main/org/apache/maven/clearcaselib/ClearcaseChangeLogGenerator.java =================================================================== --- src/main/org/apache/maven/clearcaselib/ClearcaseChangeLogGenerator.java (revision 168155) +++ src/main/org/apache/maven/clearcaselib/ClearcaseChangeLogGenerator.java (working copy) @@ -99,4 +99,11 @@ return argument; } + /** + * @see AbstractChangeLogGenerator#getScmTagArgument(String) + */ + protected String getScmTagArgument(String tag) + { + throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Clearcase."); + } } Index: src/main/org/apache/maven/perforcelib/PerforceChangeLogGenerator.java =================================================================== --- src/main/org/apache/maven/perforcelib/PerforceChangeLogGenerator.java (revision 168155) +++ src/main/org/apache/maven/perforcelib/PerforceChangeLogGenerator.java (working copy) @@ -109,4 +109,12 @@ throw ioe; } } + + /** + * @see AbstractChangeLogGenerator#getScmTagArgument(String) + */ + protected String getScmTagArgument(String tag) + { + throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Perforce."); + } } Index: src/main/org/apache/maven/svnlib/SvnChangeLogGenerator.java =================================================================== --- src/main/org/apache/maven/svnlib/SvnChangeLogGenerator.java (revision 168155) +++ src/main/org/apache/maven/svnlib/SvnChangeLogGenerator.java (working copy) @@ -88,6 +88,14 @@ outputDate.format(before) + "}\""; } + /** + * @see AbstractChangeLogGenerator#getScmTagArgument(String) + */ + protected String getScmTagArgument(String tag) + { + throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Subversion."); + } + /** * Handle ChangeLogParser IOExceptions. * Index: plugin.properties =================================================================== --- plugin.properties (revision 168155) +++ plugin.properties (working copy) @@ -22,4 +22,8 @@ maven.changelog.basedir=${basedir} +maven.changelog.type = range maven.changelog.range = 30 +#maven.changelog.date = +#maven.changelog.tag = + Index: plugin.jelly =================================================================== --- plugin.jelly (revision 168155) +++ plugin.jelly (working copy) @@ -69,6 +69,27 @@ ${pom.repository.developerConnection} + + + + + + + + The maven.changelog.date property is required when maven.changelog.type==date. The value should be the absolute date for the start of the log. + + + + + The maven.changelog.tag property is required when maven.changelog.type==tag. The value should be the value of the tag for the start of the log. + + + + The maven.changelog.type property has an invalid value: ${maven.changelog.type} The value should be "range", "date", or "tag". + + + + Generating the changelog report