1 package org.apache.continuum.buildagent.action;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.continuum.buildagent.configuration.BuildAgentConfigurationService;
23 import org.apache.continuum.buildagent.utils.ContinuumBuildAgentUtil;
24 import org.apache.continuum.scm.ContinuumScm;
25 import org.apache.continuum.scm.ContinuumScmConfiguration;
26 import org.apache.continuum.scm.ContinuumScmUtils;
27 import org.apache.maven.continuum.model.project.Project;
28 import org.apache.maven.continuum.model.scm.ChangeFile;
29 import org.apache.maven.continuum.model.scm.ChangeSet;
30 import org.apache.maven.continuum.model.scm.ScmResult;
31 import org.apache.maven.scm.ScmException;
32 import org.apache.maven.scm.ScmFile;
33 import org.apache.maven.scm.command.update.UpdateScmResult;
34 import org.apache.maven.scm.manager.NoSuchScmProviderException;
35 import org.apache.maven.scm.repository.ScmRepositoryException;
36 import org.codehaus.plexus.action.AbstractAction;
37
38 import java.io.File;
39 import java.util.Date;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43
44
45
46
47 public class UpdateWorkingDirectoryAction
48 extends AbstractAction
49 {
50
51
52
53 private BuildAgentConfigurationService buildAgentConfigurationService;
54
55
56
57
58 private ContinuumScm scm;
59
60 public void execute( Map context )
61 throws Exception
62 {
63 Project project = ContinuumBuildAgentUtil.getProject( context );
64
65 UpdateScmResult scmResult;
66
67 ScmResult result;
68
69 try
70 {
71 File workingDirectory = buildAgentConfigurationService.getWorkingDirectory( project.getId() );
72 ContinuumScmConfiguration config = createScmConfiguration( project, workingDirectory );
73 config.setLatestUpdateDate( ContinuumBuildAgentUtil.getLatestUpdateDate( context ) );
74 String tag = config.getTag();
75 String msg = project.getName() + "', id: '" + project.getId() + "' to '" +
76 workingDirectory.getAbsolutePath() + "'" + ( tag != null ? " with branch/tag " + tag + "." : "." );
77 getLogger().info( "Updating project: " + msg );
78 scmResult = scm.update( config );
79
80 if ( !scmResult.isSuccess() )
81 {
82 getLogger().warn( "Error while updating the code for project: '" + msg );
83
84 getLogger().warn( "Command output: " + scmResult.getCommandOutput() );
85
86 getLogger().warn( "Provider message: " + scmResult.getProviderMessage() );
87 }
88
89 if ( scmResult.getUpdatedFiles() != null && scmResult.getUpdatedFiles().size() > 0 )
90 {
91 getLogger().info( "Updated " + scmResult.getUpdatedFiles().size() + " files." );
92 }
93
94 result = convertScmResult( scmResult );
95 }
96 catch ( ScmRepositoryException e )
97 {
98 result = new ScmResult();
99
100 result.setSuccess( false );
101
102 result.setProviderMessage( e.getMessage() + ": " + getValidationMessages( e ) );
103
104 getLogger().error( e.getMessage(), e );
105 }
106 catch ( NoSuchScmProviderException e )
107 {
108
109 result = new ScmResult();
110
111 result.setSuccess( false );
112
113 result.setProviderMessage( e.getMessage() );
114
115 getLogger().error( e.getMessage(), e );
116 }
117 catch ( ScmException e )
118 {
119 result = new ScmResult();
120
121 result.setSuccess( false );
122
123 result.setException( ContinuumBuildAgentUtil.throwableMessagesToString( e ) );
124
125 getLogger().error( e.getMessage(), e );
126 }
127
128 context.put( ContinuumBuildAgentUtil.KEY_UPDATE_SCM_RESULT, result );
129
130 Date latestUpdateDate = getLatestUpdateDate( result );
131
132 if ( latestUpdateDate == null )
133 {
134 latestUpdateDate = ContinuumBuildAgentUtil.getLatestUpdateDate( context );
135 }
136
137 context.put( ContinuumBuildAgentUtil.KEY_LATEST_UPDATE_DATE, latestUpdateDate );
138 }
139
140 private ContinuumScmConfiguration createScmConfiguration( Project project, File workingDirectory )
141 {
142 ContinuumScmConfiguration config = new ContinuumScmConfiguration();
143 config.setUrl( project.getScmUrl() );
144
145
146 config = ContinuumScmUtils.setSCMCredentialsforSSH( config, project.getScmUrl(), project.getScmUsername(),
147 project.getScmPassword() );
148
149 config.setUseCredentialsCache( project.isScmUseCache() );
150 config.setWorkingDirectory( workingDirectory );
151 config.setTag( project.getScmTag() );
152 return config;
153 }
154
155 private ScmResult convertScmResult( UpdateScmResult scmResult )
156 {
157 ScmResult result = new ScmResult();
158
159 result.setCommandLine( maskPassword( scmResult.getCommandLine() ) );
160
161 result.setSuccess( scmResult.isSuccess() );
162
163 result.setCommandOutput( scmResult.getCommandOutput() );
164
165 result.setProviderMessage( scmResult.getProviderMessage() );
166
167 if ( scmResult.getChanges() != null && !scmResult.getChanges().isEmpty() )
168 {
169 for ( org.apache.maven.scm.ChangeSet scmChangeSet : (List<org.apache.maven.scm.ChangeSet>) scmResult.getChanges() )
170 {
171 ChangeSet change = new ChangeSet();
172
173 change.setAuthor( scmChangeSet.getAuthor() );
174
175 change.setComment( scmChangeSet.getComment() );
176
177 if ( scmChangeSet.getDate() != null )
178 {
179 change.setDate( scmChangeSet.getDate().getTime() );
180 }
181
182 if ( scmChangeSet.getFiles() != null )
183 {
184 for ( org.apache.maven.scm.ChangeFile f : (List<org.apache.maven.scm.ChangeFile>) scmChangeSet.getFiles() )
185 {
186 ChangeFile file = new ChangeFile();
187
188 file.setName( f.getName() );
189
190 file.setRevision( f.getRevision() );
191
192 change.addFile( file );
193 }
194 }
195
196 result.addChange( change );
197 }
198 }
199 else
200 {
201
202
203 ChangeSet changeSet = convertScmFileSetToChangeSet( scmResult.getUpdatedFiles() );
204
205 if ( changeSet != null )
206 {
207 result.addChange( changeSet );
208 }
209 }
210 return result;
211 }
212
213 private static ChangeSet convertScmFileSetToChangeSet( List<ScmFile> files )
214 {
215 ChangeSet changeSet = null;
216
217 if ( files != null && !files.isEmpty() )
218 {
219 changeSet = new ChangeSet();
220
221
222 for ( ScmFile scmFile : files )
223 {
224 ChangeFile file = new ChangeFile();
225
226 file.setName( scmFile.getPath() );
227
228
229
230 file.setStatus( scmFile.getStatus().toString() );
231
232 changeSet.addFile( file );
233 }
234 }
235 return changeSet;
236 }
237
238
239 private String maskPassword( String commandLine )
240 {
241 String cmd = commandLine;
242
243 if ( cmd != null && cmd.startsWith( "svn" ) )
244 {
245 String pwdString = "--password";
246
247 if ( cmd.indexOf( pwdString ) > 0 )
248 {
249 int index = cmd.indexOf( pwdString ) + pwdString.length() + 1;
250
251 int nextSpace = cmd.indexOf( " ", index );
252
253 cmd = cmd.substring( 0, index ) + "********" + cmd.substring( nextSpace );
254 }
255 }
256
257 return cmd;
258 }
259
260 private String getValidationMessages( ScmRepositoryException ex )
261 {
262 List<String> messages = ex.getValidationMessages();
263
264 StringBuffer message = new StringBuffer();
265
266 if ( messages != null && !messages.isEmpty() )
267 {
268 for ( Iterator<String> i = messages.iterator(); i.hasNext(); )
269 {
270 message.append( i.next() );
271
272 if ( i.hasNext() )
273 {
274 message.append( System.getProperty( "line.separator" ) );
275 }
276 }
277 }
278 return message.toString();
279 }
280
281 private Date getLatestUpdateDate( ScmResult result )
282 {
283 List<ChangeSet> changes = result.getChanges();
284
285 if ( changes != null && !changes.isEmpty() )
286 {
287 long date = 0;
288
289 for ( ChangeSet change : changes )
290 {
291 if ( date < change.getDate() )
292 {
293 date = change.getDate();
294 }
295 }
296
297 if ( date != 0 )
298 {
299 return new Date( date );
300 }
301 }
302
303 return null;
304 }
305 }