MPSIMIAN-14 upgrade simian

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@209890 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
epugh
2005-07-08 21:11:08 +00:00
parent 77da7a60d5
commit ba4ae919eb
9 changed files with 184 additions and 483 deletions

View File

@@ -30,14 +30,6 @@
xmlns:ant="jelly:ant"
xmlns:simian="simian">
<define:taglib uri="simian">
<define:jellybean
name="simianLog"
className="org.apache.maven.simian.SimianLog"
method="process"
/>
</define:taglib>
<goal name="maven-simian-plugin"
description="Generate Simian (Code Similarity Analyzer) report."
prereqs="maven-simian-plugin:report"/>
@@ -65,10 +57,11 @@
</ant:classpath>
</ant:taskdef>
<ant:simian output="${maven.build.dir}/generated-xdocs/simian.log"
lineCount="${maven.simian.linecount}"
failOnDuplication="${maven.simian.failonduplication}">
<echo>Generating the Simian raw report ...</echo>
<ant:simian threshold="${maven.simian.linecount}">
<formatter type="plain" toFile="${maven.build.dir}/simian-raw-report.log"/>
<formatter type="xml" toFile="${maven.build.dir}/simian-raw-report.xml"/>
<ant:fileset dir="${pom.build.sourceDirectory}">
<ant:include name="${maven.simian.includes}"/>
<ant:exclude name="${maven.simian.excludes}"/>
@@ -122,86 +115,25 @@
</ant:simian>
<!-- Run JSL to transform the report into XDOC -->
<echo>Converting the Simian report to xdoc ...</echo>
<doc:jsl
input="${maven.build.dir}/simian-raw-report.xml"
output="simian-report.xml"
stylesheet="${plugin.resources}/simian.jsl"
outputMode="xml"
prettyPrint="true"
/>
</goal>
<goal name="maven-simian-plugin:report">
<j:choose>
<j:when test="${sourcesPresent}">
<attainGoal name="maven-simian-plugin:analyze"/>
<simian:simianLog
logFile="${maven.build.dir}/generated-xdocs/simian.log"
jellyContext="${context}"
sourceDirectory="${pom.build.sourceDirectory}"
unitTestSourceDirectory="${pom.build.unitTestSourceDirectory}"
/>
<j:set var="simLog" value="${context.getVariable('simianLog')}"/>
<j:file name="${maven.build.dir}/generated-xdocs/simian-report.xml" prettyPrint="true">
<j:whitespace xmlns="dummy">
<document>
<properties>
<title>Simian Report</title>
</properties>
<body>
<section name="Summary">
<p>${simLog.copyright1}</p>
<p>${simLog.copyright2}</p>
<table summary="Simian report summary">
<tbody>
<tr>
<th>Similarity threshold (lines)</th>
<td>${maven.simian.linecount}</td>
</tr>
<tr>
<th>Total number of duplicate lines</th>
<td>${simLog.totalDuplicateLineCount}</td>
</tr>
<tr>
<th>Total number of duplicate blocks</th>
<td>${simLog.blockCount}</td>
</tr>
<tr>
<th>Total number of files with duplicates</th>
<td>${simLog.fileWithDuplicateCount}</td>
</tr>
<tr>
<th>Total number of processed lines</th>
<td>${simLog.loc}</td>
</tr>
<tr>
<th>Total number of processed files</th>
<td>${simLog.fileParseCount}</td>
</tr>
<tr>
<th>Scan time</th>
<td>${simLog.time}</td>
</tr>
</tbody>
</table>
</section>
<section name="Duplications">
<j:forEach var="duplication" items="${simLog.duplications}">
<subsection name="Duplication: ${duplication.lineCount} lines">
<ul>
<j:forEach var="duplicationArea" items="${duplication.duplicationAreas}">
<j:set var="className" value="${duplicationArea.className}"/>
<li><a href="${duplicationArea.pathToClass}.html#${duplicationArea.startLine}">${duplicationArea.className}(${duplicationArea.startLine}-${duplicationArea.endLine})</a></li>
</j:forEach>
</ul>
</subsection>
</j:forEach>
</section>
</body>
</document>
</j:whitespace>
</j:file>
</j:when>
<j:otherwise>
<ant:echo>No sources to run Simian on</ant:echo>

View File

