1 | package org.apache.maven.continuum.release; |
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 java.io.File; |
23 | import java.util.Hashtable; |
24 | import java.util.Map; |
25 | import java.util.Properties; |
26 | |
27 | import org.apache.commons.lang.BooleanUtils; |
28 | import org.apache.continuum.model.repository.LocalRepository; |
29 | import org.apache.continuum.release.config.ContinuumReleaseDescriptor; |
30 | import org.apache.maven.continuum.model.project.Project; |
31 | import org.apache.maven.continuum.release.tasks.PerformReleaseProjectTask; |
32 | import org.apache.maven.continuum.release.tasks.PrepareReleaseProjectTask; |
33 | import org.apache.maven.continuum.release.tasks.RollbackReleaseProjectTask; |
34 | import org.apache.maven.scm.manager.ScmManager; |
35 | import org.apache.maven.scm.provider.ScmProvider; |
36 | import org.apache.maven.scm.repository.ScmRepository; |
37 | import org.apache.maven.shared.release.ReleaseManagerListener; |
38 | import org.apache.maven.shared.release.config.ReleaseDescriptor; |
39 | import org.apache.maven.shared.release.config.ReleaseDescriptorStore; |
40 | import org.apache.maven.shared.release.config.ReleaseDescriptorStoreException; |
41 | import org.codehaus.plexus.taskqueue.Task; |
42 | import org.codehaus.plexus.taskqueue.TaskQueue; |
43 | import org.codehaus.plexus.taskqueue.TaskQueueException; |
44 | import org.codehaus.plexus.util.StringUtils; |
45 | |
46 | /** |
47 | * @author Jason van Zyl |
48 | * @author Edwin Punzalan |
49 | * @version $Id: DefaultContinuumReleaseManager.java 781888 2009-06-05 02:06:19Z ctan $ |
50 | */ |
51 | public class DefaultContinuumReleaseManager |
52 | implements ContinuumReleaseManager |
53 | { |
54 | /** |
55 | * @plexus.requirement |
56 | */ |
57 | private ReleaseDescriptorStore releaseStore; |
58 | |
59 | /** |
60 | * @plexus.requirement |
61 | */ |
62 | private TaskQueue prepareReleaseQueue; |
63 | |
64 | /** |
65 | * @plexus.requirement |
66 | */ |
67 | private TaskQueue performReleaseQueue; |
68 | |
69 | /** |
70 | * @plexus.requirement |
71 | */ |
72 | private TaskQueue rollbackReleaseQueue; |
73 | |
74 | /** |
75 | * @plexus.requirement |
76 | */ |
77 | private ScmManager scmManager; |
78 | |
79 | private Map<String, ContinuumReleaseManagerListener> listeners; |
80 | |
81 | /** |
82 | * contains previous release:prepare descriptors; one per project |
83 | * |
84 | * @todo remove static when singleton strategy is working |
85 | */ |
86 | private static Map preparedReleases; |
87 | |
88 | /** |
89 | * contains results |
90 | * |
91 | * @todo remove static when singleton strategy is working |
92 | */ |
93 | private static Map releaseResults; |
94 | |
95 | public String prepare( Project project, Properties releaseProperties, Map<String, String> relVersions, |
96 | Map<String, String> devVersions, ContinuumReleaseManagerListener listener, |
97 | String workingDirectory ) |
98 | throws ContinuumReleaseException |
99 | { |
100 | return prepare( project, releaseProperties, relVersions, devVersions, listener, workingDirectory, null, null ); |
101 | } |
102 | |
103 | public String prepare( Project project, Properties releaseProperties, Map<String, String> relVersions, |
104 | Map<String, String> devVersions, ContinuumReleaseManagerListener listener, |
105 | String workingDirectory, Map<String, String> environments, String executable ) |
106 | throws ContinuumReleaseException |
107 | { |
108 | String releaseId = project.getGroupId() + ":" + project.getArtifactId(); |
109 | |
110 | ReleaseDescriptor descriptor = |
111 | getReleaseDescriptor( project, releaseProperties, relVersions, devVersions, environments, workingDirectory, |
112 | executable ); |
113 | |
114 | getListeners().put( releaseId, listener ); |
115 | |
116 | try |
117 | { |
118 | prepareReleaseQueue.put( |
119 | new PrepareReleaseProjectTask( releaseId, descriptor, (ReleaseManagerListener) listener ) ); |
120 | } |
121 | catch ( TaskQueueException e ) |
122 | { |
123 | throw new ContinuumReleaseException( "Failed to add prepare release task in queue.", e ); |
124 | } |
125 | |
126 | return releaseId; |
127 | } |
128 | |
129 | public void perform( String releaseId, File buildDirectory, String goals, String arguments, |
130 | boolean useReleaseProfile, ContinuumReleaseManagerListener listener ) |
131 | throws ContinuumReleaseException |
132 | { |
133 | perform( releaseId, buildDirectory, goals, arguments, useReleaseProfile, listener, null ); |
134 | } |
135 | |
136 | public void perform( String releaseId, File buildDirectory, String goals, String arguments, |
137 | boolean useReleaseProfile, ContinuumReleaseManagerListener listener, |
138 | LocalRepository repository ) |
139 | throws ContinuumReleaseException |
140 | { |
141 | ReleaseDescriptor descriptor = (ReleaseDescriptor) getPreparedReleases().get( releaseId ); |
142 | if ( descriptor != null ) |
143 | { |
144 | perform( releaseId, descriptor, buildDirectory, goals, arguments, useReleaseProfile, listener, repository ); |
145 | } |
146 | } |
147 | |
148 | public void perform( String releaseId, String workingDirectory, File buildDirectory, String goals, String arguments, |
149 | boolean useReleaseProfile, ContinuumReleaseManagerListener listener ) |
150 | throws ContinuumReleaseException |
151 | { |
152 | ReleaseDescriptor descriptor = readReleaseDescriptor( workingDirectory ); |
153 | |
154 | perform( releaseId, descriptor, buildDirectory, goals, arguments, useReleaseProfile, listener, null ); |
155 | } |
156 | |
157 | private void perform( String releaseId, ReleaseDescriptor descriptor, File buildDirectory, String goals, |
158 | String arguments, boolean useReleaseProfile, ContinuumReleaseManagerListener listener, |
159 | LocalRepository repository ) |
160 | throws ContinuumReleaseException |
161 | { |
162 | if ( descriptor != null ) |
163 | { |
164 | descriptor.setAdditionalArguments( arguments ); |
165 | } |
166 | |
167 | try |
168 | { |
169 | getListeners().put( releaseId, listener ); |
170 | |
171 | performReleaseQueue.put( |
172 | new PerformReleaseProjectTask( releaseId, descriptor, buildDirectory, goals, useReleaseProfile, |
173 | (ReleaseManagerListener) listener, repository ) ); |
174 | } |
175 | catch ( TaskQueueException e ) |
176 | { |
177 | throw new ContinuumReleaseException( "Failed to add perform release task in queue.", e ); |
178 | } |
179 | } |
180 | |
181 | public void rollback( String releaseId, String workingDirectory, ContinuumReleaseManagerListener listener ) |
182 | throws ContinuumReleaseException |
183 | { |
184 | ReleaseDescriptor descriptor = readReleaseDescriptor( workingDirectory ); |
185 | |
186 | rollback( releaseId, descriptor, listener ); |
187 | } |
188 | |
189 | private void rollback( String releaseId, ReleaseDescriptor descriptor, ContinuumReleaseManagerListener listener ) |
190 | throws ContinuumReleaseException |
191 | { |
192 | Task releaseTask = new RollbackReleaseProjectTask( releaseId, descriptor, (ReleaseManagerListener) listener ); |
193 | |
194 | try |
195 | { |
196 | rollbackReleaseQueue.put( releaseTask ); |
197 | } |
198 | catch ( TaskQueueException e ) |
199 | { |
200 | throw new ContinuumReleaseException( "Failed to rollback release.", e ); |
201 | } |
202 | } |
203 | |
204 | public Map getPreparedReleases() |
205 | { |
206 | if ( preparedReleases == null ) |
207 | { |
208 | preparedReleases = new Hashtable(); |
209 | } |
210 | |
211 | return preparedReleases; |
212 | } |
213 | |
214 | public Map getReleaseResults() |
215 | { |
216 | if ( releaseResults == null ) |
217 | { |
218 | releaseResults = new Hashtable(); |
219 | } |
220 | |
221 | return releaseResults; |
222 | } |
223 | |
224 | private ReleaseDescriptor getReleaseDescriptor( Project project, Properties releaseProperties, |
225 | Map<String, String> relVersions, Map<String, String> devVersions, |
226 | Map<String, String> environments, String workingDirectory, |
227 | String executable ) |
228 | { |
229 | ContinuumReleaseDescriptor descriptor = new ContinuumReleaseDescriptor(); |
230 | |
231 | //release properties from the project |
232 | descriptor.setWorkingDirectory( workingDirectory ); |
233 | descriptor.setScmSourceUrl( project.getScmUrl() ); |
234 | |
235 | //required properties |
236 | descriptor.setScmReleaseLabel( releaseProperties.getProperty( "tag" ) ); |
237 | descriptor.setScmTagBase( releaseProperties.getProperty( "tagBase" ) ); |
238 | descriptor.setReleaseVersions( relVersions ); |
239 | descriptor.setDevelopmentVersions( devVersions ); |
240 | descriptor.setPreparationGoals( releaseProperties.getProperty( "prepareGoals" ) ); |
241 | descriptor.setAdditionalArguments( releaseProperties.getProperty( "arguments" ) ); |
242 | descriptor.setAddSchema( Boolean.valueOf( releaseProperties.getProperty( "addSchema" ) ) ); |
243 | descriptor.setAutoVersionSubmodules( |
244 | Boolean.valueOf( releaseProperties.getProperty( "autoVersionSubmodules" ) ) ); |
245 | |
246 | String useEditMode = releaseProperties.getProperty( "useEditMode" ); |
247 | if ( BooleanUtils.toBoolean( useEditMode ) ) |
248 | { |
249 | descriptor.setScmUseEditMode( Boolean.valueOf( useEditMode ) ); |
250 | } |
251 | |
252 | LocalRepository repository = project.getProjectGroup().getLocalRepository(); |
253 | |
254 | if ( repository != null ) |
255 | { |
256 | String args = descriptor.getAdditionalArguments(); |
257 | |
258 | if ( StringUtils.isNotEmpty( args ) ) |
259 | { |
260 | descriptor.setAdditionalArguments( args + |
261 | " \"-Dmaven.repo.local=" + repository.getLocation() + "\"" ); |
262 | } |
263 | else |
264 | { |
265 | descriptor.setAdditionalArguments( "\"-Dmaven.repo.local=" + repository.getLocation() + "\"" ); |
266 | } |
267 | } |
268 | |
269 | //other properties |
270 | if ( releaseProperties.containsKey( "username" ) ) |
271 | { |
272 | descriptor.setScmUsername( releaseProperties.getProperty( "username" ) ); |
273 | } |
274 | if ( releaseProperties.containsKey( "password" ) ) |
275 | { |
276 | descriptor.setScmPassword( releaseProperties.getProperty( "password" ) ); |
277 | } |
278 | if ( releaseProperties.containsKey( "commentPrefix" ) ) |
279 | { |
280 | descriptor.setScmCommentPrefix( releaseProperties.getProperty( "commentPrefix" ) ); |
281 | } |
282 | if ( releaseProperties.containsKey( "useReleaseProfile" ) ) |
283 | { |
284 | descriptor.setUseReleaseProfile( Boolean.valueOf( releaseProperties.getProperty( "useReleaseProfile" ) ) ); |
285 | } |
286 | |
287 | //forced properties |
288 | descriptor.setInteractive( false ); |
289 | |
290 | //set environments |
291 | descriptor.setEnvironments( environments ); |
292 | descriptor.setExecutable( executable ); |
293 | |
294 | return descriptor; |
295 | } |
296 | |
297 | private ReleaseDescriptor readReleaseDescriptor( String workingDirectory ) |
298 | throws ContinuumReleaseException |
299 | { |
300 | ReleaseDescriptor descriptor = new ContinuumReleaseDescriptor(); |
301 | descriptor.setWorkingDirectory( workingDirectory ); |
302 | |
303 | try |
304 | { |
305 | descriptor = releaseStore.read( descriptor ); |
306 | } |
307 | catch ( ReleaseDescriptorStoreException e ) |
308 | { |
309 | throw new ContinuumReleaseException( "Failed to parse descriptor file.", e ); |
310 | } |
311 | |
312 | return descriptor; |
313 | } |
314 | |
315 | public Map<String, ContinuumReleaseManagerListener> getListeners() |
316 | { |
317 | if ( listeners == null ) |
318 | { |
319 | listeners = new Hashtable<String, ContinuumReleaseManagerListener>(); |
320 | } |
321 | |
322 | return listeners; |
323 | } |
324 | |
325 | public String sanitizeTagName( String scmUrl, String tagName ) |
326 | throws Exception |
327 | { |
328 | ScmRepository scmRepo = scmManager.makeScmRepository( scmUrl ); |
329 | ScmProvider scmProvider = scmManager.getProviderByRepository( scmRepo ); |
330 | return scmProvider.sanitizeTagName( tagName ); |
331 | } |
332 | } |