From 3498dc8ceec0250b059153b1f4555e16bbb1b4ef Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 20 Nov 2023 15:00:58 +0100 Subject: [PATCH 1/4] Add links to flux-commands.md (#488) The tsv to enrich the flux-commands.md is taken from the repo metafacture/metafacture-documentation. --- .../org/metafacture/flux/HelpPrinter.java | 84 ++++++++++++++----- .../metafacture/flux/parser/FluxProgramm.java | 5 +- .../metafacture/flux/FluxProgrammTest.java | 8 +- 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java index 045a81c4..c1494a66 100644 --- a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java +++ b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java @@ -26,24 +26,34 @@ import org.metafacture.framework.annotations.Out; import org.metafacture.framework.annotations.ReturnsAvailableArguments; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** - * Prints Flux help for a given {@link ObjectFactory} + * Prints Flux help for a given {@link ObjectFactory}. + * If the file at {@value #PATH_TO_EXAMPLES} exists it's taken to insert links to examples and to the source code. * * @author Markus Michael Geipel */ public final class HelpPrinter { + private static final String PATH_TO_EXAMPLES = "../metafacture-documentation/linksAndExamples.tsv"; + private static final Map EXAMPLES_MAP = new HashMap<>(); + private static final int COLUMN_TO_PG_EXAMPLE = 3; + private static final int REQUIRED_COLUMNS_OF_EXAMPLE = 2; private HelpPrinter() { // no instances @@ -55,8 +65,9 @@ private HelpPrinter() { * @param args unused * * @see #print + * @throws IOException when an I/O error occurs */ - public static void main(final String[] args) { + public static void main(final String[] args) throws IOException { FluxProgramm.printHelp(System.out); } @@ -66,9 +77,10 @@ public static void main(final String[] args) { * * @param factory the ObjectFactory * @param out the PrintStream to print to + * @throws IOException when an I/O error occurs */ public static void print(final ObjectFactory factory, - final PrintStream out) { + final PrintStream out) throws IOException { out.println("Welcome to Metafacture"); out.println("======================"); out.println(); @@ -77,9 +89,9 @@ public static void print(final ObjectFactory factory, out.println("\nUsage:\tflux FLOW_FILE [VARNAME=VALUE ...]\n"); out.println("Available flux commands:\n"); - final List keyWords = new ArrayList(); - keyWords.addAll(factory.keySet()); + final List keyWords = new ArrayList<>(factory.keySet()); Collections.sort(keyWords); + loadExamples(); for (final String name : keyWords) { describe(name, factory, out); } @@ -111,8 +123,42 @@ private static void describe(final String name, final ObjectFactory facto out.println("- arguments:\t" + arguments); } - final Map attributes = configurableClass.getSetters(); + printAttributes(out, configurableClass, configurableClass.getSetters()); + printSignature(out, moduleClass); + final String[] examplesEntry = EXAMPLES_MAP.get(name); + if (!EXAMPLES_MAP.isEmpty() && (examplesEntry == null || examplesEntry.length < REQUIRED_COLUMNS_OF_EXAMPLE)) { + throw new MetafactureException( + "Failed to load build infos: tsv with links hasn't at least " + REQUIRED_COLUMNS_OF_EXAMPLE + + " for the entry '" + name + "'"); + } + if (examplesEntry != null && examplesEntry.length == COLUMN_TO_PG_EXAMPLE) { + out.println("- [example in Playground]" + "(" + examplesEntry[COLUMN_TO_PG_EXAMPLE - 1] + ")"); + } + if (examplesEntry != null) { + out.println("- java class:\t[" + moduleClass.getCanonicalName() + "](" + examplesEntry[1] + ")"); + } + else { + out.println("- java class:\t" + moduleClass.getCanonicalName()); + } + out.println(); + } + + private static void printSignature(final PrintStream out, final Class moduleClass) { + String inString = ""; + String outString = ""; + final In inClass = moduleClass.getAnnotation(In.class); + if (inClass != null) { + inString = inClass.value().getSimpleName(); + } + final Out outClass = moduleClass.getAnnotation(Out.class); + if (outClass != null) { + outString = outClass.value().getSimpleName(); + } + out.println("- signature:\t" + inString + " -> " + outString); + } + + private static void printAttributes(final PrintStream out, final ConfigurableClass configurableClass, final Map attributes) { if (!attributes.isEmpty()) { out.print("- options:\t"); final StringBuilder builder = new StringBuilder(); @@ -140,20 +186,6 @@ private static void describe(final String name, final ObjectFactory facto } out.println(builder.substring(0, builder.length() - 2)); } - - String inString = ""; - String outString = ""; - final In inClass = moduleClass.getAnnotation(In.class); - if (inClass != null) { - inString = inClass.value().getSimpleName(); - } - final Out outClass = moduleClass.getAnnotation(Out.class); - if (outClass != null) { - outString = outClass.value().getSimpleName(); - } - out.println("- signature:\t" + inString + " -> " + outString); - out.println("- java class:\t" + moduleClass.getCanonicalName()); - out.println(); } @SuppressWarnings("unchecked") @@ -171,4 +203,16 @@ private static Collection getAvailableArguments(final Class moduleCla return Collections.emptyList(); } + private static void loadExamples() throws IOException { + final File f = new File(PATH_TO_EXAMPLES); + if (Files.exists(f.toPath())) { + final BufferedReader bufferedReader = new BufferedReader(new FileReader(f)); + String line; + while ((line = bufferedReader.readLine()) != null) { + final String[] tsv = line.split("\t"); + EXAMPLES_MAP.put(tsv[0], tsv); + } + } + } + } diff --git a/metafacture-flux/src/main/java/org/metafacture/flux/parser/FluxProgramm.java b/metafacture-flux/src/main/java/org/metafacture/flux/parser/FluxProgramm.java index 6c3aa98a..927274c9 100644 --- a/metafacture-flux/src/main/java/org/metafacture/flux/parser/FluxProgramm.java +++ b/metafacture-flux/src/main/java/org/metafacture/flux/parser/FluxProgramm.java @@ -178,9 +178,10 @@ public void start() { /** * Prints the help to the given PrintStream. * - * @param out the PrintStream to orint to + * @param out the PrintStream to print to + * @throws IOException when an I/O error occurs */ - public static void printHelp(final PrintStream out) { + public static void printHelp(final PrintStream out) throws IOException { HelpPrinter.print(COMMAND_FACTORY, out); } diff --git a/metafacture-flux/src/test/java/org/metafacture/flux/FluxProgrammTest.java b/metafacture-flux/src/test/java/org/metafacture/flux/FluxProgrammTest.java index 482764d5..703f694c 100644 --- a/metafacture-flux/src/test/java/org/metafacture/flux/FluxProgrammTest.java +++ b/metafacture-flux/src/test/java/org/metafacture/flux/FluxProgrammTest.java @@ -16,13 +16,13 @@ package org.metafacture.flux; +import org.junit.Test; +import org.metafacture.flux.parser.FluxProgramm; + import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import org.junit.Test; -import org.metafacture.flux.parser.FluxProgramm; - /** * Tests {@link FluxProgramm} * @@ -33,7 +33,7 @@ public final class FluxProgrammTest { @Test - public void testCommandRegistration() { + public void testCommandRegistration() throws IOException { // all commands must properly load to print the help FluxProgramm.printHelp(discardOutput()); From ab656cb5ca6d72b5f8a181cf2130a054a592351f Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 21 Nov 2023 12:05:03 +0100 Subject: [PATCH 2/4] Update metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java Co-authored-by: Jens Wille --- .../src/main/java/org/metafacture/flux/HelpPrinter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java index c1494a66..9fa9c397 100644 --- a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java +++ b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java @@ -33,7 +33,6 @@ import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -205,7 +204,7 @@ private static Collection getAvailableArguments(final Class moduleCla private static void loadExamples() throws IOException { final File f = new File(PATH_TO_EXAMPLES); - if (Files.exists(f.toPath())) { + if (f.exists()) { final BufferedReader bufferedReader = new BufferedReader(new FileReader(f)); String line; while ((line = bufferedReader.readLine()) != null) { From b68b58e1567fb9441db4b151b36c3ccd304a54dd Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 21 Nov 2023 13:48:40 +0100 Subject: [PATCH 3/4] Validate boundaries of tsv --- .../src/main/java/org/metafacture/flux/HelpPrinter.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java index 9fa9c397..a5a4620e 100644 --- a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java +++ b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java @@ -52,7 +52,8 @@ public final class HelpPrinter { private static final String PATH_TO_EXAMPLES = "../metafacture-documentation/linksAndExamples.tsv"; private static final Map EXAMPLES_MAP = new HashMap<>(); private static final int COLUMN_TO_PG_EXAMPLE = 3; - private static final int REQUIRED_COLUMNS_OF_EXAMPLE = 2; + private static final int MAX_COLUMNS_OF_EXAMPLE = COLUMN_TO_PG_EXAMPLE; + private static final int MIN_COLUMNS_OF_EXAMPLE = 2; private HelpPrinter() { // no instances @@ -126,9 +127,11 @@ private static void describe(final String name, final ObjectFactory facto printSignature(out, moduleClass); final String[] examplesEntry = EXAMPLES_MAP.get(name); - if (!EXAMPLES_MAP.isEmpty() && (examplesEntry == null || examplesEntry.length < REQUIRED_COLUMNS_OF_EXAMPLE)) { + if (!EXAMPLES_MAP.isEmpty() && (examplesEntry == null || examplesEntry.length < MIN_COLUMNS_OF_EXAMPLE || + examplesEntry.length > MAX_COLUMNS_OF_EXAMPLE)) { throw new MetafactureException( - "Failed to load build infos: tsv with links hasn't at least " + REQUIRED_COLUMNS_OF_EXAMPLE + + "Failed to load build infos: tsv with links hasn't at least " + MIN_COLUMNS_OF_EXAMPLE + " " + + "or exceeds the number of allowed columns (i.e. " + MAX_COLUMNS_OF_EXAMPLE + ")" + " for the entry '" + name + "'"); } if (examplesEntry != null && examplesEntry.length == COLUMN_TO_PG_EXAMPLE) { From 25a2779b924304dc57f283ac2420107476811dc0 Mon Sep 17 00:00:00 2001 From: Jens Wille Date: Tue, 21 Nov 2023 16:08:11 +0100 Subject: [PATCH 4/4] Future-proof additional command info; print warning instead of throwing an exception for invalid/incomplete entries. (#509) --- .../org/metafacture/flux/HelpPrinter.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java index a5a4620e..c0bdc156 100644 --- a/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java +++ b/metafacture-flux/src/main/java/org/metafacture/flux/HelpPrinter.java @@ -49,11 +49,9 @@ * @author Markus Michael Geipel */ public final class HelpPrinter { + private static final String PATH_TO_EXAMPLES = "../metafacture-documentation/linksAndExamples.tsv"; private static final Map EXAMPLES_MAP = new HashMap<>(); - private static final int COLUMN_TO_PG_EXAMPLE = 3; - private static final int MAX_COLUMNS_OF_EXAMPLE = COLUMN_TO_PG_EXAMPLE; - private static final int MIN_COLUMNS_OF_EXAMPLE = 2; private HelpPrinter() { // no instances @@ -127,17 +125,10 @@ private static void describe(final String name, final ObjectFactory facto printSignature(out, moduleClass); final String[] examplesEntry = EXAMPLES_MAP.get(name); - if (!EXAMPLES_MAP.isEmpty() && (examplesEntry == null || examplesEntry.length < MIN_COLUMNS_OF_EXAMPLE || - examplesEntry.length > MAX_COLUMNS_OF_EXAMPLE)) { - throw new MetafactureException( - "Failed to load build infos: tsv with links hasn't at least " + MIN_COLUMNS_OF_EXAMPLE + " " + - "or exceeds the number of allowed columns (i.e. " + MAX_COLUMNS_OF_EXAMPLE + ")" + - " for the entry '" + name + "'"); - } - if (examplesEntry != null && examplesEntry.length == COLUMN_TO_PG_EXAMPLE) { - out.println("- [example in Playground]" + "(" + examplesEntry[COLUMN_TO_PG_EXAMPLE - 1] + ")"); + if (examplesEntry != null && examplesEntry.length > 2) { + out.println("- [example in Playground]" + "(" + examplesEntry[2] + ")"); } - if (examplesEntry != null) { + if (examplesEntry != null && examplesEntry.length > 1) { out.println("- java class:\t[" + moduleClass.getCanonicalName() + "](" + examplesEntry[1] + ")"); } else { @@ -213,6 +204,10 @@ private static void loadExamples() throws IOException { while ((line = bufferedReader.readLine()) != null) { final String[] tsv = line.split("\t"); EXAMPLES_MAP.put(tsv[0], tsv); + + if (tsv.length < 2) { + System.err.println("Invalid command info: " + line); + } } } }