Author: dfabulich
Date: Fri Nov  5 19:15:58 2010
New Revision: 1031727

URL: http://svn.apache.org/viewvc?rev=1031727&view=rev
Log:
scm-changes-maven-extension

Added:
    maven/sandbox/trunk/shared/scm-changes-maven-extension/README.txt
    maven/sandbox/trunk/shared/scm-changes-maven-extension/pom.xml
    maven/sandbox/trunk/shared/scm-changes-maven-extension/src/
    maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/
    maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/
    maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/
    
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/
    
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/
    
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/shared/
    
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/shared/scmchanges/
    
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/shared/scmchanges/MakeScmChanges.java

Added: maven/sandbox/trunk/shared/scm-changes-maven-extension/README.txt
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/shared/scm-changes-maven-extension/README.txt?rev=1031727&view=auto
==============================================================================
--- maven/sandbox/trunk/shared/scm-changes-maven-extension/README.txt (added)
+++ maven/sandbox/trunk/shared/scm-changes-maven-extension/README.txt Fri Nov  
5 19:15:58 2010
@@ -0,0 +1,37 @@
+SCM Changes Maven Extension
+---------------------------
+
+Build only projects containing files that that you personally have changed 
(according to SCM), and projects that
+depend on those projects (downstream).
+
+To use, add this to your parent POM:
+
+<build>
+  <extensions>
+    <extension>
+      <groupId>org.apache.maven.examples</groupId>
+      <artifactId>retro-maven-extension</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </extension>
+  </extensions>
+</build>
+
+Be sure to also specify an SCM connection:
+
+<scm>
+  
<connection>scm:svn:http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-reactor-plugin/</connection>
+  
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/plugins/trunk/maven-reactor-plugin/</developerConnection>
+  
<url>http://svn.apache.org/viewvc/maven/plugins/trunk/maven-reactor-plugin/</url>
+</scm>
+
+Then run your build like this:
+
+  mvn install -Dmake.scmChanges
+
+That will build only those projects that you changed, and projects that depend 
on those projects (downstream).
+
+IF IT DOESN'T APPEAR TO BE WORKING:  Try running mvn with -X to get debug logs.
+
+Note that if you modify the root POM (to add this extension) without checking 
it in, then EVERYTHING is downstream of
+the root POM, so -Dmake.scmChanges will cause a full rebuild; it will appear 
as if it's not working. You can use
+-Dmake.ignoreRootPom to ignore changes in the root POM while testing this 
extension.
\ No newline at end of file

Added: maven/sandbox/trunk/shared/scm-changes-maven-extension/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/shared/scm-changes-maven-extension/pom.xml?rev=1031727&view=auto
==============================================================================
--- maven/sandbox/trunk/shared/scm-changes-maven-extension/pom.xml (added)
+++ maven/sandbox/trunk/shared/scm-changes-maven-extension/pom.xml Fri Nov  5 
19:15:58 2010
@@ -0,0 +1,48 @@
+<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.shared</groupId>
+  <artifactId>scm-changes-maven-extension</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <name>SCM Changes Extension</name>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-compat</artifactId>
+      <version>3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+      <version>3.0</version>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.maven.scm</groupId>
+        <artifactId>maven-scm-providers-standard</artifactId>
+        <version>1.4</version>
+        <type>pom</type>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.maven.scm</groupId>
+        <artifactId>maven-scm-manager-plexus</artifactId>
+        <version>1.4</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.plexus</groupId>
+        <artifactId>plexus-component-metadata</artifactId>
+        <version>1.5.5</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate-metadata</goal>
+              <goal>generate-test-metadata</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Added: 
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/shared/scmchanges/MakeScmChanges.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/shared/scmchanges/MakeScmChanges.java?rev=1031727&view=auto
==============================================================================
--- 
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/shared/scmchanges/MakeScmChanges.java
 (added)
+++ 
maven/sandbox/trunk/shared/scm-changes-maven-extension/src/main/java/org/apache/maven/shared/scmchanges/MakeScmChanges.java
 Fri Nov  5 19:15:58 2010
