1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.maven.plugins.nodejs.mojo;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.List;
25
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.maven.artifact.Artifact;
28 import org.apache.maven.artifact.DefaultArtifact;
29 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
30 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
31 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
32 import org.apache.maven.artifact.resolver.ArtifactResolver;
33 import org.apache.maven.artifact.versioning.ComparableVersion;
34 import org.apache.maven.artifact.versioning.VersionRange;
35 import org.apache.maven.execution.MavenSession;
36 import org.apache.maven.model.Dependency;
37 import org.apache.maven.plugin.AbstractMojo;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugins.annotations.Component;
40 import org.apache.maven.plugins.annotations.Parameter;
41 import org.apache.maven.project.MavenProject;
42 import org.codehaus.plexus.util.FileUtils;
43
44 import io.wcm.maven.plugins.nodejs.installation.NodeInstallationInformation;
45 import io.wcm.maven.plugins.nodejs.installation.NodeUnarchiveTask;
46
47
48
49
50 public abstract class AbstractNodeJsMojo extends AbstractMojo {
51
52
53
54
55 @Parameter(property = "nodejs.version", defaultValue = "10.15.3", required = true)
56 protected String nodeJsVersion;
57
58
59
60
61 @Parameter(property = "nodejs.npm.version")
62 protected String npmVersion;
63
64
65
66
67 @Parameter(property = "nodejs.directory", defaultValue = "${java.io.tmpdir}/nodejs")
68 protected File nodeJsDirectory;
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 @Parameter
116 protected List<? extends Task> tasks;
117
118
119
120
121 @Parameter(defaultValue = "true")
122 protected boolean stopOnError;
123
124
125
126
127 @Parameter(property = "nodejs.skip")
128 protected boolean skip;
129
130 @Parameter(defaultValue = "${project}", readonly = true)
131 private MavenProject project;
132 @Parameter(defaultValue = "${session}", readonly = true)
133 private MavenSession session;
134 @Component
135 private ArtifactHandlerManager artifactHandlerManager;
136 @Component
137 private ArtifactResolver resolver;
138
139 private static final ComparableVersion NODEJS_MIN_VERSION = new ComparableVersion("6.3.0");
140
141
142
143
144
145 public void run() throws MojoExecutionException {
146 if (skip) {
147 return;
148 }
149
150 if (tasks == null || tasks.isEmpty()) {
151 getLog().warn("No Node.js tasks have been defined. Nothing to do.");
152 }
153
154
155 ComparableVersion nodeJsVersionComparable = new ComparableVersion(nodeJsVersion);
156 if (nodeJsVersionComparable.compareTo(NODEJS_MIN_VERSION) < 0) {
157 throw new MojoExecutionException("This plugin supports Node.js " + NODEJS_MIN_VERSION + " and up.");
158 }
159
160 NodeInstallationInformation information = getOrInstallNodeJS();
161
162 if (tasks != null) {
163 for (Task task : tasks) {
164 task.setLog(getLog());
165 task.execute(information);
166 }
167 }
168 }
169
170 private NodeInstallationInformation getOrInstallNodeJS() throws MojoExecutionException {
171 NodeInstallationInformation information = NodeInstallationInformation.forVersion(nodeJsVersion, npmVersion, nodeJsDirectory);
172 try {
173 if (!information.getNodeExecutable().exists() || !information.getNpmExecutableBundledWithNodeJs().exists()) {
174 getLog().info("Install Node.js to " + information.getNodeJsInstallPath());
175 if (!cleanNodeJsInstallPath(information)) {
176 throw new MojoExecutionException("Could not delete node js directory: " + information.getNodeJsInstallPath());
177 }
178 File nodeJsBinary = resolveArtifact(information.getNodeJsDependency());
179 FileUtils.copyFile(nodeJsBinary, information.getArchive());
180 Task installationTask = new NodeUnarchiveTask(nodeJsDirectory.getAbsolutePath());
181 installationTask.setLog(getLog());
182 installationTask.execute(information);
183 }
184
185 if (StringUtils.isNotEmpty(npmVersion) && !information.getNpmExecutable().exists()) {
186 updateNPMExecutable(information);
187 }
188 }
189 catch (java.net.MalformedURLException ex) {
190 throw new MojoExecutionException("Malformed provided node URL", ex);
191 }
192 catch (IOException ex) {
193 getLog().error("Failed to get nodeJs from " + information.getNodeJsDependency(), ex);
194 throw new MojoExecutionException("Failed to downloading nodeJs from " + information.getNodeJsDependency(), ex);
195 }
196 catch (MojoExecutionException ex) {
197 getLog().error("Execution Exception", ex);
198 if (stopOnError) {
199 throw new MojoExecutionException("Execution Exception", ex);
200 }
201 }
202 return information;
203 }
204
205 private boolean cleanNodeJsInstallPath(NodeInstallationInformation information) {
206 File directory = new File(information.getNodeJsInstallPath());
207 if (directory.exists()) {
208 try {
209 FileUtils.deleteDirectory(directory);
210 }
211 catch (IOException ex) {
212 getLog().error(ex);
213 return false;
214 }
215 }
216
217 if (information.getArchive().exists()) {
218 if (!information.getArchive().delete()) {
219 return false;
220 }
221 }
222
223 return true;
224 }
225
226
227
228
229
230 private void updateNPMExecutable(NodeInstallationInformation information) throws MojoExecutionException {
231 getLog().info("Installing specified npm version " + npmVersion);
232 NpmInstallTask npmInstallTask = new NpmInstallTask();
233 npmInstallTask.setLog(getLog());
234 npmInstallTask.setNpmBundledWithNodeJs(true);
235 npmInstallTask.setArguments(new String[] {
236 "--prefix", information.getNpmPrefixPath(), "--global", "npm@" + npmVersion
237 });
238 npmInstallTask.execute(information);
239 }
240
241 @SuppressWarnings("deprecation")
242 private File resolveArtifact(Dependency dependency) throws MojoExecutionException {
243 Artifact artifact = new DefaultArtifact(dependency.getGroupId(),
244 dependency.getArtifactId(),
245 VersionRange.createFromVersion(dependency.getVersion()),
246 Artifact.SCOPE_PROVIDED,
247 dependency.getType(),
248 dependency.getClassifier(),
249 artifactHandlerManager.getArtifactHandler(dependency.getType()));
250 try {
251 resolver.resolve(artifact, project.getRemoteArtifactRepositories(), session.getLocalRepository());
252 }
253 catch (ArtifactResolutionException ex) {
254 throw new MojoExecutionException("Unable to get artifact for " + dependency, ex);
255 }
256 catch (ArtifactNotFoundException ex) {
257 throw new MojoExecutionException("Unable to get artifact for " + dependency, ex);
258 }
259 return artifact.getFile();
260 }
261
262 }