Skip to content

Commit 57063e2

Browse files
author
ntwigg
committed
First cut.
1 parent 3170355 commit 57063e2

File tree

1 file changed

+120
-4
lines changed

1 file changed

+120
-4
lines changed

src/main/java/com/diffplug/webtools/node/NodePlugin.java

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@
1616
package com.diffplug.webtools.node;
1717

1818
import com.github.eirslett.maven.plugins.frontend.lib.ProxyConfig;
19+
import java.io.BufferedReader;
1920
import java.io.File;
2021
import java.io.IOException;
22+
import java.io.InputStreamReader;
2123
import java.nio.charset.StandardCharsets;
2224
import java.nio.file.Files;
25+
import java.util.ArrayList;
2326
import java.util.Collections;
27+
import java.util.List;
2428
import java.util.Objects;
2529
import java.util.TreeMap;
30+
import java.util.concurrent.CompletableFuture;
2631
import org.gradle.api.Action;
2732
import org.gradle.api.DefaultTask;
2833
import org.gradle.api.Plugin;
@@ -97,11 +102,122 @@ public TreeMap<String, String> getEnvironment() {
97102
@TaskAction
98103
public void npmCiRunTask() throws Exception {
99104
SetupCleanupNode setup = getSetup().get();
105+
File projectDir = getProjectDir().get().getAsFile();
106+
107+
System.out.println("=== NPM Task: " + npmTaskName + " ===");
108+
System.out.println("Installing Node.js dependencies...");
109+
100110
// install node, npm, and package-lock.json
101-
setup.start(getProjectDir().get().getAsFile());
102-
// run the gulp task
103-
ProxyConfig proxyConfig = new ProxyConfig(Collections.emptyList());
104-
setup.factory().getNpmRunner(proxyConfig, null).execute("run " + npmTaskName, environment);
111+
setup.start(projectDir);
112+
113+
System.out.println("Running: npm run " + npmTaskName);
114+
if (!environment.isEmpty()) {
115+
System.out.println("Environment variables:");
116+
environment.forEach((key, value) -> System.out.println(" " + key + "=" + value));
117+
}
118+
System.out.println();
119+
120+
try {
121+
// Use ProcessBuilder for direct console output instead of NpmRunner
122+
File installDir = new File(projectDir, "build/node-install");
123+
File npmExe;
124+
125+
// Based on frontend-maven-plugin structure, npm is directly in the node directory
126+
File nodeExe = new File(installDir, "node/node");
127+
if (System.getProperty("os.name").toLowerCase().contains("win")) {
128+
nodeExe = new File(installDir, "node/node.exe");
129+
npmExe = new File(installDir, "node/npm.cmd");
130+
} else {
131+
npmExe = new File(installDir, "node/npm");
132+
}
133+
134+
System.out.println("Using node executable: " + nodeExe.getAbsolutePath());
135+
System.out.println("Node executable exists: " + nodeExe.exists());
136+
System.out.println("Using npm executable: " + npmExe.getAbsolutePath());
137+
System.out.println("NPM executable exists: " + npmExe.exists());
138+
139+
ProcessBuilder processBuilder = new ProcessBuilder(npmExe.getAbsolutePath(), "run", npmTaskName);
140+
141+
processBuilder.directory(projectDir);
142+
processBuilder.environment().putAll(environment);
143+
144+
Process process = processBuilder.start();
145+
146+
// Buffer output to only show on failure
147+
List<String> stdoutLines = new ArrayList<>();
148+
List<String> stderrLines = new ArrayList<>();
149+
150+
// Create threads to read stdout and stderr concurrently
151+
CompletableFuture<Void> stdoutFuture = CompletableFuture.runAsync(() -> {
152+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
153+
String line;
154+
while ((line = reader.readLine()) != null) {
155+
synchronized (stdoutLines) {
156+
stdoutLines.add(line);
157+
}
158+
}
159+
} catch (IOException e) {
160+
synchronized (stdoutLines) {
161+
stdoutLines.add("Error reading stdout: " + e.getMessage());
162+
}
163+
}
164+
});
165+
166+
CompletableFuture<Void> stderrFuture = CompletableFuture.runAsync(() -> {
167+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
168+
String line;
169+
while ((line = reader.readLine()) != null) {
170+
synchronized (stderrLines) {
171+
stderrLines.add(line);
172+
}
173+
}
174+
} catch (IOException e) {
175+
synchronized (stderrLines) {
176+
stderrLines.add("Error reading stderr: " + e.getMessage());
177+
}
178+
}
179+
});
180+
181+
int exitCode = process.waitFor();
182+
183+
// Wait for output streams to finish
184+
CompletableFuture.allOf(stdoutFuture, stderrFuture).join();
185+
186+
System.out.println();
187+
if (exitCode == 0) {
188+
System.out.println("✓ NPM task '" + npmTaskName + "' completed successfully");
189+
} else {
190+
System.out.println("✗ NPM task '" + npmTaskName + "' failed with exit code " + exitCode);
191+
System.out.println();
192+
System.out.println("=== NPM OUTPUT ===");
193+
194+
// Print stdout if there's any
195+
if (!stdoutLines.isEmpty()) {
196+
System.out.println("STDOUT:");
197+
for (String line : stdoutLines) {
198+
System.out.println(line);
199+
}
200+
System.out.println();
201+
}
202+
203+
// Print stderr if there's any
204+
if (!stderrLines.isEmpty()) {
205+
System.out.println("STDERR:");
206+
for (String line : stderrLines) {
207+
System.out.println(line);
208+
}
209+
}
210+
211+
System.out.println("==================");
212+
throw new RuntimeException("npm run " + npmTaskName + " failed with exit code " + exitCode);
213+
}
214+
} catch (Exception e) {
215+
System.out.println();
216+
System.out.println("✗ NPM task '" + npmTaskName + "' failed");
217+
System.out.println("Command: npm run " + npmTaskName);
218+
System.out.println("Error: " + e.getMessage());
219+
throw e;
220+
}
105221
}
106222
}
107223

0 commit comments

Comments
 (0)