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

Added run and test commands.

Refactoring of existing commands for customization and modularity.
This commit is contained in:
Geert Bevin 2023-03-12 11:05:00 -04:00
parent 162e536b4b
commit 7899a72bd5
9 changed files with 289 additions and 73 deletions

View file

@ -57,7 +57,7 @@ public class BuildExecutor {
var command = arguments_.remove(0);
try {
if (runCommand(command)) {
if (executeCommand(command)) {
break;
}
} catch (Exception e) {
@ -71,7 +71,7 @@ public class BuildExecutor {
}
}
public boolean runCommand(String command)
public boolean executeCommand(String command)
throws Exception {
var method = buildCommands().get(command);
if (method != null) {

View file

@ -56,10 +56,17 @@ public abstract class Project extends BuildExecutor {
}
@BuildCommand(help = RunCommand.Help.class)
public void run() {
public void run()
throws Exception {
new RunCommand(this).execute();
}
@BuildCommand(help = TestCommand.Help.class)
public void test()
throws Exception {
new TestCommand(this).execute();
}
/*
* Useful methods
*/
@ -108,6 +115,15 @@ public abstract class Project extends BuildExecutor {
return StringUtils.join(paths, File.pathSeparator);
}
@SafeVarargs
public static List<String> combinePaths(List<String>... paths) {
var result = new ArrayList<String>();
for (var p : paths) {
result.addAll(p);
}
return result;
}
/*
* Project directories
*/
@ -196,21 +212,55 @@ public abstract class Project extends BuildExecutor {
return new File(buildDirectory(), "test");
}
/*
* Process options
*/
public List<String> compileJavacOptions() {
return Collections.emptyList();
}
public String javaTool() {
return "java";
}
public List<String> runJavaOptions() {
return Collections.emptyList();
}
public List<String> testJavaOptions() {
return Collections.emptyList();
}
public String testToolMainClass() {
return "org.junit.platform.console.ConsoleLauncher";
}
public List<String> testToolOptions() {
var result = new ArrayList<String>();
result.add("--scan-classpath");
result.add("--exclude-engine=junit-platform-suite");
result.add("--exclude-engine=junit-vintage");
return result;
}
/*
* File collections
*/
private static final Pattern JAVA_FILE_PATTERN = Pattern.compile("^.*\\.java$");
public List<File> mainSourceFiles() {
// get all the main java sources
var src_main_java_dir_abs = srcMainJavaDirectory().getAbsoluteFile();
return FileUtils.getFileList(src_main_java_dir_abs, Pattern.compile("^.*\\.java$"), null)
return FileUtils.getFileList(src_main_java_dir_abs, JAVA_FILE_PATTERN, null)
.stream().map(file -> new File(src_main_java_dir_abs, file)).toList();
}
public List<File> testSourceFiles() {
// get all the test java sources
var src_test_java_dir_abs = srcTestJavaDirectory().getAbsoluteFile();
return FileUtils.getFileList(src_test_java_dir_abs, Pattern.compile("^.*\\.java$"), null)
return FileUtils.getFileList(src_test_java_dir_abs, JAVA_FILE_PATTERN, null)
.stream().map(file -> new File(src_test_java_dir_abs, file)).toList();
}
@ -218,28 +268,67 @@ public abstract class Project extends BuildExecutor {
* Project classpaths
*/
public List<String> compileClasspath() {
private static final Pattern JAR_FILE_PATTERN = Pattern.compile("^.*\\.jar$");
public List<String> compileClasspathJars() {
// detect the jar files in the compile lib directory
var lib_compile_dir_abs = libCompileDirectory().getAbsoluteFile();
var lib_compile_jar_files = FileUtils.getFileList(lib_compile_dir_abs, Pattern.compile("^.*\\.jar$"), null);
var dir_abs = libCompileDirectory().getAbsoluteFile();
var jar_files = FileUtils.getFileList(dir_abs, JAR_FILE_PATTERN, null);
// build the compilation classpath
var compile_classpath_paths = new ArrayList<>(lib_compile_jar_files.stream().map(file -> new File(lib_compile_dir_abs, file).getAbsolutePath()).toList());
compile_classpath_paths.add(0, buildMainDirectory().getAbsolutePath());
return new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file).getAbsolutePath()).toList());
}
return compile_classpath_paths;
public List<String> runtimeClasspathJars() {
// detect the jar files in the runtime lib directory
var dir_abs = libRuntimeDirectory().getAbsoluteFile();
var jar_files = FileUtils.getFileList(dir_abs, JAR_FILE_PATTERN, null);
// build the runtime classpath
return new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file).getAbsolutePath()).toList());
}
public List<String> standaloneClasspathJars() {
// detect the jar files in the standalone lib directory
var dir_abs = libStandaloneDirectory().getAbsoluteFile();
var jar_files = FileUtils.getFileList(dir_abs, JAR_FILE_PATTERN, null);
// build the standalone classpath
return new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file).getAbsolutePath()).toList());
}
public List<String> testClasspathJars() {
// detect the jar files in the test lib directory
var dir_abs = libTestDirectory().getAbsoluteFile();
var jar_files = FileUtils.getFileList(dir_abs, JAR_FILE_PATTERN, null);
// build the test classpath
return new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file).getAbsolutePath()).toList());
}
public List<String> compileMainClasspath() {
return compileClasspathJars();
}
public List<String> compileTestClasspath() {
var paths = Project.combinePaths(compileClasspathJars(), testClasspathJars());
paths.add(buildMainDirectory().getAbsolutePath());
return paths;
}
public List<String> runClasspath() {
var paths = Project.combinePaths(compileClasspathJars(), runtimeClasspathJars(), standaloneClasspathJars());
paths.add(srcMainResourcesTemplatesDirectory().getAbsolutePath());
paths.add(buildMainDirectory().getAbsolutePath());
return paths;
}
public List<String> testClasspath() {
// detect the jar files in the test lib directory
var lib_test_dir_abs = libTestDirectory().getAbsoluteFile();
var lib_test_jar_files = FileUtils.getFileList(lib_test_dir_abs, Pattern.compile("^.*\\.jar$"), null);
// build the test classpath
var test_classpath_paths = new ArrayList<>(lib_test_jar_files.stream().map(file -> new File(lib_test_dir_abs, file).getAbsolutePath()).toList());
test_classpath_paths.addAll(0, compileClasspath());
return test_classpath_paths;
var paths = Project.combinePaths(compileClasspathJars(), runtimeClasspathJars(), standaloneClasspathJars(), testClasspathJars());
paths.add(srcMainResourcesTemplatesDirectory().getAbsolutePath());
paths.add(buildMainDirectory().getAbsolutePath());
paths.add(buildTestDirectory().getAbsolutePath());
return paths;
}
public void start(String[] args) {

View file

@ -27,24 +27,37 @@ public class CleanCommand {
}
public void execute() {
cleanDistDirectory();
cleanMainDirectory();
cleanProjectDirectory();
cleanTestDirectory();
}
public void cleanDistDirectory() {
try {
FileUtils.deleteDirectory(project.buildDistDirectory());
} catch (FileUtilsErrorException e) {
// no-op
}
}
public void cleanMainDirectory() {
try {
FileUtils.deleteDirectory(project.buildMainDirectory());
} catch (FileUtilsErrorException e) {
// no-op
}
}
public void cleanProjectDirectory() {
try {
FileUtils.deleteDirectory(project.buildProjectDirectory());
} catch (FileUtilsErrorException e) {
// no-op
}
}
public void cleanTestDirectory() {
try {
FileUtils.deleteDirectory(project.buildTestDirectory());
} catch (FileUtilsErrorException e) {

View file

@ -39,65 +39,87 @@ public class CompileCommand {
project.buildProjectDirectory().mkdirs();
project.buildTestDirectory().mkdirs();
// compile both the main and the test java sources
var compiler = ToolProvider.getSystemJavaCompiler();
try (var file_manager = compiler.getStandardFileManager(null, null, null)) {
buildProjectSources(compiler, file_manager,
Project.joinPaths(project.compileClasspath()),
project.mainSourceFiles(),
project.buildMainDirectory().getAbsolutePath());
buildProjectSources(compiler, file_manager,
Project.joinPaths(project.testClasspath()),
project.testSourceFiles(),
project.buildTestDirectory().getAbsolutePath());
}
buildMainSources();
buildTestSources();
}
public void buildProjectSources(JavaCompiler compiler, StandardJavaFileManager fileManager, String classpath, List<File> sources, String destination)
public void buildMainSources()
throws IOException {
var compilation_units = fileManager.getJavaFileObjectsFromFiles(sources);
var diagnostics = new DiagnosticCollector<JavaFileObject>();
var options = List.of("-d", destination, "-cp", classpath);
var compilation_task = compiler.getTask(null, fileManager, diagnostics, options, null, compilation_units);
if (!compilation_task.call()) {
outputDiagnostics(diagnostics);
buildSources(
Project.joinPaths(project.compileMainClasspath()),
project.mainSourceFiles(),
project.buildMainDirectory().getAbsolutePath());
}
public void buildTestSources()
throws IOException {
buildSources(
Project.joinPaths(project.compileTestClasspath()),
project.testSourceFiles(),
project.buildTestDirectory().getAbsolutePath());
}
public List<String> compileOptions() {
return project.compileJavacOptions();
}
public void buildSources(String classpath, List<File> sources, String 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));
options.addAll(compileOptions());
var compilation_task = compiler.getTask(null, file_manager, diagnostics, options, null, compilation_units);
if (!compilation_task.call()) {
outputDiagnostics(diagnostics);
}
}
}
public void outputDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics)
throws IOException {
for (var diagnostic : diagnostics.getDiagnostics()) {
var source = diagnostic.getSource().getCharContent(true).toString();
var lines = StringUtils.split(source, "\n");
var message = diagnostic.getMessage(Locale.getDefault());
var message_lines = StringUtils.split(message, "\n");
var main_message = "";
var remaining_message = "";
int line_number = (int) diagnostic.getLineNumber() - 1;
int column_number = (int) diagnostic.getColumnNumber() - 1;
if (!message_lines.isEmpty()) {
main_message = message_lines.remove(0);
main_message = StringUtils.replace(main_message, "\r", "");
remaining_message = StringUtils.join(message_lines, "\n");
}
System.err.format("%s:%d: %s: %s%n",
diagnostic.getSource().toUri().getPath(),
diagnostic.getLineNumber(),
diagnostic.getKind().name().toLowerCase(),
main_message);
if (line_number >= 0 && line_number < lines.size()) {
var line = lines.get(line_number);
line = StringUtils.replace(line, "\r", "");
System.err.println(line);
if (column_number >= 0 && column_number < line.length()) {
System.err.println(StringUtils.repeat(" ", column_number) + "^");
}
}
if (!remaining_message.isEmpty()) {
System.err.println(remaining_message);
}
System.err.print(formatDiagnostic(diagnostic));
}
}
public String formatDiagnostic(Diagnostic<? extends JavaFileObject> diagnostic)
throws IOException {
var formatted = new StringBuilder();
var source = diagnostic.getSource().getCharContent(true).toString();
var lines = StringUtils.split(source, "\n");
var message = diagnostic.getMessage(Locale.getDefault());
var message_lines = StringUtils.split(message, "\n");
var main_message = "";
var remaining_message = "";
int line_number = (int) diagnostic.getLineNumber() - 1;
int column_number = (int) diagnostic.getColumnNumber() - 1;
if (!message_lines.isEmpty()) {
main_message = message_lines.remove(0);
main_message = StringUtils.replace(main_message, "\r", "");
remaining_message = StringUtils.join(message_lines, "\n");
}
formatted.append(String.format("%s:%d: %s: %s%n",
diagnostic.getSource().toUri().getPath(),
diagnostic.getLineNumber(),
diagnostic.getKind().name().toLowerCase(),
main_message));
if (line_number >= 0 && line_number < lines.size()) {
var line = lines.get(line_number);
line = StringUtils.replace(line, "\r", "");
formatted.append(line).append(System.lineSeparator());
if (column_number >= 0 && column_number < line.length()) {
formatted.append(StringUtils.repeat(" ", column_number)).append("^").append(System.lineSeparator());
}
}
if (!remaining_message.isEmpty()) {
formatted.append(remaining_message).append(System.lineSeparator());
}
return formatted.toString();
}
}

