Menu

#10 Multiple source directories for cobertura-report

closed-accepted
nobody
None
9
2005-08-22
2005-03-25
No

Many projects divide source code into multiple
directory trees. For instance Jaxen separates test and
main code into different directry trees. XOM separates
Java 1.4 from 1.5 code. It shoudl be possible for the
cobertura-report task to specify multiple directories
in which to look for source files so it's possible to
generate a report that covers multiple directory trees.

Discussion

  • Nobody/Anonymous

    Logged In: NO

    Also VERY important for me! Cobertura Ant task should have
    support for multiple <src path="..."/> elements like JavaC
    or at least accept a list of directories in srcdir attribute.

     
  • Mark Doliner

    Mark Doliner - 2005-04-13
    • priority: 5 --> 9
     
  • Julien Rentrop

    Julien Rentrop - 2005-05-11

    Logged In: YES
    user_id=1276478

    I also agree this should be an important feature. We also
    use multiple project source trees which we all want in one
    coverage report.

    I think the solution should be to support nested fileset
    elements in the cobertura-report target. This would be
    similar to the instrument task which uses filesets to define
    the classes. The srcdir property should be optional: It
    would not be needed if you have a fileset.

    I created a workaround for this problem:
    Example code
    <mkdir dir="${src.all}"/>
    <copy todir="${src.all}">
    <fileset dir="PROJECT1/src">
    <include name="**/*.java" />
    </fileset>
    <fileset dir="PROJECT2/src">
    <include name="**/*.java" />
    </fileset>
    </copy>

    <cobertura-report srcdir="${src.all}" destdir="report"/>

     
  • Mark Doliner

    Mark Doliner - 2005-05-19
    • summary: Multiple source directories --> Multiple source directories for cobertura-report
     
  • Ludovic Dewailly

    Logged In: YES
    user_id=719739

    Not sure this is exactly what you need but for my onw needs
    I created the class SourceFileLocator (see below) that I use
    to search source files. To use it, create an instance in
    HTMLReport and use it to search the source files. Then, all
    you have to do is specify in the ant script the top-level
    directory containing all your source repositories:

    --------------------------------------------------------------------------

    package net.sourceforge.cobertura.reporting;

    import java.io.File;
    import java.io.FileFilter;
    import java.util.ArrayList;

    /**
    * Because the source files can be dispersed in different
    * folders, we need to recursively search through the given
    * source folder
    *
    * @author Ludovic Dewailly
    * @version 1.0
    */
    public class SourceFileLocator {

    /**
    * Set it to true if you want some information output
    */
    private static final boolean VERBOSE = false;

    /**
    * The root directory
    */
    private File sourceDir;

    /**
    * Our cache
    */
    private ArrayList cache;

    /**
    * The list of directories we don't want to search
    */
    private static final String[] BLACK_LIST = new String[]
    {/* put here the list of directories */};

    /**
    * The FileFilter we use
    */
    private static FileFilter filter = new FileFilter() {

    /* (non-Javadoc)
    * @see java.io.FileFilter#accept(java.io.File)
    */
    public boolean accept(File pathname) {

    if (pathname.isDirectory()) {
    // We check the black list
    String path = pathname.getAbsolutePath();
    // We check the directory is not blacklisted
    for (int i = 0; i < BLACK_LIST.length; i++) {
    if (path.indexOf(BLACK_LIST[i]) != -1)
    return false;
    }

    return true;
    }

    // We only search for .java files
    if (pathname.getName().endsWith(".java"))
    return true;

    return false;
    }
    };

    /**
    * Constructs a new FileSourceLocator
    *
    * @param sourceDir the root directory
    */
    public SourceFileLocator(File sourceDir) {
    this.sourceDir = sourceDir;
    cache = new ArrayList(100);
    }

    /**
    * Locates the given source file
    *
    * @param className the name of the source file
    (pkg1/pkg2/../MyClass.java)
    *
    * @return the source file
    */
    public File locateSourceFile(String className) {

    if (sourceDir == null || !sourceDir.exists())
    // Nothing to do
    return null;

    // We first check if we are searching for inner classes
    int index = className.indexOf('$');
    if (index != -1)
    className = className.substring(0, index) + ".java";

    if (VERBOSE) {
    System.out.println("Locating " + className + "...");
    }

    // we check our cache
    File file = searchCache(className);

    if (file == null) {
    // We need to check the file system
    file = searchFileSystem(sourceDir, className);
    }

    return file;
    }

    /**
    * Searches the cache for the given class name
    *
    * @param className the source file name
    *
    * @return the source file or null if not found
    */
    private File searchCache(String className) {

    if (VERBOSE) {
    System.out.println("Searching cache...");
    }

    for (int i = 0; i < cache.size(); i++) {
    String file = (String) cache.get(i);
    if (file.endsWith(className)) {

    if (VERBOSE) {
    System.out.println("Found in cache");
    }

    return new File(file);
    }
    }

    if (VERBOSE) {
    System.out.println("Nothing found");
    }

    return null;
    }

    /**
    * We recursively search the file system starting from
    * the given directory and cache all found java source
    * files that don't match <code>className</code>
    *
    * @param dir the directory to start searching from
    * @param className the source file we are looking for
    * @return the source file or null if not found
    */
    private File searchFileSystem(File dir, String className) {

    if (VERBOSE) {
    System.out.println("Searching dir " +
    dir.getPath() + "...");
    }

    File sourceFile = null;
    File[] children = dir.listFiles(filter);
    for (int i = 0; i < children.length; i++) {
    File child = children[i];
    if (child.isDirectory()) {
    sourceFile = searchFileSystem(child, className);
    if (sourceFile != null)
    // We found it!
    break;
    }
    else {
    // We have a java file

    String path = child.getPath().replace('\\',
    '/');

    if (path.endsWith(className)) {

    if (VERBOSE) {
    System.out.println("Found in file
    system");
    }

    // We found it
    sourceFile = child;
    break;
    }
    else if (!cache.contains(path)) {

    if (VERBOSE) {
    System.out.println("Caching " + path
    + "...");
    }

    // we cache it
    cache.add(path);
    }
    }
    }

    return sourceFile;
    }
    }

     
  • Grzegorz Lukasik

    Logged In: YES
    user_id=1216999

    Could you please check the newest version from CVS? It
    should be fixed now.

    I have attached cobertura.jar compiled from sources in CVS
    to this RFE. You can use it by replacing cobertura.jar from
    Cobertura 1.5.

     
  • Grzegorz Lukasik

    Distribution file created from current CVS sources.

     
  • Mark Doliner

    Mark Doliner - 2005-08-22
    • status: open --> closed-accepted
     
  • Mark Doliner

    Mark Doliner - 2005-08-22

    Logged In: YES
    user_id=20979

    This is supported in Cobertura 1.6.