Skip to content

Commit 436bd91

Browse files
authored
Merge pull request #1116 from jonkoops/fix-pnpm-bin
Use a script to proxy PNPM executable on Windows
2 parents b4738a7 + ceb0068 commit 436bd91

File tree

4 files changed

+88
-105
lines changed

4 files changed

+88
-105
lines changed

.github/workflows/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
distribution: temurin
2929
- name: "Run Maven"
3030
shell: bash
31-
run: mvn clean install --batch-mode -PintegrationTests -DintegrationTestProfiles=it-${{ runner.os }}
31+
run: mvn clean install --batch-mode -PintegrationTests
3232
- name: "Deploy"
3333
if: github.repository_owner == 'eirslett' && github.ref == 'refs/heads/master' && matrix.os == 'ubuntu-latest'
3434
shell: bash

frontend-maven-plugin/pom.xml

-5
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
<maven>3.6.0</maven>
1616
</prerequisites>
1717

18-
<properties>
19-
<integrationTestProfiles>it-Linux</integrationTestProfiles>
20-
</properties>
21-
2218
<description>
2319
This Maven plugin lets you install Node/NPM locally
2420
for your project, install dependencies with NPM,
@@ -134,7 +130,6 @@
134130

135131
<configuration>
136132
<debug>true</debug>
137-
<profiles>${integrationTestProfiles}</profiles>
138133
<projectsDirectory>src/it</projectsDirectory>
139134
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
140135
<settingsFile>src/it/settings.xml</settingsFile>

frontend-maven-plugin/src/it/pnpm-integration/pom.xml

+11-57
Original file line numberDiff line numberDiff line change
@@ -41,65 +41,19 @@
4141
<arguments>install</arguments>
4242
</configuration>
4343
</execution>
44-
</executions>
45-
</plugin>
46-
</plugins>
47-
</build>
48-
49-
<profiles>
50-
<profile>
51-
<id>it-Linux</id>
52-
<build>
53-
<plugins>
54-
<plugin>
55-
<groupId>com.github.eirslett</groupId>
56-
<artifactId>frontend-maven-plugin</artifactId>
57-
58-
<configuration>
59-
<installDirectory>target</installDirectory>
60-
</configuration>
61-
62-
<executions>
63-
<execution>
64-
<id>pnpm test</id>
65-
<goals>
66-
<goal>pnpm</goal>
67-
</goals>
68-
<configuration>
69-
<arguments>test</arguments>
70-
</configuration>
71-
</execution>
72-
</executions>
73-
</plugin>
74-
</plugins>
75-
</build>
76-
</profile>
77-
<profile>
78-
<id>it-macOs</id>
79-
<build>
80-
<plugins>
81-
<plugin>
82-
<groupId>com.github.eirslett</groupId>
83-
<artifactId>frontend-maven-plugin</artifactId>
8444

45+
<execution>
46+
<id>pnpm test</id>
47+
<goals>
48+
<goal>pnpm</goal>
49+
</goals>
8550
<configuration>
86-
<installDirectory>target</installDirectory>
51+
<arguments>test</arguments>
8752
</configuration>
53+
</execution>
8854

89-
<executions>
90-
<execution>
91-
<id>pnpm test</id>
92-
<goals>
93-
<goal>pnpm</goal>
94-
</goals>
95-
<configuration>
96-
<arguments>test</arguments>
97-
</configuration>
98-
</execution>
99-
</executions>
100-
</plugin>
101-
</plugins>
102-
</build>
103-
</profile>
104-
</profiles>
55+
</executions>
56+
</plugin>
57+
</plugins>
58+
</build>
10559
</project>

frontend-plugin-core/src/main/java/com/github/eirslett/maven/plugins/frontend/lib/PnpmInstaller.java

+76-42
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package com.github.eirslett.maven.plugins.frontend.lib;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4-
import java.io.EOFException;
5-
import java.io.File;
6-
import java.io.IOException;
7-
import java.nio.file.Files;
8-
import java.util.Arrays;
9-
import java.util.HashMap;
104
import org.apache.commons.io.FileUtils;
115
import org.slf4j.Logger;
126
import org.slf4j.LoggerFactory;
137

8+
import java.io.*;
9+
import java.nio.file.Files;
10+
import java.nio.file.Path;
11+
import java.util.HashMap;
12+
1413
public class PnpmInstaller {
1514

1615
private static final String VERSION = "version";
@@ -69,7 +68,12 @@ public void install() throws InstallationException {
6968
if (!pnpmIsAlreadyInstalled()) {
7069
installPnpm();
7170
}
72-
copyPnpmScripts();
71+
72+
if (this.config.getPlatform().isWindows()) {
73+
linkExecutableWindows();
74+
} else {
75+
linkExecutable();
76+
}
7377
}
7478
}
7579

@@ -169,42 +173,72 @@ private void installPnpm() throws InstallationException {
169173
}
170174
}
171175

