2
0
Fork 0
mirror of https://github.com/ethauvin/rife2.git synced 2025-04-30 18:48:13 -07:00

Compile operation javadocs and tests.

This commit is contained in:
Geert Bevin 2023-03-14 23:28:30 -04:00
parent 6daea9cb6e
commit 11dd257385
4 changed files with 394 additions and 19 deletions

View file

@ -11,6 +11,12 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Compiles main and test sources in the relevant build directories.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.5
*/
public class CompileOperation {
private File buildMainDirectory_;
private File buildTestDirectory_;
@ -19,8 +25,13 @@ public class CompileOperation {
private List<File> mainSourceFiles_ = new ArrayList<>();
private List<File> testSourceFiles_ = new ArrayList<>();
private List<String> compileOptions_ = new ArrayList<>();
private List<Diagnostic<? extends JavaFileObject>> diagnostics_ = Collections.emptyList();
private final List<Diagnostic<? extends JavaFileObject>> diagnostics_ = new ArrayList<>();
/**
* Performs the compile operation.
*
* @since 1.5
*/
public void execute()
throws Exception {
executeCreateBuildDirectories();
@ -28,53 +39,95 @@ public class CompileOperation {
executeBuildTestSources();
}
/**
* Part of the {@link #execute} operation, creates the build directories.
*
* @since 1.5
*/
public void executeCreateBuildDirectories() {
buildMainDirectory().mkdirs();
buildTestDirectory().mkdirs();
}
/**
* Part of the {@link #execute} operation, builds the main sources.
*
* @since 1.5
*/
public void executeBuildMainSources()
throws IOException {
executeBuildSources(
Project.joinPaths(compileMainClasspath()),
compileMainClasspath(),
mainSourceFiles(),
buildMainDirectory().getAbsolutePath());
buildMainDirectory());
}
/**
* Part of the {@link #execute} operation, builds the test sources.
*
* @since 1.5
*/
public void executeBuildTestSources()
throws IOException {
executeBuildSources(
Project.joinPaths(compileTestClasspath()),
compileTestClasspath(),
testSourceFiles(),
buildTestDirectory().getAbsolutePath());
buildTestDirectory());
}
public void executeBuildSources(String classpath, List<File> sources, String destination)
/**
* Part of the {@link #execute} operation, build sources to a destination.
*
* @param classpath the classpath list used for the compilation
* @param sources the source files to compile
* @param destination the destination directory
* @since 1.5
*/
public void executeBuildSources(List<String> classpath, List<File> sources, File destination)
throws IOException {
var compiler = ToolProvider.getSystemJavaCompiler();
try (var file_manager = compiler.getStandardFileManager(null, null, null)) {
var compilation_units = file_manager.getJavaFileObjectsFromFiles(sources);
var diagnostics = new DiagnosticCollector<JavaFileObject>();
var options = new ArrayList<>(List.of("-d", destination, "-cp", classpath));
var options = new ArrayList<>(List.of("-d", destination.getAbsolutePath(), "-cp", Project.joinPaths(classpath)));
options.addAll(compileOptions());
var compilation_task = compiler.getTask(null, file_manager, diagnostics, options, null, compilation_units);
if (!compilation_task.call()) {
diagnostics_ = diagnostics.getDiagnostics();
executeOutputDiagnostics(diagnostics);
diagnostics_.addAll(diagnostics.getDiagnostics());
executeProcessDiagnostics(diagnostics);
}
}
}
public void executeOutputDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
/**
* Part of the {@link #execute} operation, processes the compilation diagnostics.
*
* @param diagnostics the diagnostics to process
* @since 1.5
*/
public void executeProcessDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
for (var diagnostic : diagnostics.getDiagnostics()) {
System.err.print(executeFormatDiagnostic(diagnostic));
}
}
/**
* Part of the {@link #execute} operation, format a single diagnostic.
*
* @param diagnostic the diagnostic to format
* @return a string representation of the diagnostic
* @since 1.5
*/
public String executeFormatDiagnostic(Diagnostic<? extends JavaFileObject> diagnostic) {
return diagnostic.toString() + System.lineSeparator();
}
/**
* Configures a compile operation from a {@link Project}.
*
* @param project the project to configure the compile operation from
* @since 1.5
*/
public CompileOperation fromProject(Project project) {
return buildMainDirectory(project.buildMainDirectory())
.buildTestDirectory(project.buildTestDirectory())
@ -85,69 +138,186 @@ public class CompileOperation {
.compileOptions(project.compileJavacOptions());
}
/**
* Provides the main build destination directory.
*
* @param directory the directory to use for the main build destination
* @return this {@code CompileOperation} instance
* @since 1.5
*/
public CompileOperation buildMainDirectory(File directory) {
buildMainDirectory_ = directory;
return this;
}
/**
* Provides the test build destination directory.
*
* @param directory the directory to use for the test build destination
* @return this {@code CompileOperation} instance
* @since 1.5
*/
public CompileOperation buildTestDirectory(File directory) {
buildTestDirectory_ = directory;
return this;
}
/**
* Provides a list of entries for the main compilation classpath.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param classpath the list of classpath entries
* @return this {@code CompileOperation} instance
* @since 1.5
*/
public CompileOperation compileMainClasspath(List<String> classpath) {
compileMainClasspath_ = new ArrayList<>(classpath);
return this;
}
/**
* Provides a list of entries for the test compilation classpath.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param classpath the list of classpath entries
* @return this {@code CompileOperation} instance
* @since 1.5
*/
public CompileOperation compileTestClasspath(List<String> classpath) {
compileTestClasspath_ = new ArrayList<>(classpath);
return this;
}
/**
* Provides the list of main files that should be compiled.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param files the list of main files
* @return this {@code CompileOperation} instance
* @since 1.5
*/
public CompileOperation mainSourceFiles(List<File> files) {
mainSourceFiles_ = new ArrayList<>(files);
return this;
}
/**
* Provides the list of test files that should be compiled.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param files the list of test files
* @return this {@code CompileOperation} instance
* @since 1.5
*/
public CompileOperation testSourceFiles(List<File> files) {
testSourceFiles_ = new ArrayList<>(files);
return this;
}
/**
* Provides a list of compilation options to provide to the compiler.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param options the list of compilation options
* @return this {@code CompileOperation} instance
* @since 1.5
*/
public CompileOperation compileOptions(List<String> options) {
compileOptions_ = new ArrayList<>(options);
return this;
}
/**
* Retrieves the main build destination directory.
*
* @return the main build destination
* @since 1.5
*/
public File buildMainDirectory() {
return buildMainDirectory_;
}
/**
* Retrieves the test build destination directory.
*
* @return the test build destination
* @since 1.5
*/
public File buildTestDirectory() {
return buildTestDirectory_;
}
/**
* Retrieves the list of entries for the main compilation classpath.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the main compilation classpath list
* @since 1.5
*/
public List<String> compileMainClasspath() {
return compileMainClasspath_;
}
/**
* Retrieves the list of entries for the test compilation classpath.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the test compilation classpath list
* @since 1.5
*/
public List<String> compileTestClasspath() {
return compileTestClasspath_;
}
/**
* Retrieves the list of main files that should be compiled.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the list of main files to compile
* @since 1.5
*/
public List<File> mainSourceFiles() {
return mainSourceFiles_;
}
/**
* Retrieves the list of test files that should be compiled.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the list of test files to compile
* @since 1.5
*/
public List<File> testSourceFiles() {
return testSourceFiles_;
}
/**
* Retrieves the list of compilation options for the compiler.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the list of compiler options
* @since 1.5
*/
public List<String> compileOptions() {
return compileOptions_;
}
/**
* Retrieves the list of diagnostics resulting from the compilation.
*
* @return the list of compilation diagnostics
* @since 1.5
*/
public List<Diagnostic<? extends JavaFileObject>> diagnostics() {
return diagnostics_;
}

View file

@ -0,0 +1,211 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.operations;
import org.junit.jupiter.api.Test;
import rife.bld.Project;
import rife.bld.WebProject;
import rife.tools.FileUtils;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
public class TestCompileOperation {
@Test
void testInstantiation() {
var operation = new CompileOperation();
assertNull(operation.buildMainDirectory());
assertNull(operation.buildTestDirectory());
assertTrue(operation.compileMainClasspath().isEmpty());
assertTrue(operation.compileTestClasspath().isEmpty());
assertTrue(operation.mainSourceFiles().isEmpty());
assertTrue(operation.testSourceFiles().isEmpty());
assertTrue(operation.compileOptions().isEmpty());
assertTrue(operation.diagnostics().isEmpty());
}
@Test
void testExecute()
throws Exception {
var tmp = Files.createTempDirectory("test").toFile();
try {
var source_file1 = new File(tmp, "Source1.java");
var source_file2 = new File(tmp, "Source2.java");
var source_file3 = new File(tmp, "Source3.java");
FileUtils.writeString("""
public class Source1 {
public final String name_;
public Source1() {
name_ = "source1";
}
}
""", source_file1);
FileUtils.writeString("""
public class Source2 {
public final String name_;
public Source2(Source1 source1) {
name_ = source1.name_;
}
}
""", source_file2);
FileUtils.writeString("""
public class Source3 {
public final String name1_;
public final String name2_;
public Source3(Source1 source1, Source2 source2) {
name1_ = source1.name_;
name2_ = source2.name_;
}
}
""", source_file3);
var build_main = new File(tmp, "buildMain");
var build_test = new File(tmp, "buildTest");
var build_main_class1 = new File(build_main, "Source1.class");
var build_main_class2 = new File(build_main, "Source2.class");
var build_test_class3 = new File(build_test, "Source3.class");
assertFalse(build_main_class1.exists());
assertFalse(build_main_class2.exists());
assertFalse(build_test_class3.exists());
var operation = new CompileOperation()
.buildMainDirectory(build_main)
.buildTestDirectory(build_test)
.compileMainClasspath(List.of(build_main.getAbsolutePath()))
.compileTestClasspath(List.of(build_main.getAbsolutePath(), build_test.getAbsolutePath()))
.mainSourceFiles(List.of(source_file1, source_file2))
.testSourceFiles(List.of(source_file3));
operation.execute();
assertTrue(operation.diagnostics().isEmpty());
assertTrue(build_main_class1.exists());
assertTrue(build_main_class2.exists());
assertTrue(build_test_class3.exists());
} finally {
FileUtils.deleteDirectory(tmp);
}
}
@Test
void testFromProject()
throws Exception {
var tmp = Files.createTempDirectory("test").toFile();
try {
var create_operation = new CreateBlankOperation()
.workDirectory(tmp)
.packageName("tst")
.projectName("app")
.downloadDependencies(true);
create_operation.execute();
var compile_operation = new CompileOperation()
.fromProject(create_operation.project());
var main_app_class = new File(new File(compile_operation.buildMainDirectory(), "tst"), "App.class");
var test_app_class = new File(new File(compile_operation.buildTestDirectory(), "tst"), "AppTest.class");
assertFalse(main_app_class.exists());
assertFalse(test_app_class.exists());
compile_operation.execute();
assertTrue(compile_operation.diagnostics().isEmpty());
assertTrue(main_app_class.exists());
assertTrue(test_app_class.exists());
} finally {
FileUtils.deleteDirectory(tmp);
}
}
@Test
void testExecuteCompilationErrors()
throws Exception {
var tmp = Files.createTempDirectory("test").toFile();
try {
var source_file1 = new File(tmp, "Source1.java");
var source_file2 = new File(tmp, "Source2.java");
var source_file3 = new File(tmp, "Source3.java");
FileUtils.writeString("""
public class Source1 {
public final String;
public Source1() {
name_ = "source1";
}
}
""", source_file1);
FileUtils.writeString("""
public class Source2 {
public final String name_;
public Source2(Source1B source1) {
noName_ = source1.name_;
}
}
""", source_file2);
FileUtils.writeString("""
public class Source3 {
public final String name1_;
public final String name2_;
public Source3(Source1 source1, Source2 source2) {
name_ = source1.name_;
name_ = source2.name_;
}
}
""", source_file3);
var build_main = new File(tmp, "buildMain");
var build_test = new File(tmp, "buildTest");
var build_main_class1 = new File(build_main, "Source1.class");
var build_main_class2 = new File(build_main, "Source2.class");
var build_test_class3 = new File(build_test, "Source3.class");
assertFalse(build_main_class1.exists());
assertFalse(build_main_class2.exists());
assertFalse(build_test_class3.exists());
var operation = new CompileOperation() {
public void executeProcessDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
// don't output diagnostics
}
};
operation.buildMainDirectory(build_main)
.buildTestDirectory(build_test)
.compileMainClasspath(List.of(build_main.getAbsolutePath()))
.compileTestClasspath(List.of(build_main.getAbsolutePath(), build_test.getAbsolutePath()))
.mainSourceFiles(List.of(source_file1, source_file2))
.testSourceFiles(List.of(source_file3));
operation.execute();
assertEquals(5, operation.diagnostics().size());
var diagnostic1 = operation.diagnostics().get(0);
var diagnostic2 = operation.diagnostics().get(1);
var diagnostic3 = operation.diagnostics().get(2);
var diagnostic4 = operation.diagnostics().get(3);
var diagnostic5 = operation.diagnostics().get(4);
assertEquals("/Source1.java", diagnostic1.getSource().toUri().getPath().substring(tmp.getAbsolutePath().length()));
assertEquals("/Source3.java", diagnostic2.getSource().toUri().getPath().substring(tmp.getAbsolutePath().length()));
assertEquals("/Source3.java", diagnostic3.getSource().toUri().getPath().substring(tmp.getAbsolutePath().length()));
assertEquals("/Source3.java", diagnostic4.getSource().toUri().getPath().substring(tmp.getAbsolutePath().length()));
assertEquals("/Source3.java", diagnostic5.getSource().toUri().getPath().substring(tmp.getAbsolutePath().length()));
assertFalse(build_main_class1.exists());
assertFalse(build_main_class2.exists());
assertFalse(build_test_class3.exists());
} finally {
FileUtils.deleteDirectory(tmp);
}
}
}

