Skip to content

Commit

Permalink
Use UUID for indexers with names that exceed the file name length.
Browse files Browse the repository at this point in the history
Fixes #4106.
  • Loading branch information
sjudd committed Mar 27, 2020
1 parent cbbb254 commit 7cc865a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;

Expand Down Expand Up @@ -46,6 +47,7 @@
*/
final class IndexerGenerator {
private static final String INDEXER_NAME_PREFIX = "GlideIndexer_";
private static final int MAXIMUM_FILE_NAME_LENGTH = 255;
private final ProcessorUtil processorUtil;

IndexerGenerator(ProcessorUtil processorUtil) {
Expand Down Expand Up @@ -79,7 +81,7 @@ TypeSpec generate(List<TypeElement> types) {
}
}

private static TypeSpec generate(
private TypeSpec generate(
List<TypeElement> libraryModules, Class<? extends Annotation> annotation) {
AnnotationSpec.Builder annotationBuilder = AnnotationSpec.builder(Index.class);

Expand All @@ -88,15 +90,25 @@ private static TypeSpec generate(
annotationBuilder.addMember(value, "$S", ClassName.get(childModule).toString());
}

StringBuilder indexerName =
StringBuilder indexerNameBuilder =
new StringBuilder(INDEXER_NAME_PREFIX + annotation.getSimpleName() + "_");
for (TypeElement element : libraryModules) {
indexerName.append(element.getQualifiedName().toString().replace(".", "_"));
indexerName.append("_");
indexerNameBuilder.append(element.getQualifiedName().toString().replace(".", "_"));
indexerNameBuilder.append("_");
}
indexerNameBuilder =
new StringBuilder(indexerNameBuilder.substring(0, indexerNameBuilder.length() - 1));
String indexerName = indexerNameBuilder.toString();
// If the indexer name has too many packages/modules, it can exceed the file name length
// allowed by the file system, which can break compilation. To avoid that, fall back to a
// deterministic UUID.
if (indexerName.length() >= (MAXIMUM_FILE_NAME_LENGTH - INDEXER_NAME_PREFIX.length())) {
indexerName =
INDEXER_NAME_PREFIX
+ UUID.nameUUIDFromBytes(indexerName.getBytes()).toString().replace("-", "_");
}
indexerName = new StringBuilder(indexerName.substring(0, indexerName.length() - 1));

return TypeSpec.classBuilder(indexerName.toString())
return TypeSpec.classBuilder(indexerName)
.addAnnotation(annotationBuilder.build())
.addModifiers(Modifier.PUBLIC)
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.bumptech.glide.annotation.compiler;

import static com.google.testing.compile.Compiler.javac;

import com.bumptech.glide.annotation.compiler.test.CompilationProvider;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.CompilationSubject;
import com.google.testing.compile.JavaFileObjects;
import java.io.File;
import java.io.IOException;
import javax.tools.JavaFileObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
* Makes sure that we can handle indexers based on long package or file names, or many modules.
*
* <p>See #4106.
*/
@RunWith(JUnit4.class)
public class OverlyLongFileNameTest implements CompilationProvider {
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
private Compilation compilation;
private static final String FILE_NAME_LONGER_THAN_255_CHARS =
"SomeReallyReallyRidiculouslyLongFileNameOrPackageNameIGuessThatExceedsTwoHundredAndFiftyFive"
+ "CharactersThoughThatsOnlyAroundOneHundredCharactersWhichMeansINeedToKeepTypingToGetTo"
+ "TwoHundredAndFiftyFiveSomehowThankfullyOnlyLikeFiftyToGoNowMaybeButNotQuiteYet"
+ "SomewhereAroundNowIsProbablyGood";

@Before
public void setUp() {
compilation =
javac()
.withProcessors(new GlideAnnotationProcessor())
.compile(
JavaFileObjects.forSourceLines(
FILE_NAME_LONGER_THAN_255_CHARS,
"package com.bumptech.glide.test;",
"import com.bumptech.glide.annotation.GlideModule;",
"import com.bumptech.glide.module.LibraryGlideModule;",
"@GlideModule",
"public final class "
+ FILE_NAME_LONGER_THAN_255_CHARS
+ " extends LibraryGlideModule {}"));
}

@Test
public void compilingLongClassAndOrPackageNameShouldSucceed() throws IOException {
CompilationSubject.assertThat(compilation).succeededWithoutWarnings();
for (JavaFileObject file : compilation.generatedFiles()) {
temporaryFolder.create();
String actualFileName = new File(file.getName()).getName();
if (!actualFileName.startsWith(FILE_NAME_LONGER_THAN_255_CHARS)) {
try {
temporaryFolder.newFile(actualFileName).createNewFile();
} catch (IOException e) {
throw new RuntimeException("Failed to create: " + actualFileName, e);
}
}
}
}

@Override
public Compilation getCompilation() {
return compilation;
}
}

0 comments on commit 7cc865a

Please sign in to comment.