172-
private void copyPnpmScripts() throws InstallationException{
173-
File installDirectory = getNodeInstallDirectory();
174-
175-
File nodeModulesDirectory = new File(installDirectory, "node_modules");
176-
File pnpmDirectory = new File(nodeModulesDirectory, "pnpm");
177-
// create a copy of the pnpm scripts next to the node executable
178-
for (String script : Arrays.asList("pnpm", "pnpm.cmd")) {
179-
File scriptFile = new File(pnpmDirectory, "bin" + File.separator + script);
180-
if (scriptFile.exists()) {
181-
File copy = new File(installDirectory, script);
182-
if (!copy.exists()) {
183-
try
184-
{
185-
FileUtils.copyFile(scriptFile, copy);
186-
}
187-
catch (IOException e)
188-
{
189-
throw new InstallationException("Could not copy pnpm", e);
190-
}
191-
copy.setExecutable(true);
192-
}
193-
}
176+
private void linkExecutable() throws InstallationException{
177+
File nodeInstallDirectory = getNodeInstallDirectory();
178+
File pnpmExecutable = new File(nodeInstallDirectory, "pnpm");
179+
180+
if (pnpmExecutable.exists()) {
181+
this.logger.info("Existing pnpm executable found, skipping linking.");
182+
return;
194183
}
195-
// On non-windows platforms, if no predefined executables exist, symlink the .cjs executable
196-
File pnpmExecutable = new File(installDirectory, "pnpm");
197-
if (!pnpmExecutable.exists() && !this.config.getPlatform().isWindows()) {
198-
199-
File pnpmJsExecutable = new File(pnpmDirectory, "bin" + File.separator + "pnpm.cjs");
200-
if (pnpmJsExecutable.exists()) {
201-
this.logger.info("No pnpm executable found, creating symlink to {}", pnpmJsExecutable.toPath());
202-
try {
203-
Files.createSymbolicLink(pnpmExecutable.toPath(), pnpmJsExecutable.toPath());
204-
} catch (IOException e) {
205-
throw new InstallationException("Could not copy pnpm", e);
206-
}
207-
}
184+
185+
NodeExecutorConfig executorConfig = new InstallNodeExecutorConfig(this.config);
186+
File pnpmJsExecutable = executorConfig.getPnpmCjsPath();
187+
188+
if (!pnpmJsExecutable.exists()) {
189+
throw new InstallationException("Could not link to pnpm executable, no pnpm installation found.");
190+
}
191+
192+
this.logger.info("No pnpm executable found, creating symbolic link to {}.", pnpmJsExecutable.toPath());
193+
194+
try {
195+
Files.createSymbolicLink(pnpmExecutable.toPath(), pnpmJsExecutable.toPath());
196+
} catch (IOException e) {
197+
throw new InstallationException("Could not create symbolic link for pnpm executable.", e);
198+
}
199+
}
200+
201+
private void linkExecutableWindows() throws InstallationException{
202+
File nodeInstallDirectory = getNodeInstallDirectory();
203+
File pnpmExecutable = new File(nodeInstallDirectory, "pnpm.cmd");
204+
205+
if (pnpmExecutable.exists()) {
206+
this.logger.info("Existing pnpm executable found, skipping linking.");
207+
return;
208+
}
209+
210+
NodeExecutorConfig executorConfig = new InstallNodeExecutorConfig(this.config);
211+
File pnpmJsExecutable = executorConfig.getPnpmCjsPath();
212+
213+
if (!pnpmJsExecutable.exists()) {
214+
throw new InstallationException("Could not link to pnpm executable, no pnpm installation found.");
215+
}
216+
217+
this.logger.info("No pnpm executable found, creating proxy script to {}.", pnpmJsExecutable.toPath());
218+
219+
Path nodePath = executorConfig.getNodePath().toPath();
220+
Path relativeNodePath = nodeInstallDirectory.toPath().relativize(nodePath);
221+
Path relativePnpmPath = nodeInstallDirectory.toPath().relativize(pnpmJsExecutable.toPath());
222+
223+
// Create a script that will proxy any commands passed into it to the pnpm executable.
224+
String scriptContents = new StringBuilder()
225+
.append(":: Created by frontend-maven-plugin, please don't edit manually.\r\n")
226+
.append("@ECHO OFF\r\n")
227+
.append("\r\n")
228+
.append("SETLOCAL\r\n")
229+
.append("\r\n")
230+
.append(String.format("SET \"NODE_EXE=%%~dp0\\%s\"\r\n", relativeNodePath))
231+
.append(String.format("SET \"PNPM_CLI_JS=%%~dp0\\%s\"\r\n", relativePnpmPath))
232+
.append("\r\n")
233+
.append("\"%NODE_EXE%\" \"%PNPM_CLI_JS%\" %*")
234+
.toString();
235+
236+
try {
237+
BufferedWriter writer = new BufferedWriter(new FileWriter(pnpmExecutable));
238+
writer.write(scriptContents);
239+
writer.close();
240+
} catch (IOException e) {
241+
throw new InstallationException("Could not create proxy script for pnpm executable.", e);
208242
}
209243
}
210244

0 commit comments

Comments
 (0)