View file

@ -238,7 +238,7 @@ public class TestCreateBlankOperation {
.collect(Collectors.joining("\n")));
var compile_operation = new CompileOperation() {
public void executeOutputDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
public void executeProcessDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
// don't output errors
}
};
@ -246,9 +246,6 @@ public class TestCreateBlankOperation {
compile_operation.execute();
var diagnostics = compile_operation.diagnostics();
assertEquals(4, diagnostics.size());
for (var diagnostic : diagnostics) {
assertEquals("/yourthing/src/test/java/org/stuff/YourthingTest.java", diagnostic.getSource().toUri().getPath().substring(tmp.getAbsolutePath().length()));
}
} finally {
FileUtils.deleteDirectory(tmp);
}

View file

@ -293,17 +293,14 @@ public class TestCreateRife2Operation {
.collect(Collectors.joining("\n")));
var compile_operation = new CompileOperation() {
public void executeOutputDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
public void executeProcessDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
// don't output errors
}
};
compile_operation.fromProject(create_operation.project());
compile_operation.execute();
var diagnostics = compile_operation.diagnostics();
assertEquals(9, diagnostics.size());
for (var diagnostic : diagnostics) {
assertEquals("/yourthing/src/test/java/org/stuff/YourthingTest.java", diagnostic.getSource().toUri().getPath().substring(tmp.getAbsolutePath().length()));
}
assertEquals(16, diagnostics.size());
} finally {
FileUtils.deleteDirectory(tmp);
}