You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by df...@apache.org on 2008/08/15 04:46:19 UTC

svn commit: r686117 - in /maven/sandbox/trunk/plugins: ./ maven-reactor-plugin/ maven-reactor-plugin/src/ maven-reactor-plugin/src/main/ maven-reactor-plugin/src/main/java/ maven-reactor-plugin/src/main/java/org/ maven-reactor-plugin/src/main/java/org/...

Author: dfabulich
Date: Thu Aug 14 19:46:18 2008
New Revision: 686117

URL: http://svn.apache.org/viewvc?rev=686117&view=rev
Log:
Added maven-reactor-plugin

Added:
    maven/sandbox/trunk/plugins/maven-reactor-plugin/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/pom.xml
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeDependentsMojo.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMojo.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMyChanges.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MissingProjectException.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/NonReactorException.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/RelativePather.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/ResumeMojo.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SimpleInvoker.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SuperProjectSorter.java
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/plugin/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/plugin/reactor/
    maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/plugin/reactor/RelativePatherTest.java
Modified:
    maven/sandbox/trunk/plugins/pom.xml

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/pom.xml?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/pom.xml (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/pom.xml Thu Aug 14 19:46:18 2008
@@ -0,0 +1,51 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-reactor-plugin</artifactId>
+  <packaging>maven-plugin</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>maven-reactor-plugin</name>
+  <description>Build a subset of interdependent projects in a reactor</description>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>2.0.9</version>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.maven.shared</groupId>
+        <artifactId>maven-invoker</artifactId>
+        <version>2.0.10-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-scm-plugin</artifactId>
+        <version>1.0</version>
+    </dependency>
+    <!-- DGF it's too painful to depend on all of the providers plus the API + plexus and track their versions ... -->
+    <!--
+    <dependency>
+        <groupId>org.apache.maven.scm</groupId>
+        <artifactId>maven-scm-api</artifactId>
+        <version>1.0</version>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.maven.scm</groupId>
+        <artifactId>maven-scm-manager-plexus</artifactId>
+        <version>1.0</version>
+    </dependency>-->
+    <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-project</artifactId>
+        <version>2.0.9</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeDependentsMojo.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeDependentsMojo.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeDependentsMojo.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeDependentsMojo.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,49 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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.Set;
+
+import org.codehaus.plexus.util.dag.Vertex;
+
+/**
+ * Goal to build a project X and all of the reactor projects that depend on X 
+ *
+ * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
+ * @goal makeDependents
+ * @aggregator
+ * @phase process-sources
+ */
+public class MakeDependentsMojo
+    extends MakeMojo
+{
+    // gather parents instead of children
+    protected Set gatherProjects( Vertex v, SuperProjectSorter ps, Set visited, Set out )
+    {
+        visited.add(v);
+        out.add(ps.getProjectMap().get(v.getLabel()));
+        List parents = v.getParents();
+        for (int i = 0; i < parents.size(); i++) {
+            Vertex parent = (Vertex) parents.get(i);
+            if (visited.contains(parent)) continue;
+            gatherProjects(parent, ps, visited, out);
+        }
+        return out;
+    }
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMojo.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMojo.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMojo.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMojo.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,201 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.invoker.Invoker;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.dag.DAG;
+import org.codehaus.plexus.util.dag.Vertex;
+
+/**
+ * Goal to build a project X and all of the reactor projects on which X depends 
+ *
+ * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
+ * @goal make
+ * @aggregator
+ * @phase process-sources
+ */
+public class MakeMojo
+    extends AbstractMojo
+{
+    /**
+     * Location of the file.
+     * @parameter expression="${basedir}"
+     * @required
+     */
+    File baseDir;
+    
+    /**
+     * @parameter expression="${project.collectedProjects}"
+     */
+    List collectedProjects;
+    
+    /**
+     * @parameter expression="${make.group}" default-value="${project.groupId}"
+     * @required
+     */
+    String defaultGroup;
+    
+    /**
+     * A list of artifacts to build, e.g. "com.mycompany:bar,com.mycompany:foo" or just "foo,bar", or just "foo" 
+     * @parameter expression="${make.artifacts}"
+     */
+    String artifactList;
+    
+    /**
+     * A list of relative paths to build, e.g. "foo,baz/bar"
+     * @parameter expression="${make.folders}"
+     */
+    String folderList;
+    
+    /**
+     * Goals to run on subproject
+     * @parameter expression="${make.goals}" default-value="install"
+     */
+    String goals;
+    
+    /**
+     * @component
+     */
+    Invoker invoker;
+    
+    /**
+     * Don't really do anything; just print a command that describes what the command would have done
+     * @parameter expression="${make.printOnly}"
+     */
+    private boolean printOnly = true;
+    
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        if (artifactList == null && folderList == null) {
+            throw new MojoFailureException("You must specify either folders or projects with -Dmake.folders=foo,baz/bar or -Dmake.projects=com.mycompany:foo,com.mycompany:bar");
+        }
+        String[] reactorIncludes;
+        try
+        {
+            if (collectedProjects.size() == 0) {
+                throw new NonReactorException();
+            }
+            SuperProjectSorter ps = new SuperProjectSorter( collectedProjects );
+            DAG dag = ps.getDAG();
+            
+            // gather projects
+            collectArtifactListFromFolderList( collectedProjects );
+            String[] artifacts = StringUtils.split( artifactList, "," );
+            Set visited = new HashSet();
+            Set out = new HashSet();
+            for (int i = 0; i < artifacts.length; i++) {
+                String project = artifacts[i];
+                if ( project.indexOf(':') == -1 ) {
+                    project = defaultGroup + ":" + project;
+                }
+                Vertex projectVertex = dag.getVertex( project );
+                if ( projectVertex == null ) throw new MissingProjectException(project);
+                gatherProjects( projectVertex, ps, visited, out );
+            }
+            
+            // sort them again
+            ps = new SuperProjectSorter( new ArrayList( out ) );
+            List sortedProjects = ps.getSortedProjects();
+            
+            // construct array of relative POM paths
+            reactorIncludes = new String[sortedProjects.size()];
+            for ( int i = 0; i < sortedProjects.size(); i++ )
+            {
+                MavenProject mp = (MavenProject) sortedProjects.get( i );
+                String path = RelativePather.getRelativePath( baseDir, mp.getFile() );
+                reactorIncludes[i] = path;
+            }
+        }
+        catch (MojoFailureException e) {
+            throw e;
+        }        
+        catch ( Exception e )
+        {
+            throw new MojoExecutionException( "Problem generating dependency tree", e );
+        }
+
+        new SimpleInvoker().runReactor( reactorIncludes, Arrays.asList( goals.split( "," ) ), invoker, printOnly, getLog() );
+
+    }
+
+    void collectArtifactListFromFolderList(List collectedProjects) throws MojoFailureException
+    {
+        if ( folderList == null )
+            return;
+        String[] folders = StringUtils.split( folderList, "," );
+        Set pathSet = new HashSet();
+        for ( int i = 0; i < folders.length; i++ )
+        {
+            File file = new File( baseDir, folders[i] );
+            if ( !file.exists() )
+            {
+                throw new MojoFailureException("Folder doesn't exist: " + file.getAbsolutePath() );
+            }
+            String path = file.getAbsolutePath();
+            pathSet.add( path );
+        }
+        if (artifactList == null) artifactList = "";
+        StringBuffer artifactBuffer = new StringBuffer(artifactList);
+        for ( int i = 0; i < collectedProjects.size(); i++ )
+        {
+            MavenProject mp = (MavenProject) collectedProjects.get( i );
+            if ( pathSet.contains( mp.getFile().getParentFile().getAbsolutePath() ) )
+            {
+                if ( artifactBuffer.length() > 0 )
+                {
+                    artifactBuffer.append( ',' );
+                }
+                String id = ArtifactUtils.versionlessKey( mp.getGroupId(), mp.getArtifactId() );
+                artifactBuffer.append( id );
+            }
+        }
+        if ( artifactBuffer.length() == 0 )
+        {
+            throw new MojoFailureException("No folders matched: " + folderList);
+        }
+        artifactList = artifactBuffer.toString();
+    }
+
+    protected Set gatherProjects( Vertex v, SuperProjectSorter ps, Set visited, Set out )
+    {
+        visited.add( v );
+        out.add( ps.getProjectMap().get( v.getLabel() ) );
+        List children = v.getChildren();
+        for ( int i = 0; i < children.size(); i++ )
+        {
+            Vertex child = (Vertex) children.get( i );
+            if ( visited.contains( child ) )
+                continue;
+            gatherProjects( child, ps, visited, out );
+        }
+        return out;
+    }
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMyChanges.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMyChanges.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMyChanges.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MakeMyChanges.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,107 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.scm.ScmFile;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.command.status.StatusScmResult;
+import org.apache.maven.scm.manager.ScmManager;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Goal to build all projects that you personally have changed (according to SCM) 
+ *
+ * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
+ * @goal makeMyChanges
+ * @aggregator
+ * @phase process-sources
+ */
+public class MakeMyChanges
+    extends MakeDependentsMojo
+{
+    /**
+     * @parameter expression="${make.scmUrl}" default-value="${project.scm.connection}"
+     * @required
+     */
+    private String scmUrl;
+    
+    /**
+     * @parameter expression="${component.org.apache.maven.scm.manager.ScmManager}"
+     */
+    private ScmManager scmManager;
+    
+    private MavenProject project;
+    
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        if (collectedProjects.size() == 0) {
+            throw new NonReactorException();
+        }
+        StatusScmResult result = null;
+        try
+        {
+            ScmRepository repository = scmManager.makeScmRepository( scmUrl );
+            result = scmManager.status( repository, new ScmFileSet( baseDir ) );
+        }
+        catch ( Exception e )
+        {
+            throw new MojoExecutionException("Couldn't configure SCM repository: " + e.getLocalizedMessage(),e);
+        }
+        
+        List changedFiles = result.getChangedFiles();
+        // TODO There's a cleverer/faster way to code this...?
+        List projectDirectories = getProjectDirectories();
+        Set changedDirectories = new HashSet();
+        for (int i = 0; i < changedFiles.size(); i++) {
+            ScmFile changedScmFile = (ScmFile) changedFiles.get( i );
+            File changedFile = new File(changedScmFile.getPath());
+            for (int j = 0; j < projectDirectories.size(); j++) {
+                File projectDirectory = (File) projectDirectories.get( j );
+                if (changedFile.getAbsolutePath().startsWith( projectDirectory.getAbsolutePath() )) {
+                    changedDirectories.add( RelativePather.getRelativePath( baseDir, projectDirectory ) );
+                    break;
+                }
+            }
+        }
+        folderList = StringUtils.join( changedDirectories.iterator(), "," );
+        getLog().info( "Going to make dependents for: " + folderList );
+        super.execute();
+
+    }
+    
+    private List getProjectDirectories() {
+        List dirs = new ArrayList(collectedProjects.size());
+        for (int i = 0; i < collectedProjects.size(); i++)
+        {
+            MavenProject mp = (MavenProject) collectedProjects.get( i );
+            dirs.add( mp.getFile().getParentFile() );
+        }
+        return dirs;
+    }
+
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MissingProjectException.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MissingProjectException.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MissingProjectException.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/MissingProjectException.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,31 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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.maven.plugin.MojoFailureException;
+
+class MissingProjectException
+    extends MojoFailureException
+{
+
+    private static final long serialVersionUID = 1L;
+
+    public MissingProjectException(String project)
+    {
+        super( "Couldn't find project " + project + " in reactor; make sure you specified the correct group:artifactId (may differ from folder name)" );
+    }
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/NonReactorException.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/NonReactorException.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/NonReactorException.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/NonReactorException.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,29 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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.maven.plugin.MojoFailureException;
+
+class NonReactorException
+    extends MojoFailureException
+{
+    private static final long serialVersionUID = 1L;
+
+    public NonReactorException() {
+        super("This isn't a reactor build.  This command must be run from the root of the reactor (the project with <modules> in it)");
+    }
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/RelativePather.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/RelativePather.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/RelativePather.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/RelativePather.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,117 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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.io.File;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * Calculates relative paths
+ * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
+ *
+ */
+class RelativePather {
+    /**
+     * Calculates a relative path
+     * @param context the "current" context directory
+     * @param dest the directory to be described by a relative path
+     * @return a relative path from the context directory to the dest directory
+     */
+    public static String getRelativePath(File context, File dest) {
+        LinkedList contextChunks = getPathChunks(context);
+        LinkedList destChunks = getPathChunks(dest);
+        if (!contextChunks.getFirst().equals(destChunks.getFirst())) throw new DifferentRootsException("Roots differ");
+        int count = 0;
+        Iterator contextChunker = contextChunks.iterator();
+        Iterator destChunker = destChunks.iterator();
+        String contextChunk = (String) contextChunker.next();
+        String destChunk = (String) destChunker.next();
+        boolean pathsDiffer = false;
+        while (true) {
+            count++;
+            if (!contextChunker.hasNext()) break;
+            if (!destChunker.hasNext()) break;
+            contextChunk = (String) contextChunker.next();
+            destChunk = (String) destChunker.next();
+            if (!contextChunk.equals(destChunk)) {
+                pathsDiffer = true;
+                break;
+            }
+        }
+        
+        // the paths agree for the first N chunks
+        
+        StringBuffer relativePath = new StringBuffer();
+        
+        if (count < contextChunks.size()) {
+            int dotDotCount = contextChunks.size() - count;
+            for (int i = 0; i < dotDotCount; i++) {
+                relativePath.append("..");
+                // omit trailing slash
+                if (i < dotDotCount -1) {
+                    relativePath.append(File.separatorChar);
+                }
+            }
+        }
+        if (pathsDiffer) {
+            if (relativePath.length() > 0) {
+                relativePath.append(File.separatorChar);
+            }
+            relativePath.append(destChunk);
+        }
+        while (destChunker.hasNext()) {
+            if (relativePath.length() > 0) {
+                relativePath.append(File.separatorChar);
+            }
+            relativePath.append(destChunker.next());
+        }
+        
+        return relativePath.toString();
+    }
+    
+    private static LinkedList getPathChunks(File f) {
+        LinkedList l = new LinkedList();
+        while (f.getParentFile() != null) {
+            l.addFirst(f.getName());
+            f = f.getParentFile();
+        }
+        l.addFirst(f.getAbsolutePath());
+        return l;
+    }
+    
+    static class DifferentRootsException extends RuntimeException {
+        private static final long serialVersionUID = 1L;
+
+        public DifferentRootsException() {
+            super();
+        }
+
+        public DifferentRootsException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+        public DifferentRootsException(String message) {
+            super(message);
+        }
+
+        public DifferentRootsException(Throwable cause) {
+            super(cause);
+        }
+        
+    }
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/ResumeMojo.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/ResumeMojo.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/ResumeMojo.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/ResumeMojo.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,168 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectSorter;
+import org.apache.maven.shared.invoker.Invoker;
+
+/**
+ * Goal to resume building a reactor at a certain point 
+ *
+ * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
+ * @goal resume
+ * @aggregator
+ * @phase process-sources
+ */
+public class ResumeMojo
+    extends AbstractMojo
+{
+    
+    /**
+     * @parameter expression="${project.collectedProjects}"
+     */
+    private List collectedProjects;
+    
+    /**
+     * Location of the file.
+     * @parameter expression="${basedir}"
+     * @required
+     */
+    private File baseDir;
+    
+    /**
+     * @parameter expression="${make.group}" default-value="${project.groupId}"
+     * @required
+     */
+    private String continueFromGroup;
+    
+    /**
+     * The artifact from which we'll resume, e.g. "com.mycompany:foo" or just "foo"
+     * @parameter expression="${fromArtifact}"
+     */
+    private String continueFromProject;
+    
+    /**
+     * The project folder from which we'll resume
+     * @parameter expression="${from}"
+     */
+    private File continueFromFolder;
+    
+    /**
+     * Goals to run on subproject
+     * @parameter expression="${make.goals}" default-value="install"
+     */
+    private String goals;
+    
+    /**
+     * @component
+     */
+    private Invoker invoker;
+    
+    /**
+     * Don't really do anything; just print a message that describes what the command would have done
+     * @parameter expression="${make.printOnly}"
+     */
+    private boolean printOnly = true;
+    
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        if ( continueFromFolder == null && continueFromProject == null )
+        {
+            throw new MojoFailureException("You must specify either a folder or a project with -Dfrom=baz/bar or -DfromArtifact=com.mycompany:foo (groupId is optional)");
+        }
+        if (continueFromFolder != null && continueFromProject != null )
+        {
+            throw new MojoFailureException("You can't specify both a folder (" + continueFromFolder + ") and an artifact (" + continueFromProject + ")");
+        }
+        if ( continueFromFolder != null && !continueFromFolder.exists() )
+        {
+            throw new MojoFailureException("Folder doesn't exist: " + continueFromFolder.getAbsolutePath() );
+        }
+        String[] reactorIncludes;
+        try
+        {
+            
+            if (collectedProjects.size() == 0) {
+                throw new NonReactorException();
+            }
+            ProjectSorter ps = new ProjectSorter( collectedProjects );
+                        
+            List sortedProjects = ps.getSortedProjects();
+            
+            String projectName = null;
+            if ( continueFromProject != null)
+            {
+                projectName = continueFromProject;
+                if ( projectName.indexOf(':') != -1 ) {
+                    int index = continueFromProject.indexOf(':');
+                    continueFromGroup = continueFromProject.substring( 0, index );
+                    projectName = continueFromProject.substring( index+1 );
+                }
+            }
+            
+            boolean found = false;
+            int i = 0;
+            for (; i < sortedProjects.size(); i++) {
+                MavenProject mp = (MavenProject) sortedProjects.get( i );
+                if ( continueFromFolder == null )
+                {
+                    if ( continueFromGroup.equals( mp.getGroupId() ) && projectName.equals( mp.getArtifactId() ) )
+                    {
+                        found = true;
+                        break;
+                    }
+                } else {
+                    if ( continueFromFolder.equals( mp.getFile().getParentFile() ) )
+                    {
+                        found = true;
+                        break;
+                    }
+                }
+            }
+            
+            if (!found) throw new MissingProjectException(continueFromGroup + ":" + projectName);
+            
+            // construct array of relative POM paths
+            reactorIncludes = new String[sortedProjects.size() - i];
+            for ( int j = i; j < sortedProjects.size(); j++ )
+            {
+                MavenProject mp = (MavenProject) sortedProjects.get( j );
+                String path = RelativePather.getRelativePath( baseDir, mp.getFile() );
+                reactorIncludes[j- i] = path;
+            }
+        }
+        catch (MojoFailureException e) {
+            throw e;
+        }
+        catch ( Exception e )
+        {
+            throw new MojoExecutionException( "Problem generating dependency tree", e );
+        }
+
+        new SimpleInvoker().runReactor( reactorIncludes, Arrays.asList( goals.split( "," ) ), invoker, printOnly, getLog() );
+
+    }
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SimpleInvoker.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SimpleInvoker.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SimpleInvoker.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SimpleInvoker.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,104 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Copyright 2008 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 org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.shared.invoker.CommandLineConfigurationException;
+import org.apache.maven.shared.invoker.DefaultInvocationRequest;
+import org.apache.maven.shared.invoker.InvocationRequest;
+import org.apache.maven.shared.invoker.InvocationResult;
+import org.apache.maven.shared.invoker.Invoker;
+import org.apache.maven.shared.invoker.MavenCommandLineBuilder;
+
+/** Simplified wrapper for Maven invoker
+ * 
+ * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
+ *
+ */
+class SimpleInvoker
+{
+    /** Runs a "mvn --reactor" build with the specified includes
+     * 
+     * @param reactorIncludes the list of include patterns for --reactor
+     * @param goalList the list of goals (you can also pass other flags in here; they're just command-line args)
+     * @param invoker the Maven Invoker (let Maven provide to you as a component)
+     * @param printOnly if true, don't actually run anything, just log a message
+     * @param log logger
+     * @throws InvokerExecutionException if build fails for any reason
+     */
+    void runReactor( String[] reactorIncludes, List goalList, Invoker invoker, boolean printOnly, Log log )
+        throws InvokerExecutionException
+    {
+        InvocationRequest request = new DefaultInvocationRequest();
+        request.activateReactor( reactorIncludes, null/* excludes */);
+        request.setGoals( goalList );
+        request.setRecursive( false );
+        try
+        {
+            log.info( "Executing: " + new MavenCommandLineBuilder().build( request ) );
+        }
+        catch ( CommandLineConfigurationException e )
+        {
+            throw new InvokerExecutionException( "Failed to display command line", e );
+        }
+
+        if ( !printOnly )
+        {
+            try
+            {
+                InvocationResult result = invoker.execute( request );
+                if ( result.getExecutionException() != null )
+                    throw result.getExecutionException();
+                if ( result.getExitCode() != 0 )
+                    throw new InvokerExecutionException( "Exit code was " + result.getExitCode() );
+            }
+            catch ( Exception e )
+            {
+                throw new InvokerExecutionException( "Maven build failed: " + e.getLocalizedMessage(), e );
+            }
+        }
+    }
+    
+    class InvokerExecutionException extends MojoExecutionException {
+
+        private static final long serialVersionUID = 1L;
+
+        public InvokerExecutionException( Object source, String shortMessage, String longMessage )
+        {
+            super( source, shortMessage, longMessage );
+        }
+
+        public InvokerExecutionException( String message, Exception cause )
+        {
+            super( message, cause );
+        }
+
+        public InvokerExecutionException( String message, Throwable cause )
+        {
+            super( message, cause );
+        }
+
+        public InvokerExecutionException( String message )
+        {
+            super( message );
+        }
+        
+    }
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SuperProjectSorter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SuperProjectSorter.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SuperProjectSorter.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/main/java/org/apache/maven/plugin/reactor/SuperProjectSorter.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,247 @@
+package org.apache.maven.plugin.reactor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.project.DuplicateProjectException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+import org.codehaus.plexus.util.dag.DAG;
+import org.codehaus.plexus.util.dag.TopologicalSorter;
+
+/**
+ * Sort projects by dependencies.  Just like ProjectSorter from maven-project, but this one exposes
+ * the DAG and the projectMap in getters.
+ *  
+ *
+ * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class SuperProjectSorter
+{
+    private final DAG dag;
+
+    private final Map projectMap;
+    
+    private final List sortedProjects;
+
+    private MavenProject topLevelProject;
+
+    /**
+     * Sort a list of projects.
+     * <ul>
+     * <li>collect all the vertices for the projects that we want to build.</li>
+     * <li>iterate through the deps of each project and if that dep is within
+     * the set of projects we want to build then add an edge, otherwise throw
+     * the edge away because that dependency is not within the set of projects
+     * we are trying to build. we assume a closed set.</li>
+     * <li>do a topo sort on the graph that remains.</li>
+     * </ul>
+     * @throws DuplicateProjectException if any projects are duplicated by id
+     */
+    public SuperProjectSorter( List projects )
+        throws CycleDetectedException, DuplicateProjectException
+    {
+        dag = new DAG();
+
+        projectMap = new HashMap();
+
+        for ( Iterator i = projects.iterator(); i.hasNext(); )
+        {
+            MavenProject project = (MavenProject) i.next();
+
+            String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
+
+            if ( dag.getVertex( id ) != null )
+            {
+                throw new DuplicateProjectException( "Project '" + id + "' is duplicated in the reactor" );
+            }
+
+            dag.addVertex( id );
+
+            projectMap.put( id, project );
+        }
+
+        for ( Iterator i = projects.iterator(); i.hasNext(); )
+        {
+            MavenProject project = (MavenProject) i.next();
+
+            String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
+
+            for ( Iterator j = project.getDependencies().iterator(); j.hasNext(); )
+            {
+                Dependency dependency = (Dependency) j.next();
+
+                String dependencyId = ArtifactUtils
+                    .versionlessKey( dependency.getGroupId(), dependency.getArtifactId() );
+
+                if ( dag.getVertex( dependencyId ) != null )
+                {
+                    project.addProjectReference( (MavenProject) projectMap.get( dependencyId ) );
+
+                    dag.addEdge( id, dependencyId );
+                }
+            }
+
+            MavenProject parent = project.getParent();
+            if ( parent != null )
+            {
+                String parentId = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
+                if ( dag.getVertex( parentId ) != null )
+                {
+                    // Parent is added as an edge, but must not cause a cycle - so we remove any other edges it has in conflict
+                    if ( dag.hasEdge( parentId, id ) )
+                    {
+                        dag.removeEdge( parentId, id );
+                    }
+                    dag.addEdge( id, parentId );
+                }
+            }
+
+            List buildPlugins = project.getBuildPlugins();
+            if ( buildPlugins != null )
+            {
+                for ( Iterator j = buildPlugins.iterator(); j.hasNext(); )
+                {
+                    Plugin plugin = (Plugin) j.next();
+                    String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
+                    if ( dag.getVertex( pluginId ) != null && !pluginId.equals( id ) )
+                    {
+                        addEdgeWithParentCheck( projectMap, pluginId, project, id );
+                    }
+                }
+            }
+
+            List reportPlugins = project.getReportPlugins();
+            if ( reportPlugins != null )
+            {
+                for ( Iterator j = reportPlugins.iterator(); j.hasNext(); )
+                {
+                    ReportPlugin plugin = (ReportPlugin) j.next();
+                    String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
+                    if ( dag.getVertex( pluginId ) != null && !pluginId.equals( id ) )
+                    {
+                        addEdgeWithParentCheck( projectMap, pluginId, project, id );
+                    }
+                }
+            }
+
+            for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
+            {
+                Extension extension = (Extension) j.next();
+                String extensionId = ArtifactUtils.versionlessKey( extension.getGroupId(), extension.getArtifactId() );
+                if ( dag.getVertex( extensionId ) != null )
+                {
+                    addEdgeWithParentCheck( projectMap, extensionId, project, id );
+                }
+            }
+        }
+
+        List sortedProjects = new ArrayList();
+
+        for ( Iterator i = TopologicalSorter.sort( dag ).iterator(); i.hasNext(); )
+        {
+            String id = (String) i.next();
+
+            sortedProjects.add( projectMap.get( id ) );
+        }
+
+        this.sortedProjects = Collections.unmodifiableList( sortedProjects );
+    }
+
+    private void addEdgeWithParentCheck( Map projectMap, String projectRefId, MavenProject project, String id )
+        throws CycleDetectedException
+    {
+        MavenProject extProject = (MavenProject) projectMap.get( projectRefId );
+        
+        if ( extProject == null )
+        {
+            return;
+        }
+
+        project.addProjectReference( extProject );
+
+        MavenProject extParent = extProject.getParent();
+        if ( extParent != null )
+        {
+            String parentId = ArtifactUtils.versionlessKey( extParent.getGroupId(), extParent.getArtifactId() );
+            // Don't add edge from parent to extension if a reverse edge already exists
+            if ( !dag.hasEdge( projectRefId, id ) || !parentId.equals( id ) )
+            {
+                dag.addEdge( id, projectRefId );
+            }
+        }
+    }
+
+    // TODO: !![jc; 28-jul-2005] check this; if we're using '-r' and there are aggregator tasks, this will result in weirdness.
+    public MavenProject getTopLevelProject()
+    {
+        if ( topLevelProject == null )
+        {
+            for ( Iterator i = sortedProjects.iterator(); i.hasNext() && topLevelProject == null; )
+            {
+                MavenProject project = (MavenProject) i.next();
+                if ( project.isExecutionRoot() )
+                {
+                    topLevelProject = project;
+                }
+            }
+        }
+
+        return topLevelProject;
+    }
+
+    public List getSortedProjects()
+    {
+        return sortedProjects;
+    }
+
+    public boolean hasMultipleProjects()
+    {
+        return sortedProjects.size() > 1;
+    }
+
+    public List getDependents( String id )
+    {
+        return dag.getParentLabels( id );
+    }
+    
+    public DAG getDAG()
+    {
+        return dag;
+    }
+    
+    public Map getProjectMap()
+    {
+        return projectMap;
+    }
+    
+}

Added: maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/plugin/reactor/RelativePatherTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/plugin/reactor/RelativePatherTest.java?rev=686117&view=auto
==============================================================================
--- maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/plugin/reactor/RelativePatherTest.java (added)
+++ maven/sandbox/trunk/plugins/maven-reactor-plugin/src/test/java/org/apache/maven/plugin/reactor/RelativePatherTest.java Thu Aug 14 19:46:18 2008
@@ -0,0 +1,70 @@
+package org.apache.maven.plugin.reactor;
+
+import java.io.File;
+
+import org.apache.maven.plugin.reactor.RelativePather.DifferentRootsException;
+
+import junit.framework.TestCase;
+
+public class RelativePatherTest extends TestCase {
+    File root;
+    File differentRoot;
+    char S = File.separatorChar;
+    
+    public void setUp() {
+        File[] roots = File.listRoots();
+        root = roots[0];
+        if (roots.length > 1) {
+            differentRoot = roots[1];
+        }
+    }
+    
+    public void testIdenticalRoots() {
+        assertEquals("", getRelativePath(root, root));
+    }
+    
+    public void testDifferentRoots() {
+        // skip this test on systems with only one root
+        if (differentRoot == null) return;
+        try {
+            getRelativePath(root, differentRoot);
+            fail("Expected different roots exception");
+        } catch (DifferentRootsException e) {}
+    }
+    
+    public void testIdenticalFoo() {
+        File foo = new File(root, "foo");
+        assertEquals("", getRelativePath(foo, foo));
+    }
+    
+    public void testIdenticalFooFoo() {
+        File foo = new File(root, "foo/foo");
+        assertEquals("", getRelativePath(foo, foo));
+    }
+    
+    public void testFooBar() {
+        File foo = new File(root, "foo");
+        File bar = new File(root, "bar");   
+        assertEquals(".." + S + "bar", getRelativePath(foo, bar));
+    }
+    
+    public void testRootFoo() {
+        File foo = new File(root, "foo");
+        assertEquals("foo", getRelativePath(root, foo));
+    }
+    
+    public void testFooRoot() {
+        File foo = new File(root, "foo");
+        assertEquals("..", getRelativePath(foo, root));
+    }
+
+    public void testFooFooBarBar() {
+        File foo = new File(root, "foo/foo");
+        File bar = new File(root, "bar/bar");   
+        assertEquals(".." + S + ".." + S + "bar" + S + "bar", getRelativePath(foo, bar));
+    }
+    
+    public String getRelativePath(File context, File dest) {
+        return RelativePather.getRelativePath(context, dest);
+    }
+}

Modified: maven/sandbox/trunk/plugins/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plugins/pom.xml?rev=686117&r1=686116&r2=686117&view=diff
==============================================================================
--- maven/sandbox/trunk/plugins/pom.xml (original)
+++ maven/sandbox/trunk/plugins/pom.xml Thu Aug 14 19:46:18 2008
@@ -26,6 +26,7 @@
     <module>maven-plugin-management-plugin</module>
     <module>maven-pom-plugin</module>
     <module>maven-property-setting-plugin</module>
+    <module>maven-reactor-plugin</module>
     <module>maven-shade-plugin</module>
     <module>maven-swizzle-plugin</module>
     <module>maven-xcode-plugin</module>