View Javadoc
1   /*
2    * Copyright 2013 vagrant-maven-plugin contributors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.nicoulaj.maven.plugins.vagrant;
17  
18  import de.saumya.mojo.gem.AbstractGemMojo;
19  import de.saumya.mojo.jruby.AbstractJRubyMojo;
20  import de.saumya.mojo.ruby.gems.GemManager;
21  import de.saumya.mojo.ruby.script.Script;
22  import de.saumya.mojo.ruby.script.ScriptException;
23  import org.apache.maven.artifact.repository.ArtifactRepository;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.MojoFailureException;
26  import org.apache.maven.plugin.descriptor.PluginDescriptor;
27  import org.apache.maven.plugins.annotations.Component;
28  import org.apache.maven.plugins.annotations.Parameter;
29  import org.apache.maven.project.MavenProject;
30  import org.apache.maven.repository.RepositorySystem;
31  import org.codehaus.classworlds.ClassRealm;
32  import org.codehaus.plexus.archiver.UnArchiver;
33  import org.sonatype.plexus.build.incremental.BuildContext;
34  
35  import java.io.File;
36  import java.io.IOException;
37  import java.lang.reflect.Field;
38  
39  import static java.util.Arrays.asList;
40  import static org.codehaus.plexus.util.StringUtils.isNotBlank;
41  
42  /**
43   * Base class for {@code Mojo}s invoking Vagrant.
44   *
45   * @author <a href="http://github.com/nicoulaj">Julien Nicoulaud</a>
46   * @since 1.0
47   */
48  abstract class AbstractVagrantMojo extends AbstractGemMojo {
49  
50      /**
51       * Custom gems directory.
52       * <p/>
53       * Modifying this property has an impact on isolation/build portability, eg:
54       * <ul>
55       * <li>In {@code project.build.directory} (default): user installation can not impact build, but gems are unpacked at every build.</li>
56       * <li>In {@code project.basedir}: user installation can not impact build, gems are unpacked once for all, but files are created outside of build directory.</li>
57       * <li>Outside {@code project.basedir} (Vagrant default): user installation can impact build.</li>
58       * </ul>
59       *
60       * @since 1.0
61       */
62      @Parameter(defaultValue = "${project.build.directory}/vagrant/gems")
63      protected File gemHome;
64  
65      /**
66       * Custom {@code VAGRANT_HOME}, which is the directory where Vagrant boxes are stored.
67       * <p/>
68       * Modifying this property has an impact on isolation/build portability, eg:
69       * <ul>
70       * <li>In {@code project.build.directory} (default): boxes must be imported every time, but no file is created outside of build directory.</li>
71       * <li>In {@code project.basedir}: boxes can be imported once for all, but files are created outside of build directory.</li>
72       * <li>In {@code ~/.vagrant.d} (Vagrant default): user boxes can be directly used, but files are created outside of project structure.</li>
73       * </ul>
74       *
75       * @since 1.0
76       */
77      @Parameter(defaultValue = "${project.build.directory}/vagrant/vagrant.d")
78      protected File vagrantHome;
79  
80      /**
81       * Custom {@code VAGRANT_RC}, which is the configuration file used by Vagrant.
82       * <p/>
83       * Modifying this property has an impact on isolation/build portability, eg:
84       * <ul>
85       * <li>In {@code project.build.directory} (default): user installation can not impact build.</li>
86       * <li>In {@code project.basedir}: user installation can not impact build.</li>
87       * <li>In {@code ~/.vagrantrc} (Vagrant default): user installation can impact build.</li>
88       * </ul>
89       *
90       * @since 1.0
91       */
92      @Parameter(defaultValue = "${project.build.directory}/vagrant/vagrantrc")
93      protected File vagrantRc;
94  
95      /**
96       * Required by {@link AbstractGemMojo}.
97       */
98      @Parameter( defaultValue = "${project}", readonly = true )
99      protected MavenProject project;
100 
101     /**
102      * Required by {@link AbstractGemMojo}.
103      */
104     @Parameter( defaultValue = "${plugin}", readonly = true )
105     protected PluginDescriptor plugin;
106 
107     /**
108      * Required by {@link AbstractGemMojo}.
109      */
110     @Component
111     protected RepositorySystem repositorySystem;
112 
113     /**
114      * Required by {@link AbstractGemMojo}.
115      */
116     @Parameter( readonly = true, defaultValue="${localRepository}" )
117     protected ArtifactRepository localRepository;
118 
119     /**
120      * Required by {@link AbstractGemMojo}.
121      */
122     @Parameter( readonly = true, defaultValue="${dummy}" )
123     protected ClassRealm classRealm;
124 
125     /**
126      * Required by {@link AbstractGemMojo}.
127      *
128      * @component role-hint="zip"
129      */
130     @Component(hint="zip")
131     protected UnArchiver unzip;
132 
133     /**
134      * Required by {@link AbstractGemMojo}.
135      */
136     @Component
137     protected GemManager manager;
138 
139     /**
140      * Required by {@link AbstractGemMojo}.
141      */
142     @Component
143     protected BuildContext buildContext;
144 
145     /** Setup {@link AbstractGemMojo}. */
146     private void setup() throws MojoFailureException {
147         super.project = this.project;
148         super.localRepository = this.localRepository;
149         super.classRealm = this.classRealm;
150         super.repositorySystem = this.repositorySystem;
151         super.jrubyFork = true;
152         super.jrubyVerbose = false;
153         super.unzip = unzip;
154         super.plugin = plugin;
155         super.includeOpenSSL = true;
156         super.includeRubygemsInTestResources = false;
157         super.installRDoc = false;
158         super.installRI = false;
159         super.gemUseSystem = false;
160         super.gemHome = this.gemHome;
161         super.gemPath = this.gemHome;
162         super.binDirectory = new File(gemHome.getAbsolutePath() + "-" + plugin.getArtifactId(), "bin");
163         super.supportNative = true;
164         super.manager = this.manager;
165         try {
166             Field field = AbstractJRubyMojo.class.getDeclaredField("buildContext");
167             field.setAccessible(true);
168             field.set(this, buildContext);
169         } catch (NoSuchFieldException e) {
170             throw new MojoFailureException("Mojo configuration failed",e);
171         } catch (IllegalAccessException e) {
172             throw new MojoFailureException("Mojo configuration failed",e);
173         }
174     }
175 
176     @Override
177     public final void execute() throws MojoExecutionException, MojoFailureException {
178         setup();
179         super.execute();
180     }
181 
182     @Override
183     protected final void executeWithGems() throws MojoExecutionException, MojoFailureException {
184         try {
185             doExecute();
186         } catch (IOException e) {
187             throw new MojoFailureException("Vagrant execution failed", e);
188         } catch (ScriptException e) {
189             throw new MojoFailureException("Vagrant execution failed", e);
190         }
191     }
192 
193     abstract protected void doExecute() throws IOException, ScriptException;
194 
195     protected final void cli(String... args) throws IOException, ScriptException {
196         cli(asList(args));
197     }
198 
199     protected final void cli(Iterable<String> args) throws IOException, ScriptException {
200         factory.addEnv("VAGRANT_HOME", vagrantHome);
201         factory.addEnv("VAGRANT_RC", vagrantRc);
202         final Script script = factory.newScriptFromSearchPath("vagrant");
203         for (String arg : args) if (isNotBlank(arg)) script.addArg(arg);
204         script.execute();
205     }
206 }