Skip to content

Commit

Permalink
Make GIT_ATTRIBUTES_FAST_ALLSAME faster.
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg committed Sep 28, 2023
1 parent 54c0af2 commit 809fb4b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,41 @@ public final class GitAttributesLineEndings {
// prevent direct instantiation
private GitAttributesLineEndings() {}

/**
* Creates a line-endings policy which matches {@link #create(File, Supplier)},
* which is much faster at the cost that every file under the policy
* is assumed to have the same line endings as the first file.
*/
public static LineEnding.Policy createFastAllSame(File projectDir, Supplier<Iterable<File>> toFormat) {
return new LazyAllTheSame(projectDir, toFormat);
}

static class LazyAllTheSame extends LazyForwardingEquality<String> implements LineEnding.Policy {
transient File projectDir;
transient Supplier<Iterable<File>> toFormat;

public LazyAllTheSame(File projectDir, Supplier<Iterable<File>> toFormat) {
this.projectDir = projectDir;
this.toFormat = toFormat;
}

@Override
protected String calculateState() throws Exception {
var files = toFormat.get().iterator();
if (files.hasNext()) {
Runtime runtime = new RuntimeInit(projectDir).atRuntime();
return runtime.getEndingFor(files.next());
} else {
return LineEnding.UNIX.str();
}
}

@Override
public String getEndingFor(File file) {
return state();
}
}

/**
* Creates a line-endings policy whose serialized state is relativized against projectDir,
* at the cost of eagerly evaluating the line-ending state of every target file when the
Expand Down
56 changes: 12 additions & 44 deletions lib/src/main/java/com/diffplug/spotless/LineEnding.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,52 +59,20 @@ public Policy createPolicy() {
public Policy createPolicy(File projectDir, Supplier<Iterable<File>> toFormat) {
Objects.requireNonNull(projectDir, "projectDir");
Objects.requireNonNull(toFormat, "toFormat");
if (this != GIT_ATTRIBUTES && this != GIT_ATTRIBUTES_FAST_ALLSAME) {
return createPolicy();
String gitAttributesMethod;
if (this == GIT_ATTRIBUTES) {
gitAttributesMethod = "create";
} else if (this == GIT_ATTRIBUTES_FAST_ALLSAME) {
gitAttributesMethod = "createFastAllSame";
} else {
if (gitAttributesPolicyCreator == null) {
try {
Class<?> clazz = Class.forName("com.diffplug.spotless.extra.GitAttributesLineEndings");
Method method = clazz.getMethod("create", File.class, Supplier.class);
gitAttributesPolicyCreator = (proj, target) -> ThrowingEx.get(() -> (Policy) method.invoke(null, proj, target));
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
throw new IllegalStateException("LineEnding.GIT_ATTRIBUTES requires the spotless-lib-extra library, but it is not on the classpath", e);
}
}
// gitAttributesPolicyCreator will always be nonnull at this point
Policy policy = gitAttributesPolicyCreator.apply(projectDir, toFormat);
if (this == GIT_ATTRIBUTES) {
return policy;
} else if (this == GIT_ATTRIBUTES_FAST_ALLSAME) {
return new LazyAllTheSame(policy, toFormat);
} else {
throw new IllegalArgumentException("Unknown " + this);
}
}
}

static class LazyAllTheSame extends LazyForwardingEquality<String> implements Policy {
private transient Policy policy;
private transient Supplier<Iterable<File>> toFormat;

public LazyAllTheSame(Policy policy, Supplier<Iterable<File>> toFormat) {
this.policy = policy;
this.toFormat = toFormat;
}

@Override
protected String calculateState() throws Exception {
var files = toFormat.get().iterator();
if (files.hasNext()) {
return policy.getEndingFor(files.next());
} else {
return LineEnding.UNIX.str();
}
return createPolicy();
}

@Override
public String getEndingFor(File file) {
return state();
try {
Class<?> clazz = Class.forName("com.diffplug.spotless.extra.GitAttributesLineEndings");
Method method = clazz.getMethod(gitAttributesMethod, File.class, Supplier.class);
return ThrowingEx.get(() -> (Policy) method.invoke(null, projectDir, toFormat));
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
throw new IllegalStateException("LineEnding.GIT_ATTRIBUTES requires the spotless-lib-extra library, but it is not on the classpath", e);
}
}

Expand Down

0 comments on commit 809fb4b

Please sign in to comment.