forked from sashimono-dev/sashimono
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request sashimono-dev#13 from stuartwdouglas/reproducability
Make sure builds are reproducible
- Loading branch information
Showing
9 changed files
with
304 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
builder/src/main/java/dev/sashimono/builder/util/FileUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package dev.sashimono.builder.util; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.stream.Stream; | ||
|
||
public class FileUtil { | ||
public static void deleteRecursive(final java.nio.file.Path file) { | ||
try { | ||
if (Files.isDirectory(file)) { | ||
try (Stream<Path> files = Files.list(file)) { | ||
files.forEach(FileUtil::deleteRecursive); | ||
} | ||
} | ||
Files.delete(file); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
builder/src/test/java/dev/sashimono/builder/test/BuildExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package dev.sashimono.builder.test; | ||
|
||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
|
||
import org.junit.jupiter.api.extension.BeforeEachCallback; | ||
import org.junit.jupiter.api.extension.ExtensionContext; | ||
import org.junit.jupiter.api.extension.ParameterContext; | ||
import org.junit.jupiter.api.extension.ParameterResolutionException; | ||
import org.junit.jupiter.api.extension.ParameterResolver; | ||
import org.junit.jupiter.api.io.TempDirFactory; | ||
|
||
import dev.sashimono.builder.Sashimono; | ||
|
||
class BuildExtension implements BeforeEachCallback, ParameterResolver { | ||
|
||
Path tempDir; | ||
|
||
@Override | ||
public void beforeEach(ExtensionContext context) throws Exception { | ||
tempDir = TempDirFactory.Standard.INSTANCE.createTempDirectory(null, context); | ||
var ann = context.getRequiredTestMethod().getAnnotation(BuildTest.class); | ||
Path project = Paths.get(ann.value()); | ||
Sashimono.builder().setProjectRoot(project).setOutputDir(tempDir).build().buildProject(); | ||
} | ||
|
||
@Override | ||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) | ||
throws ParameterResolutionException { | ||
Class<?> type = parameterContext.getParameter().getType(); | ||
return type == BuildResult.class; | ||
} | ||
|
||
@Override | ||
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) | ||
throws ParameterResolutionException { | ||
return new BuildResult(tempDir); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
builder/src/test/java/dev/sashimono/builder/test/BuildResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package dev.sashimono.builder.test; | ||
|
||
import java.nio.file.Path; | ||
|
||
/** | ||
* The results of a build, currently just the output directory. | ||
* | ||
* @param output | ||
*/ | ||
public record BuildResult(Path output) { | ||
|
||
} |
24 changes: 24 additions & 0 deletions
24
builder/src/test/java/dev/sashimono/builder/test/BuildTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package dev.sashimono.builder.test; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import org.junit.jupiter.api.TestTemplate; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
|
||
/** | ||
* Runs a Sashimono build against the specified directory. | ||
* | ||
* The test is actually run twice and the results are compared to make sure the build is reproducible. | ||
* | ||
* The results can be injected via {@link BuildResult} | ||
*/ | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@ExtendWith(BuildTestExtension.class) | ||
@Target(ElementType.METHOD) | ||
@TestTemplate | ||
public @interface BuildTest { | ||
String value(); | ||
} |
58 changes: 58 additions & 0 deletions
58
builder/src/test/java/dev/sashimono/builder/test/BuildTestExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package dev.sashimono.builder.test; | ||
|
||
import static org.junit.platform.commons.util.AnnotationUtils.isAnnotated; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Stream; | ||
|
||
import org.junit.jupiter.api.extension.Extension; | ||
import org.junit.jupiter.api.extension.ExtensionContext; | ||
import org.junit.jupiter.api.extension.TestTemplateInvocationContext; | ||
import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; | ||
|
||
/** | ||
* Extension that builds a project multiple times and checks the result is reproducible. | ||
*/ | ||
public class BuildTestExtension implements TestTemplateInvocationContextProvider { | ||
|
||
@Override | ||
public boolean supportsTestTemplate(ExtensionContext context) { | ||
return isAnnotated(context.getTestMethod(), BuildTest.class); | ||
} | ||
|
||
@Override | ||
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) { | ||
Method testMethod = context.getRequiredTestMethod(); | ||
String displayName = context.getDisplayName(); | ||
BuildExtension first = new BuildExtension(); | ||
BuildExtension second = new BuildExtension(); | ||
List<TestTemplateInvocationContext> tests = new ArrayList<>(); | ||
tests.add(new BuildTestContext(displayName + " [First]", List.of(first))); | ||
tests.add(new BuildTestContext(displayName + " [Second]", List.of(second))); | ||
tests.add(new BuildTestContext(displayName + " [Reproducibility Check]", | ||
List.of(new ProjectCompareExtension(first, second)))); | ||
return tests.stream(); | ||
} | ||
|
||
class BuildTestContext implements TestTemplateInvocationContext { | ||
final String name; | ||
final List<Extension> extensions; | ||
|
||
BuildTestContext(String name, List<Extension> extensions) { | ||
this.name = name; | ||
this.extensions = extensions; | ||
} | ||
|
||
@Override | ||
public String getDisplayName(int invocationIndex) { | ||
return name; | ||
} | ||
|
||
@Override | ||
public List<Extension> getAdditionalExtensions() { | ||
return extensions; | ||
} | ||
} | ||
} |
Oops, something went wrong.