diff --git a/pom.xml b/pom.xml index 71f6616..86f4047 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.utplsql cli - 3.0.5-SNAPSHOT + 3.1.0-SNAPSHOT jar cli @@ -22,7 +22,7 @@ org.utplsql java-api - 3.0.5-SNAPSHOT + 3.1.0-SNAPSHOT compile diff --git a/src/main/java/org/utplsql/cli/Cli.java b/src/main/java/org/utplsql/cli/Cli.java index f2db442..9189367 100644 --- a/src/main/java/org/utplsql/cli/Cli.java +++ b/src/main/java/org/utplsql/cli/Cli.java @@ -19,6 +19,7 @@ public static void main(String[] args) { LocaleInitializer.initLocale(); JCommander jc = new JCommander(); + jc.setProgramName("utplsql"); // jc.addCommand(HELP_CMD, new HelpCommand()); RunCommand runCmd = new RunCommand(); jc.addCommand(RUN_CMD, runCmd); diff --git a/src/main/java/org/utplsql/cli/ReporterFactoryProvider.java b/src/main/java/org/utplsql/cli/ReporterFactoryProvider.java new file mode 100644 index 0000000..31fd314 --- /dev/null +++ b/src/main/java/org/utplsql/cli/ReporterFactoryProvider.java @@ -0,0 +1,20 @@ +package org.utplsql.cli; + +import org.utplsql.api.compatibility.CompatibilityProxy; +import org.utplsql.api.reporter.CoreReporters; +import org.utplsql.api.reporter.ReporterFactory; +import org.utplsql.cli.reporters.LocalAssetsCoverageHTMLReporter; + +/** A simple class to provide a ReporterFactory for the RunCommand + * + * @author pesse + */ +public class ReporterFactoryProvider { + + public static ReporterFactory createReporterFactory(CompatibilityProxy proxy ) { + ReporterFactory reporterFactory = ReporterFactory.createDefault(proxy); + reporterFactory.registerReporterFactoryMethod(CoreReporters.UT_COVERAGE_HTML_REPORTER.name(), LocalAssetsCoverageHTMLReporter::new, "Will copy all necessary assets to a folder named after the Output-File"); + + return reporterFactory; + } +} diff --git a/src/main/java/org/utplsql/cli/ReporterManager.java b/src/main/java/org/utplsql/cli/ReporterManager.java new file mode 100644 index 0000000..be44ea3 --- /dev/null +++ b/src/main/java/org/utplsql/cli/ReporterManager.java @@ -0,0 +1,118 @@ +package org.utplsql.cli; + +import org.utplsql.api.compatibility.CompatibilityProxy; +import org.utplsql.api.reporter.CoreReporters; +import org.utplsql.api.reporter.Reporter; +import org.utplsql.api.reporter.ReporterFactory; +import org.utplsql.cli.reporters.ReporterOptionsAware; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; + +class ReporterManager { + + private List reporterOptionsList; + + ReporterManager(List reporterParams ) { + initReporterOptionsList(reporterParams); + } + + private void initReporterOptionsList( List reporterParams ) { + reporterOptionsList = new ArrayList<>(); + ReporterOptions reporterOptions = null; + + for (String p : reporterParams) { + if (reporterOptions == null || !p.startsWith("-")) { + reporterOptions = new ReporterOptions(p); + reporterOptionsList.add(reporterOptions); + } + else + if (p.startsWith("-o=")) { + reporterOptions.setOutputFileName(p.substring(3)); + } + else + if (p.equals("-s")) { + reporterOptions.forceOutputToScreen(true); + } + } + + // If no reporter parameters were passed, use default reporter. + if (reporterOptionsList.isEmpty()) { + reporterOptionsList.add(new ReporterOptions(CoreReporters.UT_DOCUMENTATION_REPORTER.name())); + } + } + + + /** Initializes the reporters so we can use the id to gather results + * + * @param conn Active Connection + * @return List of Reporters + * @throws SQLException + */ + public List initReporters(Connection conn, ReporterFactory reporterFactory, CompatibilityProxy compatibilityProxy) throws SQLException + { + final List reporterList = new ArrayList<>(); + + for (ReporterOptions ro : reporterOptionsList) { + Reporter reporter = reporterFactory.createReporter(ro.getReporterName()); + + if ( reporter instanceof ReporterOptionsAware) + ((ReporterOptionsAware) reporter).setReporterOptions(ro); + + reporter.init(conn, compatibilityProxy, reporterFactory); + + ro.setReporterObj(reporter); + reporterList.add(reporter); + } + + return reporterList; + } + + /** Starts a separate thread for each Reporter to gather its results + * + * @param executorService + * @param ci + * @param returnCode + */ + public void startReporterGatherers(ExecutorService executorService, final ConnectionInfo ci, final int[] returnCode) + { + // TODO: Implement Init-check + // Gather each reporter results on a separate thread. + for (ReporterOptions ro : reporterOptionsList) { + executorService.submit(() -> { + List printStreams = new ArrayList<>(); + PrintStream fileOutStream = null; + + try (Connection conn = ci.getConnection()) { + if (ro.outputToScreen()) { + printStreams.add(System.out); + } + + if (ro.outputToFile()) { + fileOutStream = new PrintStream(new FileOutputStream(ro.getOutputFileName())); + printStreams.add(fileOutStream); + } + + ro.getReporterObj().getOutputBuffer().printAvailable(conn, printStreams); + } catch (SQLException | FileNotFoundException e) { + System.out.println(e.getMessage()); + returnCode[0] = Cli.DEFAULT_ERROR_CODE; + executorService.shutdownNow(); + } finally { + if (fileOutStream != null) + fileOutStream.close(); + } + }); + } + } + + public List getReporterOptionsList() { + return reporterOptionsList; + } +} diff --git a/src/main/java/org/utplsql/cli/RunCommand.java b/src/main/java/org/utplsql/cli/RunCommand.java index fbf5e3c..2251853 100644 --- a/src/main/java/org/utplsql/cli/RunCommand.java +++ b/src/main/java/org/utplsql/cli/RunCommand.java @@ -2,19 +2,17 @@ import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; -import org.utplsql.api.*; +import org.utplsql.api.FileMapperOptions; +import org.utplsql.api.KeyValuePair; +import org.utplsql.api.TestRunner; +import org.utplsql.api.Version; import org.utplsql.api.compatibility.CompatibilityProxy; import org.utplsql.api.exception.SomeTestsFailedException; -import org.utplsql.api.reporter.CoverageHTMLReporter; import org.utplsql.api.reporter.Reporter; import org.utplsql.api.reporter.ReporterFactory; import org.utplsql.cli.exception.DatabaseConnectionFailed; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.PrintStream; -import java.nio.file.Paths; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; @@ -100,6 +98,8 @@ public class RunCommand { private CompatibilityProxy compatibilityProxy; + private ReporterFactory reporterFactory; + private ReporterManager reporterManager; public ConnectionInfo getConnectionInfo() { return connectionInfoList.get(0); @@ -116,7 +116,6 @@ public int run() throws Exception { final ConnectionInfo ci = getConnectionInfo(); final List reporterList; - final List reporterOptionsList = getReporterOptionsList(); final List testPaths = getTestPaths(); final File baseDir = new File("").getAbsoluteFile(); @@ -154,8 +153,9 @@ public int run() throws Exception { // First of all do a compatibility check and fail-fast compatibilityProxy = checkFrameworkCompatibility(conn); + reporterFactory = ReporterFactoryProvider.createReporterFactory(compatibilityProxy); - reporterList = initReporters(conn, reporterOptionsList); + reporterList = getReporterManager().initReporters(conn, reporterFactory, compatibilityProxy); } catch (SQLException e) { if ( e.getErrorCode() == 1017 || e.getErrorCode() == 12514 ) { @@ -199,78 +199,15 @@ public int run() throws Exception { }); // Gather each reporter results on a separate thread. - startReporterGatherers(reporterOptionsList, executorService, ci, returnCode); + getReporterManager().startReporterGatherers(executorService, ci, returnCode); executorService.shutdown(); executorService.awaitTermination(60, TimeUnit.MINUTES); return returnCode[0]; } - /** Initializes the reporters so we can use the id to gather results - * - * @param conn Active Connection - * @param reporterOptionsList - * @return List of Reporters - * @throws SQLException - */ - private List initReporters( Connection conn, List reporterOptionsList ) throws SQLException - { - final List reporterList = new ArrayList<>(); - for (ReporterOptions ro : reporterOptionsList) { - Reporter reporter = ReporterFactory.createReporter(ro.getReporterName()); - // Quick-hack for CoverageHTML Reporter - if ( reporter instanceof CoverageHTMLReporter && ro.outputToFile() ) { - ((CoverageHTMLReporter)reporter).setAssetsPath(ro.getOutputFileName()+"_assets/"); - CoverageHTMLReporter.writeReportAssetsTo(Paths.get(ro.getOutputFileName()+"_assets/")); - } - - reporter.init(conn); - ro.setReporterObj(reporter); - reporterList.add(reporter); - } - - return reporterList; - } - - /** Starts a separate thread for each Reporter to gather its results - * - * @param reporterOptionsList - * @param executorService - * @param ci - * @param returnCode - */ - private void startReporterGatherers(List reporterOptionsList, ExecutorService executorService, final ConnectionInfo ci, final int[] returnCode) - { - // Gather each reporter results on a separate thread. - for (ReporterOptions ro : reporterOptionsList) { - executorService.submit(() -> { - List printStreams = new ArrayList<>(); - PrintStream fileOutStream = null; - - try (Connection conn = ci.getConnection()) { - if (ro.outputToScreen()) { - printStreams.add(System.out); - } - - if (ro.outputToFile()) { - fileOutStream = new PrintStream(new FileOutputStream(ro.getOutputFileName())); - printStreams.add(fileOutStream); - } - - new OutputBuffer(ro.getReporterObj()).printAvailable(conn, printStreams); - } catch (SQLException | FileNotFoundException e) { - System.out.println(e.getMessage()); - returnCode[0] = Cli.DEFAULT_ERROR_CODE; - executorService.shutdownNow(); - } finally { - if (fileOutStream != null) - fileOutStream.close(); - } - }); - } - } /** Returns FileMapperOptions for the first item of a given param list in a baseDir * @@ -289,33 +226,6 @@ private FileMapperOptions getFileMapperOptionsByParamListItem(List pathP return null; } - public List getReporterOptionsList() { - List reporterOptionsList = new ArrayList<>(); - ReporterOptions reporterOptions = null; - - for (String p : reporterParams) { - if (reporterOptions == null || !p.startsWith("-")) { - reporterOptions = new ReporterOptions(p); - reporterOptionsList.add(reporterOptions); - } - else - if (p.startsWith("-o=")) { - reporterOptions.setOutputFileName(p.substring(3)); - } - else - if (p.equals("-s")) { - reporterOptions.forceOutputToScreen(true); - } - } - - // If no reporter parameters were passed, use default reporter. - if (reporterOptionsList.isEmpty()) { - reporterOptionsList.add(new ReporterOptions(CustomTypes.UT_DOCUMENTATION_REPORTER)); - } - - return reporterOptionsList; - } - /** Checks whether cli is compatible with the database framework * * @param conn Active Connection @@ -393,4 +303,15 @@ public Version getDatabaseVersion() { return null; } + + private ReporterManager getReporterManager() { + if ( reporterManager == null ) + reporterManager = new ReporterManager(reporterParams); + + return reporterManager; + } + + public List getReporterOptionsList() { + return getReporterManager().getReporterOptionsList(); + } } diff --git a/src/main/java/org/utplsql/cli/reporters/LocalAssetsCoverageHTMLReporter.java b/src/main/java/org/utplsql/cli/reporters/LocalAssetsCoverageHTMLReporter.java new file mode 100644 index 0000000..a61d41a --- /dev/null +++ b/src/main/java/org/utplsql/cli/reporters/LocalAssetsCoverageHTMLReporter.java @@ -0,0 +1,52 @@ +package org.utplsql.cli.reporters; + +import org.utplsql.api.compatibility.CompatibilityProxy; +import org.utplsql.api.reporter.CoverageHTMLReporter; +import org.utplsql.api.reporter.Reporter; +import org.utplsql.api.reporter.ReporterFactory; +import org.utplsql.cli.ReporterOptions; + +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.SQLException; + +/** Simple replacement of the CoverageHTMLReporter which writes the necessary assets to a folder + * named after the Output File's name. + * + * @author pesse + */ +public class LocalAssetsCoverageHTMLReporter extends CoverageHTMLReporter implements ReporterOptionsAware { + + private ReporterOptions options; + + public LocalAssetsCoverageHTMLReporter(String selfType, Object[] attributes) { + super(selfType, attributes); + } + + @Override + public Reporter init(Connection con, CompatibilityProxy compatibilityProxy, ReporterFactory reporterFactory) throws SQLException { + super.init(con, compatibilityProxy, reporterFactory); + + if ( options != null && options.outputToFile() ) + writeReportAssetsTo(Paths.get(getAssetsPath())); + + return this; + } + + private void setAssetsPathFromOptions() { + if ( options != null && options.outputToFile() ) + setAssetsPath(options.getOutputFileName()+"_assets/"); + } + + @Override + public void setReporterOptions(ReporterOptions options) { + this.options = options; + setAssetsPathFromOptions(); + } + + @Override + protected void setAttributes(Object[] attributes) { + super.setAttributes(attributes); + setAssetsPathFromOptions(); + } +} diff --git a/src/main/java/org/utplsql/cli/reporters/ReporterOptionsAware.java b/src/main/java/org/utplsql/cli/reporters/ReporterOptionsAware.java new file mode 100644 index 0000000..a9c25b6 --- /dev/null +++ b/src/main/java/org/utplsql/cli/reporters/ReporterOptionsAware.java @@ -0,0 +1,11 @@ +package org.utplsql.cli.reporters; + +import org.utplsql.cli.ReporterOptions; + +/** Reporters implementing this interface will get their specific ReporterOptions before initialization + * + * @author pesse + */ +public interface ReporterOptionsAware { + void setReporterOptions(ReporterOptions options); +} diff --git a/src/test/java/org/utplsql/cli/RunCommandTest.java b/src/test/java/org/utplsql/cli/RunCommandTest.java index 775d506..ba6df7c 100644 --- a/src/test/java/org/utplsql/cli/RunCommandTest.java +++ b/src/test/java/org/utplsql/cli/RunCommandTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; import org.utplsql.api.CustomTypes; +import org.utplsql.api.reporter.CoreReporters; import java.util.List; @@ -19,7 +20,7 @@ public void reporterOptions_Default() { List reporterOptionsList = runCmd.getReporterOptionsList(); ReporterOptions reporterOptions1 = reporterOptionsList.get(0); - assertEquals(CustomTypes.UT_DOCUMENTATION_REPORTER, reporterOptions1.getReporterName()); + assertEquals(CoreReporters.UT_DOCUMENTATION_REPORTER.name(), reporterOptions1.getReporterName()); assertNull(reporterOptions1.getOutputFileName()); assertFalse(reporterOptions1.outputToFile()); assertTrue(reporterOptions1.outputToScreen()); @@ -32,7 +33,7 @@ public void reporterOptions_OneReporter() { List reporterOptionsList = runCmd.getReporterOptionsList(); ReporterOptions reporterOptions1 = reporterOptionsList.get(0); - assertEquals(CustomTypes.UT_DOCUMENTATION_REPORTER, reporterOptions1.getReporterName()); + assertEquals(CoreReporters.UT_DOCUMENTATION_REPORTER.name(), reporterOptions1.getReporterName()); assertEquals(reporterOptions1.getOutputFileName(), "output.txt"); assertTrue(reporterOptions1.outputToFile()); assertFalse(reporterOptions1.outputToScreen()); @@ -45,7 +46,7 @@ public void reporterOptions_OneReporterForceScreen() { List reporterOptionsList = runCmd.getReporterOptionsList(); ReporterOptions reporterOptions1 = reporterOptionsList.get(0); - assertEquals(CustomTypes.UT_DOCUMENTATION_REPORTER, reporterOptions1.getReporterName()); + assertEquals(CoreReporters.UT_DOCUMENTATION_REPORTER.name(), reporterOptions1.getReporterName()); assertEquals(reporterOptions1.getOutputFileName(), "output.txt"); assertTrue(reporterOptions1.outputToFile()); assertTrue(reporterOptions1.outputToScreen()); @@ -58,7 +59,7 @@ public void reporterOptions_OneReporterForceScreenInverse() { List reporterOptionsList = runCmd.getReporterOptionsList(); ReporterOptions reporterOptions1 = reporterOptionsList.get(0); - assertEquals(CustomTypes.UT_DOCUMENTATION_REPORTER, reporterOptions1.getReporterName()); + assertEquals(CoreReporters.UT_DOCUMENTATION_REPORTER.name(), reporterOptions1.getReporterName()); assertEquals(reporterOptions1.getOutputFileName(), "output.txt"); assertTrue(reporterOptions1.outputToFile()); assertTrue(reporterOptions1.outputToScreen()); @@ -73,13 +74,13 @@ public void reporterOptions_TwoReporters() { List reporterOptionsList = runCmd.getReporterOptionsList(); ReporterOptions reporterOptions1 = reporterOptionsList.get(0); - assertEquals(CustomTypes.UT_DOCUMENTATION_REPORTER, reporterOptions1.getReporterName()); + assertEquals(CoreReporters.UT_DOCUMENTATION_REPORTER.name(), reporterOptions1.getReporterName()); assertNull(reporterOptions1.getOutputFileName()); assertFalse(reporterOptions1.outputToFile()); assertTrue(reporterOptions1.outputToScreen()); ReporterOptions reporterOptions2 = reporterOptionsList.get(1); - assertEquals(CustomTypes.UT_COVERAGE_HTML_REPORTER, reporterOptions2.getReporterName()); + assertEquals(CoreReporters.UT_COVERAGE_HTML_REPORTER.name(), reporterOptions2.getReporterName()); assertEquals(reporterOptions2.getOutputFileName(), "coverage.html"); assertTrue(reporterOptions2.outputToFile()); assertTrue(reporterOptions2.outputToScreen());