Skip to content

Commit 8c9c9f6

Browse files
committed
feat: Adds Gradle fallback indent style/size to TableTestFormatter
The fallback can be used when the `.editorconfig` is absent.
1 parent 23d52bf commit 8c9c9f6

5 files changed

Lines changed: 162 additions & 19 deletions

File tree

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

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,61 @@
2727

2828
/**
2929
* Formats {@code @TableTest} annotation tables in Java and Kotlin source files.
30-
* Configuration is read from {@code .editorconfig} files.
30+
* <p>
31+
* Configuration is read from {@code .editorconfig} files. When no editorconfig is found
32+
* or the lookup fails, the configured fallback indent style and size are used.
33+
* If no fallback is configured, defaults matching {@code Config.SPACES_4} and
34+
* {@code Config.NO_INDENT} are applied.
3135
*/
3236
public final class TableTestFormatterStep implements Serializable {
3337
@Serial
34-
private static final long serialVersionUID = 1L;
38+
private static final long serialVersionUID = 2L;
3539
private static final String NAME = "tableTestFormatter";
3640
private static final String MAVEN_COORDINATE = "org.tabletest:tabletest-formatter-core:";
3741
private static final String DEFAULT_VERSION = "1.1.1";
3842

43+
/** Default fallback indent style ({@code "space"}) for Java/Kotlin files. */
44+
public static final String DEFAULT_INDENT_STYLE = "space";
45+
/** Default fallback indent size ({@code 4}) for Java/Kotlin files, matching {@code Config.SPACES_4}. */
46+
public static final int DEFAULT_INDENT_SIZE = 4;
47+
3948
private final JarState.Promised jarState;
4049
private final String version;
50+
private final String indentStyle;
51+
private final int indentSize;
4152

42-
private TableTestFormatterStep(JarState.Promised jarState, String version) {
53+
private TableTestFormatterStep(JarState.Promised jarState, String version, String indentStyle, int indentSize) {
4354
this.jarState = jarState;
4455
this.version = version;
56+
this.indentStyle = validateIndentStyle(indentStyle);
57+
this.indentSize = validateIndentSize(indentSize);
4558
}
4659

47-
/** Creates a step which formats {@code @TableTest} tables using the default version. */
60+
/** Creates a step which formats {@code @TableTest} tables using the default version and indent config. */
4861
public static FormatterStep create(Provisioner provisioner) {
4962
return create(defaultVersion(), provisioner);
5063
}
5164

52-
/** Creates a step which formats {@code @TableTest} tables using the given version. */
65+
/** Creates a step which formats {@code @TableTest} tables using the given version and default indent config. */
5366
public static FormatterStep create(String version, Provisioner provisioner) {
67+
return create(version, provisioner, DEFAULT_INDENT_STYLE, DEFAULT_INDENT_SIZE);
68+
}
69+
70+
/**
71+
* Creates a step which formats {@code @TableTest} tables using the given version and fallback indent config.
72+
* <p>
73+
* The fallback config is used when no {@code .editorconfig} is found or the lookup fails.
74+
*
75+
* @param version the tabletest-formatter-core version
76+
* @param provisioner the jar provisioner
77+
* @param indentStyle fallback indent style: {@code "space"} or {@code "tab"} (case-insensitive)
78+
* @param indentSize fallback indent size (must be &gt;= 0)
79+
*/
80+
public static FormatterStep create(String version, Provisioner provisioner, String indentStyle, int indentSize) {
5481
Objects.requireNonNull(version, "version");
5582
Objects.requireNonNull(provisioner, "provisioner");
5683
return FormatterStep.create(NAME,
57-
new TableTestFormatterStep(JarState.promise(() -> JarState.from(MAVEN_COORDINATE + version, provisioner)), version),
84+
new TableTestFormatterStep(JarState.promise(() -> JarState.from(MAVEN_COORDINATE + version, provisioner)), version, indentStyle, indentSize),
5885
TableTestFormatterStep::equalityState,
5986
State::createFormat);
6087
}
@@ -65,26 +92,46 @@ public static String defaultVersion() {
6592
}
6693

6794
private State equalityState() {
68-
return new State(jarState.get(), version);
95+
return new State(jarState.get(), version, indentStyle, indentSize);
96+
}
97+
98+
public static String validateIndentStyle(String indentStyle) {
99+
Objects.requireNonNull(indentStyle, "indentStyle");
100+
String lower = indentStyle.toLowerCase();
101+
if (!lower.equals("space") && !lower.equals("tab")) {
102+
throw new IllegalArgumentException("indentStyle must be 'space' or 'tab', got: " + indentStyle);
103+
}
104+
return lower;
105+
}
106+
107+
public static int validateIndentSize(int indentSize) {
108+
if (indentSize < 0) {
109+
throw new IllegalArgumentException("indentSize must be >= 0, got: " + indentSize);
110+
}
111+
return indentSize;
69112
}
70113

71114
private static final class State implements Serializable {
72115
@Serial
73-
private static final long serialVersionUID = 1L;
116+
private static final long serialVersionUID = 2L;
74117

75118
private final JarState jarState;
76119
private final String version;
120+
private final String indentStyle;
121+
private final int indentSize;
77122

78-
State(JarState jarState, String version) {
123+
State(JarState jarState, String version, String indentStyle, int indentSize) {
79124
this.jarState = jarState;
80125
this.version = version;
126+
this.indentStyle = indentStyle;
127+
this.indentSize = indentSize;
81128
}
82129

83130
FormatterFunc createFormat() throws Exception {
84131
ClassLoader classLoader = jarState.getClassLoader();
85132
Class<?> formatterClazz = classLoader.loadClass("com.diffplug.spotless.glue.java.TableTestFormatterFunc");
86-
Constructor<?> constructor = formatterClazz.getConstructor();
87-
return (FormatterFunc.NeedsFile) constructor.newInstance();
133+
Constructor<?> constructor = formatterClazz.getConstructor(String.class, int.class);
134+
return (FormatterFunc.NeedsFile) constructor.newInstance(indentStyle, indentSize);
88135
}
89136
}
90137
}

lib/src/tableTestFormatter/java/com/diffplug/spotless/glue/java/TableTestFormatterFunc.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,53 @@
1919

2020
import org.tabletest.formatter.config.Config;
2121
import org.tabletest.formatter.config.EditorConfigProvider;
22+
import org.tabletest.formatter.config.IndentStyle;
2223
import org.tabletest.formatter.core.SourceFileFormatter;
2324
import org.tabletest.formatter.core.TableTestFormatter;
2425

2526
import com.diffplug.spotless.FormatterFunc;
2627

2728
/**
2829
* Formats {@code @TableTest} annotation tables in Java, Kotlin, and standalone {@code .table} files.
30+
* <p>
31+
* For Java/Kotlin files, the indent config priority is:
32+
* <ol>
33+
* <li>Settings from {@code .editorconfig}</li>
34+
* <li>Configured fallback ({@code indentStyle}/{@code indentSize} constructor parameters)</li>
35+
* <li>Built-in default: {@code Config.SPACES_4}</li>
36+
* </ol>
37+
* For {@code .table} files, {@code Config.NO_INDENT} is always used.
2938
*/
3039
public class TableTestFormatterFunc implements FormatterFunc.NeedsFile {
3140

3241
private final EditorConfigProvider CONFIG_PROVIDER = new EditorConfigProvider();
42+
private final Config sourceFallbackConfig;
3343

3444
private final SourceFileFormatter sourceFormatter = new SourceFileFormatter();
3545
private final TableTestFormatter tableFormatter = new TableTestFormatter();
3646

47+
/** Creates a formatter using the built-in default fallback ({@code Config.SPACES_4}). */
48+
public TableTestFormatterFunc() {
49+
this.sourceFallbackConfig = Config.SPACES_4;
50+
}
51+
52+
/**
53+
* Creates a formatter with a configured fallback indent style and size for Java/Kotlin files.
54+
* Used when {@code .editorconfig} is absent or the lookup fails.
55+
*
56+
* @param indentStyle {@code "space"} or {@code "tab"} (case-insensitive)
57+
* @param indentSize indent size (&gt;= 0)
58+
*/
59+
public TableTestFormatterFunc(String indentStyle, int indentSize) {
60+
this.sourceFallbackConfig = new Config(IndentStyle.valueOf(indentStyle.toUpperCase()), indentSize);
61+
}
62+
3763
@Override
3864
public String applyWithFile(String unix, File file) throws Exception {
3965
String fileName = file.getName();
4066

4167
if (fileName.endsWith(".java") || fileName.endsWith(".kt")) {
42-
Config config = CONFIG_PROVIDER.lookupConfig(file.toPath(), Config.SPACES_4);
68+
Config config = CONFIG_PROVIDER.lookupConfig(file.toPath(), sourceFallbackConfig);
4369
String formatted = sourceFormatter.format(unix, config);
4470
return formatted.equals(unix) ? unix : formatted;
4571
}

plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TableTestExtension.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,37 @@ public TableTestFormatterConfig tableTestFormatter(String version) {
4646

4747
public class TableTestFormatterConfig {
4848
private final String version;
49+
private String indentStyle = TableTestFormatterStep.DEFAULT_INDENT_STYLE;
50+
private int indentSize = TableTestFormatterStep.DEFAULT_INDENT_SIZE;
4951

5052
TableTestFormatterConfig(String version) {
5153
this.version = version;
5254
addStep(createStep());
5355
}
5456

57+
/**
58+
* Sets the fallback indent style used when no {@code .editorconfig} is found.
59+
* Must be {@code "space"} or {@code "tab"} (case-insensitive).
60+
* Defaults to {@code "space"}.
61+
*/
62+
public TableTestFormatterConfig withIndentStyle(String indentStyle) {
63+
this.indentStyle = TableTestFormatterStep.validateIndentStyle(indentStyle);
64+
replaceStep(createStep());
65+
return this;
66+
}
67+
68+
/**
69+
* Sets the fallback indent size used when no {@code .editorconfig} is found.
70+
* Must be &gt;= 0. Defaults to {@code 4}.
71+
*/
72+
public TableTestFormatterConfig withIndentSize(int indentSize) {
73+
this.indentSize = TableTestFormatterStep.validateIndentSize(indentSize);
74+
replaceStep(createStep());
75+
return this;
76+
}
77+
5578
private FormatterStep createStep() {
56-
return TableTestFormatterStep.create(version, provisioner());
79+
return TableTestFormatterStep.create(version, provisioner(), indentStyle, indentSize);
5780
}
5881
}
5982
}

plugin-maven/src/main/java/com/diffplug/spotless/maven/java/TableTestFormatter.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,37 @@
2323
import com.diffplug.spotless.maven.FormatterStepFactory;
2424

2525
/**
26-
* Formats {@code @TableTest} annotation tables. Configuration is read from {@code .editorconfig} files.
26+
* Formats {@code @TableTest} annotation tables. Configuration is read from {@code .editorconfig} files,
27+
* falling back to the configured {@code indentStyle} and {@code indentSize} when no editorconfig is found.
2728
*/
2829
public class TableTestFormatter implements FormatterStepFactory {
2930

3031
@Parameter
3132
private String version;
3233

34+
/**
35+
* Fallback indent style when no {@code .editorconfig} is found: {@code space} or {@code tab}.
36+
* Defaults to {@code space}.
37+
*/
38+
@Parameter
39+
private String indentStyle;
40+
41+
/**
42+
* Fallback indent size when no {@code .editorconfig} is found. Must be &gt;= 0.
43+
* Defaults to {@code 4}.
44+
*/
45+
@Parameter
46+
private Integer indentSize;
47+
3348
@Override
3449
public FormatterStep newFormatterStep(FormatterStepConfig config) {
35-
String version = this.version != null ? this.version : TableTestFormatterStep.defaultVersion();
36-
return TableTestFormatterStep.create(version, config.getProvisioner());
50+
String resolvedVersion = this.version != null ? this.version : TableTestFormatterStep.defaultVersion();
51+
String resolvedStyle = this.indentStyle != null
52+
? TableTestFormatterStep.validateIndentStyle(this.indentStyle)
53+
: TableTestFormatterStep.DEFAULT_INDENT_STYLE;
54+
int resolvedSize = this.indentSize != null
55+
? TableTestFormatterStep.validateIndentSize(this.indentSize)
56+
: TableTestFormatterStep.DEFAULT_INDENT_SIZE;
57+
return TableTestFormatterStep.create(resolvedVersion, config.getProvisioner(), resolvedStyle, resolvedSize);
3758
}
3859
}

testlib/src/test/java/com/diffplug/spotless/java/TableTestFormatterStepTest.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,50 @@ void editorConfigChangesAreHonored() {
7474
}
7575
}
7676

77+
@Test
78+
void behaviorWithConfiguredFallback() {
79+
// When no .editorconfig is present, the configured indentSize is used as the fallback
80+
// instead of the built-in default (Config.SPACES_4 = 4 spaces).
81+
// Configuring indentSize=2 should produce the same output as when editorconfig sets
82+
// indent_size=2.
83+
FormatterStep step = TableTestFormatterStep.create(VERSION, TestProvisioner.mavenCentral(), "space", 2);
84+
try (StepHarnessWithFile harness = StepHarnessWithFile.forStep(this, step)) {
85+
harness.testResource("CalculatorTest.java",
86+
"java/tableTestFormatter/JavaCodeUnformatted.test",
87+
"java/tableTestFormatter/JavaCodeFormattedWith2SpaceIndent.test");
88+
}
89+
}
90+
7791
@Test
7892
void equality() {
7993
new SerializableEqualityTester() {
8094
String version = VERSION;
95+
String indentStyle = TableTestFormatterStep.DEFAULT_INDENT_STYLE;
96+
int indentSize = TableTestFormatterStep.DEFAULT_INDENT_SIZE;
8197

8298
@Override
8399
protected void setupTest(API api) {
84-
// same version == same
100+
// same version + defaults == same
85101
api.areDifferentThan();
86102

87-
// change the version, and it's different
103+
// change the version
88104
version = "1.0.0";
89105
api.areDifferentThan();
106+
107+
// restore version, change indent size
108+
version = VERSION;
109+
indentSize = 2;
110+
api.areDifferentThan();
111+
112+
// change indent style
113+
indentSize = TableTestFormatterStep.DEFAULT_INDENT_SIZE;
114+
indentStyle = "tab";
115+
api.areDifferentThan();
90116
}
91117

92118
@Override
93119
protected FormatterStep create() {
94-
return TableTestFormatterStep.create(version, TestProvisioner.mavenCentral());
120+
return TableTestFormatterStep.create(version, TestProvisioner.mavenCentral(), indentStyle, indentSize);
95121
}
96122
}.testEquals();
97123
}

0 commit comments

Comments
 (0)