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>
           &lt;style in="diff.xml" 
                  out="diff.html" 
  -               style="your-path-to/etc/revisiondiff.xsl"&gt;
  +               style="your-path-to/etc/diff.xsl"&gt;
             &lt;param name="title" expression="Jakarta BCEL diff"/&gt;
             &lt;param name="repo" 
expression="http://svn.apache.org/repos/asf/jakarta/bcel/trunk"/&gt;
           &lt;/style&gt;
  
  
  
  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>&lt;svn&gt;</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
    |
    |
    -----&gt; trunk
    -----&gt; tags
             |
             |
             ----------&gt; tag1
             ----------&gt; 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>
    &lt;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>
    &lt;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>
    &lt;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>
          &lt;style in="diff.xml" 
                 out="diff.html" 
                 style="your-path-to/etc/diff.xsl"&gt;
            &lt;param name="title" expression="Jakarta BCEL diff"/&gt;
            &lt;param name="repo" 
expression="http://svn.apache.org/repos/asf/jakarta/bcel/trunk"/&gt;
          &lt;/style&gt;
  </pre>
  
  <h4>(Shortened) Example Output</h4>
  <pre>
  &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;tagdiff tag1="BCEL_5_0" 
svnurl="http://svn.apache.org/repos/asf/jakarta/bcel/"; &gt;
    &lt;path&gt;
      &lt;name&gt;&lt;![CDATA[default.properties]]&gt;&lt;/name&gt;
      &lt;action&gt;added&lt;/action&gt;
    &lt;/path&gt;
    &lt;path&gt;
      &lt;name&gt;&lt;![CDATA[xdocs/images/classloader.gif]]&gt;&lt;/name&gt;
      &lt;action&gt;modified&lt;/action&gt;
    &lt;/path&gt;
    &lt;path&gt;
      &lt;name&gt;&lt;![CDATA[README]]&gt;&lt;/name&gt;
      &lt;action&gt;deleted&lt;/action&gt;
    &lt;/path&gt;
  &lt;/tagdiff&gt;
  </pre>
  
  <hr><p align="center">Copyright &copy; 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 @@
    * &lt;!-- Root element --&gt;
    * &lt;!ELEMENT revisiondiff ( paths? ) &gt;
    * &lt;!-- Start revision of the report --&gt;
  - * &lt;!ATTLIST revisiondiff startRevision NMTOKEN #IMPLIED &gt;
  + * &lt;!ATTLIST revisiondiff start NMTOKEN #IMPLIED &gt;
    * &lt;!-- End revision of the report --&gt;
  - * &lt;!ATTLIST revisiondiff endRevision NMTOKEN #IMPLIED &gt;
  - * &lt;!-- Start date of the report --&gt;
  + * &lt;!ATTLIST revisiondiff end NMTOKEN #IMPLIED &gt;
  + * &lt;!-- Subversion URL if known  --&gt;
  + * &lt;!ATTLIST revisiondiff svnurl NMTOKEN #IMPLIED &gt;
    *
    * &lt;!-- Path added, changed or removed --&gt;
    * &lt;!ELEMENT path ( name,action ) &gt;
  @@ -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
   *   |
   *   |
   *   -----&gt; trunk
   *   -----&gt; tags
   *            |
   *            |
   *            ----------&gt; tag1
   *            ----------&gt; tag2
   * </pre>
   *
   * It produces an XML output representing the list of changes.
   * <PRE>
   * &lt;!-- Root element --&gt;
   * &lt;!ELEMENT tagdiff ( paths? ) &gt;
   * &lt;!-- First tag --&gt;
   * &lt;!ATTLIST tagdiff tag1 NMTOKEN #IMPLIED &gt;
   * &lt;!-- Second tag --&gt;
   * &lt;!ATTLIST tagdiff tag2 NMTOKEN #IMPLIED &gt;
   * &lt;!-- Subversion BaseURL --&gt;
   * &lt;!ATTLIST tagdiff svnurl NMTOKEN #IMPLIED &gt;
   *
   * &lt;!-- Path added, changed or removed --&gt;
   * &lt;!ELEMENT path ( name,action ) &gt;
   * &lt;!-- Name of the file --&gt;
   * &lt;!ELEMENT name ( #PCDATA ) &gt;
   * &lt;!ELEMENT action (added|modified|deleted)&gt;
   * </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]

Reply via email to