Skip to content

Commit e9962c5

Browse files
authored
Make the npm steps roundtrip serializable (#2135)
2 parents 9e1255e + a80b71c commit e9962c5

13 files changed

+163
-188
lines changed

lib/src/main/java/com/diffplug/spotless/FileSignature.java

+4
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ public static Promised promise(Iterable<File> files) {
125125
return new Promised(MoreIterables.toNullHostileList(files), null);
126126
}
127127

128+
public static Promised promise(File file) {
129+
return new Promised(List.of(file), null);
130+
}
131+
128132
/** Returns all of the files in this signature, throwing an exception if there are more or less than 1 file. */
129133
public Collection<File> files() {
130134
return Collections.unmodifiableList(files);

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

+7-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2023 DiffPlug
2+
* Copyright 2016-2024 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.
@@ -16,37 +16,22 @@
1616
package com.diffplug.spotless.npm;
1717

1818
import java.io.File;
19-
import java.io.IOException;
2019
import java.io.Serializable;
2120

2221
import javax.annotation.Nullable;
2322

2423
import com.diffplug.spotless.FileSignature;
25-
import com.diffplug.spotless.ThrowingEx;
26-
27-
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2824

2925
public class EslintConfig implements Serializable {
30-
31-
private static final long serialVersionUID = -6196834313082791248L;
32-
33-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
34-
@Nullable
35-
private final transient File eslintConfigPath;
26+
private static final long serialVersionUID = 1L;
3627

3728
@SuppressWarnings("unused")
38-
private final FileSignature eslintConfigPathSignature;
39-
29+
private final FileSignature.Promised eslintConfigPathSignature;
4030
private final String eslintConfigJs;
4131

4232
public EslintConfig(@Nullable File eslintConfigPath, @Nullable String eslintConfigJs) {
43-
try {
44-
this.eslintConfigPath = eslintConfigPath;
45-
this.eslintConfigPathSignature = eslintConfigPath != null ? FileSignature.signAsList(this.eslintConfigPath) : FileSignature.signAsList();
46-
this.eslintConfigJs = eslintConfigJs;
47-
} catch (IOException e) {
48-
throw ThrowingEx.asRuntime(e);
49-
}
33+
this.eslintConfigPathSignature = eslintConfigPath == null ? null : FileSignature.promise(eslintConfigPath);
34+
this.eslintConfigJs = eslintConfigJs;
5035
}
5136

5237
public EslintConfig withEslintConfigPath(@Nullable File eslintConfigPath) {
@@ -55,7 +40,7 @@ public EslintConfig withEslintConfigPath(@Nullable File eslintConfigPath) {
5540

5641
@Nullable
5742
public File getEslintConfigPath() {
58-
return eslintConfigPath;
43+
return eslintConfigPathSignature == null ? null : eslintConfigPathSignature.get().getOnlyFile();
5944
}
6045

6146
@Nullable
@@ -64,7 +49,7 @@ public String getEslintConfigJs() {
6449
}
6550

6651
public EslintConfig verify() {
67-
if (eslintConfigPath == null && eslintConfigJs == null) {
52+
if (eslintConfigPathSignature == null && eslintConfigJs == null) {
6853
throw new IllegalArgumentException("ESLint must be configured using either a configFile or a configJs - but both are null.");
6954
}
7055
return this;

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

+9-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2023 DiffPlug
2+
* Copyright 2016-2024 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.
@@ -39,8 +39,6 @@
3939
import com.diffplug.spotless.ThrowingEx;
4040
import com.diffplug.spotless.npm.EslintRestService.FormatOption;
4141

42-
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
43-
4442
public class EslintFormatterStep {
4543

4644
private static final Logger logger = LoggerFactory.getLogger(EslintFormatterStep.class);
@@ -81,12 +79,10 @@ public static FormatterStep create(Map<String, String> devDependencies, Provisio
8179
}
8280

8381
private static class State extends NpmFormatterStepStateBase implements Serializable {
82+
private static final long serialVersionUID = 1L;
8483

85-
private static final long serialVersionUID = -539537027004745812L;
8684
private final EslintConfig origEslintConfig;
87-
88-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
89-
private transient EslintConfig eslintConfigInUse;
85+
private EslintConfig eslintConfigInUse;
9086

9187
State(String stepName, Map<String, String> devDependencies, File projectDir, File buildDir, File cacheDir, NpmPathResolver npmPathResolver, EslintConfig eslintConfig) throws IOException {
9288
super(stepName,
@@ -102,15 +98,14 @@ private static class State extends NpmFormatterStepStateBase implements Serializ
10298
projectDir,
10399
buildDir,
104100
cacheDir,
105-
npmPathResolver::resolveNpmExecutable,
106-
npmPathResolver::resolveNodeExecutable));
101+
npmPathResolver));
107102
this.origEslintConfig = requireNonNull(eslintConfig.verify());
108103
this.eslintConfigInUse = eslintConfig;
109104
}
110105

111106
@Override
112-
protected void prepareNodeServerLayout() throws IOException {
113-
super.prepareNodeServerLayout();
107+
protected void prepareNodeServerLayout(NodeServerLayout nodeServerLayout) throws IOException {
108+
super.prepareNodeServerLayout(nodeServerLayout);
114109
if (origEslintConfig.getEslintConfigPath() != null) {
115110
// If any config files are provided, we need to make sure they are at the same location as the node modules
116111
// as eslint will try to resolve plugin/config names relatively to the config file location and some
@@ -126,9 +121,10 @@ protected void prepareNodeServerLayout() throws IOException {
126121
public FormatterFunc createFormatterFunc() {
127122
try {
128123
logger.info("Creating formatter function (starting server)");
129-
ServerProcessInfo eslintRestServer = npmRunServer();
124+
Runtime runtime = toRuntime();
125+
ServerProcessInfo eslintRestServer = runtime.npmRunServer();
130126
EslintRestService restService = new EslintRestService(eslintRestServer.getBaseUrl());
131-
return Closeable.ofDangerous(() -> endServer(restService, eslintRestServer), new EslintFilePathPassingFormatterFunc(locations.projectDir(), nodeServerLayout.nodeModulesDir(), eslintConfigInUse, restService));
127+
return Closeable.ofDangerous(() -> endServer(restService, eslintRestServer), new EslintFilePathPassingFormatterFunc(locations.projectDir(), runtime.nodeServerLayout().nodeModulesDir(), eslintConfigInUse, restService));
132128
} catch (IOException e) {
133129
throw ThrowingEx.asRuntime(e);
134130
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 DiffPlug
2+
* Copyright 2022-2024 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.
@@ -16,43 +16,29 @@
1616
package com.diffplug.spotless.npm;
1717

1818
import java.io.File;
19-
import java.io.IOException;
2019

2120
import javax.annotation.Nullable;
2221

2322
import com.diffplug.spotless.FileSignature;
24-
import com.diffplug.spotless.ThrowingEx;
25-
26-
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2723

2824
public class EslintTypescriptConfig extends EslintConfig {
29-
30-
private static final long serialVersionUID = -126864670181617006L;
31-
32-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
33-
@Nullable
34-
private final transient File typescriptConfigPath;
25+
private static final long serialVersionUID = 2L;
3526

3627
@SuppressWarnings("unused")
37-
private final FileSignature typescriptConfigPathSignature;
28+
private final FileSignature.Promised typescriptConfigPathSignature;
3829

3930
public EslintTypescriptConfig(@Nullable File eslintConfigPath, @Nullable String eslintConfigJs, @Nullable File typescriptConfigPath) {
4031
super(eslintConfigPath, eslintConfigJs);
41-
try {
42-
this.typescriptConfigPath = typescriptConfigPath;
43-
this.typescriptConfigPathSignature = typescriptConfigPath != null ? FileSignature.signAsList(this.typescriptConfigPath) : FileSignature.signAsList();
44-
} catch (IOException e) {
45-
throw ThrowingEx.asRuntime(e);
46-
}
32+
this.typescriptConfigPathSignature = typescriptConfigPath != null ? FileSignature.promise(typescriptConfigPath) : null;
4733
}
4834

4935
@Override
5036
public EslintConfig withEslintConfigPath(@Nullable File eslintConfigPath) {
51-
return new EslintTypescriptConfig(eslintConfigPath, this.getEslintConfigJs(), this.typescriptConfigPath);
37+
return new EslintTypescriptConfig(eslintConfigPath, this.getEslintConfigJs(), getTypescriptConfigPath());
5238
}
5339

5440
@Nullable
5541
public File getTypescriptConfigPath() {
56-
return typescriptConfigPath;
42+
return typescriptConfigPathSignature == null ? null : this.typescriptConfigPathSignature.get().getOnlyFile();
5743
}
5844
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 DiffPlug
2+
* Copyright 2023-2024 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.
@@ -19,36 +19,23 @@
1919

2020
import java.io.File;
2121
import java.io.Serializable;
22-
import java.util.function.Supplier;
2322

2423
import javax.annotation.Nonnull;
2524

26-
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
27-
2825
class NpmFormatterStepLocations implements Serializable {
2926

3027
private static final long serialVersionUID = -1055408537924029969L;
31-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
32-
private final transient File projectDir;
33-
34-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
35-
private final transient File buildDir;
36-
37-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
38-
private final transient File cacheDir;
39-
40-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
41-
private final transient Supplier<File> npmExecutable;
4228

43-
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
44-
private final transient Supplier<File> nodeExecutable;
29+
private final File projectDir;
30+
private final File buildDir;
31+
private final File cacheDir;
32+
private final NpmPathResolver resolver;
4533

46-
public NpmFormatterStepLocations(@Nonnull File projectDir, @Nonnull File buildDir, File cacheDir, @Nonnull Supplier<File> npmExecutable, @Nonnull Supplier<File> nodeExecutable) {
34+
public NpmFormatterStepLocations(@Nonnull File projectDir, @Nonnull File buildDir, File cacheDir, @Nonnull NpmPathResolver resolver) {
4735
this.projectDir = requireNonNull(projectDir);
4836
this.buildDir = requireNonNull(buildDir);
4937
this.cacheDir = cacheDir;
50-
this.npmExecutable = requireNonNull(npmExecutable);
51-
this.nodeExecutable = requireNonNull(nodeExecutable);
38+
this.resolver = requireNonNull(resolver);
5239
}
5340

5441
public File projectDir() {
@@ -64,10 +51,10 @@ public File cacheDir() {
6451
}
6552

6653
public File npmExecutable() {
67-
return npmExecutable.get();
54+
return resolver.resolveNpmExecutable();
6855
}
6956

7057
public File nodeExecutable() {
71-
return nodeExecutable.get();
58+
return resolver.resolveNodeExecutable();
7259
}
7360
}

0 commit comments

Comments
 (0)