View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm.plugin;
20  
21  import java.io.File;
22  
23  import org.apache.commons.lang3.StringUtils;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugins.annotations.Mojo;
26  import org.apache.maven.plugins.annotations.Parameter;
27  import org.apache.maven.scm.ScmResult;
28  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
29  import org.codehaus.plexus.util.Os;
30  import org.codehaus.plexus.util.cli.CommandLineException;
31  import org.codehaus.plexus.util.cli.CommandLineUtils;
32  import org.codehaus.plexus.util.cli.Commandline;
33  import org.codehaus.plexus.util.cli.DefaultConsumer;
34  import org.codehaus.plexus.util.cli.StreamConsumer;
35  
36  /**
37   * Pull the project source from the configured scm and execute the configured goals.
38   *
39   * @author <a href="dantran@gmail.com">Dan T. Tran</a>
40   */
41  @Mojo(name = "bootstrap", requiresProject = false)
42  public class BootstrapMojo extends CheckoutMojo {
43      /**
44       * The goals to run on the clean checkout of a project for the bootstrap goal.
45       * If none are specified, then the default goal for the project is executed.
46       * Multiple goals should be comma separated.
47       */
48      @Parameter(property = "goals")
49      private String goals;
50  
51      /**
52       * A list of profiles to run with the goals.
53       * Multiple profiles must be comma separated with no spaces.
54       */
55      @Parameter(property = "profiles")
56      private String profiles;
57  
58      /**
59       * The subdirectory (under the project directory) in which to run the goals.
60       * The project directory is the same as the checkout directory in most cases,
61       * but for some SCMs, it is a subdirectory of the checkout directory.
62       */
63      @Parameter(property = "goalsDirectory")
64      private String goalsDirectory;
65  
66      /**
67       * The path where your maven is installed
68       */
69      @Parameter(property = "mavenHome", defaultValue = "${maven.home}")
70      private File mavenHome;
71  
72      /** {@inheritDoc} */
73      public void execute() throws MojoExecutionException {
74          super.execute();
75  
76          if (this.getCheckoutResult() != null) {
77  
78              ScmResult checkoutResult = this.getCheckoutResult();
79  
80              // At the time of useExport feature is requested only SVN has export command implemented
81              // add relativePathProjectDirectory support to ExportScmResult
82              String relativePathProjectDirectory = "";
83              if (checkoutResult instanceof CheckOutScmResult) {
84                  relativePathProjectDirectory = ((CheckOutScmResult) checkoutResult).getRelativePathProjectDirectory();
85              }
86  
87              runGoals(relativePathProjectDirectory);
88          }
89      }
90  
91      /**
92       * @param relativePathProjectDirectory the project directory's path relative to the checkout
93       *                                     directory; or "" if they are the same
94       * @throws MojoExecutionException if any
95       */
96      private void runGoals(String relativePathProjectDirectory) throws MojoExecutionException {
97          Commandline cl = new Commandline();
98          try {
99              cl.addSystemEnvironment();
100         } catch (Exception e) {
101             throw new MojoExecutionException("Can't add system environment variables to mvn command line.", e);
102         }
103         cl.addEnvironment("MAVEN_TERMINATE_CMD", "on");
104 
105         if (this.mavenHome == null) {
106             cl.setExecutable("mvn"); // none windows only
107         } else {
108             String mvnPath = this.mavenHome.getAbsolutePath() + "/bin/mvn";
109             if (Os.isFamily("windows")) {
110                 String winMvnPath = mvnPath + ".cmd";
111                 if (!new File(winMvnPath).exists()) {
112                     winMvnPath = mvnPath + ".bat";
113                 }
114                 mvnPath = winMvnPath;
115             }
116             cl.setExecutable(mvnPath);
117         }
118 
119         cl.setWorkingDirectory(determineWorkingDirectoryPath(
120                 this.getCheckoutDirectory(), //
121                 relativePathProjectDirectory,
122                 goalsDirectory));
123 
124         if (this.goals != null) {
125             String[] tokens = StringUtils.split(this.goals, ", ");
126 
127             for (int i = 0; i < tokens.length; ++i) {
128                 cl.createArg().setValue(tokens[i]);
129             }
130         }
131 
132         if (!StringUtils.isEmpty(this.profiles)) {
133             cl.createArg().setValue("-P" + this.profiles);
134         }
135 
136         StreamConsumer consumer = new DefaultConsumer();
137 
138         try {
139             int result = CommandLineUtils.executeCommandLine(cl, consumer, consumer);
140 
141             if (result != 0) {
142                 throw new MojoExecutionException("Result of mvn execution is: \'" + result + "\'. Release failed.");
143             }
144         } catch (CommandLineException e) {
145             throw new MojoExecutionException("Can't run goal " + goals, e);
146         }
147     }
148 
149     /**
150      * Determines the path of the working directory. By default, this is the checkout directory. For some SCMs,
151      * the project root directory is not the checkout directory itself, but a SCM-specific subdirectory. The
152      * build can furthermore optionally be executed in a subdirectory of this project directory, in case.
153      *
154      * @param checkoutDirectory
155      * @param relativePathProjectDirectory
156      * @param goalsDirectory
157      * @return TODO
158      */
159     protected String determineWorkingDirectoryPath(
160             File checkoutDirectory, String relativePathProjectDirectory, String goalsDirectory) {
161         File projectDirectory;
162         if (relativePathProjectDirectory != null && !relativePathProjectDirectory.isEmpty()) {
163             projectDirectory = new File(checkoutDirectory, relativePathProjectDirectory);
164         } else {
165             projectDirectory = checkoutDirectory;
166         }
167 
168         if (goalsDirectory == null || goalsDirectory.isEmpty()) {
169             return projectDirectory.getPath();
170         }
171 
172         return new File(projectDirectory, goalsDirectory).getPath();
173     }
174 }