@@ -22,7 +22,7 @@
<extend>../plugin-parent/project.xml</extend>
<id>maven-simian-plugin</id>
<name>Maven Simian Plugin</name>
<currentVersion>1.4.1-SNAPSHOT</currentVersion>
<currentVersion>1.5-SNAPSHOT</currentVersion>
<description>Simian Plugin for Maven</description>
<shortDescription>Simian Plugin for Maven</shortDescription>
<url>http://maven.apache.org/reference/plugins/simian/</url>
@@ -89,12 +89,17 @@
<name>Maurice Montgénie</name>
<email>maurice@maguyane.net</email>
</contributor>
<contributor>
<name>Benoit Xhenseval</name>
<email>benoitx@sourceforge.net</email>
<organization>ObjectLab.co.uk</organization>
</contributor>
</contributors>
<dependencies>
<dependency>
<groupId>redhill</groupId>
<artifactId>simian</artifactId>
<version>1.9.1</version>
<version>2.2.4</version>
<url>http://www.redhillconsulting.com.au/products/simian/</url>
</dependency>
<dependency>

View File

@@ -1,49 +0,0 @@
package org.apache.maven.simian;
/* ====================================================================
* Copyright 2001-2004 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.
* ====================================================================
*/
import java.util.List;
import java.util.ArrayList;
/**
* Represents a duplication. Has two or more DuplicationAreas.
*
* @author Aslak Hellesoy
* @version $Revision$
*/
public class Duplication {
int lineCount;
private List duplicationAreas = new ArrayList();
public Duplication(int lineCount) {
this.lineCount = lineCount;
}
public void addDuplicationArea(DuplicationArea duplicationArea) {
duplicationAreas.add(duplicationArea);
}
public int getLineCount() {
return lineCount;
}
public DuplicationArea[] getDuplicationAreas() {
return (DuplicationArea[]) duplicationAreas.toArray(new DuplicationArea[duplicationAreas.size()]);
}
}

View File

@@ -1,54 +0,0 @@
package org.apache.maven.simian;
/* ====================================================================
* Copyright 2001-2004 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.
* ====================================================================
*/
/**
* Represents one area in a file containing dupe code.
*
* @author Aslak Hellesoy
* @version $Revision$
*/
public class DuplicationArea {
private final int startLine;
private final int endLine;
private final String pathToClass;
private final String className;
public DuplicationArea(int startLine, int endLine, String pathToClass, String className) {
this.startLine = startLine;
this.endLine = endLine;
this.pathToClass = pathToClass;
this.className = className;
}
public int getStartLine() {
return startLine;
}
public int getEndLine() {
return endLine;
}
public String getPathToClass() {
return pathToClass;
}
public String getClassName() {
return className;
}
}

View File

