Skip to content

Commit e97764f

Browse files
committed
1480: allow dynamic npmInstall process
based on cacheDir
1 parent bdceb88 commit e97764f

12 files changed

+68
-21
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ public static Map<String, String> defaultDevDependenciesWithEslint(String versio
7171
return Collections.singletonMap("eslint", version);
7272
}
7373

74-
public static FormatterStep create(Map<String, String> devDependencies, Provisioner provisioner, File projectDir, File buildDir, NpmPathResolver npmPathResolver, EslintConfig eslintConfig) {
74+
public static FormatterStep create(Map<String, String> devDependencies, Provisioner provisioner, File projectDir, File buildDir, File cacheDir, NpmPathResolver npmPathResolver, EslintConfig eslintConfig) {
7575
requireNonNull(devDependencies);
7676
requireNonNull(provisioner);
7777
requireNonNull(projectDir);
7878
requireNonNull(buildDir);
7979
return FormatterStep.createLazy(NAME,
80-
() -> new State(NAME, devDependencies, projectDir, buildDir, npmPathResolver, eslintConfig),
80+
() -> new State(NAME, devDependencies, projectDir, buildDir, cacheDir, npmPathResolver, eslintConfig),
8181
State::createFormatterFunc);
8282
}
8383

@@ -89,7 +89,7 @@ private static class State extends NpmFormatterStepStateBase implements Serializ
8989
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
9090
private transient EslintConfig eslintConfigInUse;
9191

92-
State(String stepName, Map<String, String> devDependencies, File projectDir, File buildDir, NpmPathResolver npmPathResolver, EslintConfig eslintConfig) throws IOException {
92+
State(String stepName, Map<String, String> devDependencies, File projectDir, File buildDir, File cacheDir, NpmPathResolver npmPathResolver, EslintConfig eslintConfig) throws IOException {
9393
super(stepName,
9494
new NpmConfig(
9595
replaceDevDependencies(
@@ -102,6 +102,7 @@ private static class State extends NpmFormatterStepStateBase implements Serializ
102102
new NpmFormatterStepLocations(
103103
projectDir,
104104
buildDir,
105+
cacheDir,
105106
npmPathResolver::resolveNpmExecutable,
106107
npmPathResolver::resolveNodeExecutable));
107108
this.origEslintConfig = requireNonNull(eslintConfig.verify());

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,22 @@ public class NodeApp {
4242
@Nonnull
4343
protected final NpmFormatterStepLocations formatterStepLocations;
4444

45-
public NodeApp(@Nonnull NodeServerLayout nodeServerLayout, @Nonnull NpmConfig npmConfig, @Nonnull NpmProcessFactory npmProcessFactory, @Nonnull NpmFormatterStepLocations formatterStepLocations) {
45+
public NodeApp(@Nonnull NodeServerLayout nodeServerLayout, @Nonnull NpmConfig npmConfig, @Nonnull NpmFormatterStepLocations formatterStepLocations) {
4646
this.nodeServerLayout = Objects.requireNonNull(nodeServerLayout);
4747
this.npmConfig = Objects.requireNonNull(npmConfig);
48-
this.npmProcessFactory = Objects.requireNonNull(npmProcessFactory);
48+
this.npmProcessFactory = processFactory(formatterStepLocations);
4949
this.formatterStepLocations = Objects.requireNonNull(formatterStepLocations);
5050
}
5151

52+
private static NpmProcessFactory processFactory(NpmFormatterStepLocations formatterStepLocations) {
53+
if (formatterStepLocations.cacheDir() != null) {
54+
logger.info("Caching npm install results in {}.", formatterStepLocations.cacheDir());
55+
return NodeModulesCachingNpmProcessFactory.create(formatterStepLocations.cacheDir());
56+
}
57+
logger.debug("Not caching npm install results.");
58+
return StandardNpmProcessFactory.INSTANCE;
59+
}
60+
5261
boolean needsNpmInstall() {
5362
return !this.nodeServerLayout.isNodeModulesPrepared();
5463
}

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
import java.io.File;
1919
import java.util.List;
20+
import java.util.Objects;
21+
22+
import javax.annotation.Nonnull;
2023

2124
import org.slf4j.Logger;
2225
import org.slf4j.LoggerFactory;
@@ -34,8 +37,8 @@ public class NodeModulesCachingNpmProcessFactory implements NpmProcessFactory {
3437

3538
private final ShadowCopy shadowCopy;
3639

37-
private NodeModulesCachingNpmProcessFactory(File cacheDir) {
38-
this.cacheDir = cacheDir;
40+
private NodeModulesCachingNpmProcessFactory(@Nonnull File cacheDir) {
41+
this.cacheDir = Objects.requireNonNull(cacheDir);
3942
assertDir(cacheDir);
4043
this.shadowCopy = new ShadowCopy(cacheDir);
4144
}
@@ -51,7 +54,7 @@ private void assertDir(File cacheDir) {
5154
}
5255
}
5356

54-
public static NodeModulesCachingNpmProcessFactory forCacheDir(File cacheDir) {
57+
public static NodeModulesCachingNpmProcessFactory create(@Nonnull File cacheDir) {
5558
return new NodeModulesCachingNpmProcessFactory(cacheDir);
5659
}
5760

@@ -87,13 +90,16 @@ public Result waitFor() {
8790
Result result = timedLogger.withInfo("calling actual npm install {}", actualNpmInstallProcess.describe())
8891
.call(actualNpmInstallProcess::waitFor);
8992
assert result.exitCode() == 0;
90-
// TODO: maybe spawn a thread to do this in the background?
91-
timedLogger.withInfo("Caching node_modules for {} in {}", entryName, cacheDir)
92-
.run(() -> shadowCopy.addEntry(entryName(), new File(nodeServerLayout.nodeModulesDir(), NodeServerLayout.NODE_MODULES)));
93+
storeShadowCopy(entryName);
9394
return result;
9495
}
9596
}
9697

98+
private void storeShadowCopy(String entryName) {
99+
timedLogger.withInfo("Caching node_modules for {} in {}", entryName, cacheDir)
100+
.run(() -> shadowCopy.addEntry(entryName(), new File(nodeServerLayout.nodeModulesDir(), NodeServerLayout.NODE_MODULES)));
101+
}
102+
97103
private String entryName() {
98104
return nodeServerLayout.nodeModulesDir().getName();
99105
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public class NodeServeApp extends NodeApp {
2929

3030
private static final TimedLogger timedLogger = TimedLogger.forLogger(logger);
3131

32-
public NodeServeApp(@Nonnull NodeServerLayout nodeServerLayout, @Nonnull NpmConfig npmConfig, @Nonnull NpmProcessFactory npmProcessFactory, @Nonnull NpmFormatterStepLocations formatterStepLocations) {
33-
super(nodeServerLayout, npmConfig, npmProcessFactory, formatterStepLocations);
32+
public NodeServeApp(@Nonnull NodeServerLayout nodeServerLayout, @Nonnull NpmConfig npmConfig, @Nonnull NpmFormatterStepLocations formatterStepLocations) {
33+
super(nodeServerLayout, npmConfig, formatterStepLocations);
3434
}
3535

3636
ProcessRunner.LongRunningProcess startNpmServeProcess() {

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.io.Serializable;
2222
import java.util.function.Supplier;
2323

24+
import javax.annotation.Nonnull;
25+
2426
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2527

2628
class NpmFormatterStepLocations implements Serializable {
@@ -32,15 +34,19 @@ class NpmFormatterStepLocations implements Serializable {
3234
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
3335
private final transient File buildDir;
3436

37+
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
38+
private final transient File cacheDir;
39+
3540
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
3641
private final transient Supplier<File> npmExecutable;
3742

3843
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
3944
private final transient Supplier<File> nodeExecutable;
4045

41-
public NpmFormatterStepLocations(File projectDir, File buildDir, Supplier<File> npmExecutable, Supplier<File> nodeExecutable) {
46+
public NpmFormatterStepLocations(@Nonnull File projectDir, @Nonnull File buildDir, File cacheDir, @Nonnull Supplier<File> npmExecutable, @Nonnull Supplier<File> nodeExecutable) {
4247
this.projectDir = requireNonNull(projectDir);
4348
this.buildDir = requireNonNull(buildDir);
49+
this.cacheDir = cacheDir;
4450
this.npmExecutable = requireNonNull(npmExecutable);
4551
this.nodeExecutable = requireNonNull(nodeExecutable);
4652
}
@@ -53,6 +59,10 @@ public File buildDir() {
5359
return buildDir;
5460
}
5561

62+
public File cacheDir() {
63+
return cacheDir;
64+
}
65+
5666
public File npmExecutable() {
5767
return npmExecutable.get();
5868
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ protected NpmFormatterStepStateBase(String stepName, NpmConfig npmConfig, NpmFor
6262
this.npmConfig = requireNonNull(npmConfig);
6363
this.locations = locations;
6464
this.nodeServerLayout = new NodeServerLayout(locations.buildDir(), npmConfig.getPackageJsonContent());
65-
this.nodeServeApp = new NodeServeApp(nodeServerLayout, npmConfig, NodeModulesCachingNpmProcessFactory.forCacheDir(new File(locations.buildDir(), "spotless-npm-cache"))/*StandardNpmProcessFactory.INSTANCE*/, locations);
65+
this.nodeServeApp = new NodeServeApp(nodeServerLayout, npmConfig, locations);
6666
}
6767

6868
protected void prepareNodeServerLayout() throws IOException {

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ public static final Map<String, String> defaultDevDependenciesWithPrettier(Strin
5050
return Collections.singletonMap("prettier", version);
5151
}
5252

53-
public static FormatterStep create(Map<String, String> devDependencies, Provisioner provisioner, File projectDir, File buildDir, NpmPathResolver npmPathResolver, PrettierConfig prettierConfig) {
53+
public static FormatterStep create(Map<String, String> devDependencies, Provisioner provisioner, File projectDir, File buildDir, File cacheDir, NpmPathResolver npmPathResolver, PrettierConfig prettierConfig) {
5454
requireNonNull(devDependencies);
5555
requireNonNull(provisioner);
5656
requireNonNull(buildDir);
5757
return FormatterStep.createLazy(NAME,
58-
() -> new State(NAME, devDependencies, projectDir, buildDir, npmPathResolver, prettierConfig),
58+
() -> new State(NAME, devDependencies, projectDir, buildDir, cacheDir, npmPathResolver, prettierConfig),
5959
State::createFormatterFunc);
6060
}
6161

@@ -64,7 +64,7 @@ private static class State extends NpmFormatterStepStateBase implements Serializ
6464
private static final long serialVersionUID = -539537027004745812L;
6565
private final PrettierConfig prettierConfig;
6666

67-
State(String stepName, Map<String, String> devDependencies, File projectDir, File buildDir, NpmPathResolver npmPathResolver, PrettierConfig prettierConfig) throws IOException {
67+
State(String stepName, Map<String, String> devDependencies, File projectDir, File buildDir, File cacheDir, NpmPathResolver npmPathResolver, PrettierConfig prettierConfig) throws IOException {
6868
super(stepName,
6969
new NpmConfig(
7070
replaceDevDependencies(
@@ -77,6 +77,7 @@ private static class State extends NpmFormatterStepStateBase implements Serializ
7777
new NpmFormatterStepLocations(
7878
projectDir,
7979
buildDir,
80+
cacheDir,
8081
npmPathResolver::resolveNpmExecutable,
8182
npmPathResolver::resolveNodeExecutable));
8283
this.prettierConfig = requireNonNull(prettierConfig);

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ public class TsFmtFormatterStep {
4040

4141
public static final String NAME = "tsfmt-format";
4242

43-
public static FormatterStep create(Map<String, String> versions, Provisioner provisioner, File projectDir, File buildDir, NpmPathResolver npmPathResolver, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map<String, Object> inlineTsFmtSettings) {
43+
public static FormatterStep create(Map<String, String> versions, Provisioner provisioner, File projectDir, File buildDir, File cacheDir, NpmPathResolver npmPathResolver, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map<String, Object> inlineTsFmtSettings) {
4444
requireNonNull(provisioner);
4545
requireNonNull(buildDir);
4646
return FormatterStep.createLazy(NAME,
47-
() -> new State(NAME, versions, projectDir, buildDir, npmPathResolver, configFile, inlineTsFmtSettings),
47+
() -> new State(NAME, versions, projectDir, buildDir, cacheDir, npmPathResolver, configFile, inlineTsFmtSettings),
4848
State::createFormatterFunc);
4949
}
5050

@@ -71,7 +71,7 @@ public static class State extends NpmFormatterStepStateBase implements Serializa
7171
@Nullable
7272
private final TypedTsFmtConfigFile configFile;
7373

74-
public State(String stepName, Map<String, String> versions, File projectDir, File buildDir, NpmPathResolver npmPathResolver, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map<String, Object> inlineTsFmtSettings) throws IOException {
74+
public State(String stepName, Map<String, String> versions, File projectDir, File buildDir, File cacheDir, NpmPathResolver npmPathResolver, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map<String, Object> inlineTsFmtSettings) throws IOException {
7575
super(stepName,
7676
new NpmConfig(
7777
replaceDevDependencies(NpmResourceHelper.readUtf8StringFromClasspath(TsFmtFormatterStep.class, "/com/diffplug/spotless/npm/tsfmt-package.json"), new TreeMap<>(versions)),
@@ -82,6 +82,7 @@ public State(String stepName, Map<String, String> versions, File projectDir, Fil
8282
new NpmFormatterStepLocations(
8383
projectDir,
8484
buildDir,
85+
cacheDir,
8586
npmPathResolver::resolveNpmExecutable,
8687
npmPathResolver::resolveNodeExecutable));
8788
this.buildDir = requireNonNull(buildDir);

testlib/src/test/java/com/diffplug/spotless/npm/EslintFormatterStepTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ void formattingUsingRulesetsFile(String ruleSetName) throws Exception {
6464
TestProvisioner.mavenCentral(),
6565
projectDir(),
6666
buildDir(),
67+
cacheDir(),
6768
npmPathResolver(),
6869
new EslintConfig(eslintRc, null));
6970

@@ -107,6 +108,7 @@ void formattingUsingRulesetsFile(String ruleSetName) throws Exception {
107108
TestProvisioner.mavenCentral(),
108109
projectDir(),
109110
buildDir(),
111+
cacheDir(),
110112
npmPathResolver(),
111113
new EslintTypescriptConfig(eslintRc, null, tsconfigFile));
112114

@@ -164,6 +166,7 @@ void formattingUsingInlineXoConfig() throws Exception {
164166
TestProvisioner.mavenCentral(),
165167
projectDir(),
166168
buildDir(),
169+
cacheDir(),
167170
npmPathResolver(),
168171
new EslintTypescriptConfig(null, esLintConfig, tsconfigFile));
169172

testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,13 @@ protected File projectDir() throws IOException {
5656
}
5757
return this.projectDir;
5858
}
59+
60+
private File cacheDir = null;
61+
62+
protected File cacheDir() throws IOException {
63+
if (this.cacheDir == null) {
64+
this.cacheDir = newFolder("cache-dir");
65+
}
66+
return this.cacheDir;
67+
}
5968
}

0 commit comments

Comments
 (0)