bodewig 2005/02/16 06:08:41 Modified: proposal/sandbox/svn/docs revisiondiff.html proposal/sandbox/svn/src/etc/testcases revisiondiff.xml proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn SvnRevisionDiff.java antlib.xml proposal/sandbox/svn/src/testcases/org/apache/tools/ant/taskdefs/svn SvnRevisionDiffTest.java Added: proposal/sandbox/svn/docs tagdiff.html proposal/sandbox/svn/src/etc diff.xsl proposal/sandbox/svn/src/etc/testcases tagdiff.xml proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn SvnDiffHandler.java SvnTagDiff.java proposal/sandbox/svn/src/testcases/org/apache/tools/ant/taskdefs/svn SvnTagDiffTest.java Removed: proposal/sandbox/svn/src/etc revisiondiff.xsl Log: Add a tagdiff, which is probably more usefull than revisiondiff Revision Changes Path 1.2 +1 -1 ant/proposal/sandbox/svn/docs/revisiondiff.html Index: revisiondiff.html =================================================================== RCS file: /home/cvs/ant/proposal/sandbox/svn/docs/revisiondiff.html,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- revisiondiff.html 15 Feb 2005 13:30:49 -0000 1.1 +++ revisiondiff.html 16 Feb 2005 14:08:41 -0000 1.2 @@ -100,7 +100,7 @@ <pre> <style in="diff.xml" out="diff.html" - style="your-path-to/etc/revisiondiff.xsl"> + style="your-path-to/etc/diff.xsl"> <param name="title" expression="Jakarta BCEL diff"/> <param name="repo" expression="http://svn.apache.org/repos/asf/jakarta/bcel/trunk"/> </style> 1.1 ant/proposal/sandbox/svn/docs/tagdiff.html Index: tagdiff.html =================================================================== <html> <head> <meta http-equiv="Content-Language" content="en-us"> <title>RevisionDiff Task</title> </head> <body> <h2><a name="tagdiff">TagDiff</a></h2> <h3>Description</h3> <p>Generates an XML-formatted report file of the changes between two tags recorded in a <a href="http://subversion.tigris.org/" target="_top">Subversion</a> repository. </p> <p><b>Important:</b> This task needs "svn" on the path. If it isn't, you will get an error (such as error 2 on windows). If <code><svn></code> doesn't work, try to execute <code>svn.exe</code> from the command line in the target directory in which you are working.</p> <p>This task assumes that your repository follows the best-practice layout of</p> <pre> BASEURL | | -----> trunk -----> tags | | ----------> tag1 ----------> tag2 </pre> <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">tag1</td> <td valign="top">The first tag.</td> <td align="center" valign="top">Yes.</td> </tr> <tr> <td valign="top">tag2</td> <td valign="top">The second tag.</td> <td align="center" valign="top">No, defaults to "trunk/"</td> </tr> <tr> <td valign="top">destfile</td> <td valign="top">The file in which to write the diff report.</td> <td align="center" valign="top">Yes</td> </tr> <tr> <td valign="top">baseURL</td> <td valign="top">The baseURL of the repository, used to calculate the two URLs to compare.</td> <td align="center" valign="top">Yes</td> </tr> </table> <h3>Parameters inherited from the <code>svn</code> task</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">failonerror</td> <td valign="top">Stop the buildprocess if the command exits with a returncode other than 0. Defaults to false</td> <td align="center" valign="top">No</td> </tr> </table> <h3>Examples</h3> <pre> <tagdiff failonerror="true" baseURL="http://svn.apache.org/repos/asf/jakarta/bcel/" destfile="diff.xml" tag1="initial" tag2="BCEL_5_0" /> </pre> <p>Generates a tagdiff report for all the changes that have been made in the <code>Apache BCEL</code> module between the tags <code>initial</code> and <code>BCEL_5_0</code>. It writes these changes into the file <code>diff.xml</code>.</p> <pre> <tagdiff failonerror="true" baseURL="http://svn.apache.org/repos/asf/jakarta/bcel/" destfile="diff.xml" tag1="BCEL_5_0" tag2="trunk" /> </pre> <p>Generates a tagdiff report for all the changes that have been made in the <code>Apache BCEL</code> module between the tag <code>BCEL_5_0</code> and the <code>trunk</code>. It writes these changes into the file <code>diff.xml</code>.</p> <pre> <tagdiff failonerror="true" baseURL="http://svn.apache.org/repos/asf/jakarta/bcel/" destfile="diff.xml" tag1="BCEL_5_0" /> </pre> <p>Does the same, using <code>trunk</code> as <code>tag2</code> implicitly.</p> <h4>Generate Report</h4> <p>This antlib includes a basic XSLT stylesheet that you can use to generate a HTML report based on the xml output. The following example illustrates how to generate a HTML report from the XML report.</p> <pre> <style in="diff.xml" out="diff.html" style="your-path-to/etc/diff.xsl"> <param name="title" expression="Jakarta BCEL diff"/> <param name="repo" expression="http://svn.apache.org/repos/asf/jakarta/bcel/trunk"/> </style> </pre> <h4>(Shortened) Example Output</h4> <pre> <?xml version="1.0" encoding="UTF-8"?> <tagdiff tag1="BCEL_5_0" svnurl="http://svn.apache.org/repos/asf/jakarta/bcel/" > <path> <name><![CDATA[default.properties]]></name> <action>added</action> </path> <path> <name><![CDATA[xdocs/images/classloader.gif]]></name> <action>modified</action> </path> <path> <name><![CDATA[README]]></name> <action>deleted</action> </path> </tagdiff> </pre> <hr><p align="center">Copyright © 2005 The Apache Software Foundation. All rights Reserved.</p> </body> </html> 1.1 ant/proposal/sandbox/svn/src/etc/diff.xsl Index: diff.xsl =================================================================== <!-- Copyright 2005 The Apache Software Foundation Licensed 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. --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="title"/> <xsl:param name="repo"/> <xsl:output method="html" indent="yes"/> <!-- Copy standard document elements. Elements that should be ignored must be filtered by apply-templates tags. --> <xsl:template match="*"> <xsl:copy> <xsl:copy-of select="attribute::*[. != '']"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="revisiondiff|tagdiff"> <HTML> <HEAD> <TITLE><xsl:value-of select="$title"/></TITLE> </HEAD> <BODY link="#000000" alink="#000000" vlink="#000000" text="#000000"> <style type="text/css"> body, p { font-family: verdana,arial,helvetica; font-size: 80%; color:#000000; } .dateAndAuthor { font-family: verdana,arial,helvetica; font-size: 80%; font-weight: bold; text-align:left; background:#a6caf0; } tr, td{ font-family: verdana,arial,helvetica; font-size: 80%; background:#eeeee0; } </style> <h1> <a name="top"><xsl:value-of select="$title"/></a> </h1> diff between <xsl:value-of select="@start"/><xsl:value-of select="@tag1"/> and <xsl:value-of select="@end"/><xsl:value-of select="@tag2"/> <p align="right">Designed for use with <a href="http://ant.apache.org/">Apache Ant</a>.</p> <hr size="2"/> <a name="TOP"/> <table width="100%"> <tr> <td align="right"> <a href="#New">New Files</a> | <a href="#Modified">Modified Files</a> | <a href="#Removed">Removed Files</a> </td> </tr> </table> <TABLE BORDER="0" WIDTH="100%" CELLPADDING="3" CELLSPACING="1"> <xsl:call-template name="show-paths"> <xsl:with-param name="title">New Files</xsl:with-param> <xsl:with-param name="anchor">New</xsl:with-param> <xsl:with-param name="paths" select=".//path[action='added']"/> </xsl:call-template> <xsl:call-template name="show-paths"> <xsl:with-param name="title">Modified Files</xsl:with-param> <xsl:with-param name="anchor">Modified</xsl:with-param> <xsl:with-param name="paths" select=".//path[action='modified']"/> </xsl:call-template> <xsl:call-template name="show-paths"> <xsl:with-param name="title">Removed Files</xsl:with-param> <xsl:with-param name="anchor">Removed</xsl:with-param> <xsl:with-param name="paths" select=".//path[action='deleted']"/> </xsl:call-template> </TABLE> </BODY> </HTML> </xsl:template> <xsl:template name="show-paths"> <xsl:param name="title"/> <xsl:param name="anchor"/> <xsl:param name="paths"/> <TR> <TD colspan="2" class="dateAndAuthor"> <a> <xsl:attribute name="name"><xsl:value-of select="$anchor"/></xsl:attribute> <xsl:value-of select="$title"/> - <xsl:value-of select="count($paths)"/> entries </a> <a href="#TOP">(back to top)</a> </TD> </TR> <TR> <TD width="20"> <xsl:text> </xsl:text> </TD> <TD> <ul> <xsl:apply-templates select="$paths"/> </ul> </TD> </TR> </xsl:template> <xsl:template match="path"> <li> <a target="_new"> <xsl:attribute name="href"><xsl:value-of select="$repo"/>/<xsl:value-of select="name" /></xsl:attribute> <xsl:value-of select="name" /> </a> </li> </xsl:template> <!-- Any elements within a msg are processed, so that we can preserve HTML tags. --> <xsl:template match="msg"> <b><xsl:apply-templates/></b> </xsl:template> </xsl:stylesheet> 1.3 +1 -1 ant/proposal/sandbox/svn/src/etc/testcases/revisiondiff.xml Index: revisiondiff.xml =================================================================== RCS file: /home/cvs/ant/proposal/sandbox/svn/src/etc/testcases/revisiondiff.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- revisiondiff.xml 15 Feb 2005 14:46:46 -0000 1.2 +++ revisiondiff.xml 16 Feb 2005 14:08:41 -0000 1.3 @@ -46,7 +46,7 @@ <target name="report" depends="diff-using-url"> <style in="${tmpdir}/diff.xml" out="${tmpdir}/diff.html" - style="src/etc/revisiondiff.xsl"> + style="src/etc/diff.xsl"> <param name="title" expression="Jakarta BCEL diff"/> <param name="repo" expression="http://svn.apache.org/repos/asf/jakarta/bcel/trunk"/> </style> 1.1 ant/proposal/sandbox/svn/src/etc/testcases/tagdiff.xml Index: tagdiff.xml =================================================================== <?xml version="1.0"?> <!-- Copyright 2005 The Apache Software Foundation Licensed 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. --> <project name="revisiondiff-test" basedir="../../../" default="diff-with-implicit-trunk" xmlns:svn="antlib:org.apache.tools.ant.taskdefs.svn"> <property name="tmpdir" value="tmpdir"/> <target name="dir-prep"> <mkdir dir="${tmpdir}"/> </target> <target name="diff-with-two-tags" depends="dir-prep"> <svn:tagdiff failonerror="true" baseURL="http://svn.apache.org/repos/asf/jakarta/bcel/" destfile="${tmpdir}/diff.xml" tag2="BCEL_5_0" tag1="initial"/> </target> <target name="diff-with-explicit-trunk" depends="dir-prep"> <svn:tagdiff failonerror="true" baseURL="http://svn.apache.org/repos/asf/jakarta/bcel/" destfile="${tmpdir}/diff.xml" tag1="BCEL_5_0" tag2="trunk"/> </target> <target name="diff-with-implicit-trunk" depends="dir-prep"> <svn:tagdiff failonerror="true" baseURL="http://svn.apache.org/repos/asf/jakarta/bcel/" destfile="${tmpdir}/diff.xml" tag1="BCEL_5_0"/> </target> <!--target name="report" depends="diff-with-implicit-trunk"--> <target name="report"> <style in="/tmp/diff.xml" out="/tmp/diff.html" style="src/etc/diff.xsl"> <param name="title" expression="Jakarta BCEL diff"/> <param name="repo" expression="http://svn.apache.org/repos/asf/jakarta/bcel/trunk"/> </style> </target> <target name="cleanup"> <delete dir="${tmpdir}" /> </target> </project> 1.2 +9 -168 ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnRevisionDiff.java Index: SvnRevisionDiff.java =================================================================== RCS file: /home/cvs/ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnRevisionDiff.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SvnRevisionDiff.java 15 Feb 2005 13:30:49 -0000 1.1 +++ SvnRevisionDiff.java 16 Feb 2005 14:08:41 -0000 1.2 @@ -39,10 +39,11 @@ * <!-- Root element --> * <!ELEMENT revisiondiff ( paths? ) > * <!-- Start revision of the report --> - * <!ATTLIST revisiondiff startRevision NMTOKEN #IMPLIED > + * <!ATTLIST revisiondiff start NMTOKEN #IMPLIED > * <!-- End revision of the report --> - * <!ATTLIST revisiondiff endRevision NMTOKEN #IMPLIED > - * <!-- Start date of the report --> + * <!ATTLIST revisiondiff end NMTOKEN #IMPLIED > + * <!-- Subversion URL if known --> + * <!ATTLIST revisiondiff svnurl NMTOKEN #IMPLIED > * * <!-- Path added, changed or removed --> * <!ELEMENT path ( name,action ) > @@ -61,25 +62,6 @@ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); /** - * Token to identify the word file in the rdiff log - */ - static final String INDEX = "Index: "; - /** - * Token to identify a deleted file based on the Index line. - */ - static final String DELETED = " (deleted)"; - - /** - * Token to identify added files based on the diff line. - */ - static final String IS_NEW = "\t(revision 0)"; - - /** - * Token that starts diff line of old revision. - */ - static final String DASHES = "--- "; - - /** * The earliest revision from which diffs are to be included in the report. */ private String mystartRevision; @@ -145,12 +127,13 @@ // run the svn command super.execute(); - // parse the rdiff - SvnEntry.Path[] entries = parseDiff(tmpFile); + // parse the diff + SvnEntry.Path[] entries = SvnDiffHandler.parseDiff(tmpFile); // write the revision diff - writeRevisionDiff(entries); - + SvnDiffHandler.writeDiff(mydestfile, entries, "revisiondiff", + "start", mystartRevision, + "end", myendRevision, getSvnURL()); } finally { if (tmpFile != null) { tmpFile.delete(); @@ -159,148 +142,6 @@ } /** - * Parse the tmpFile and return and array of SvnRevisionEntry to be - * written in the output. - * - * @param tmpFile the File containing the output of the svn rdiff command - * @return the entries in the output - * @exception BuildException if an error occurs - */ - private SvnEntry.Path[] parseDiff(File tmpFile) throws BuildException { - // parse the output of the command - BufferedReader reader = null; - - try { - reader = new BufferedReader(new FileReader(tmpFile)); - ArrayList entries = new ArrayList(); - - String line = reader.readLine(); - String name = null; - String currDiffLine = null; - boolean deleted = false; - boolean added = false; - - while (null != line) { - if (line.length() > INDEX.length()) { - if (line.startsWith(INDEX)) { - if (name != null) { - SvnEntry.Path p = - new SvnEntry.Path(name, - deleted - ? SvnEntry.Path.DELETED - : (added - ? SvnEntry.Path.ADDED - : SvnEntry.Path.MODIFIED) - ); - entries.add(p); - deleted = added = false; - } - - name = line.substring(INDEX.length()); - if (line.endsWith(DELETED)) { - name = name.substring(0, name.length() - - DELETED.length()); - deleted = true; - } - - currDiffLine = DASHES + name; - } else if (currDiffLine != null - && line.startsWith(currDiffLine) - && line.endsWith(IS_NEW)) { - added = true; - } - } - line = reader.readLine(); - } - if (name != null) { - SvnEntry.Path p = new SvnEntry.Path(name, - deleted - ? SvnEntry.Path.DELETED - : (added - ? SvnEntry.Path.ADDED - : SvnEntry.Path.MODIFIED) - ); - entries.add(p); - } - - SvnEntry.Path[] array = (SvnEntry.Path[]) - entries.toArray(new SvnEntry.Path[entries.size()]); - return array; - } catch (IOException e) { - throw new BuildException("Error in parsing", e); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - log(e.toString(), Project.MSG_ERR); - } - } - } - } - - /** - * Write the rdiff log. - * - * @param entries a <code>SvnRevisionEntry[]</code> value - * @exception BuildException if an error occurs - */ - private void writeRevisionDiff(SvnEntry.Path[] entries) throws BuildException { - FileOutputStream output = null; - try { - output = new FileOutputStream(mydestfile); - PrintWriter writer = new PrintWriter( - new OutputStreamWriter(output, "UTF-8")); - writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - writer.print("<revisiondiff "); - if (mystartRevision != null) { - writer.print("start=\"" + mystartRevision + "\" "); - } - if (myendRevision != null) { - writer.print("end=\"" + myendRevision + "\" "); - } - - if (getSvnURL() != null) { - writer.print("svnurl=\"" + getSvnURL() + "\" "); - } - - writer.println(">"); - for (int i = 0, c = entries.length; i < c; i++) { - writeRevisionEntry(writer, entries[i]); - } - writer.println("</revisiondiff>"); - writer.flush(); - writer.close(); - } catch (UnsupportedEncodingException uee) { - log(uee.toString(), Project.MSG_ERR); - } catch (IOException ioe) { - throw new BuildException(ioe.toString(), ioe); - } finally { - if (null != output) { - try { - output.close(); - } catch (IOException ioe) { - log(ioe.toString(), Project.MSG_ERR); - } - } - } - } - - /** - * Write a single entry to the given writer. - * - * @param writer a <code>PrintWriter</code> value - * @param entry a <code>SvnRevisionEntry</code> value - */ - private void writeRevisionEntry(PrintWriter writer, SvnEntry.Path entry) { - writer.println("\t<path>"); - writer.println("\t\t<name><![CDATA[" + entry.getName() + "]]></name>"); - writer.println("\t\t<action>" + entry.getActionDescription() - + "</action>"); - writer.println("\t</path>"); - } - - /** * Validate the parameters specified for task. * * @exception BuildException if a parameter is not correctly set 1.4 +4 -0 ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/antlib.xml Index: antlib.xml =================================================================== RCS file: /home/cvs/ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/antlib.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- antlib.xml 15 Feb 2005 13:30:49 -0000 1.3 +++ antlib.xml 16 Feb 2005 14:08:41 -0000 1.4 @@ -27,4 +27,8 @@ name="revisiondiff" classname="org.apache.tools.ant.taskdefs.svn.SvnRevisionDiff" /> + <taskdef + name="tagdiff" + classname="org.apache.tools.ant.taskdefs.svn.SvnTagDiff" + /> </antlib> 1.1 ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnDiffHandler.java Index: SvnDiffHandler.java =================================================================== /* * Copyright 2005 The Apache Software Foundation * * Licensed 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.svn; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.StringTokenizer; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.util.FileUtils; /** * Parses the output of a svn diff command and/or writes an XML report * based on such a diff output. * * It produces an XML output representing the list of changes. */ final class SvnDiffHandler { /** * Token to identify the word file in the rdiff log */ private static final String INDEX = "Index: "; /** * Token to identify a deleted file based on the Index line. */ private static final String DELETED = " (deleted)"; /** * Token to identify added files based on the diff line. */ private static final String IS_NEW = "\t(revision 0)"; /** * Token that starts diff line of old revision. */ private static final String DASHES = "--- "; /** * Parse the tmpFile and return and array of entries to be written * in the output. * * @param tmpFile the File containing the output of the svn rdiff command * @return the entries in the output * @exception BuildException if an error occurs */ static SvnEntry.Path[] parseDiff(File tmpFile) throws BuildException { // parse the output of the command BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(tmpFile)); ArrayList entries = new ArrayList(); String line = reader.readLine(); String name = null; String currDiffLine = null; boolean deleted = false; boolean added = false; while (null != line) { if (line.length() > INDEX.length()) { if (line.startsWith(INDEX)) { if (name != null) { SvnEntry.Path p = new SvnEntry.Path(name, deleted ? SvnEntry.Path.DELETED : (added ? SvnEntry.Path.ADDED : SvnEntry.Path.MODIFIED) ); entries.add(p); deleted = added = false; } name = line.substring(INDEX.length()); if (line.endsWith(DELETED)) { name = name.substring(0, name.length() - DELETED.length()); deleted = true; } currDiffLine = DASHES + name; } else if (currDiffLine != null && line.startsWith(currDiffLine) && line.endsWith(IS_NEW)) { added = true; } } line = reader.readLine(); } if (name != null) { SvnEntry.Path p = new SvnEntry.Path(name, deleted ? SvnEntry.Path.DELETED : (added ? SvnEntry.Path.ADDED : SvnEntry.Path.MODIFIED) ); entries.add(p); } SvnEntry.Path[] array = (SvnEntry.Path[]) entries.toArray(new SvnEntry.Path[entries.size()]); return array; } catch (IOException e) { throw new BuildException("Error in parsing", e); } finally { FileUtils.close(reader); } } /** * Write the diff log. * * @param entries a <code>SvnRevisionEntry[]</code> value * @exception BuildException if an error occurs */ static void writeDiff(File destFile, SvnEntry.Path[] entries, String rootElementName, String tag1Name, String tag1Value, String tag2Name, String tag2Value, String svnURL) throws BuildException { FileOutputStream output = null; try { output = new FileOutputStream(destFile); PrintWriter writer = new PrintWriter( new OutputStreamWriter(output, "UTF-8")); writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); writer.print("<" + rootElementName + " "); if (tag1Name != null && tag1Value != null) { writer.print(tag1Name + "=\"" + tag1Value + "\" "); } if (tag2Name != null && tag2Value != null) { writer.print(tag2Name + "=\"" + tag2Value + "\" "); } if (svnURL != null) { writer.print("svnurl=\"" + svnURL + "\" "); } writer.println(">"); for (int i = 0, c = entries.length; i < c; i++) { writeRevisionEntry(writer, entries[i]); } writer.println("</" + rootElementName + ">"); writer.flush(); writer.close(); } catch (UnsupportedEncodingException uee) { throw new BuildException(uee); } catch (IOException ioe) { throw new BuildException(ioe.toString(), ioe); } finally { FileUtils.close(output); } } /** * Write a single entry to the given writer. * * @param writer a <code>PrintWriter</code> value * @param entry a <code>SvnRevisionEntry</code> value */ private static void writeRevisionEntry(PrintWriter writer, SvnEntry.Path entry) { writer.println("\t<path>"); writer.println("\t\t<name><![CDATA[" + entry.getName() + "]]></name>"); writer.println("\t\t<action>" + entry.getActionDescription() + "</action>"); writer.println("\t</path>"); } } 1.1 ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnTagDiff.java Index: SvnTagDiff.java =================================================================== /* * Copyright 2005 The Apache Software Foundation * * Licensed 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.svn; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.StringTokenizer; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.util.FileUtils; /** * Examines the output of svn diff between two tags or a tag and trunk. * * <p>This task only works if you follow the best-practice structure of * <pre> * BASEURL * | * | * -----> trunk * -----> tags * | * | * ----------> tag1 * ----------> tag2 * </pre> * * It produces an XML output representing the list of changes. * <PRE> * <!-- Root element --> * <!ELEMENT tagdiff ( paths? ) > * <!-- First tag --> * <!ATTLIST tagdiff tag1 NMTOKEN #IMPLIED > * <!-- Second tag --> * <!ATTLIST tagdiff tag2 NMTOKEN #IMPLIED > * <!-- Subversion BaseURL --> * <!ATTLIST tagdiff svnurl NMTOKEN #IMPLIED > * * <!-- Path added, changed or removed --> * <!ELEMENT path ( name,action ) > * <!-- Name of the file --> * <!ELEMENT name ( #PCDATA ) > * <!ELEMENT action (added|modified|deleted)> * </PRE> * * @ant.task name="svntagdiff" */ public class SvnTagDiff extends AbstractSvnTask { /** * Used to create the temp file for svn log */ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); /** * The earliest revision from which diffs are to be included in the report. */ private String tag1; /** * The latest revision from which diffs are to be included in the report. */ private String tag2; /** * The file in which to write the diff report. */ private File mydestfile; /** * Base URL. */ private String baseURL; /** * Set the first tag. * * @param s the first tag. */ public void setTag1(String s) { tag1 = s; } /** * Set the second tag. * * @param s the second tag. */ public void setTag2(String s) { tag2 = s; } /** * Set the output file for the diff. * * @param f the output file for the diff. */ public void setDestFile(File f) { mydestfile = f; } /** * Set the base URL from which to calculate tag URLs. * * @param u the base URL from which to calculate tag URLs. */ public void setBaseURL(String u) { baseURL = u; if (!u.endsWith("/")) { baseURL += "/"; } } /** * Execute task. * * @exception BuildException if an error occurs */ public void execute() throws BuildException { // validate the input parameters validate(); // build the rdiff command setSubCommand("diff"); addSubCommandArgument("--no-diff-deleted"); if (tag1.equals("trunk") || tag1.equals("trunk/")) { addSubCommandArgument(baseURL + "trunk/"); } else { if (tag1.endsWith("/")) { addSubCommandArgument(baseURL + "tags/" + tag1); } else { addSubCommandArgument(baseURL + "tags/" + tag1 + "/"); } } if (tag2 == null || tag2.equals("trunk") || tag2.equals("trunk/")) { addSubCommandArgument(baseURL + "trunk/"); } else { if (tag2.endsWith("/")) { addSubCommandArgument(baseURL + "tags/" + tag2); } else { addSubCommandArgument(baseURL + "tags/" + tag2 + "/"); } } File tmpFile = null; try { tmpFile = FILE_UTILS.createTempFile("svntagdiff", ".log", null); tmpFile.deleteOnExit(); setOutput(tmpFile); // run the svn command super.execute(); // parse the diff SvnEntry.Path[] entries = SvnDiffHandler.parseDiff(tmpFile); // write the revision diff SvnDiffHandler.writeDiff(mydestfile, entries, "tagdiff", "tag1", tag1, "tag2", tag2 == null ? "trunk" : tag2, baseURL); } finally { if (tmpFile != null) { tmpFile.delete(); } } } /** * Validate the parameters specified for task. * * @exception BuildException if a parameter is not correctly set */ private void validate() throws BuildException { if (null == mydestfile) { throw new BuildException("Destfile must be set."); } if (null == tag1) { throw new BuildException("tag1 must be set."); } if (null == baseURL) { throw new BuildException("baseURL must be set."); } } } 1.2 +2 -2 ant/proposal/sandbox/svn/src/testcases/org/apache/tools/ant/taskdefs/svn/SvnRevisionDiffTest.java Index: SvnRevisionDiffTest.java =================================================================== RCS file: /home/cvs/ant/proposal/sandbox/svn/src/testcases/org/apache/tools/ant/taskdefs/svn/SvnRevisionDiffTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SvnRevisionDiffTest.java 15 Feb 2005 14:46:46 -0000 1.1 +++ SvnRevisionDiffTest.java 16 Feb 2005 14:08:41 -0000 1.2 @@ -74,9 +74,9 @@ int end = log.indexOf(">", start); Assert.assertTrue(end > -1); Assert.assertTrue(log.indexOf("start=\"152904\"", start) > -1); - Assert.assertTrue(log.indexOf("start=\"152904\"") < end); + Assert.assertTrue(log.indexOf("start=\"152904\"", start) < end); Assert.assertTrue(log.indexOf("end=\"153682\"", start) > -1); - Assert.assertTrue(log.indexOf("end=\"153682\"") < end); + Assert.assertTrue(log.indexOf("end=\"153682\"", start) < end); } private static final void assertAttributesNoURL(String log) { 1.1 ant/proposal/sandbox/svn/src/testcases/org/apache/tools/ant/taskdefs/svn/SvnTagDiffTest.java Index: SvnTagDiffTest.java =================================================================== /* * Copyright 2005 The Apache Software Foundation * * Licensed 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.svn; import java.io.IOException; import java.io.FileReader; import org.apache.tools.ant.BuildFileTest; import org.apache.tools.ant.util.FileUtils; import junit.framework.Assert; /** */ public class SvnTagDiffTest extends BuildFileTest { public SvnTagDiffTest(String name) { super(name); } public void setUp() { configureProject("src/etc/testcases/tagdiff.xml"); } public void tearDown() { executeTarget("cleanup"); } public void testDiffWithTwoTags() throws IOException { String log = executeTargetAndReadLogFully("diff-with-two-tags"); assertAttributes(log, "initial", "BCEL_5_0"); assertAdded1(log); } public void testDiffWithExplicitTrunk() throws IOException { String log = executeTargetAndReadLogFully("diff-with-explicit-trunk"); assertDiffWithTrunk(log); } public void testDiffWithImplicitTrunk() throws IOException { String log = executeTargetAndReadLogFully("diff-with-implicit-trunk"); assertDiffWithTrunk(log); } private static void assertDiffWithTrunk(String log) { assertAttributes(log, "BCEL_5_0", "trunk"); assertAdded(log); assertModified(log); assertDeleted(log); } private String executeTargetAndReadLogFully(String target) throws IOException { executeTarget(target); FileReader r = new FileReader(getProject() .resolveFile("tmpdir/diff.xml")); try { return FileUtils.readFully(r); } finally { r.close(); } } private static final void assertAttributes(String log, String tag1, String tag2) { int start = log.indexOf("<tagdiff"); Assert.assertTrue(start > -1); int end = log.indexOf(">", start); Assert.assertTrue(end > -1); Assert.assertTrue(log.indexOf("tag1=\"" + tag1 + "\"", start) > -1); Assert.assertTrue(log.indexOf("tag1=\"" + tag1 + "\"", start) < end); Assert.assertTrue(log.indexOf("tag2=\"" + tag2 + "\"", start) > -1); Assert.assertTrue(log.indexOf("tag2=\"" + tag2 + "\"", start) < end); Assert.assertTrue(log.indexOf("svnurl=\"http://svn.apache.org/repos/" + "asf/jakarta/bcel/\"", start) > -1); Assert.assertTrue(log.indexOf("svnurl=\"http://svn.apache.org/repos/" + "asf/jakarta/bcel/\"", start) < end); } private static final void assertAdded(String log) { int name = log.indexOf("<![CDATA[LICENSE.txt]]>"); Assert.assertTrue(name > -1); int pathAfterName = log.indexOf("</path>", name); Assert.assertTrue(pathAfterName > -1); Assert.assertTrue(log.indexOf("<action>added</action>", name) > -1); Assert.assertTrue(log.indexOf("<action>added</action>", name) < pathAfterName); } private static final void assertModified(String log) { int name = log.indexOf("<name><![CDATA[src/java/org/apache/bcel/" + "Repository.java]]></name>"); Assert.assertTrue(name > -1); int pathAfterName = log.indexOf("</path>", name); Assert.assertTrue(pathAfterName > -1); Assert.assertTrue(log.indexOf("<action>modified</action>", name) > -1); Assert.assertTrue(log.indexOf("<action>modified</action>", name) < pathAfterName); } private static final void assertDeleted(String log) { int name = log.indexOf("<name><![CDATA[LICENSE]]></name>"); Assert.assertTrue(name > -1); int pathAfterName = log.indexOf("</path>", name); Assert.assertTrue(pathAfterName > -1); Assert.assertTrue(log.indexOf("<action>deleted</action>", name) > -1); Assert.assertTrue(log.indexOf("<action>deleted</action>", name) < pathAfterName); } private static final void assertAdded1(String log) { int name = log.indexOf("<name><![CDATA[src/java/org/apache/bcel/" + "Repository.java]]></name>"); Assert.assertTrue(name > -1); int pathAfterName = log.indexOf("</path>", name); Assert.assertTrue(pathAfterName > -1); Assert.assertTrue(log.indexOf("<action>added</action>", name) > -1); Assert.assertTrue(log.indexOf("<action>added</action>", name) < pathAfterName); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]