@@ -17,24 +17,14 @@ package org.apache.maven.simian;
* ====================================================================
*/
import au.com.redhillconsulting.simian.b;
import au.com.redhillconsulting.simian.SimianTask;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
/**
* Simian Task that writes the output to a file.
@@ -42,13 +32,22 @@ import org.apache.tools.ant.Task;
* @author Aslak Hellesoy
* @version $Revision$
*/
public class FileSimianTask extends SimianTask {
public class FileSimianTask extends SimianTask
{
public void setOutput(File output) {
/**
* Make sure the directory structure exists and
* send the output to a specified file.
*/
public void setOutput(File output)
{
output.getParentFile().mkdirs();
try {
try
{
setOutput(new FileOutputStream(output));
} catch (FileNotFoundException e) {
}
catch (FileNotFoundException e)
{
throw new BuildException("Couldn't set output to " + output.getAbsolutePath(), e);
}
}

View File

@@ -1,219 +0,0 @@
package org.apache.maven.simian;
/* ====================================================================
* Copyright 2001-2004 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.
* ====================================================================
*/
import org.apache.commons.jelly.JellyContext;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* This class represents a model of a Simian log file.
* An instance of this class will be passed to Jelly to generate
* an xdoc document. Finally, this xdoc file is weaved into the
* Maven documentation, with links pointing to the JXR sources.
*
* @author Aslak Hellesoy
* @version $Revision$
*/
public class SimianLog {
private File logFile;
private JellyContext jellyContext;
private Duplication[] duplications;
private String copyright1;
private String copyright2;
private int totalDuplicateLineCount;
private int loc;
private int fileParseCount;
private String time;
private int blockCount;
private int fileWithDuplicateCount;
private String sourceDirectory;
private String unitTestSourceDirectory;
public void setLogFile(File logFile) {
this.logFile = logFile;
}
public void setJellyContext(JellyContext jellyContext) {
this.jellyContext = jellyContext;
}
public void setSourceDirectory(String sourceDirectory) throws IOException {
this.sourceDirectory = new File(sourceDirectory).getCanonicalPath();
}
public void setUnitTestSourceDirectory(String unitTestSourceDirectory) throws IOException {
this.unitTestSourceDirectory = new File(unitTestSourceDirectory).getCanonicalPath();
}
public Duplication[] getDuplications() {
return duplications;
}
public String getCopyright1() {
return copyright1;
}
public String getCopyright2() {
return copyright2;
}
private String linkify(String s) {
StringBuffer sb = new StringBuffer();
StringTokenizer st = new StringTokenizer(s, " ", true);
while (st.hasMoreTokens()) {
String token = st.nextToken();
if(token.startsWith("http://")) {
token = "<a href=\"" + token + "\">" + token + "</a>";
}
sb.append(token);
}
return sb.toString();
}
public int getTotalDuplicateLineCount() {
return totalDuplicateLineCount;
}
public int getLoc() {
return loc;
}
public int getFileParseCount() {
return fileParseCount;
}
public String getTime() {
return time;
}
public int getBlockCount() {
return blockCount;
}
public int getFileWithDuplicateCount() {
return fileWithDuplicateCount;
}
public void process() throws IOException {
List duplicationList = new ArrayList();
Duplication duplication = null;
BufferedReader logReader = new BufferedReader( new FileReader(logFile) );
// Skip 3 lines of header.
copyright1 = logReader.readLine();
copyright2 = logReader.readLine();
String line;
while( (line = logReader.readLine()) != null ) {
if( line.endsWith("duplicate lines in the following files:") ) {
// New duplication
StringTokenizer dupeTokenizer = new StringTokenizer(line);
// Skip "Found" token
dupeTokenizer.nextToken();
int dupeSize = Integer.parseInt(dupeTokenizer.nextToken());
duplication = new Duplication(dupeSize);
duplicationList.add(duplication);
} else if( line.startsWith(" Between") ) {
// New duplication area within a duplication
StringTokenizer dupeEntryTokenizer = new StringTokenizer(line);
// Skip "Between" and "lines" tokens.
dupeEntryTokenizer.nextToken();
dupeEntryTokenizer.nextToken();
int startLine = Integer.parseInt(dupeEntryTokenizer.nextToken());
// Skip "and".
dupeEntryTokenizer.nextToken();
int endLine = Integer.parseInt(dupeEntryTokenizer.nextToken());
// Skip "in".
dupeEntryTokenizer.nextToken();
// filePath could have spaces, we really want all tokens
StringBuffer filePathBuffer = new StringBuffer();
while (dupeEntryTokenizer.hasMoreTokens())
{
filePathBuffer.append(dupeEntryTokenizer.nextToken());
filePathBuffer.append(' ');
}
String filePath = filePathBuffer.toString();
String pathToClass = null;
if( filePath.startsWith(sourceDirectory) ) {
pathToClass = "xref/" + getPathToClass(sourceDirectory, filePath);
} else if( filePath.startsWith(unitTestSourceDirectory) ) {
pathToClass = "xref-test/" + getPathToClass(unitTestSourceDirectory, filePath);
} else {
throw new IllegalStateException( "Couldn't find relative path for " + filePath + " in " + sourceDirectory + " or " + unitTestSourceDirectory);
}
DuplicationArea duplicationArea = new DuplicationArea(startLine, endLine, pathToClass,
getPathToClass(sourceDirectory, filePath).replace('/', '.'));
duplication.addDuplicationArea(duplicationArea);
} else if( line.indexOf("duplicate lines of code in") != -1 ) {
// Summary (Line 1)
StringTokenizer summaryTokenizer = new StringTokenizer(line);
// Skip "Found".
summaryTokenizer.nextToken();
totalDuplicateLineCount = Integer.parseInt(summaryTokenizer.nextToken());
// Skip "duplicate lines of code in".
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
blockCount = Integer.parseInt(summaryTokenizer.nextToken());
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
fileWithDuplicateCount = Integer.parseInt(summaryTokenizer.nextToken());
} else if( line.startsWith("Processed a total of") ) {
// Summary (Line 2)
StringTokenizer summaryTokenizer = new StringTokenizer(line);
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
loc = Integer.parseInt(summaryTokenizer.nextToken());
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
fileParseCount = Integer.parseInt(summaryTokenizer.nextToken());
} else if( line.startsWith("Processing time:") ) {
StringTokenizer summaryTokenizer = new StringTokenizer(line);
summaryTokenizer.nextToken();
summaryTokenizer.nextToken();
time = summaryTokenizer.nextToken();
}
}
duplications = (Duplication[]) duplicationList.toArray(new Duplication[duplicationList.size()]);
// Set ourself on the context, so Jelly can reference us as a regular bean.
jellyContext.setVariable("simianLog", this);
}
private String getPathToClass(String directory, String filePath) {
int classStart = directory.length() + 1;
int classEnd = filePath.lastIndexOf(".java");
String result = filePath.substring(classStart, classEnd).replace(File.separatorChar, '/');
return result;
}
}

View File

@@ -0,0 +1,144 @@
<?xml version="1.0"?>
<!--
* ========================================================================
*
* Copyright 2004 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.
*
* ========================================================================
-->
<jsl:stylesheet
select="$doc"
xmlns:j="jelly:core"
xmlns:jsl="jelly:jsl"
xmlns:util="jelly:util"
xmlns:x="jelly:xml"
xmlns:doc="doc"
xmlns="dummy" trim="false">
<!-- This needs to be instantiated here to be available in the template matches -->
<j:useBean var="mavenTool" class="org.apache.maven.util.MavenTool"/>
<j:useBean var="fileutil" class="org.apache.velocity.texen.util.FileUtil"/>
<jsl:template match="simian">
<document>
<properties>
<author email="qalab@objectlab.co.uk">Benoit Xhenseval</author>
<title>Simian Results</title>
</properties>
<body>
<section name="Simian Results">
<p>
The following document contains the results of
<a href="http://www.redhillconsulting.com.au/products/simian/index.html">Simian <x:expr select="./@version"/></a>.</p>
</section>
<section name="Summary">
<table summary="Simian report summary">
<tbody>
<tr>
<th>Similarity threshold (lines)</th>
<td><x:expr select="./check/@threshold"/></td>
</tr>
<tr>
<th>Total number of duplicate lines</th>
<td><x:expr select="./check/summary/@duplicateLineCount"/></td>
</tr>
<tr>
<th>Total number of duplicate blocks</th>
<td><x:expr select="./check/summary/@duplicateBlockCount"/></td>
</tr>
<tr>
<th>Total number of files with duplicates</th>
<td><x:expr select="./check/summary/@duplicateFileCount"/></td>
</tr>
<tr>
<th>Total number of processed lines</th>
<td><x:expr select="./check/summary/@totalSignificantLineCount"/></td>
</tr>
<tr>
<th>Total number of processed files</th>
<td><x:expr select="./check/summary/@totalFileCount"/></td>
</tr>
<tr>
<th>Scan time</th>
<td><x:expr select="./check/summary/@processingTime"/> ms.</td>
</tr>
</tbody>
</table>
</section>
<section name="Duplications">
<j:set var="fullSrcDir" value="${pom.build.sourceDirectory}"/>
<j:set var="fullTestSrcDir" value="${pom.build.unitTestSourceDirectory}"/>
<j:set var="srcDir" value="${fileutil.file(fullSrcDir).getCanonicalPath()}"/>
<j:set var="testDir" value="${fileutil.file(fullTestSrcDir).getCanonicalPath()}"/>
<x:set var="sets" select="./check/set"/>
<j:forEach var="duplication" items="${sets}">
<subsection name="Duplication: ${duplication.attribute('lineCount').getValue()} lines">
<x:set var="blocks" select="$duplication/block"/>
<ul>
<j:forEach var="duplicationArea" items="${blocks}">
<j:set var="name" value="${duplicationArea.attribute('sourceFile').getValue()}"/>
<j:set var="srcDirLength" value="${srcDir.length() + 1}"/>
<j:set var="testDirLength" value="${testDir.length() + 1}"/>
<j:set var="testIndex" value="${name.lastIndexOf(testDir)}"/>
<j:choose>
<j:when test="${testIndex > 0}">
<j:set var="name" value="${name.substring(mavenTool.toInteger(testDirLength.toString()))}"/>
</j:when>
<j:otherwise>
<j:set var="name" value="${name.substring(mavenTool.toInteger(srcDirLength.toString()))}"/>
</j:otherwise>
</j:choose>
<j:set var="lastIndex" value="${name.lastIndexOf('.java')}"/>
<j:choose>
<j:when test="${lastIndex > 0}">
<j:set var="index" value="${mavenTool.toInteger(lastIndex.toString())}"/>
<j:set var="nameWithoutJavaExtension" value="${name.substring(0, index)}"/>
<util:replace var="nameWithoutJavaExtension" value="${nameWithoutJavaExtension}" oldChar="\\" newChar="/"/>
<j:choose>
<j:when test="${testIndex > 0}">
<li><a href="xref/${nameWithoutJavaExtension}.html#${duplicationArea.attribute('startLineNumber').getValue()}">${nameWithoutJavaExtension} ( ${duplicationArea.attribute('startLineNumber').getValue()} - ${duplicationArea.attribute('endLineNumber').getValue()} )</a></li>
</j:when>
<j:otherwise>
<li><a href="xref-test/${nameWithoutJavaExtension}.html#${duplicationArea.attribute('startLineNumber').getValue()}">${nameWithoutJavaExtension} ( ${duplicationArea.attribute('startLineNumber').getValue()} - ${duplicationArea.attribute('endLineNumber').getValue()} )</a></li>
</j:otherwise>
</j:choose>
</j:when>
<j:otherwise>
<j:choose>
<j:when test="${testIndex > 0}">
<li><a href="xref/${name}.html#${duplicationArea.attribute('startLineNumber').getValue()}">${nameWithoutJavaExtension} ( ${duplicationArea.attribute('startLineNumber').getValue()} - ${duplicationArea.attribute('endLineNumber').getValue()} )</a></li>
</j:when>
<j:otherwise>
<li><a href="xref-test/${name}.html#${duplicationArea.attribute('startLineNumber').getValue()}">${nameWithoutJavaExtension} ( ${duplicationArea.attribute('startLineNumber').getValue()} - ${duplicationArea.attribute('endLineNumber').getValue()} )</a></li>
</j:otherwise>
</j:choose>
</j:otherwise>
</j:choose>
</j:forEach>
</ul>
</subsection>
</j:forEach>
</section>
</body>
</document>
</jsl:template>
</jsl:stylesheet>

View File

@@ -1,60 +0,0 @@
package org.apache.maven.simian;
/* ====================================================================
* Copyright 2001-2004 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.
* ====================================================================
*/
import junit.framework.TestCase;
import java.io.*;
import org.apache.commons.jelly.JellyContext;
/**
*
* @author Aslak Hellesoy
* @version $Revision$
*/
public class SimianLogTest extends TestCase {
public void testGetDuplications() throws IOException {
SimianLog simianLog = new SimianLog();
File logFile = new File(FileUtils.getRoot(getClass()).getParentFile().getParentFile(), "target/simian-test/simian.log" );
simianLog.setLogFile(logFile);
JellyContext ctx = new JellyContext();
simianLog.setJellyContext(ctx);
String sourceDirectory = new File(FileUtils.getRoot(getClass()).getParentFile().getParentFile(), "src/test" ).getAbsolutePath();
simianLog.setSourceDirectory(sourceDirectory);
simianLog.process();
Duplication[] duplications = simianLog.getDuplications();
assertEquals("There should be 1 duplication", 1, duplications.length );
Duplication duplication = duplications[0];
DuplicationArea[] duplicationAreas = duplication.getDuplicationAreas();
assertEquals("There should be 2 duplicated areas", 2, duplicationAreas.length );
String pathToClass = duplicationAreas[0].getPathToClass();
assertTrue( "The pathToClass should start with xref/org/apache/maven/simian, but was " + pathToClass,
pathToClass.startsWith("xref/org/apache/maven/simian") );
assertSame("The SimianLog should be on the Jelly Context", simianLog, ctx.getVariable("simianLog") );
}
}

View File

@@ -25,6 +25,9 @@
<author email="maurice@maguyane.net">Maurice Montg?nie</author>
</properties>
<body>
<release version="1.5" date="in CVS">
<action dev="benoitx" type="update">Upgrade to Simian 2.2.4 and XML file output from Simian.</action>
</release>
<release version="1.4.1-SNAPSHOT" date="in CVS">
<action dev="dion" type="update">Ant dependency changed to 1.5.3.1.</action>
</release>