You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ch...@apache.org on 2015/05/26 14:49:00 UTC

maven-scm git commit: [SCM-775] Improved parsing of scm status output.

Repository: maven-scm
Updated Branches:
  refs/heads/master 61f9c973b -> 5a9b53bac


[SCM-775] Improved parsing of scm status output.


Project: http://git-wip-us.apache.org/repos/asf/maven-scm/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-scm/commit/5a9b53ba
Tree: http://git-wip-us.apache.org/repos/asf/maven-scm/tree/5a9b53ba
Diff: http://git-wip-us.apache.org/repos/asf/maven-scm/diff/5a9b53ba

Branch: refs/heads/master
Commit: 5a9b53bacfea523c59c84d5187eff620699d6ec8
Parents: 61f9c97
Author: Chris Graham <ch...@apache.org>
Authored: Tue May 26 22:48:29 2015 +1000
Committer: Chris Graham <ch...@apache.org>
Committed: Tue May 26 22:48:29 2015 +1000

----------------------------------------------------------------------
 .../maven-scm-provider-jazz/pom.xml             |  50 ++++
 .../command/checkin/JazzCheckInCommand.java     |   2 +-
 .../jazz/command/status/JazzStatusConsumer.java | 185 +++++++++++--
 .../repository/JazzScmProviderRepository.java   |  37 ++-
 .../command/status/JazzStatusCommandTest.java   | 276 +++++++++++++++++--
 pom.xml                                         |  61 ++++
 6 files changed, 558 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-scm/blob/5a9b53ba/maven-scm-providers/maven-scm-provider-jazz/pom.xml
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-jazz/pom.xml b/maven-scm-providers/maven-scm-provider-jazz/pom.xml
index 3545670..af62700 100644
--- a/maven-scm-providers/maven-scm-provider-jazz/pom.xml
+++ b/maven-scm-providers/maven-scm-provider-jazz/pom.xml
@@ -77,6 +77,56 @@
         </executions>
       </plugin>
     </plugins>
