View Javadoc
1   package org.apache.maven.scm.provider.jazz.command.tag;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.scm.ScmException;
23  import org.apache.maven.scm.ScmFile;
24  import org.apache.maven.scm.ScmFileSet;
25  import org.apache.maven.scm.ScmFileStatus;
26  import org.apache.maven.scm.ScmResult;
27  import org.apache.maven.scm.ScmTagParameters;
28  import org.apache.maven.scm.command.tag.AbstractTagCommand;
29  import org.apache.maven.scm.command.tag.TagScmResult;
30  import org.apache.maven.scm.provider.ScmProviderRepository;
31  import org.apache.maven.scm.provider.jazz.command.JazzConstants;
32  import org.apache.maven.scm.provider.jazz.command.JazzScmCommand;
33  import org.apache.maven.scm.provider.jazz.command.consumer.DebugLoggerConsumer;
34  import org.apache.maven.scm.provider.jazz.command.consumer.ErrorConsumer;
35  import org.apache.maven.scm.provider.jazz.repository.JazzScmProviderRepository;
36  import org.codehaus.plexus.util.cli.StreamConsumer;
37  
38  import java.io.File;
39  import java.util.ArrayList;
40  import java.util.List;
41  
42  // The Maven SCM Plugin "tag" goal is equivalent to the RTC "create snapshot" command.
43  //
44  // Once the tag (snapshot in RTC terms) has been created, a repository workspace is then created
45  // based upon that snapshot. This is done to allow the checkout of a tag (maven release plugin) to function.
46  // As, currently, the underlying scm command does not allow us to check out (load in RTC terms) a snapshot directly.
47  //
48  // See the following links for additional information on the RTC "create snapshot" command:
49  // RTC 2.0.0.2:
50  // http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_create.html
51  // RTC 3.0:
52  // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_create.html
53  // RTC 3.0.1:
54  // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_create.html
55  //
56  // See the following links for additional information on the RTC "deliver" command:
57  // RTC 2.0.0.2:
58  // http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html
59  // RTC 3.0:
60  // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html
61  // RTC 3.0.1:
62  // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html
63  
64  /**
65   * @author <a href="mailto:ChrisGWarp@gmail.com">Chris Graham</a>
66   */
67  public class JazzTagCommand
68      extends AbstractTagCommand
69  {
70      /**
71       * {@inheritDoc}
72       */
73      protected ScmResult executeTagCommand( ScmProviderRepository repo, ScmFileSet fileSet, String tag,
74                                             ScmTagParameters scmTagParameters )
75          throws ScmException
76      {
77          if ( getLogger().isDebugEnabled() )
78          {
79              getLogger().debug( "Executing tag command..." );
80          }
81  
82          JazzScmProviderRepository jazzRepo = (JazzScmProviderRepository) repo;
83  
84          getLogger().debug( "Creating Snapshot..." );
85          StreamConsumer tagConsumer =
86              new DebugLoggerConsumer( getLogger() );      // No need for a dedicated consumer for this
87          ErrorConsumer errConsumer = new ErrorConsumer( getLogger() );
88          JazzScmCommand tagCreateSnapshotCmd =
89              createTagCreateSnapshotCommand( jazzRepo, fileSet, tag, scmTagParameters );
90          int status = tagCreateSnapshotCmd.execute( tagConsumer, errConsumer );
91  
92          if ( status != 0 || errConsumer.hasBeenFed() )
93          {
94              return new TagScmResult( tagCreateSnapshotCmd.getCommandString(),
95                                       "Error code for Jazz SCM tag (SNAPSHOT) command - " + status,
96                                       errConsumer.getOutput(), false );
97          }
98  
99          // ------------------------------------------------------------------
100         // We create the workspace based on the tag here, as the scm tool
101         // can not currently check directly out from a snapshot (only a workspace).
102         getLogger().debug( "Creating Workspace from Snapshot..." );
103         JazzScmCommand tagCreateWorkspaceCmd = createTagCreateWorkspaceCommand( jazzRepo, fileSet, tag );
104         errConsumer = new ErrorConsumer( getLogger() );
105         status = tagCreateWorkspaceCmd.execute( tagConsumer, errConsumer );
106 
107         if ( status != 0 || errConsumer.hasBeenFed() )
108         {
109             return new TagScmResult( tagCreateWorkspaceCmd.getCommandString(),
110                                      "Error code for Jazz SCM tag (WORKSPACE) command - " + status,
111                                      errConsumer.getOutput(), false );
112         }
113         // ------------------------------------------------------------------
114 
115         if ( jazzRepo.isPushChangesAndHaveFlowTargets() )
116         {
117             // isPushChanges = true, and we have something to deliver and promote to.
118             getLogger().debug( "Promoting and delivering..." );
119 
120             // So we deliver the code to the target stream (or workspace)
121             getLogger().debug( "Delivering..." );
122             JazzScmCommand tagDeliverCommand = createTagDeliverCommand( jazzRepo, fileSet, tag );
123             errConsumer = new ErrorConsumer( getLogger() );
124             status = tagDeliverCommand.execute( tagConsumer, errConsumer );
125             if ( status != 0 || errConsumer.hasBeenFed() )
126             {
127                 return new TagScmResult( tagDeliverCommand.getCommandString(),
128                                          "Error code for Jazz SCM deliver command - " + status, errConsumer.getOutput(),
129                                          false );
130             }
131 
132             // And now we promote the snapshot to the target stream (or workspace)
133             getLogger().debug( "Promoting snapshot..." );
134             JazzScmCommand tagSnapshotPromoteCommand = createTagSnapshotPromoteCommand( jazzRepo, fileSet, tag );
135             errConsumer = new ErrorConsumer( getLogger() );
136             status = tagSnapshotPromoteCommand.execute( tagConsumer, errConsumer );
137             if ( status != 0 || errConsumer.hasBeenFed() )
138             {
139                 return new TagScmResult( tagSnapshotPromoteCommand.getCommandString(),
140                                          "Error code for Jazz SCM snapshot promote command - " + status,
141                                          errConsumer.getOutput(), false );
142             }
143         }
144 
145         // We don't have a JazzTagConsumer so just build up all the files...
146         List<ScmFile> taggedFiles = new ArrayList<ScmFile>( fileSet.getFileList().size() );
147         for ( File f : fileSet.getFileList() )
148         {
149             taggedFiles.add( new ScmFile( f.getPath(), ScmFileStatus.TAGGED ) );
150         }
151 
152         // We return the "main" or "primary" command executed.
153         // This is similar to the git provider, where the main command is returned.
154         // So we return tagSnapshotCmd and not tagWorkspaceCmd.
155         return new TagScmResult( tagCreateSnapshotCmd.getCommandString(), taggedFiles );
156     }
157 
158     // Create the JazzScmCommand to execute the "scm create snapshot ..." command
159     // This will create a snapshot of the remote repository
160     public JazzScmCommand createTagCreateSnapshotCommand( JazzScmProviderRepository repo, ScmFileSet fileSet,
161                                                           String tag, ScmTagParameters scmTagParameters )
162     {
163         JazzScmCommand command =
164             new JazzScmCommand( JazzConstants.CMD_CREATE, JazzConstants.CMD_SUB_SNAPSHOT, repo, fileSet, getLogger() );
165 
166         if ( tag != null && !tag.trim().equals( "" ) )
167         {
168             command.addArgument( JazzConstants.ARG_SNAPSHOT_NAME );
169             command.addArgument( tag );
170         }
171 
172         String message = scmTagParameters.getMessage();
173         if ( message != null && !message.trim().equals( "" ) )
174         {
175             command.addArgument( JazzConstants.ARG_SNAPSHOT_DESCRIPTION );
176             command.addArgument( message );
177         }
178 
179         command.addArgument( repo.getRepositoryWorkspace() );
180 
181         return command;
182     }
183 
184     // Create the JazzScmCommand to execute the "scm snapshot promote ..." command
185     // This will promote the snapshot to the flow target (the stream or other workspace).
186     public JazzScmCommand createTagSnapshotPromoteCommand( JazzScmProviderRepository repo, ScmFileSet fileSet,
187                                                            String tag )
188     {
189         JazzScmCommand command =
190             new JazzScmCommand( JazzConstants.CMD_SNAPSHOT, JazzConstants.CMD_SUB_PROMOTE, repo, fileSet, getLogger() );
191 
192         if ( repo.getFlowTarget() != null && !repo.getFlowTarget().equals( "" ) )
193         {
194             command.addArgument( repo.getFlowTarget() );
195         }
196         if ( tag != null && !tag.trim().equals( "" ) )
197         {
198             command.addArgument( tag );
199         }
200 
201         return command;
202     }
203 
204     // Create the JazzScmCommand to execute the "scm deliver ..." command
205     // This will deliver the changes to the flow target (stream or other workspace).
206     public JazzScmCommand createTagDeliverCommand( JazzScmProviderRepository repo, ScmFileSet fileSet, String tag )
207     {
208         JazzScmCommand command = new JazzScmCommand( JazzConstants.CMD_DELIVER, repo, fileSet, getLogger() );
209 
210         if ( repo.getWorkspace() != null && !repo.getWorkspace().equals( "" ) )
211         {
212             // Don't deliver from the workspace, as it has the release.properties etc files in it
213             // and jazz will choke on them, so use the workspace that we just created (tag) instead.
214             command.addArgument( JazzConstants.ARG_DELIVER_SOURCE );
215             command.addArgument( tag );
216         }
217 
218         if ( repo.getFlowTarget() != null && !repo.getFlowTarget().equals( "" ) )
219         {
220             command.addArgument( JazzConstants.ARG_DELIVER_TARGET );
221             command.addArgument( repo.getFlowTarget() );
222         }
223 
224         return command;
225     }
226 
227     // Create the JazzScmCommand to execute the "scm create workspace ..." command
228     // This will create a workspace of the same name as the tag.
229     public JazzScmCommand createTagCreateWorkspaceCommand( JazzScmProviderRepository repo, ScmFileSet fileSet,
230                                                            String tag )
231     {
232         JazzScmCommand command =
233             new JazzScmCommand( JazzConstants.CMD_CREATE, JazzConstants.CMD_SUB_WORKSPACE, repo, fileSet, getLogger() );
234 
235         if ( tag != null && !tag.trim().equals( "" ) )
236         {
237             command.addArgument( tag );
238             command.addArgument( JazzConstants.ARG_WORKSPACE_SNAPSHOT );
239             command.addArgument( tag );
240         }
241 
242         return command;
243     }
244 
245 }