001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.plugin; 020 021import java.io.File; 022 023import org.apache.commons.lang3.StringUtils; 024import org.apache.maven.plugin.MojoExecutionException; 025import org.apache.maven.plugins.annotations.Mojo; 026import org.apache.maven.plugins.annotations.Parameter; 027import org.apache.maven.scm.ScmResult; 028import org.apache.maven.scm.command.checkout.CheckOutScmResult; 029import org.codehaus.plexus.util.Os; 030import org.codehaus.plexus.util.cli.CommandLineException; 031import org.codehaus.plexus.util.cli.CommandLineUtils; 032import org.codehaus.plexus.util.cli.Commandline; 033import org.codehaus.plexus.util.cli.DefaultConsumer; 034import org.codehaus.plexus.util.cli.StreamConsumer; 035 036/** 037 * Pull the project source from the configured scm and execute the configured goals. 038 * 039 * @author <a href="dantran@gmail.com">Dan T. Tran</a> 040 */ 041@Mojo(name = "bootstrap", requiresProject = false) 042public class BootstrapMojo extends CheckoutMojo { 043 /** 044 * The goals to run on the clean checkout of a project for the bootstrap goal. 045 * If none are specified, then the default goal for the project is executed. 046 * Multiple goals should be comma separated. 047 */ 048 @Parameter(property = "goals") 049 private String goals; 050 051 /** 052 * A list of profiles to run with the goals. 053 * Multiple profiles must be comma separated with no spaces. 054 */ 055 @Parameter(property = "profiles") 056 private String profiles; 057 058 /** 059 * The subdirectory (under the project directory) in which to run the goals. 060 * The project directory is the same as the checkout directory in most cases, 061 * but for some SCMs, it is a subdirectory of the checkout directory. 062 */ 063 @Parameter(property = "goalsDirectory") 064 private String goalsDirectory; 065 066 /** 067 * The path where your maven is installed 068 */ 069 @Parameter(property = "mavenHome", defaultValue = "${maven.home}") 070 private File mavenHome; 071 072 /** {@inheritDoc} */ 073 public void execute() throws MojoExecutionException { 074 super.execute(); 075 076 if (this.getCheckoutResult() != null) { 077 078 ScmResult checkoutResult = this.getCheckoutResult(); 079 080 // At the time of useExport feature is requested only SVN has export command implemented 081 // add relativePathProjectDirectory support to ExportScmResult 082 String relativePathProjectDirectory = ""; 083 if (checkoutResult instanceof CheckOutScmResult) { 084 relativePathProjectDirectory = ((CheckOutScmResult) checkoutResult).getRelativePathProjectDirectory(); 085 } 086 087 runGoals(relativePathProjectDirectory); 088 } 089 } 090 091 /** 092 * @param relativePathProjectDirectory the project directory's path relative to the checkout 093 * directory; or "" if they are the same 094 * @throws MojoExecutionException if any 095 */ 096 private void runGoals(String relativePathProjectDirectory) throws MojoExecutionException { 097 Commandline cl = new Commandline(); 098 try { 099 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 (!(this.profiles == null || this.profiles.isEmpty())) { 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}