+    <pluginManagement>
+    	<plugins>
+    		<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+    		<plugin>
+    			<groupId>org.eclipse.m2e</groupId>
+    			<artifactId>lifecycle-mapping</artifactId>
+    			<version>1.0.0</version>
+    			<configuration>
+    				<lifecycleMappingMetadata>
+    					<pluginExecutions>
+    						<pluginExecution>
+    							<pluginExecutionFilter>
+    								<groupId>org.apache.rat</groupId>
+    								<artifactId>
+    									apache-rat-plugin
+    								</artifactId>
+    								<versionRange>[0.11,)</versionRange>
+    								<goals>
+    									<goal>check</goal>
+    								</goals>
+    							</pluginExecutionFilter>
+    							<action>
+    								<ignore></ignore>
+    							</action>
+    						</pluginExecution>
+    						<pluginExecution>
+    							<pluginExecutionFilter>
+    								<groupId>
+    									org.codehaus.plexus
+    								</groupId>
+    								<artifactId>
+    									plexus-component-metadata
+    								</artifactId>
+    								<versionRange>
+    									[1.5.5,)
+    								</versionRange>
+    								<goals>
+    									<goal>generate-metadata</goal>
+    								</goals>
+    							</pluginExecutionFilter>
+    							<action>
+    								<ignore></ignore>
+    							</action>
+    						</pluginExecution>
+    					</pluginExecutions>
+    				</lifecycleMappingMetadata>
+    			</configuration>
+    		</plugin>
+    	</plugins>
+    </pluginManagement>
   </build>
 
   <profiles>

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/5a9b53ba/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/checkin/JazzCheckInCommand.java
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/checkin/JazzCheckInCommand.java b/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/checkin/JazzCheckInCommand.java
index 123cec8..7c34b7c 100644
--- a/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/checkin/JazzCheckInCommand.java
+++ b/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/checkin/JazzCheckInCommand.java
@@ -130,7 +130,7 @@ public class JazzCheckInCommand
         JazzScmProviderRepository jazzRepo = (JazzScmProviderRepository) repository;
         if ( jazzRepo.isPushChangesAndHaveFlowTargets() && StringUtils.isNotEmpty( jazzRepo.getWorkItem() ) )
         {
-            List<Integer> changeSetAliases = jazzRepo.getChangeSetAliases();
+            List<Integer> changeSetAliases = jazzRepo.getOutgoingChangeSetAliases();
             if ( changeSetAliases != null && !changeSetAliases.isEmpty() )
             {
                 for ( Integer changeSetAlias : changeSetAliases )

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/5a9b53ba/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusConsumer.java
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusConsumer.java b/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusConsumer.java
index 19eba7a..b96b87e 100644
--- a/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusConsumer.java
+++ b/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusConsumer.java
@@ -40,7 +40,12 @@ import java.util.regex.Pattern;
  * are also collected and set back in the JazzScmProviderRepository.
  * The Workspace and Component names are needed for some other commands (list,
  * for example), so we can easily get this information here.
- *
+ * <p/>
+ * As this class has expanded over time, it has become more and more of a state
+ * machine, one that needs to parse the output of the "scm status --wide" command.
+ * If there are any issues with this provider, I would suggest this is a good
+ * place to start.
+ * 
  * @author <a href="mailto:ChrisGWarp@gmail.com">Chris Graham</a>
  */
 public class JazzStatusConsumer
@@ -83,8 +88,9 @@ public class JazzStatusConsumer
 //          Change sets:
 //            (2365) ---@  "This is my changeset comment." 26-Apr-2015 09:36 PM
 //
-// We can also have a multiple changesets, although, if the correct build procedure has been followed, namely we
-// start with a clean starting point, with nothing outstanding, then we should never see this (famous last words!)
+// We can also have a multiple changesets. These will be seen when a JBE is used to perform
+// the release and has been instructed to create a baseline prior to starting the build.
+// Multiple changesets will also be seen when a maven release process fails (for whatever reason).
 //
 //  Workspace: (1156) "GPDBWorkspace" <-> (1157) "GPDBStream"
 //    Component: (1158) "GPDB"
@@ -94,8 +100,69 @@ public class JazzStatusConsumer
 //            (2366) *--@  62 "Release the next release of GPDB." - "Man Created Changeset: X.Y.Z" 28-Apr-2015 07:55 PM
 //            (2365) ---@  "This is my changeset comment." 26-Apr-2015 09:36 PM
 //
+// We can also have Baselines, of which there may be more than one (especially true if an update (accept changes)
+// has not been done in a while.
+//
+// So the most complete/complex example I can find is something like this:
+//
+//  Workspace: (1756) "Scott's GPDBWorkspace" <-> (1157) "GPDBStream"
+//    Component: (1158) "GPDB"
+//      Baseline: (1718) 25 "GPDB-1.0.25"
+//      Unresolved:
+//        -c- /GPDB/pom.xml
+//      Outgoing:
+//        Change sets:
+//          (2389) *--@  "<No comment>" 23-May-2015 07:09 PM
+//      Incoming:
+//        Change sets:
+//          (2385) ---$ Deb 62 "Release the next release of GPDB." - \
+//             + "[maven-release-plugin] prepare for next development itera..." 02-May-2015 11:01 PM
+//      Baselines:
+//        (2386) 52 "GPDB-1.0.53"
+//        (2387) 51 "GPDB-1.0.52"
+//        (2388) 50 "GPDB-1.0.51"
+//        (2369) 49 "GPDB-MAN-1.0.50"
+//        (2362) 48 "GPDB-1.0.50"
+//        (2357) 47 "GPDB-1.0.49"
+//        (2352) 46 "GPDB-1.0.48"
+//        (2347) 45 "GPDB-1.0.47"
+//        (2292) 44 "GPDB-1.0.46"
+//        (2285) 42 "GPDB-1.0.42"
+//        (2276) 41 "GPDB-1.0.41"
+//        (2259) 40 "GPDB-1.0.40"
+//        (2250) 39 "GPDB-1.0.39"
+//        (2241) 38 "GPDB-1.0.38"
+//        (2232) 37 "GPDB-1.0.37"
+//        (2222) 36 "GPDB-1.0.36"
+//        (2212) 35 "GPDB-1.0.35"
+//        (2202) 34 "GPDB-1.0.34"
+//        (2191) 33 "GPDB-1.0.33"
+//        (2181) 32 "GPDB-1.0.32"
+//        (2171) 31 "GPDB-1.0.31"
+//        (2160) 30 "GPDB-1.0.30"
+//        (2147) 29 "GPDB-1.0.29"
+//        (2079) 28 "GPDB-1.0.28"
+//        (1851) 27 "GPDB-1.0.27"
+//        (1807) 26 "GPDB-1.0.26"
+//
 // Because the "Change sets:" line exists by itself, and it is followed by the changeset
-// lines, we need to implement a state machine... (seenChangeSets)
+// lines, we need to implement a state machine... (seenIncomingChangeSets and seenOutgoingChangeSets)
+//
+// We can also have collisions:
+//
+//  Workspace: (8551) "myNewWorkspace" <-> (8552) "stream19_test_max_results_1256765247692134"
+//    Component: (8553) "Flux Capacitor"
+//      Baseline: (8554) 1 "Initial Baseline"
+//      Outgoing:
+//        Change sets:
+//          (8617) -#@ "Update from November planning meeting"
+//            Changes:
+//              -#-c /flux.capacitor/requirements.txt
+//      Incoming:
+//        Change sets:
+//          (8616) -#$ "Results of initial trials"
+//            Changes:
+//              -#-c /flux.capacitor/requirements.txt
 
     //  Workspace: (1000) "BogusRepositoryWorkspace" <-> (1000) "BogusRepositoryWorkspace"
     //  Workspace: (1156) "GPDBWorkspace" <-> (1157) "GPDBStream"
@@ -135,10 +202,25 @@ public class JazzStatusConsumer
     public static final String STATUS_CMD_BASELINE = "Baseline:";
 
     /**
+     * The "Status" command output line that contains the "Outgoing" eye catcher.
+     */
+    public static final String STATUS_CMD_OUTGOING = "Outgoing:";
+
+    /**
+     * The "Status" command output line that contains the "Incoming" eye catcher.
+     */
+    public static final String STATUS_CMD_INCOMING = "Incoming:";
+
+    /**
      * The "Status" command output line that contains the line "Change sets:".
-     * This will be followed by the 
+     * This will be followed by the change set lines themselves. 
      */
     public static final String STATUS_CMD_CHANGE_SETS = "Change sets:";
+
+    /**
+     * The "Status" command output line that contains the "Baselines" eye catcher.
+     */
+    public static final String STATUS_CMD_BASELINES = "Baselines:";
     
     // File Status Commands (eye catchers)
 
@@ -169,9 +251,14 @@ public class JazzStatusConsumer
     private List<ScmFile> fChangedFiles = new ArrayList<ScmFile>();
 
     /**
-     * Implement a simple state machine: Have we seen the "Change sets:" line or not?
+     * Implement a simple state machine: Have we seen the "Change sets:" (outgoing) line or not?
      */
-    private boolean seenChangeSets = false;
+    private boolean seenOutgoingChangeSets = false;
+
+    /**
+     * Implement a simple state machine: Have we seen the "Change sets:" (incoming) line or not?
+     */
+    private boolean seenIncomingChangeSets = false;
 
     /**
      * Constructor for our "scm status" consumer.
@@ -209,13 +296,53 @@ public class JazzStatusConsumer
         {
             extractChangedFile( line );
         }
-        if ( containsChangeSets( line ) )
+        if ( containsOutgoing( line ) )
         {
-            seenChangeSets = true;
+            // Now looking for outgoing, not incoming
+            seenOutgoingChangeSets = true;
+            seenIncomingChangeSets = false;
         }
-        if ( seenChangeSets )
+        if ( containsIncoming( line ) )
         {
-            extractChangeSetAlias( line );
+            // Now looking for incoming, not outgoing
+            seenOutgoingChangeSets = false;
+            seenIncomingChangeSets = true;
+        }
+        if ( containsBaselines( line ) )
+        {
+            // Got to baselines, stop looking for all changesets
+            seenOutgoingChangeSets = false;
+            seenIncomingChangeSets = false;
+        }
+        if ( seenOutgoingChangeSets )
+        {
+            Integer changeSetAlias = extractChangeSetAlias( line );
+            if ( changeSetAlias != null )
+            {
+                // We are now supporting multiple change sets, as this allows
+                // us to cater for multiple changeset caused by previous failed
+                // release attempts.
+                // Our starting point should always be a clean slate of a workspace
+                // or sandbox, however, if something fails, then we will have some
+                // changesets already created, so we need to be able to deal with them effectively.
+                JazzScmProviderRepository jazzRepository = (JazzScmProviderRepository) getRepository();
+                jazzRepository.getOutgoingChangeSetAliases().add( new Integer( changeSetAlias ) );
+            }
+        }
+        if ( seenIncomingChangeSets )
+        {
+            Integer changeSetAlias = extractChangeSetAlias( line );
+            if ( changeSetAlias != null )
+            {
+                // We are now supporting multiple change sets, as this allows
+                // us to cater for multiple changeset caused by previous failed
+                // release attempts.
+                // Our starting point should always be a clean slate of a workspace
+                // or sandbox, however, if something fails, then we will have some
+                // changesets already created, so we need to be able to deal with them effectively.
+                JazzScmProviderRepository jazzRepository = (JazzScmProviderRepository) getRepository();
+                jazzRepository.getIncomingChangeSetAliases().add( new Integer( changeSetAlias ) );
+            }
         }
     }
 
@@ -382,33 +509,45 @@ public class JazzStatusConsumer
         return fChangedFiles;
     }
 
-    private boolean containsChangeSets( String line )
+    private boolean containsOutgoing( String line )
     {
-        return line.trim().startsWith( STATUS_CMD_CHANGE_SETS );
+        return line.trim().startsWith( STATUS_CMD_OUTGOING );
     }
 
-    private void extractChangeSetAlias( String line )
+    private boolean containsIncoming( String line )
+    {
+        return line.trim().startsWith( STATUS_CMD_INCOMING );
+    }
+
+    private boolean containsBaselines( String line )
+    {
+        return line.trim().startsWith( STATUS_CMD_BASELINES );
+    }
+
+    /**
+     * Extract and return an Integer of a change set alias, from both
+     * incoming and outgoing changesets.
+     * @param line The line to extract the change sets from.
+     * @return A parsed Integer value, or null if not able to parse.
+     */
+    private Integer extractChangeSetAlias( String line )
     {
         // (2365) ---@  "This is my changeset comment." 26-Apr-2015 09:36 PM
 
         Matcher matcher = CHANGESET_PATTERN.matcher( line );
         if ( matcher.find() )
         {
-            JazzScmProviderRepository jazzRepository = (JazzScmProviderRepository) getRepository();
-
             int changeSetAlias = Integer.parseInt( matcher.group( 1 ) );
             if ( getLogger().isDebugEnabled() )
             {
                 getLogger().debug( "Successfully parsed post \"Change sets:\" line:" );
                 getLogger().debug( "  changeSetAlias = " + changeSetAlias );
             }
-            // We are now supporting multiple change sets, as this allows
-            // us to cater for multiple changeset caused by previous failed
-            // release attempts.
-            // Our starting point should always be a clean slate of a workspace
-            // or sandbox, however, if something fails, then we will have some
-            // changesets already created, so we need to be able to deal with them effectively.
-            jazzRepository.getChangeSetAliases().add( new Integer( changeSetAlias ) );
+            return new Integer( changeSetAlias );
+        }
+        else
+        {
+            return null;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/5a9b53ba/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/repository/JazzScmProviderRepository.java
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/repository/JazzScmProviderRepository.java b/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/repository/JazzScmProviderRepository.java
index f1ee5c5..9951e9d 100644
--- a/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/repository/JazzScmProviderRepository.java
+++ b/maven-scm-providers/maven-scm-provider-jazz/src/main/java/org/apache/maven/scm/provider/jazz/repository/JazzScmProviderRepository.java
@@ -87,9 +87,14 @@ public class JazzScmProviderRepository
     private String fBaseline;
 
     /**
-     * The alias of the change set, as returned from the "scm status" command.
+     * The outgoing aliases of the change sets, as returned from the "scm status" command.
      */
-    private List<Integer> fChangeSetAliases = new ArrayList<Integer>();
+    private List<Integer> fOutgoingChangeSetAliases = new ArrayList<Integer>();
+
+    /**
+     * The incoming aliases of the change sets, as returned from the "scm status" command.
+     */
+    private List<Integer> fIncomingChangeSetAliases = new ArrayList<Integer>();
 
     // TODO In the future we might expand the details of this repository.
     // For example we might extend the scm url to include a stream (as well as the repository workspace)
@@ -252,19 +257,35 @@ public class JazzScmProviderRepository
     }
 
     /**
-     * @return The List<Integer> of aliases of the changesets, as returned from the "scm status" command.
+     * @return The List<Integer> of aliases of the outgoing changesets, as returned from the "scm status" command.
+     */
+    public List<Integer> getOutgoingChangeSetAliases()
+    {
+        return fOutgoingChangeSetAliases;
+    }
+
+    /**
+     * @param outgoingChangeSetAliases The List of Integers of outgoing change set aliases to set
+     */
+    public void setOutgoingChangeSetAliases( List<Integer> outgoingChangeSetAliases )
+    {
+        this.fOutgoingChangeSetAliases = outgoingChangeSetAliases;
+    }
+    
+    /**
+     * @return The List<Integer> of aliases of the incoming changesets, as returned from the "scm status" command.
      */
-    public List<Integer> getChangeSetAliases()
+    public List<Integer> getIncomingChangeSetAliases()
     {
-        return fChangeSetAliases;
+        return fIncomingChangeSetAliases;
     }
 
     /**
-     * @param ChangeSetAliases the List of Integers of change set aliases to set
+     * @param incomingChangeSetAliases The List of Integers of incoming change set aliases to set
      */
-    public void setChangeSetAliases( List<Integer> changeSetAliases )
+    public void setIncomingChangeSetAliases( List<Integer> incomingChangeSetAliases )
     {
-        this.fChangeSetAliases = changeSetAliases;
+        this.fIncomingChangeSetAliases = incomingChangeSetAliases;
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/5a9b53ba/maven-scm-providers/maven-scm-provider-jazz/src/test/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusCommandTest.java
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-jazz/src/test/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusCommandTest.java b/maven-scm-providers/maven-scm-provider-jazz/src/test/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusCommandTest.java
index ede7e91..41d612c 100644
--- a/maven-scm-providers/maven-scm-provider-jazz/src/test/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusCommandTest.java
+++ b/maven-scm-providers/maven-scm-provider-jazz/src/test/java/org/apache/maven/scm/provider/jazz/command/status/JazzStatusCommandTest.java
@@ -83,9 +83,9 @@ public class JazzStatusCommandTest
         assertEquals( "Flow Target Alias is incorrect!", 1001, repo.getFlowTargetAlias() );
         assertEquals( "Component is incorrect!", "SCM Plugins", repo.getComponent() );
         assertEquals( "Baseline is incorrect!", "Initial Baseline", repo.getBaseline() );
-        assertNotNull( repo.getChangeSetAliases() );
-        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getChangeSetAliases().size() );
-        assertEquals( "Change Set Alias is incorrect!", new Integer(1008), repo.getChangeSetAliases().get(0));
+        assertNotNull( repo.getOutgoingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getOutgoingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias is incorrect!", new Integer(1008), repo.getOutgoingChangeSetAliases().get(0));
 
         // Test the stream parsing and isPushChanges bits.
         assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
@@ -217,15 +217,15 @@ public class JazzStatusCommandTest
         assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
 
 
-        assertNotNull( repo.getChangeSetAliases() );
-        assertEquals( "Change Set Alias length is incorrect!", 7, repo.getChangeSetAliases().size() );
-        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(1012), repo.getChangeSetAliases().get(0));
-        assertEquals( "Change Set Alias [1] is incorrect!", new Integer(1011), repo.getChangeSetAliases().get(1));
-        assertEquals( "Change Set Alias [2] is incorrect!", new Integer(1010), repo.getChangeSetAliases().get(2));
-        assertEquals( "Change Set Alias [3] is incorrect!", new Integer(1009), repo.getChangeSetAliases().get(3));
-        assertEquals( "Change Set Alias [4] is incorrect!", new Integer(1008), repo.getChangeSetAliases().get(4));
-        assertEquals( "Change Set Alias [5] is incorrect!", new Integer(1007), repo.getChangeSetAliases().get(5));
-        assertEquals( "Change Set Alias [6] is incorrect!", new Integer(1006), repo.getChangeSetAliases().get(6));
+        assertNotNull( repo.getOutgoingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 7, repo.getOutgoingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(1012), repo.getOutgoingChangeSetAliases().get(0));
+        assertEquals( "Change Set Alias [1] is incorrect!", new Integer(1011), repo.getOutgoingChangeSetAliases().get(1));
+        assertEquals( "Change Set Alias [2] is incorrect!", new Integer(1010), repo.getOutgoingChangeSetAliases().get(2));
+        assertEquals( "Change Set Alias [3] is incorrect!", new Integer(1009), repo.getOutgoingChangeSetAliases().get(3));
+        assertEquals( "Change Set Alias [4] is incorrect!", new Integer(1008), repo.getOutgoingChangeSetAliases().get(4));
+        assertEquals( "Change Set Alias [5] is incorrect!", new Integer(1007), repo.getOutgoingChangeSetAliases().get(5));
+        assertEquals( "Change Set Alias [6] is incorrect!", new Integer(1006), repo.getOutgoingChangeSetAliases().get(6));
     }
 
     public void testConsumerWithMultipleChangeSetsAndWorkItems()
@@ -270,14 +270,248 @@ public class JazzStatusCommandTest
         repo.setPushChanges( true );
         assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
 
-        assertNotNull( repo.getChangeSetAliases() );
-        assertEquals( "Change Set Alias length is incorrect!", 7, repo.getChangeSetAliases().size() );
-        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(1012), repo.getChangeSetAliases().get(0));
-        assertEquals( "Change Set Alias [1] is incorrect!", new Integer(1011), repo.getChangeSetAliases().get(1));
-        assertEquals( "Change Set Alias [2] is incorrect!", new Integer(1010), repo.getChangeSetAliases().get(2));
-        assertEquals( "Change Set Alias [3] is incorrect!", new Integer(1009), repo.getChangeSetAliases().get(3));
-        assertEquals( "Change Set Alias [4] is incorrect!", new Integer(1008), repo.getChangeSetAliases().get(4));
-        assertEquals( "Change Set Alias [5] is incorrect!", new Integer(1007), repo.getChangeSetAliases().get(5));
-        assertEquals( "Change Set Alias [6] is incorrect!", new Integer(1006), repo.getChangeSetAliases().get(6));
+        assertNotNull( repo.getOutgoingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 7, repo.getOutgoingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(1012), repo.getOutgoingChangeSetAliases().get(0));
+        assertEquals( "Change Set Alias [1] is incorrect!", new Integer(1011), repo.getOutgoingChangeSetAliases().get(1));
+        assertEquals( "Change Set Alias [2] is incorrect!", new Integer(1010), repo.getOutgoingChangeSetAliases().get(2));
+        assertEquals( "Change Set Alias [3] is incorrect!", new Integer(1009), repo.getOutgoingChangeSetAliases().get(3));
+        assertEquals( "Change Set Alias [4] is incorrect!", new Integer(1008), repo.getOutgoingChangeSetAliases().get(4));
+        assertEquals( "Change Set Alias [5] is incorrect!", new Integer(1007), repo.getOutgoingChangeSetAliases().get(5));
+        assertEquals( "Change Set Alias [6] is incorrect!", new Integer(1006), repo.getOutgoingChangeSetAliases().get(6));
+    }
+    
+    public void testConsumerUnresolvedIncomingOutgoing()
+    {
+    	statusConsumer.consumeLine( "Workspace: (1756) \"Scott's GPDBWorkspace\" <-> (1157) \"GPDBStream\"" );
+    	statusConsumer.consumeLine( "  Component: (1158) \"GPDB\"" );
+    	statusConsumer.consumeLine( "    Baseline: (1718) 25 \"GPDB-1.0.25\"" );
+    	statusConsumer.consumeLine( "    Unresolved:" );
+    	statusConsumer.consumeLine( "      -c- /GPDB/pom.xml" );
+    	statusConsumer.consumeLine( "    Outgoing:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (2389) *--@  \"<No comment>\" 23-May-2015 07:09 PM" );
+    	statusConsumer.consumeLine( "    Incoming:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (2385) ---$ Deb 62 \"Release the next release of GPDB.\""
+    	    + " - \"[maven-release-plugin] prepare for next development itera...\" 02-May-2015 11:01 PM" );
+    	statusConsumer.consumeLine( "    Baselines:" );
+    	statusConsumer.consumeLine( "      (2386) 52 \"GPDB-1.0.53\"" );
+    	statusConsumer.consumeLine( "      (2387) 51 \"GPDB-1.0.52\"" );
+    	statusConsumer.consumeLine( "      (2388) 50 \"GPDB-1.0.51\"" );
+    	statusConsumer.consumeLine( "      (2369) 49 \"GPDB-MAN-1.0.50\"" );
+    	statusConsumer.consumeLine( "      (2362) 48 \"GPDB-1.0.50\"" );
+    	statusConsumer.consumeLine( "      (2357) 47 \"GPDB-1.0.49\"" );
+    	statusConsumer.consumeLine( "      (2352) 46 \"GPDB-1.0.48\"" );
+    	statusConsumer.consumeLine( "      (2347) 45 \"GPDB-1.0.47\"" );
+    	statusConsumer.consumeLine( "      (2292) 44 \"GPDB-1.0.46\"" );
+    	statusConsumer.consumeLine( "      (2285) 42 \"GPDB-1.0.42\"" );
+    	statusConsumer.consumeLine( "      (2276) 41 \"GPDB-1.0.41\"" );
+    	statusConsumer.consumeLine( "      (2259) 40 \"GPDB-1.0.40\"" );
+    	statusConsumer.consumeLine( "      (2250) 39 \"GPDB-1.0.39\"" );
+    	statusConsumer.consumeLine( "      (2241) 38 \"GPDB-1.0.38\"" );
+    	statusConsumer.consumeLine( "      (2232) 37 \"GPDB-1.0.37\"" );
+    	statusConsumer.consumeLine( "      (2222) 36 \"GPDB-1.0.36\"" );
+    	statusConsumer.consumeLine( "      (2212) 35 \"GPDB-1.0.35\"" );
+    	statusConsumer.consumeLine( "      (2202) 34 \"GPDB-1.0.34\"" );
+    	statusConsumer.consumeLine( "      (2191) 33 \"GPDB-1.0.33\"" );
+    	statusConsumer.consumeLine( "      (2181) 32 \"GPDB-1.0.32\"" );
+    	statusConsumer.consumeLine( "      (2171) 31 \"GPDB-1.0.31\"" );
+    	statusConsumer.consumeLine( "      (2160) 30 \"GPDB-1.0.30\"" );
+    	statusConsumer.consumeLine( "      (2147) 29 \"GPDB-1.0.29\"" );
+    	statusConsumer.consumeLine( "      (2079) 28 \"GPDB-1.0.28\"" );
+    	statusConsumer.consumeLine( "      (1851) 27 \"GPDB-1.0.27\"" );
+    	statusConsumer.consumeLine( "      (1807) 26 \"GPDB-1.0.26\"" );
+
+        // Test the additional collected data, Workspace, Component, Baseline.
+        assertEquals( "Workspace is incorrect!", "Scott's GPDBWorkspace", repo.getWorkspace() );
+        assertEquals( "Workspace Alias is incorrect!", 1756, repo.getWorkspaceAlias() );
+        assertEquals( "Flow Target is incorrect!", "GPDBStream", repo.getFlowTarget() );
+        assertEquals( "Flow Target Alias is incorrect!", 1157, repo.getFlowTargetAlias() );
+        assertEquals( "Component is incorrect!", "GPDB", repo.getComponent() );
+        assertEquals( "Baseline is incorrect!", "GPDB-1.0.25", repo.getBaseline() );
+
+        // Test the stream parsing and isPushChanges bits.
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( false );
+        assertFalse( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( true );
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+
+        assertNotNull( repo.getOutgoingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getOutgoingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(2389), repo.getOutgoingChangeSetAliases().get(0));
+
+        assertNotNull( repo.getIncomingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getIncomingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(2385), repo.getIncomingChangeSetAliases().get(0));
+    }
+    
+    public void testCollision()
+    {
+    	statusConsumer.consumeLine( "Workspace: (8551) \"myNewWorkspace\" <-> (8552) \"stream19_test_max_results_1256765247692134\"" );
+    	statusConsumer.consumeLine( "  Component: (8553) \"Flux Capacitor\"" );
+    	statusConsumer.consumeLine( "    Baseline: (8554) 1 \"Initial Baseline\"" );
+    	statusConsumer.consumeLine( "    Outgoing:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (8617) -#@ \"Update from November planning meeting\"" );
+    	statusConsumer.consumeLine( "          Changes:" );
+    	statusConsumer.consumeLine( "            -#-c /flux.capacitor/requirements.txt" );
+    	statusConsumer.consumeLine( "    Incoming:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (8616) -#$ \"Results of initial trials\"" );
+    	statusConsumer.consumeLine( "          Changes:" );
+    	statusConsumer.consumeLine( "            -#-c /flux.capacitor/requirements.txt" );
+
+        // Test the additional collected data, Workspace, Component, Baseline.
+        assertEquals( "Workspace is incorrect!", "myNewWorkspace", repo.getWorkspace() );
+        assertEquals( "Workspace Alias is incorrect!", 8551, repo.getWorkspaceAlias() );
+        assertEquals( "Flow Target is incorrect!", "stream19_test_max_results_1256765247692134", repo.getFlowTarget() );
+        assertEquals( "Flow Target Alias is incorrect!", 8552, repo.getFlowTargetAlias() );
+        assertEquals( "Component is incorrect!", "Flux Capacitor", repo.getComponent() );
+        assertEquals( "Baseline is incorrect!", "Initial Baseline", repo.getBaseline() );
+
+        // Test the stream parsing and isPushChanges bits.
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( false );
+        assertFalse( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( true );
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+
+        assertNotNull( repo.getOutgoingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getOutgoingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(8617), repo.getOutgoingChangeSetAliases().get(0));
+
+        assertNotNull( repo.getIncomingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getIncomingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(8616), repo.getIncomingChangeSetAliases().get(0));
+
+//        // Test the ScmFile and ScmFileStatus bits. (Needs a bit of work here)
+//        List<ScmFile> changedFiles = statusConsumer.getChangedFiles();
+//        assertNotNull( changedFiles );
+//        assertEquals( 1, changedFiles.size() );
+//        assertTrue( changedFiles.contains( new ScmFile( "/flux.capacitor/requirements.txt", ScmFileStatus.CONFLICT ) ) );
+    }
+    
+    public void testIncoming()
+    {
+    	statusConsumer.consumeLine( "Workspace: (1026) \"DEV-build-POC-Builder\" <-> (1011) \"DEV-build-Management-Release plugin POC\"" );
+    	statusConsumer.consumeLine( "  Component: (1095) \"FW-Maven-ReleasePlugin-POC\"" );
+    	statusConsumer.consumeLine( "    Baseline: (1103) 2 \"release_poc-build-0.0.3\"" );
+    	statusConsumer.consumeLine( "    Incoming:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (1106) ---$  28383 \"Detemine more efficient way to perform releases using mav...\" - \"Updated SCM settings\" 05-May-2015 10:26 AM" );
+
+        // Test the additional collected data, Workspace, Component, Baseline.
+        assertEquals( "Workspace is incorrect!", "DEV-build-POC-Builder", repo.getWorkspace() );
+        assertEquals( "Workspace Alias is incorrect!", 1026, repo.getWorkspaceAlias() );
+        assertEquals( "Flow Target is incorrect!", "DEV-build-Management-Release plugin POC", repo.getFlowTarget() );
+        assertEquals( "Flow Target Alias is incorrect!", 1011, repo.getFlowTargetAlias() );
+        assertEquals( "Component is incorrect!", "FW-Maven-ReleasePlugin-POC", repo.getComponent() );
+        assertEquals( "Baseline is incorrect!", "release_poc-build-0.0.3", repo.getBaseline() );
+
+        // Test the stream parsing and isPushChanges bits.
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( false );
+        assertFalse( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( true );
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+
+        assertNotNull( repo.getIncomingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getIncomingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(1106), repo.getIncomingChangeSetAliases().get(0));
+    }
+    
+    public void testMultipleIncoming()
+    {
+    	statusConsumer.consumeLine( "Workspace: (1000) \"Chris-Blah-Workspace\" <-> (1001) \"CHRIS_Blah_Stream\"" );
+    	statusConsumer.consumeLine( "  Component: (1002) \"Data_Models\"" );
+    	statusConsumer.consumeLine( "    Baseline: (1003) 465 \"CHRIS_BLAH_20150516_190700_1\"" );
+    	statusConsumer.consumeLine( "    Unresolved:" );
+    	statusConsumer.consumeLine( "      -c- /Data Model/.settings/org.eclipse.core.resources.prefs" );
+    	statusConsumer.consumeLine( "    Incoming:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (1004) ---$ chrisgwarp 1573 \"Manage Work Order Business Spec\" - \"PROJ-1001 - Added Hist...\" 15-May-2015 12:53 PM" );
+    	statusConsumer.consumeLine( "        (1005) ---$ chrisgwarp 1573 \"Manage Work Order Business Spec\" - \"PROJ-1001 - Removed Error Code 020...\" 14-May-2015 05:59 PM" );
+
+        // Test the additional collected data, Workspace, Component, Baseline.
+        assertEquals( "Workspace is incorrect!", "Chris-Blah-Workspace", repo.getWorkspace() );
+        assertEquals( "Workspace Alias is incorrect!", 1000, repo.getWorkspaceAlias() );
+        assertEquals( "Flow Target is incorrect!", "CHRIS_Blah_Stream", repo.getFlowTarget() );
+        assertEquals( "Flow Target Alias is incorrect!", 1001, repo.getFlowTargetAlias() );
+        assertEquals( "Component is incorrect!", "Data_Models", repo.getComponent() );
+        assertEquals( "Baseline is incorrect!", "CHRIS_BLAH_20150516_190700_1", repo.getBaseline() );
+
+        // Test the stream parsing and isPushChanges bits.
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( false );
+        assertFalse( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( true );
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+
+        assertNotNull( repo.getIncomingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 2, repo.getIncomingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(1004), repo.getIncomingChangeSetAliases().get(0));
+        assertEquals( "Change Set Alias [1] is incorrect!", new Integer(1005), repo.getIncomingChangeSetAliases().get(1));
+    }
+    
+    public void testIncomingOutgoing()
+    {
+    	statusConsumer.consumeLine( "Workspace: (8551) \"myNewWorkspace\" <-> (8552) \"stream19_test_max_results_1256765247692134\"" );
+    	statusConsumer.consumeLine( "  Component: (8553) \"Flux Capacitor\"" );
+    	statusConsumer.consumeLine( "    Baseline: (8554) 1 \"Initial Baseline\"" );
+    	statusConsumer.consumeLine( "    Outgoing:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (8556) ---@" );
+    	statusConsumer.consumeLine( "          Changes:" );
+    	statusConsumer.consumeLine( "            ---c- /flux.capacitor/requirements.txt" );
+    	statusConsumer.consumeLine( "    Incoming:" );
+    	statusConsumer.consumeLine( "      Change sets:" );
+    	statusConsumer.consumeLine( "        (8615) ---$ \"Initial layout\"" );
+    	statusConsumer.consumeLine( "          Changes:" );
+    	statusConsumer.consumeLine( "            ---c- /flux.capacitor/diagrams/design.cad" );
+
+        // Test the additional collected data, Workspace, Component, Baseline.
+        assertEquals( "Workspace is incorrect!", "myNewWorkspace", repo.getWorkspace() );
+        assertEquals( "Workspace Alias is incorrect!", 8551, repo.getWorkspaceAlias() );
+        assertEquals( "Flow Target is incorrect!", "stream19_test_max_results_1256765247692134", repo.getFlowTarget() );
+        assertEquals( "Flow Target Alias is incorrect!", 8552, repo.getFlowTargetAlias() );
+        assertEquals( "Component is incorrect!", "Flux Capacitor", repo.getComponent() );
+        assertEquals( "Baseline is incorrect!", "Initial Baseline", repo.getBaseline() );
+
+        // Test the stream parsing and isPushChanges bits.
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( false );
+        assertFalse( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+        repo.setPushChanges( true );
+        assertTrue( "isPushChangesAndHaveFlowTargets is incorrect!", repo.isPushChangesAndHaveFlowTargets() );
+
+        assertNotNull( repo.getOutgoingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getOutgoingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(8556), repo.getOutgoingChangeSetAliases().get(0));
+
+        assertNotNull( repo.getIncomingChangeSetAliases() );
+        assertEquals( "Change Set Alias length is incorrect!", 1, repo.getIncomingChangeSetAliases().size() );
+        assertEquals( "Change Set Alias [0] is incorrect!", new Integer(8615), repo.getIncomingChangeSetAliases().get(0));
+    }
+    
+    public void testServerUnreachable1()
+    {
+    	statusConsumer.consumeLine( "Workspace: (1000) \"GPDBWorkspace\" (This workspace is unreachable.)" );
+    	statusConsumer.consumeLine( "  Could not log in to https://rtc:9444/jazz/ as user Deb: CRJAZ2384E Cannot" );
+    	statusConsumer.consumeLine( "  connect to the repository at URL \"https://rtc:9444/jazz\", see the nested" );
+    	statusConsumer.consumeLine( "  exception for more details. For more details, open the help system and search" );
+    	statusConsumer.consumeLine( "  for CRJAZ2384E." );
+    	
+    }
+    
+    public void testServerUnreachable2()
+    {
+    	statusConsumer.consumeLine( "Workspace: (1000) \"Chris-Blah-Workspace\" (This workspace is unreachable.)" );
+    	statusConsumer.consumeLine( "  Could not determine the URI required to connect to the repository. The UUID of" );
+    	statusConsumer.consumeLine( "  the repository is _Bzjnksdkmfsaklmz-5uTdf. If you know the repository URI run" );
+    	statusConsumer.consumeLine( "  'login' command providing the repository URI. If not, please contact your" );
+    	statusConsumer.consumeLine( "  administrator." );
+    	
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/5a9b53ba/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index aee08f6..590af3f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -352,6 +352,67 @@
             </excludes>
           </configuration>
         </plugin>
+        <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+        <plugin>
+        	<groupId>org.eclipse.m2e</groupId>
+        	<artifactId>lifecycle-mapping</artifactId>
+        	<version>1.0.0</version>
+        	<configuration>
+        		<lifecycleMappingMetadata>
+        			<pluginExecutions>
+        				<pluginExecution>
+        					<pluginExecutionFilter>
+        						<groupId>org.apache.rat</groupId>
+        						<artifactId>
+        							apache-rat-plugin
+        						</artifactId>
+        						<versionRange>[0.11,)</versionRange>
+        						<goals>
+        							<goal>check</goal>
+        						</goals>
+        					</pluginExecutionFilter>
+        					<action>
+        						<ignore></ignore>
+        					</action>
+        				</pluginExecution>
+        				<pluginExecution>
+        					<pluginExecutionFilter>
+        						<groupId>
+        							org.apache.maven.plugins
+        						</groupId>
+        						<artifactId>
+        							maven-enforcer-plugin
+        						</artifactId>
+        						<versionRange>[1.3.1,)</versionRange>
+        						<goals>
+        							<goal>enforce</goal>
+        						</goals>
+        					</pluginExecutionFilter>
+        					<action>
+        						<ignore></ignore>
+        					</action>
+        				</pluginExecution>
+        				<pluginExecution>
+        					<pluginExecutionFilter>
+        						<groupId>
+        							org.apache.maven.plugins
+        						</groupId>
+        						<artifactId>
+        							maven-remote-resources-plugin
+        						</artifactId>
+        						<versionRange>[1.5,)</versionRange>
+        						<goals>
+        							<goal>process</goal>
+        						</goals>
+        					</pluginExecutionFilter>
+        					<action>
+        						<ignore></ignore>
+        					</action>
+        				</pluginExecution>
+        			</pluginExecutions>
+        		</lifecycleMappingMetadata>
+        	</configuration>
+        </plugin>
       </plugins>
     </pluginManagement>
     <plugins>