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 2010/11/05 20:15:58 UTC
svn commit: r1031727 - in
/maven/sandbox/trunk/shared/scm-changes-maven-extension: ./ src/ src/main/
src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/maven/ src/main/java/org/apache/maven/shared/
src/main/java/org/ap...
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:dfabulich@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();
+ }
+}