@@ -0,0 +1,171 @@
+package org.apache.maven.shared.scmchanges;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.AbstractMavenLifecycleParticipant;
+import org.apache.maven.MavenExecutionException;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.RuntimeInformation;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.scm.ScmFile;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmFileStatus;
+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.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Build only projects containing files that that you personally have changed 
(according to SCM)
+ * 
+ * @author <a href="mailto:dfabul...@apache.org";>Dan Fabulich</a>
+ */
+...@component( role = AbstractMavenLifecycleParticipant.class, hint = 
"scm-changes" )
+public class MakeScmChanges
+    extends AbstractMavenLifecycleParticipant
+{
+    @Requirement
+    private Logger logger;
+
+    @Requirement
+    ScmManager scmManager;
+
+    /** SCM connection from root project */
+    String scmConnection;
+
+    /** make.ignoreUnknown: Ignore files in the "unknown" status (created but 
not added to source control) */
+    boolean ignoreUnknown = true;
+    
+    /** make.ignoreRootPom: Ignore changes in the root POM file, which would 
normally cause a full rebuild */
+    boolean ignoreRootPom = false;
+
+    /** Disabled by default; activate via -Dmake.scmChanges=true */
+    boolean enabled = false;
+
+    public void afterProjectsRead( MavenSession session )
+        throws MavenExecutionException
+    {
+        readParameters( session );
+
+        if ( !enabled )
+        {
+            logger.debug( "make.scmChanges = false, not modifying project 
list" );
+            return;
+        }
+            
+
+        List<ScmFile> changedFiles = getChangedFilesFromScm( 
session.getTopLevelProject().getBasedir() );
+
+        List<String> includedProjects = new ArrayList<String>();
+
+        for ( ScmFile changedScmFile : changedFiles )
+        {
+            logger.debug( changedScmFile.toString() );
+            ScmFileStatus status = changedScmFile.getStatus();
+            if ( !status.isStatus() ) // isStatus means "isUnknown or isDiff"
+            {
+                logger.debug( "Not a diff: " + status );
+                continue;
+            }
+            if ( ignoreUnknown && ScmFileStatus.UNKNOWN.equals( status ) )
+            {
+                logger.debug( "Ignoring unknown" );
+                continue;
+            }
+
+            File changedFile = new File( changedScmFile.getPath() );
+            
+            if ( ignoreRootPom && 
session.getTopLevelProject().getFile().getAbsoluteFile().equals( 
changedFile.getAbsoluteFile() ) )
+            {
+                continue;
+            }
+            
+            boolean found = false;
+            // TODO There's a cleverer/faster way to code this, right? This is 
O(n^2)
+            for ( MavenProject project : session.getProjects() )
+            {
+                File projectDirectory = project.getFile().getParentFile();
+                if ( changedFile.getAbsolutePath().startsWith( 
projectDirectory.getAbsolutePath() + File.separator ) )
+                {
+                    if ( !includedProjects.contains( project ) )
+                    {
+                        logger.debug( "Including " + project );
+                    }
+                    includedProjects.add( project.getGroupId() + ":" + 
project.getArtifactId() );
+                    found = true;
+                    break;
+                }
+            }
+            if ( !found )
+            {
+                logger.debug( "Couldn't find file in any project root: " + 
changedFile.getAbsolutePath() );
+            }
+        }
+
+        if ( includedProjects.isEmpty() )
+            throw new MavenExecutionException( "No SCM changes detected; 
nothing to do!",
+                                               
session.getTopLevelProject().getFile() );
+
+        MavenExecutionRequest request = session.getRequest();
+        String makeBehavior = request.getMakeBehavior();
+        if ( makeBehavior == null )
+        {
+            request.setMakeBehavior( 
MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
+        }
+        if ( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( makeBehavior 
) )
+        {
+            request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
+        }
+
+        request.setSelectedProjects( includedProjects );
+
+    }
+
+    private void readParameters( MavenSession session )
+        throws MavenExecutionException
+    {
+        Properties sessionProps = session.getUserProperties();
+        scmConnection = sessionProps.getProperty( "make.scmConnection" );
+        if ( scmConnection == null )
+        {
+            try
+            {
+                scmConnection = 
session.getTopLevelProject().getScm().getConnection();
+            }
+            catch ( NullPointerException e )
+            {
+                String message =
+                    "No SCM connection specified.  You must specify an SCM "
+                        + "connection by adding a <connection> element to your 
<scm> element in your POM";
+                throw new MavenExecutionException( message, e );
+            }
+        }
+        enabled = Boolean.parseBoolean( sessionProps.getProperty( 
"make.scmChanges", "false" ) );
+        ignoreUnknown = Boolean.parseBoolean( sessionProps.getProperty( 
"make.ignoreUnknown", "true" ) );
+        ignoreRootPom = Boolean.parseBoolean( sessionProps.getProperty( 
"make.ignoreRootPom", "false" ) );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private List<ScmFile> getChangedFilesFromScm( File baseDir )
+        throws MavenExecutionException
+    {
+        StatusScmResult result = null;
+        try
+        {
+            ScmRepository repository = scmManager.makeScmRepository( 
scmConnection );
+            result = scmManager.status( repository, new ScmFileSet( baseDir ) 
);
+        }
+        catch ( Exception e )
+        {
+            throw new MavenExecutionException( "Couldn't configure SCM 
repository: " + e.getLocalizedMessage(), e );
+        }
+
+        return (List<ScmFile>) result.getChangedFiles();
+    }
+}


Reply via email to