Skip to content

Commit 050bb45

Browse files
committed
1480: extract npm process as interface
to allow introducing another implementation
1 parent 4b663d4 commit 050bb45

File tree

3 files changed

+118
-92
lines changed

3 files changed

+118
-92
lines changed

lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ protected void prepareNodeServer() throws IOException {
8585
}
8686

8787
private void runNpmInstall(File npmProjectDir) throws IOException {
88-
new NpmProcess(npmProjectDir, this.locations.npmExecutable(), this.locations.nodeExecutable()).install();
88+
new StandardNpmProcess(npmProjectDir, this.locations.npmExecutable(), this.locations.nodeExecutable()).install();
8989
}
9090

9191
protected void assertNodeServerDirReady() throws IOException {
@@ -116,7 +116,7 @@ protected ServerProcessInfo npmRunServer() throws ServerStartException, IOExcept
116116
final File serverPortFile = new File(this.nodeServerLayout.nodeModulesDir(), "server.port");
117117
NpmResourceHelper.deleteFileIfExists(serverPortFile);
118118
// start the http server in node
119-
server = new NpmProcess(this.nodeServerLayout.nodeModulesDir(), this.locations.npmExecutable(), this.locations.nodeExecutable()).start();
119+
server = new StandardNpmProcess(this.nodeServerLayout.nodeModulesDir(), this.locations.npmExecutable(), this.locations.nodeExecutable()).start();
120120

121121
// await the readiness of the http server - wait for at most 60 seconds
122122
try {
Lines changed: 4 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2023 DiffPlug
2+
* Copyright 2023 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,96 +15,10 @@
1515
*/
1616
package com.diffplug.spotless.npm;
1717

18-
import java.io.File;
19-
import java.io.IOException;
20-
import java.util.ArrayList;
21-
import java.util.Arrays;
22-
import java.util.HashMap;
23-
import java.util.List;
24-
import java.util.Map;
25-
import java.util.concurrent.ExecutionException;
26-
import java.util.stream.Collectors;
27-
2818
import com.diffplug.spotless.ProcessRunner;
29-
import com.diffplug.spotless.ProcessRunner.LongRunningProcess;
30-
31-
class NpmProcess {
32-
33-
private final File workingDir;
34-
35-
private final File npmExecutable;
36-
37-
private final File nodeExecutable;
38-
39-
private final ProcessRunner processRunner;
40-
41-
NpmProcess(File workingDir, File npmExecutable, File nodeExecutable) {
42-
this.workingDir = workingDir;
43-
this.npmExecutable = npmExecutable;
44-
this.nodeExecutable = nodeExecutable;
45-
processRunner = ProcessRunner.usingRingBuffersOfCapacity(100 * 1024); // 100kB
46-
}
47-
48-
void install() {
49-
npmAwait("install",
50-
"--no-audit",
51-
"--no-package-lock",
52-
"--no-fund",
53-
"--prefer-offline");
54-
}
55-
56-
LongRunningProcess start() {
57-
// adding --scripts-prepend-node-path=true due to https://github.com/diffplug/spotless/issues/619#issuecomment-648018679
58-
return npm("start", "--scripts-prepend-node-path=true");
59-
}
60-
61-
private void npmAwait(String... args) {
62-
try (LongRunningProcess npmProcess = npm(args)) {
63-
if (npmProcess.waitFor() != 0) {
64-
throw new NpmProcessException("Running npm command '" + commandLine(args) + "' failed with exit code: " + npmProcess.exitValue() + "\n\n" + npmProcess.result());
65-
}
66-
} catch (InterruptedException e) {
67-
throw new NpmProcessException("Running npm command '" + commandLine(args) + "' was interrupted.", e);
68-
} catch (ExecutionException e) {
69-
throw new NpmProcessException("Running npm command '" + commandLine(args) + "' failed.", e);
70-
}
71-
}
72-
73-
private LongRunningProcess npm(String... args) {
74-
List<String> processCommand = processCommand(args);
75-
try {
76-
return processRunner.start(this.workingDir, environmentVariables(), null, true, processCommand);
77-
} catch (IOException e) {
78-
throw new NpmProcessException("Failed to launch npm command '" + commandLine(args) + "'.", e);
79-
}
80-
}
81-
82-
private List<String> processCommand(String... args) {
83-
List<String> command = new ArrayList<>(args.length + 1);
84-
command.add(this.npmExecutable.getAbsolutePath());
85-
command.addAll(Arrays.asList(args));
86-
return command;
87-
}
88-
89-
private Map<String, String> environmentVariables() {
90-
Map<String, String> environmentVariables = new HashMap<>();
91-
environmentVariables.put("PATH", this.nodeExecutable.getParentFile().getAbsolutePath() + File.pathSeparator + System.getenv("PATH"));
92-
return environmentVariables;
93-
}
94-
95-
private String commandLine(String... args) {
96-
return "npm " + Arrays.stream(args).collect(Collectors.joining(" "));
97-
}
98-
99-
static class NpmProcessException extends RuntimeException {
100-
private static final long serialVersionUID = 6424331316676759525L;
10119

102-
public NpmProcessException(String message) {
103-
super(message);
104-
}
20+
interface NpmProcess {
21+
void install();
10522

106-
public NpmProcessException(String message, Throwable cause) {
107-
super(message, cause);
108-
}
109-
}
23+
ProcessRunner.LongRunningProcess start();
11024
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright 2016-2023 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.npm;
17+
18+
import java.io.File;
19+
import java.io.IOException;
20+
import java.util.ArrayList;
21+
import java.util.Arrays;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.concurrent.ExecutionException;
26+
import java.util.stream.Collectors;
27+
28+
import com.diffplug.spotless.ProcessRunner;
29+
import com.diffplug.spotless.ProcessRunner.LongRunningProcess;
30+
31+
class StandardNpmProcess implements NpmProcess {
32+
33+
private final File workingDir;
34+
35+
private final File npmExecutable;
36+
37+
private final File nodeExecutable;
38+
39+
private final ProcessRunner processRunner;
40+
41+
StandardNpmProcess(File workingDir, File npmExecutable, File nodeExecutable) {
42+
this.workingDir = workingDir;
43+
this.npmExecutable = npmExecutable;
44+
this.nodeExecutable = nodeExecutable;
45+
processRunner = ProcessRunner.usingRingBuffersOfCapacity(100 * 1024); // 100kB
46+
}
47+
48+
@Override
49+
public void install() {
50+
npmAwait("install",
51+
"--no-audit",
52+
"--no-package-lock",
53+
"--no-fund",
54+
"--prefer-offline");
55+
}
56+
57+
@Override
58+
public LongRunningProcess start() {
59+
// adding --scripts-prepend-node-path=true due to https://github.com/diffplug/spotless/issues/619#issuecomment-648018679
60+
return npm("start", "--scripts-prepend-node-path=true");
61+
}
62+
63+
private void npmAwait(String... args) {
64+
try (LongRunningProcess npmProcess = npm(args)) {
65+
if (npmProcess.waitFor() != 0) {
66+
throw new NpmProcessException("Running npm command '" + commandLine(args) + "' failed with exit code: " + npmProcess.exitValue() + "\n\n" + npmProcess.result());
67+
}
68+
} catch (InterruptedException e) {
69+
throw new NpmProcessException("Running npm command '" + commandLine(args) + "' was interrupted.", e);
70+
} catch (ExecutionException e) {
71+
throw new NpmProcessException("Running npm command '" + commandLine(args) + "' failed.", e);
72+
}
73+
}
74+
75+
private LongRunningProcess npm(String... args) {
76+
List<String> processCommand = processCommand(args);
77+
try {
78+
return processRunner.start(this.workingDir, environmentVariables(), null, true, processCommand);
79+
} catch (IOException e) {
80+
throw new NpmProcessException("Failed to launch npm command '" + commandLine(args) + "'.", e);
81+
}
82+
}
83+
84+
private List<String> processCommand(String... args) {
85+
List<String> command = new ArrayList<>(args.length + 1);
86+
command.add(this.npmExecutable.getAbsolutePath());
87+
command.addAll(Arrays.asList(args));
88+
return command;
89+
}
90+
91+
private Map<String, String> environmentVariables() {
92+
Map<String, String> environmentVariables = new HashMap<>();
93+
environmentVariables.put("PATH", this.nodeExecutable.getParentFile().getAbsolutePath() + File.pathSeparator + System.getenv("PATH"));
94+
return environmentVariables;
95+
}
96+
97+
private String commandLine(String... args) {
98+
return "npm " + Arrays.stream(args).collect(Collectors.joining(" "));
99+
}
100+
101+
static class NpmProcessException extends RuntimeException {
102+
private static final long serialVersionUID = 6424331316676759525L;
103+
104+
public NpmProcessException(String message) {
105+
super(message);
106+
}
107+
108+
public NpmProcessException(String message, Throwable cause) {
109+
super(message, cause);
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)