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.installation;
21
22 import java.io.File;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.apache.maven.artifact.versioning.ArtifactVersion;
26 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
27 import org.apache.maven.model.Dependency;
28 import org.apache.maven.plugin.MojoExecutionException;
29 import org.codehaus.plexus.util.Os;
30
31
32
33
34 public class NodeInstallationInformation {
35
36 private static final String NODEJS_BINARIES_GROUPID = "org.nodejs.dist";
37 private static final String NODEJS_BINARIES_ARTIFACTID = "nodejs-binaries";
38 private static final String NPM_CLI_EXECUTABLE_PATH = File.separator + "npm" + File.separator + "bin" + File.separator + "npm-cli.js";
39
40 private static final String TYPE_TAR_GZ = "tar.gz";
41 static final String TYPE_ZIP = "zip";
42
43 private static final String OS_WINDOWS = "win";
44 private static final String OS_MACOS = "darwin";
45 private static final String OS_LINUX = "linux";
46
47 private Dependency nodeJsDependency;
48 private Dependency npmDependency;
49 private File archive;
50 private String nodeExecutableRelativePath;
51 private String nodeJsInstallPath;
52 private String npmPrefixPath;
53 private String nodeModulesBuiltInRootPath;
54 private String nodeModulesRootPath;
55
56 public Dependency getNodeJsDependency() {
57 return this.nodeJsDependency;
58 }
59
60 void setNodeJsDependency(Dependency nodeJsDependency) {
61 this.nodeJsDependency = nodeJsDependency;
62 }
63
64 public Dependency getNpmDependency() {
65 return this.npmDependency;
66 }
67
68 void setNpmDependency(Dependency npmDependency) {
69 this.npmDependency = npmDependency;
70 }
71
72 public File getArchive() {
73 return archive;
74 }
75
76 void setArchive(File archive) {
77 this.archive = archive;
78 }
79
80 public File getNodeExecutable() {
81 return new File(this.nodeJsInstallPath + File.separator + nodeExecutableRelativePath);
82 }
83
84 void setNodeExecutableRelativePath(String nodeExecutableRelativePath) {
85 this.nodeExecutableRelativePath = nodeExecutableRelativePath;
86 }
87
88 public File getNpmExecutable() {
89 return new File(this.nodeModulesRootPath + File.separator + "node_modules" + NPM_CLI_EXECUTABLE_PATH);
90 }
91
92 public File getNpmExecutableBundledWithNodeJs() {
93 return new File(this.nodeModulesBuiltInRootPath + File.separator + "node_modules" + NPM_CLI_EXECUTABLE_PATH);
94 }
95
96 public String getNodeJsInstallPath() {
97 return nodeJsInstallPath;
98 }
99
100 void setNodeJsInstallPath(String nodeJsInstallPath) {
101 this.nodeJsInstallPath = nodeJsInstallPath;
102 }
103
104 public String getNpmPrefixPath() {
105 return this.npmPrefixPath;
106 }
107
108 public void setNpmPrefixPath(String npmPrefixPath) {
109 this.npmPrefixPath = npmPrefixPath;
110 }
111
112 public String getNodeModulesBuiltInRootPath() {
113 return this.nodeModulesBuiltInRootPath;
114 }
115
116 void setNodeModulesBuiltInRootPath(String nodeModulesBuiltInRootPath) {
117 this.nodeModulesBuiltInRootPath = nodeModulesBuiltInRootPath;
118 }
119
120 public String getNodeModulesRootPath() {
121 return this.nodeModulesRootPath;
122 }
123
124 void setNodeModulesRootPath(String nodeModulesRootPath) {
125 this.nodeModulesRootPath = nodeModulesRootPath;
126 }
127
128
129
130
131
132
133
134
135
136 public static NodeInstallationInformation forVersion(String version, String npmVersion, File directory) throws MojoExecutionException {
137 int nodejsMajorVersion = getMajorVersion(version);
138
139 String arch;
140 if (Os.isArch("x86") || Os.isArch("i386")) {
141 arch = "x86";
142 }
143 else if (Os.isArch("x86_64") || Os.isArch("amd64")) {
144 arch = "x64";
145 }
146 else if (Os.isArch("aarch64")) {
147 if (Os.isFamily(Os.FAMILY_MAC) && nodejsMajorVersion < 16) {
148 arch = "x64";
149 }
150 else {
151 arch = "arm64";
152 }
153 }
154 else {
155 throw new MojoExecutionException("Unsupported OS arch: " + Os.OS_ARCH);
156 }
157
158 NodeInstallationInformation result = new NodeInstallationInformation();
159
160 String basePath = directory.getAbsolutePath() + File.separator;
161
162 if (Os.isFamily(Os.FAMILY_WINDOWS) || Os.isFamily(Os.FAMILY_WIN9X)) {
163 String nodeJsInstallPath = basePath + "node-v" + version + "-" + OS_WINDOWS + "-" + arch;
164 result.setNodeJsInstallPath(nodeJsInstallPath);
165 result.setNodeJsDependency(buildDependency(NODEJS_BINARIES_GROUPID, NODEJS_BINARIES_ARTIFACTID, version, OS_WINDOWS, arch, TYPE_ZIP));
166 result.setArchive(new File(nodeJsInstallPath + "." + TYPE_ZIP));
167 result.setNodeExecutableRelativePath("node.exe");
168 result.setNodeModulesBuiltInRootPath(nodeJsInstallPath);
169 result.setNpmPrefixPath(nodeJsInstallPath + getNodeModulesRootPathNpmSuffix(npmVersion));
170 result.setNodeModulesRootPath(result.getNpmPrefixPath());
171 }
172 else if (Os.isFamily(Os.FAMILY_MAC)) {
173 String nodeJsInstallPath = basePath + "node-v" + version + "-" + OS_MACOS + "-" + arch;
174 result.setNodeJsInstallPath(nodeJsInstallPath);
175 result.setNodeJsDependency(buildDependency(NODEJS_BINARIES_GROUPID, NODEJS_BINARIES_ARTIFACTID, version, OS_MACOS, arch, TYPE_TAR_GZ));
176 result.setArchive(new File(nodeJsInstallPath + "." + TYPE_TAR_GZ));
177 result.setNodeExecutableRelativePath("bin" + File.separator + "node");
178 result.setNodeModulesBuiltInRootPath(nodeJsInstallPath + File.separator + "lib");
179 result.setNpmPrefixPath(nodeJsInstallPath + getNodeModulesRootPathNpmSuffix(npmVersion));
180 result.setNodeModulesRootPath(result.getNpmPrefixPath() + File.separator + "lib");
181 }
182 else if (Os.isFamily(Os.FAMILY_UNIX)) {
183 String nodeJsInstallPath = basePath + "node-v" + version + "-" + OS_LINUX + "-" + arch;
184 result.setNodeJsInstallPath(nodeJsInstallPath);
185 result.setNodeJsDependency(buildDependency(NODEJS_BINARIES_GROUPID, NODEJS_BINARIES_ARTIFACTID, version, OS_LINUX, arch, TYPE_TAR_GZ));
186 result.setArchive(new File(nodeJsInstallPath + "." + TYPE_TAR_GZ));
187 result.setNodeExecutableRelativePath("bin" + File.separator + "node");
188 result.setNodeModulesBuiltInRootPath(nodeJsInstallPath + File.separator + "lib");
189 result.setNpmPrefixPath(nodeJsInstallPath + getNodeModulesRootPathNpmSuffix(npmVersion));
190 result.setNodeModulesRootPath(result.getNpmPrefixPath() + File.separator + "lib");
191 }
192 else {
193 throw new MojoExecutionException("Unsupported OS: " + Os.OS_FAMILY);
194 }
195
196 return result;
197 }
198
199 private static int getMajorVersion(String version) {
200 ArtifactVersion versionInfo = new DefaultArtifactVersion(version);
201 return versionInfo.getMajorVersion();
202 }
203
204 private static String getNodeModulesRootPathNpmSuffix(String npmVersion) {
205 if (StringUtils.isNotEmpty(npmVersion)) {
206 return File.separator + "npm-v" + npmVersion;
207 }
208 else {
209 return "";
210 }
211 }
212
213 @SuppressWarnings("PMD.UseStringBufferForStringAppends")
214 private static Dependency buildDependency(String groupId, String artifactId, String version, String os, String arch, String type) {
215 String classifier = null;
216 if (StringUtils.isNotEmpty(os)) {
217 classifier = os;
218 }
219 if (StringUtils.isNotEmpty(arch)) {
220 classifier += "-" + arch;
221 }
222
223 Dependency dependency = new Dependency();
224 dependency.setGroupId(groupId);
225 dependency.setArtifactId(artifactId);
226 dependency.setVersion(version);
227 dependency.setType(type);
228 dependency.setClassifier(classifier);
229 return dependency;
230 }
231
232 }