View file

@ -26,6 +26,13 @@ public class DownloadCommand {
}
public void execute() {
downloadCompileDependencies();
downloadRuntimeDependencies();
downloadStandaloneDependencies();
downloadTestDependencies();
}
public void downloadCompileDependencies() {
var compile_deps = project.dependencies.get(Scope.compile);
if (compile_deps != null) {
for (var dependency : compile_deps) {
@ -33,7 +40,9 @@ public class DownloadCommand {
.downloadTransitivelyIntoFolder(project.libCompileDirectory(), Scope.compile);
}
}
}
public void downloadRuntimeDependencies() {
var runtime_deps = project.dependencies.get(Scope.runtime);
if (runtime_deps != null) {
for (var dependency : runtime_deps) {
@ -41,7 +50,9 @@ public class DownloadCommand {
.downloadTransitivelyIntoFolder(project.libRuntimeDirectory(), Scope.runtime);
}
}
}
public void downloadStandaloneDependencies() {
var standalone_deps = project.dependencies.get(Scope.standalone);
if (standalone_deps != null) {
for (var dependency : standalone_deps) {
@ -49,7 +60,9 @@ public class DownloadCommand {
.downloadTransitivelyIntoFolder(project.libStandaloneDirectory(), Scope.compile, Scope.runtime);
}
}
}
public void downloadTestDependencies() {
var test_deps = project.dependencies.get(Scope.test);
if (test_deps != null) {
for (var dependency : test_deps) {

View file

@ -77,7 +77,6 @@ public class HelpCommand {
The following commands are supported.
""");
// test
// jar Creates an uberJar archive for a RIFE2 application
// war Creates a war archive for a RIFE2 application

View file

@ -8,6 +8,9 @@ import rife.bld.BuildHelp;
import rife.bld.Project;
import rife.tools.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class RunCommand {
public static class Help implements BuildHelp {
public String getDescription() {
@ -28,7 +31,26 @@ public class RunCommand {
this.project = project;
}
public void execute() {
public void execute()
throws Exception {
startProcess().waitFor();
}
public List<String> processCommandList() {
var args = new ArrayList<String>();
args.add(project.javaTool());
args.addAll(project.runJavaOptions());
args.add("-cp");
args.add(Project.joinPaths(project.runClasspath()));
args.add(project.mainClass);
return args;
}
public Process startProcess()
throws Exception {
var builder = new ProcessBuilder(processCommandList());
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
return builder.start();
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.commands;
import rife.bld.BuildHelp;
import rife.bld.Project;
import rife.tools.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class TestCommand {
public static class Help implements BuildHelp {
public String getDescription() {
return "Tests a RIFE2 application";
}
public String getHelp(String topic) {
return StringUtils.replace("""
Tests a RIFE2 application.
Usage : ${topic}""", "${topic}", topic);
}
}
public final Project project;
public TestCommand(Project project) {
this.project = project;
}
public void execute()
throws Exception {
startProcess().waitFor();
}
public List<String> processCommandList() {
var args = new ArrayList<String>();
args.add(project.javaTool());
args.addAll(project.testJavaOptions());
args.add("-cp");
args.add(Project.joinPaths(project.testClasspath()));
args.add(project.testToolMainClass());
args.addAll(project.testToolOptions());
return args;
}
public Process startProcess()
throws Exception {
var builder = new ProcessBuilder(processCommandList());
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
return builder.start();
}
}

View file

@ -22,7 +22,8 @@ public final class NewProjectInfo {
.include(dependency("com.uwyn.rife2", "rife2", Version.getVersionNumber()));
DEPENDENCIES.scope(test)
.include(dependency("org.jsoup", "jsoup", version(1,15,4)))
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,9,2)));
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,9,2)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,9,2)));
DEPENDENCIES.scope(standalone)
.include(dependency("org.eclipse.jetty", "jetty-server", version(11,0,14)))
.include(dependency("org.eclipse.jetty", "jetty-servlet", version(11,0,14)))