1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.install;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.maven.RepositoryUtils;
27 import org.apache.maven.execution.MavenSession;
28 import org.apache.maven.model.Plugin;
29 import org.apache.maven.model.PluginExecution;
30 import org.apache.maven.plugin.AbstractMojo;
31 import org.apache.maven.plugin.MojoExecutionException;
32 import org.apache.maven.plugin.descriptor.PluginDescriptor;
33 import org.apache.maven.plugins.annotations.Component;
34 import org.apache.maven.plugins.annotations.LifecyclePhase;
35 import org.apache.maven.plugins.annotations.Mojo;
36 import org.apache.maven.plugins.annotations.Parameter;
37 import org.apache.maven.project.MavenProject;
38 import org.apache.maven.project.artifact.ProjectArtifact;
39 import org.eclipse.aether.RepositorySystem;
40 import org.eclipse.aether.installation.InstallRequest;
41 import org.eclipse.aether.installation.InstallationException;
42
43
44
45
46
47
48
49 @Mojo(name = "install", defaultPhase = LifecyclePhase.INSTALL, threadSafe = true)
50 public class InstallMojo extends AbstractMojo {
51 @Component
52 private RepositorySystem repositorySystem;
53
54 @Parameter(defaultValue = "${session}", required = true, readonly = true)
55 private MavenSession session;
56
57 @Parameter(defaultValue = "${project}", readonly = true, required = true)
58 private MavenProject project;
59
60 @Parameter(defaultValue = "${reactorProjects}", required = true, readonly = true)
61 private List<MavenProject> reactorProjects;
62
63 @Parameter(defaultValue = "${plugin}", required = true, readonly = true)
64 private PluginDescriptor pluginDescriptor;
65
66
67
68
69
70
71
72
73 @Parameter(defaultValue = "false", property = "installAtEnd")
74 private boolean installAtEnd;
75
76
77
78
79
80
81
82 @Parameter(property = "maven.install.skip", defaultValue = "false")
83 private boolean skip;
84
85
86
87
88
89
90
91
92
93
94 @Parameter(defaultValue = "false", property = "allowIncompleteProjects")
95 private boolean allowIncompleteProjects;
96
97 private enum State {
98 SKIPPED,
99 INSTALLED,
100 TO_BE_INSTALLED
101 }
102
103 private static final String INSTALL_PROCESSED_MARKER = InstallMojo.class.getName() + ".processed";
104
105 private void putState(State state) {
106 getPluginContext().put(INSTALL_PROCESSED_MARKER, state.name());
107 }
108
109 private State getState(MavenProject project) {
110 Map<String, Object> pluginContext = session.getPluginContext(pluginDescriptor, project);
111 return State.valueOf((String) pluginContext.get(INSTALL_PROCESSED_MARKER));
112 }
113
114 private boolean hasState(MavenProject project) {
115 Map<String, Object> pluginContext = session.getPluginContext(pluginDescriptor, project);
116 return pluginContext.containsKey(INSTALL_PROCESSED_MARKER);
117 }
118
119 @Override
120 public void execute() throws MojoExecutionException {
121 if (skip) {
122 getLog().info("Skipping artifact installation");
123 putState(State.SKIPPED);
124 } else {
125 if (!installAtEnd) {
126 InstallRequest request = new InstallRequest();
127 processProject(project, request);
128 installProject(request);
129 putState(State.INSTALLED);
130 } else {
131 getLog().info("Deferring install for " + project.getGroupId() + ":" + project.getArtifactId() + ":"
132 + project.getVersion() + " at end");
133 putState(State.TO_BE_INSTALLED);
134 }
135 }
136
137 List<MavenProject> allProjectsUsingPlugin = getAllProjectsUsingPlugin();
138
139 if (allProjectsMarked(allProjectsUsingPlugin)) {
140 InstallRequest request = new InstallRequest();
141 for (MavenProject reactorProject : allProjectsUsingPlugin) {
142 State state = getState(reactorProject);
143 if (state == State.TO_BE_INSTALLED) {
144 processProject(reactorProject, request);
145 }
146 }
147 installProject(request);
148 }
149 }
150
151 private boolean allProjectsMarked(List<MavenProject> allProjectsUsingPlugin) {
152 for (MavenProject reactorProject : allProjectsUsingPlugin) {
153 if (!hasState(reactorProject)) {
154 return false;
155 }
156 }
157 return true;
158 }
159
160 private List<MavenProject> getAllProjectsUsingPlugin() {
161 ArrayList<MavenProject> result = new ArrayList<>();
162 for (MavenProject reactorProject : reactorProjects) {
163 if (hasExecution(reactorProject.getPlugin("org.apache.maven.plugins:maven-install-plugin"))) {
164 result.add(reactorProject);
165 }
166 }
167 return result;
168 }
169
170 private boolean hasExecution(Plugin plugin) {
171 if (plugin == null) {
172 return false;
173 }
174
175 for (PluginExecution execution : plugin.getExecutions()) {
176 if (!execution.getGoals().isEmpty() && !"none".equalsIgnoreCase(execution.getPhase())) {
177 return true;
178 }
179 }
180 return false;
181 }
182
183 private void installProject(InstallRequest request) throws MojoExecutionException {
184 try {
185 repositorySystem.install(session.getRepositorySession(), request);
186 } catch (InstallationException e) {
187 throw new MojoExecutionException(e.getMessage(), e);
188 }
189 }
190
191
192
193
194
195
196 private void processProject(MavenProject project, InstallRequest request) throws MojoExecutionException {
197 if (isFile(project.getFile())) {
198 request.addArtifact(RepositoryUtils.toArtifact(new ProjectArtifact(project)));
199 } else {
200 throw new MojoExecutionException("The project POM could not be attached");
201 }
202
203 if (!"pom".equals(project.getPackaging())) {
204 org.apache.maven.artifact.Artifact mavenMainArtifact = project.getArtifact();
205 if (isFile(mavenMainArtifact.getFile())) {
206 request.addArtifact(RepositoryUtils.toArtifact(mavenMainArtifact));
207 } else if (!project.getAttachedArtifacts().isEmpty()) {
208 if (allowIncompleteProjects) {
209 getLog().warn("");
210 getLog().warn("The packaging plugin for this project did not assign");
211 getLog().warn("a main file to the project but it has attachments. Change packaging to 'pom'.");
212 getLog().warn("");
213 getLog().warn("Incomplete projects like this will fail in future Maven versions!");
214 getLog().warn("");
215 } else {
216 throw new MojoExecutionException("The packaging plugin for this project did not assign "
217 + "a main file to the project but it has attachments. Change packaging to 'pom'.");
218 }
219 } else {
220 throw new MojoExecutionException(
221 "The packaging for this project did not assign a file to the build artifact");
222 }
223 }
224
225 for (org.apache.maven.artifact.Artifact attached : project.getAttachedArtifacts()) {
226 getLog().debug("Attaching for install: " + attached.getId());
227 request.addArtifact(RepositoryUtils.toArtifact(attached));
228 }
229 }
230
231 private boolean isFile(File file) {
232 return file != null && file.isFile();
233 }
234 }