Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
InstallMojo |
|
| 3.5;3,5 |
1 | package org.apache.maven.plugin.invoker; | |
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.io.IOException; | |
24 | import java.util.Collection; | |
25 | import java.util.HashMap; | |
26 | import java.util.Iterator; | |
27 | import java.util.Map; | |
28 | ||
29 | import org.apache.maven.artifact.Artifact; | |
30 | import org.apache.maven.artifact.factory.ArtifactFactory; | |
31 | import org.apache.maven.artifact.installer.ArtifactInstallationException; | |
32 | import org.apache.maven.artifact.installer.ArtifactInstaller; | |
33 | import org.apache.maven.artifact.repository.ArtifactRepository; | |
34 | import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; | |
35 | import org.apache.maven.plugin.AbstractMojo; | |
36 | import org.apache.maven.plugin.MojoExecutionException; | |
37 | import org.apache.maven.plugin.MojoFailureException; | |
38 | import org.apache.maven.project.MavenProject; | |
39 | ||
40 | /** | |
41 | * Installs the project artifacts into the local repository as a preparation to run the integration tests. More | |
42 | * precisely, all artifacts of the project itself, all its locally reachable parent POMs and all its dependencies from | |
43 | * the reactor will be installed to the local repository. | |
44 | * | |
45 | * @goal install | |
46 | * @phase pre-integration-test | |
47 | * @requiresDependencyResolution runtime | |
48 | * @since 1.2 | |
49 | * @author Paul Gier | |
50 | * @author Benjamin Bentmann | |
51 | * @version $Id: InstallMojo.java 679351 2008-07-24 10:51:40Z bentmann $ | |
52 | */ | |
53 | 0 | public class InstallMojo |
54 | extends AbstractMojo | |
55 | { | |
56 | ||
57 | /** | |
58 | * Maven artifact install component to copy artifacts to the local repository. | |
59 | * | |
60 | * @component | |
61 | */ | |
62 | private ArtifactInstaller installer; | |
63 | ||
64 | /** | |
65 | * The component used to create artifacts. | |
66 | * | |
67 | * @component | |
68 | */ | |
69 | private ArtifactFactory artifactFactory; | |
70 | ||
71 | /** | |
72 | * The component used to create artifacts. | |
73 | * | |
74 | * @component | |
75 | */ | |
76 | private ArtifactRepositoryFactory repositoryFactory; | |
77 | ||
78 | /** | |
79 | * @parameter expression="${localRepository}" | |
80 | * @required | |
81 | * @readonly | |
82 | */ | |
83 | protected ArtifactRepository localRepository; | |
84 | ||
85 | /** | |
86 | * The path to the local repository into which the project artifacts should be installed for the integration tests. | |
87 | * If not set, the regular local repository will be used. To prevent soiling of your regular local repository with | |
88 | * possibly broken artifacts, it is strongly recommended to use an isolated repository for the integration tests | |
89 | * (e.g. <code>${project.build.directory}/it-repo</code>). | |
90 | * | |
91 | * @parameter expression="${invoker.localRepositoryPath}" | |
92 | */ | |
93 | private File localRepositoryPath; | |
94 | ||
95 | /** | |
96 | * The current Maven project. | |
97 | * | |
98 | * @parameter expression="${project}" | |
99 | * @required | |
100 | * @readonly | |
101 | */ | |
102 | private MavenProject project; | |
103 | ||
104 | /** | |
105 | * The set of Maven projects in the reactor build. | |
106 | * | |
107 | * @parameter default-value="${reactorProjects}" | |
108 | * @readonly | |
109 | */ | |
110 | private Collection reactorProjects; | |
111 | ||
112 | /** | |
113 | * Performs this mojo's tasks. | |
114 | */ | |
115 | public void execute() | |
116 | throws MojoExecutionException, MojoFailureException | |
117 | { | |
118 | 0 | ArtifactRepository testRepository = createTestRepository(); |
119 | 0 | installProjectArtifacts( project, testRepository ); |
120 | 0 | installProjectParents( project, testRepository ); |
121 | 0 | installProjectDependencies( project, reactorProjects, testRepository ); |
122 | 0 | } |
123 | ||
124 | /** | |
125 | * Creates the local repository for the integration tests. If the user specified a custom repository location, the | |
126 | * custom repository will have the same identifier, layout and policies as the real local repository. That means | |
127 | * apart from the location, the custom repository will be indistinguishable from the real repository such that its | |
128 | * usage is transparent to the integration tests. | |
129 | * | |
130 | * @return The local repository for the integration tests, never <code>null</code>. | |
131 | * @throws MojoExecutionException If the repository could not be created. | |
132 | */ | |
133 | private ArtifactRepository createTestRepository() | |
134 | throws MojoExecutionException | |
135 | { | |
136 | 0 | ArtifactRepository testRepository = localRepository; |
137 | ||
138 | 0 | if ( localRepositoryPath != null ) |
139 | { | |
140 | try | |
141 | { | |
142 | 0 | if ( !localRepositoryPath.exists() && !localRepositoryPath.mkdirs() ) |
143 | { | |
144 | 0 | throw new IOException( "Failed to create directory: " + localRepositoryPath ); |
145 | } | |
146 | ||
147 | 0 | testRepository = |
148 | repositoryFactory.createArtifactRepository( localRepository.getId(), | |
149 | localRepositoryPath.toURL().toExternalForm(), | |
150 | localRepository.getLayout(), | |
151 | localRepository.getSnapshots(), | |
152 | localRepository.getReleases() ); | |
153 | } | |
154 | 0 | catch ( Exception e ) |
155 | { | |
156 | 0 | throw new MojoExecutionException( "Failed to create local repository: " + localRepositoryPath, e ); |
157 | 0 | } |
158 | } | |
159 | ||
160 | 0 | return testRepository; |
161 | } | |
162 | ||
163 | /** | |
164 | * Installs the main artifact and any attached artifacts of the specified project to the local repository. | |
165 | * | |
166 | * @param mvnProject The project whose artifacts should be installed, must not be <code>null</code>. | |
167 | * @param testRepository The local repository to install the artifacts to, must not be <code>null</code>. | |
168 | * @throws MojoExecutionException If any artifact could not be installed. | |
169 | */ | |
170 | private void installProjectArtifacts( MavenProject mvnProject, ArtifactRepository testRepository ) | |
171 | throws MojoExecutionException | |
172 | { | |
173 | try | |
174 | { | |
175 | 0 | installProjectPom( mvnProject, testRepository ); |
176 | ||
177 | // Install the main project artifact | |
178 | 0 | installer.install( mvnProject.getArtifact().getFile(), mvnProject.getArtifact(), testRepository ); |
179 | ||
180 | // Install any attached project artifacts | |
181 | 0 | Collection attachedArtifacts = mvnProject.getAttachedArtifacts(); |
182 | 0 | for ( Iterator artifactIter = attachedArtifacts.iterator(); artifactIter.hasNext(); ) |
183 | { | |
184 | 0 | Artifact theArtifact = (Artifact) artifactIter.next(); |
185 | 0 | installer.install( theArtifact.getFile(), theArtifact, testRepository ); |
186 | } | |
187 | } | |
188 | 0 | catch ( ArtifactInstallationException e ) |
189 | { | |
190 | 0 | throw new MojoExecutionException( "Failed to install project artifacts: " + mvnProject, e ); |
191 | 0 | } |
192 | 0 | } |
193 | ||
194 | /** | |
195 | * Installs the (locally reachable) parent POMs of the specified project to the local repository. The parent POMs | |
196 | * from the reactor must be installed or the forked IT builds will fail when using a clean repository. | |
197 | * | |
198 | * @param mvnProject The project whose parent POMs should be installed, must not be <code>null</code>. | |
199 | * @param testRepository The local repository to install the POMs to, must not be <code>null</code>. | |
200 | * @throws MojoExecutionException If any POM could not be installed. | |
201 | */ | |
202 | private void installProjectParents( MavenProject mvnProject, ArtifactRepository testRepository ) | |
203 | throws MojoExecutionException | |
204 | { | |
205 | 0 | for ( MavenProject parent = mvnProject.getParent(); parent != null; parent = parent.getParent() ) |
206 | { | |
207 | 0 | if ( parent.getFile() == null ) |
208 | { | |
209 | 0 | break; |
210 | } | |
211 | 0 | installProjectPom( parent, testRepository ); |
212 | } | |
213 | 0 | } |
214 | ||
215 | /** | |
216 | * Installs the POM of the specified project to the local repository. | |
217 | * | |
218 | * @param mvnProject The project whose POM should be installed, must not be <code>null</code>. | |
219 | * @param testRepository The local repository to install the POM to, must not be <code>null</code>. | |
220 | * @throws MojoExecutionException If the POM could not be installed. | |
221 | */ | |
222 | private void installProjectPom( MavenProject mvnProject, ArtifactRepository testRepository ) | |
223 | throws MojoExecutionException | |
224 | { | |
225 | try | |
226 | { | |
227 | 0 | Artifact pomArtifact = |
228 | artifactFactory.createProjectArtifact( mvnProject.getGroupId(), mvnProject.getArtifactId(), | |
229 | mvnProject.getVersion() ); | |
230 | 0 | installer.install( mvnProject.getFile(), pomArtifact, testRepository ); |
231 | } | |
232 | 0 | catch ( Exception e ) |
233 | { | |
234 | 0 | throw new MojoExecutionException( "Failed to install POM: " + mvnProject, e ); |
235 | 0 | } |
236 | 0 | } |
237 | ||
238 | /** | |
239 | * Installs the dependent projects from the reactor to the local repository. The dependencies on other modules from | |
240 | * the reactor must be installed or the forked IT builds will fail when using a clean repository. | |
241 | * | |
242 | * @param mvnProject The project whose dependent projects should be installed, must not be <code>null</code>. | |
243 | * @param reactorProjects The set of projects in the reactor build, must not be <code>null</code>. | |
244 | * @param testRepository The local repository to install the POMs to, must not be <code>null</code>. | |
245 | * @throws MojoExecutionException If any dependency could not be installed. | |
246 | */ | |
247 | private void installProjectDependencies( MavenProject mvnProject, Collection reactorProjects, | |
248 | ArtifactRepository testRepository ) | |
249 | throws MojoExecutionException | |
250 | { | |
251 | 0 | Map projects = new HashMap(); |
252 | 0 | for ( Iterator it = reactorProjects.iterator(); it.hasNext(); ) |
253 | { | |
254 | 0 | MavenProject reactorProject = (MavenProject) it.next(); |
255 | 0 | projects.put( reactorProject.getId(), reactorProject ); |
256 | } | |
257 | ||
258 | 0 | for ( Iterator it = mvnProject.getArtifacts().iterator(); it.hasNext(); ) |
259 | { | |
260 | 0 | Artifact artifact = (Artifact) it.next(); |
261 | 0 | String id = |
262 | artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getType() + ':' | |
263 | + artifact.getVersion(); | |
264 | 0 | MavenProject requiredProject = (MavenProject) projects.remove( id ); |
265 | 0 | if ( requiredProject != null ) |
266 | { | |
267 | 0 | installProjectArtifacts( requiredProject, testRepository ); |
268 | 0 | installProjectParents( requiredProject, testRepository ); |
269 | } | |
270 | } | |
271 | 0 | } |
272 | ||
273 | } |