View Javadoc

1   package org.apache.maven.plugins.patchtracker;
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.commons.lang.StringUtils;
23  import org.apache.maven.plugin.AbstractMojo;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugins.patchtracker.patching.PatchRepository;
26  import org.apache.maven.plugins.patchtracker.tracking.PatchTracker;
27  import org.apache.maven.plugins.patchtracker.tracking.PatchTrackerRequest;
28  import org.apache.maven.project.MavenProject;
29  import org.apache.maven.scm.ScmException;
30  import org.apache.maven.scm.ScmFileSet;
31  import org.apache.maven.scm.command.diff.DiffScmResult;
32  import org.apache.maven.scm.manager.NoSuchScmProviderException;
33  import org.apache.maven.scm.manager.ScmManager;
34  import org.apache.maven.scm.provider.ScmProvider;
35  import org.apache.maven.scm.repository.ScmRepository;
36  import org.apache.maven.scm.repository.ScmRepositoryException;
37  import org.apache.maven.settings.Server;
38  import org.apache.maven.settings.Settings;
39  import org.codehaus.plexus.PlexusConstants;
40  import org.codehaus.plexus.PlexusContainer;
41  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
42  import org.codehaus.plexus.components.interactivity.Prompter;
43  import org.codehaus.plexus.components.interactivity.PrompterException;
44  import org.codehaus.plexus.context.Context;
45  import org.codehaus.plexus.context.ContextException;
46  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
47  
48  import java.io.File;
49  import java.util.Arrays;
50  import java.util.Collections;
51  import java.util.List;
52  
53  /**
54   * @author Olivier Lamy
55   */
56  public abstract class AbstractPatchMojo
57      extends AbstractMojo
58      implements Contextualizable
59  {
60      /**
61       * The Maven Project Object.
62       *
63       * @parameter default-value="${project}"
64       * @required
65       * @readonly
66       */
67      protected MavenProject project;
68  
69      /**
70       * @parameter default-value="${basedir}"
71       * @required
72       * @readonly
73       */
74      protected File baseDir;
75  
76      /**
77       * @parameter expression="${scm.providerType}" default-value=""
78       */
79      protected String providerType = "";
80  
81      /**
82       * @parameter default-value="${settings}"
83       * @required
84       * @readonly
85       */
86      protected Settings settings;
87  
88  
89      /**
90       * if user/password are stored in your settings.xml in a server
91       *
92       * @parameter expression="${patch.serverId}" default-value=""
93       */
94      protected String serverId;
95  
96      /**
97       * if path tracker url is not stored in the pom.
98       * <b>For jira, url must include project key!: http://jira.codehaus.org/browse/MNG</b>
99       *
100      * @parameter expression="${patch.serverUrl}" default-value=""
101      */
102     protected String serverUrl;
103 
104     /**
105      * @parameter expression="${patch.user}" default-value=""
106      */
107     protected String user;
108 
109     /**
110      * @parameter expression="${patch.password}" default-value=""
111      */
112     protected String password;
113 
114     /**
115      * @parameter expression="${patch.issueSystem}" default-value=""
116      */
117     protected String issueSystem;
118 
119     /**
120      * @parameter expression="${patch.patchSystem}" default-value="${project.patchManagement.system}"
121      */
122     protected String patchSystem;
123 
124     /**
125      * @parameter expression="${patch.summary}" default-value=""
126      */
127     protected String summary;
128 
129     /**
130      * @parameter expression="${patch.description}" default-value=""
131      */
132     protected String description;
133 
134 
135     /**
136      * the type of the patch tracker entry to load: default 1 for jira bug
137      *
138      * @parameter expression="${patch.patchType}" default-value="1"
139      */
140     protected String patchType;
141 
142     /**
143      * the priority of the patch tracker entry to load: default 3 for jira major
144      *
145      * @parameter expression="${patch.priority}" default-value="3"
146      */
147     protected String patchPriority;
148 
149 
150     /**
151      * Component used to prompt for input.
152      *
153      * @component
154      */
155     protected Prompter prompter;
156 
157     protected PlexusContainer plexusContainer;
158 
159     /**
160      * @component
161      */
162     protected ScmManager scmManager;
163 
164 
165     protected String getPatchContent()
166         throws MojoExecutionException
167     {
168         try
169         {
170             ScmRepository scmRepository = scmManager.makeScmRepository( project.getScm().getConnection() );
171 
172             ScmProvider provider = scmManager.getProviderByType( scmRepository.getProvider() );
173 
174             getLog().debug( "scm.providerType:" + providerType );
175             if ( StringUtils.isNotEmpty( providerType ) )
176             {
177                 provider = scmManager.getProviderByType( providerType );
178             }
179 
180             DiffScmResult diffScmResult = provider.diff( scmRepository, new ScmFileSet( baseDir ), "", "" );
181             getLog().debug( diffScmResult.getPatch() );
182 
183             return diffScmResult.getPatch();
184 
185         }
186         catch ( ScmRepositoryException e )
187         {
188             throw new MojoExecutionException( e.getMessage(), e );
189         }
190         catch ( NoSuchScmProviderException e )
191         {
192             throw new MojoExecutionException( e.getMessage(), e );
193         }
194         catch ( ScmException e )
195         {
196             throw new MojoExecutionException( e.getMessage(), e );
197         }
198     }
199 
200     protected PatchTrackerRequest buidPatchTrackerRequest( boolean creation )
201         throws MojoExecutionException
202     {
203         try
204         {
205             PatchTrackerRequest patchTrackerRequest =
206                 new PatchTrackerRequest().setUrl( getPatchTrackerUrl() ).setUserName(
207                     getPatchTrackerUsername() ).setPassword( getPatchTrackerPassword() ).setPatchType(
208                     patchType ).setPatchPriority( patchPriority );
209 
210             return creation ? patchTrackerRequest.setSummary( getPatchTrackerSummary() ).setDescription(
211                 getPatchTrackerDescription() ) : patchTrackerRequest;
212 
213 
214         }
215         catch ( PrompterException e )
216         {
217             throw new MojoExecutionException( e.getMessage(), e );
218         }
219     }
220 
221 
222     protected String getPatchTrackerUrl()
223         throws PrompterException, MojoExecutionException
224     {
225         String value = project.getIssueManagement() == null ? "" : project.getIssueManagement().getUrl();
226 
227         // cli must win !
228         if ( StringUtils.isNotEmpty( serverUrl ) )
229         {
230             value = serverUrl;
231         }
232 
233         return getValue( value, "path tracker url ? (http://jira.codehaus.org/browse/MNG)", null, true,
234                          "you must configure a patch system or at least use interactive mode", value, false );
235     }
236 
237     protected String getPatchTrackerSummary()
238         throws PrompterException, MojoExecutionException
239     {
240         String value = summary;
241 
242         return getValue( value, "patch summary ? (wonderfull patch to fix ....) ", Collections.<String>emptyList(),
243                          true, "you must configure a patch summary or at least use interactive mode", null, false );
244     }
245 
246     protected String getPatchTrackerDescription()
247         throws PrompterException, MojoExecutionException
248     {
249         String value = description;
250 
251         return getValue( value, "patch description ?(this patch fix this very annoying issue ....) ", null, false,
252                          "you must configure a patch summary or at least use interactive mode", null, false );
253     }
254 
255     protected String getServerId()
256     {
257         String serverIdFromPom = (String) project.getProperties().get( "patch.tracker.serverId" );
258         if ( StringUtils.isNotEmpty( serverIdFromPom ) )
259         {
260             return serverIdFromPom;
261         }
262         return serverId;
263     }
264 
265     protected String getPatchTrackerUsername()
266         throws PrompterException, MojoExecutionException
267     {
268         String value = null;
269 
270         if ( StringUtils.isNotEmpty( getServerId() ) )
271         {
272             Server server = getServer( getServerId() );
273             if ( server == null )
274             {
275                 getLog().warn( "no server found in your settings.xml with id:" + getServerId() );
276             }
277             else
278             {
279                 value = server.getUsername();
280             }
281 
282         }
283 
284         // cli must win !
285         if ( StringUtils.isNotEmpty( user ) )
286         {
287             value = user;
288         }
289 
290         return getValue( value, "patch tracker username ?", null, true,
291                          "you must configure a user for your patch tracker or at least use interactive mode", value,
292                          false );
293     }
294 
295     protected String getPatchTrackerPassword()
296         throws PrompterException, MojoExecutionException
297     {
298         String value = null;
299 
300         if ( StringUtils.isNotEmpty( getServerId() ) )
301         {
302             Server server = getServer( getServerId() );
303             if ( server == null )
304             {
305                 getLog().warn( "no server found in your settings.xml with id:" + getServerId() );
306             }
307             else
308             {
309                 value = server.getPassword();
310             }
311 
312         }
313 
314         // cli must win !
315         if ( StringUtils.isNotEmpty( password ) )
316         {
317             value = password;
318         }
319 
320         return getValue( value, "patch tracker password ?", null, true,
321                          "you must configure a password for your patch tracker or at least use interactive mode", value,
322                          true );
323     }
324 
325     protected String getPatchTrackerSystem()
326         throws MojoExecutionException
327     {
328         String value = project.getIssueManagement() == null ? "" : project.getIssueManagement().getSystem();
329 
330         // cli must win !
331         if ( StringUtils.isNotEmpty( issueSystem ) )
332         {
333             value = issueSystem;
334         }
335 
336         try
337         {
338             return getValue( value, "path tracker system id ?", Arrays.asList( "jira" ), true,
339                              "you must configure a patch system or at least use interactive mode", "jira", false );
340         }
341         catch ( PrompterException e )
342         {
343             throw new MojoExecutionException( e.getMessage(), e );
344         }
345     }
346 
347     protected String getPatchRepositorySystem()
348         throws MojoExecutionException
349     {
350         String value = project.getProperties().getProperty( "project.patchManagement.system" );
351 
352         // cli must win !
353         if ( StringUtils.isNotEmpty( patchSystem ) )
354         {
355             value = patchSystem;
356         }
357 
358         try
359         {
360             return getValue( value, "path repository system id ?", Arrays.asList( "github" ), true,
361                              "you must configure a patch system or at least use interactive mode", "github", false );
362         }
363         catch ( PrompterException e )
364         {
365             throw new MojoExecutionException( e.getMessage(), e );
366         }
367     }
368 
369     protected String getValue( String currentValue, String message, List<String> possibleValues, boolean mandatory,
370                                String errorMessage, String defaultValue, boolean passwordPrompt )
371         throws PrompterException, MojoExecutionException
372     {
373         boolean loadFromPrompt = false;
374         String value = currentValue;
375         if ( mandatory && StringUtils.isEmpty( value ) )
376         {
377             if ( settings.isInteractiveMode() )
378             {
379 
380                 getLog().debug( "1st prompt message " + message + ", defaultValue " + defaultValue + ", possibleValues"
381                                     + possibleValues );
382                 if ( passwordPrompt )
383                 {
384                     value = prompter.promptForPassword( message );
385                 }
386                 else
387                 {
388                     value = ( possibleValues == null || possibleValues.isEmpty() )
389                         ? prompter.prompt( message, defaultValue )
390                         : prompter.prompt( message, possibleValues, defaultValue );
391                 }
392                 loadFromPrompt = StringUtils.isNotBlank( value );
393             }
394             else
395             {
396                 getLog().error( errorMessage );
397                 throw new MojoExecutionException( errorMessage );
398             }
399             if ( StringUtils.isEmpty( value ) )
400             {
401                 getLog().error( errorMessage );
402                 throw new MojoExecutionException( errorMessage );
403             }
404         }
405 
406         if ( settings.isInteractiveMode() && !loadFromPrompt )
407         {
408             getLog().debug( "2nd prompt message " + message + ", defaultValue " + defaultValue + ", possibleValues"
409                                 + possibleValues );
410             if ( passwordPrompt )
411             {
412                 value = prompter.promptForPassword( message );
413             }
414             else
415             {
416                 value = ( possibleValues == null || possibleValues.isEmpty() ) ? ( StringUtils.isEmpty( defaultValue )
417                     ? prompter.prompt( message )
418                     : prompter.prompt( message, defaultValue ) )
419                     : ( StringUtils.isEmpty( defaultValue )
420                         ? prompter.prompt( message, possibleValues )
421                         : prompter.prompt( message, possibleValues, defaultValue ) );
422             }
423             if ( StringUtils.isEmpty( value ) && mandatory )
424             {
425                 getLog().error( errorMessage );
426                 throw new MojoExecutionException( errorMessage );
427             }
428 
429         }
430         return value;
431     }
432 
433 
434     protected Server getServer( String id )
435     {
436         if ( StringUtils.isEmpty( id ) )
437         {
438             return null;
439         }
440         return settings.getServer( id );
441     }
442 
443     protected PatchTracker getPatchTracker()
444         throws MojoExecutionException, ComponentLookupException
445     {
446         String system = getPatchTrackerSystem();
447 
448         getLog().debug( "patch tracker system:" + system );
449 
450         return (PatchTracker) plexusContainer.lookup( PatchTracker.class.getName(), system );
451     }
452 
453     protected PatchRepository getPatchRepository()
454         throws MojoExecutionException, ComponentLookupException
455     {
456         String system = getPatchRepositorySystem();
457 
458         getLog().debug( "patch repository system:" + system );
459 
460         return (PatchRepository) plexusContainer.lookup( PatchRepository.class.getName(), system );
461     }
462 
463     public void contextualize( Context context )
464         throws ContextException
465     {
466         this.plexusContainer = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
467     }
468 }