Skip to content

Commit

Permalink
When --stdout used, send other out to stderr
Browse files Browse the repository at this point in the history
This change causes the command-line checker to emit its “other” output
(usage message and “verbose” messages and failure messages) to stderr
rather than stdout (in order to ensure that the only output going to
stdout are the checker errors and warnings).
  • Loading branch information
sideshowbarker committed Jun 7, 2020
1 parent 6dbb211 commit 1ce0b83
Showing 1 changed file with 50 additions and 45 deletions.
95 changes: 50 additions & 45 deletions src/nu/validator/client/SimpleCommandLineValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.Manifest;
Expand Down Expand Up @@ -66,6 +67,8 @@ public class SimpleCommandLineValidator {

private static OutputStream out;

private static PrintStream otherOut;

private static Pattern filterPattern;

private static MessageEmitterAdapter errorHandler;
Expand Down Expand Up @@ -128,6 +131,7 @@ public static void main(String[] args) throws SAXException, Exception {
}
}
out = System.err;
otherOut = System.out;
userAgent = "Validator.nu/LV";
System.setProperty("nu.validator.datatype.warn", "true");
errorsOnly = false;
Expand Down Expand Up @@ -226,9 +230,9 @@ public static void main(String[] args) throws SAXException, Exception {
userAgent = args[++i];
} else if ("--version".equals(args[i])) {
if (version != null) {
System.out.println(version);
otherOut.println(version);

This comment has been minimized.

Copy link
@mhansen

mhansen Jun 8, 2020

Contributor

My 2c: I think version should always go to stderr (I just want stdout for the structured output / json/xml/gnu/text HTML warnings). This one I'm less worried about than I am about java exceptions though.

This comment has been minimized.

Copy link
@sideshowbarker

sideshowbarker Jun 8, 2020

Author Contributor

My 2c: I think version should always go to stderr (I just want stdout for the structured output / json/xml/gnu/text HTML warnings). This one I'm less worried about than I am about java exceptions though.

See my other comment — I think what you’re describing is exactly what this change is already causing, right?

This comment has been minimized.

Copy link
@mhansen

mhansen Jun 8, 2020

Contributor

otherOut is set to System.out above, and only ever flipped to System.err below. So here otherOut will always be System.out.

This comment has been minimized.

Copy link
@sideshowbarker

sideshowbarker Jun 8, 2020

Author Contributor

otherOut is set to System.out above, and only ever flipped to System.err below. So here otherOut will always be System.out.

d’oh — thanks for catching that; will push a fix shortly

This comment has been minimized.

Copy link
@sideshowbarker

sideshowbarker Jun 8, 2020

Author Contributor

otherOut is set to System.out above, and only ever flipped to System.err below. So here otherOut will always be System.out.

OK, I just pushed a fixed for that — so I new docker image and new jar file should be available within ~10 minutes

} else {
System.out.println("[unknown version]");
otherOut.println("[unknown version]");
}
System.exit(0);
} else if ("--help".equals(args[i])) {
Expand Down Expand Up @@ -269,6 +273,7 @@ public static void main(String[] args) throws SAXException, Exception {
}
if (reportMessagesToStdOut) {
out = System.out;
otherOut = System.err;
}
if (!"".equals(filterString)) {
filterPattern = Pattern.compile(filterString);
Expand Down Expand Up @@ -331,16 +336,16 @@ private static void setSchema(String schemaUrl)
try {
validator.setUpMainSchema(schemaUrl, new SystemErrErrorHandler());
} catch (SchemaReadException e) {
System.out.println(e.getMessage() + " Terminating.");
otherOut.println(e.getMessage() + " Terminating.");

This comment has been minimized.

Copy link
@mhansen

mhansen Jun 8, 2020

Contributor

My 2c: I think these exceptions should probably still go to stderr -- idea of using --stdout is that it's just the JSON or XML or text-HTML-warnings, not intermingled with other java-level errors.

This comment has been minimized.

Copy link
@sideshowbarker

sideshowbarker Jun 8, 2020

Author Contributor

My 2c: I think these exceptions should probably still go to stderr -- idea of using --stdout is that it's just the JSON or XML or text-HTML-warnings, not intermingled with other java-level errors.

Isn’t that what this change is already causing to happen? I mean specifically, this change ensures that the exceptions don’t go the the same output stream as the normal checker errors and warnings (JSON/XML/gnu/text), right? If you use --stdout, then otherOut here will be System.err — and the normal checker errors and warnings (JSON/XML/gnu/text) will instead by going to System.out.

This comment has been minimized.

Copy link
@mhansen

mhansen Jun 8, 2020

Contributor

I think you're right, I missed this.

        otherOut = System.err;

This comment has been minimized.

Copy link
@mhansen

mhansen Jun 8, 2020

Contributor

d'oh! I found my problem. I was running this

docker run -v (pwd)/_site/:/_site validator/validator:latest vnu --skip-non-html --errors-only --format json /_site/ --stdout

which wasn't interpreting --stdout as a command line option since it was after a file argument.

This comment has been minimized.

Copy link
@sideshowbarker

sideshowbarker Jun 8, 2020

Author Contributor

d'oh! I found my problem. I was running this

docker run -v (pwd)/_site/:/_site validator/validator:latest vnu --skip-non-html --errors-only --format json /_site/ --stdout

which wasn't interpreting --stdout as a command line option since it was after a file argument.

Aha! Great — glad for that (well, not super-glad that the arguments parsing in the code is as fragile as it is, but that’s another thing to fix eventually)

System.exit(1);
} catch (StackOverflowError e) {
System.out.println("StackOverflowError"
otherOut.println("StackOverflowError"
+ " while evaluating HTML schema.");
System.out.println("The checker requires a java thread stack size"
otherOut.println("The checker requires a java thread stack size"
+ " of at least 512k.");
System.out.println("Consider invoking java with the -Xss"
otherOut.println("Consider invoking java with the -Xss"
+ " option. For example:");
System.out.println("\n java -Xss512k -jar ~/vnu.jar FILE.html");
otherOut.println("\n java -Xss512k -jar ~/vnu.jar FILE.html");
System.exit(1);
}
validator.setUpValidatorAndParsers(errorHandler, noStream, loadEntities);
Expand Down Expand Up @@ -561,7 +566,7 @@ private static boolean isHtml(File file) {

private static void emitFilename(String name) {
if (verbose) {
System.out.println(name);
otherOut.println(name);
}
}

Expand Down Expand Up @@ -595,49 +600,49 @@ private static void setErrorHandler() {
}

private static void usage() {
System.out.println("Usage:");
System.out.println("");
System.out.println(" vnu-runtime-image/bin/vnu OPTIONS FILES (Linux or macOS)");
System.out.println(" vnu-runtime-image\\bin\\vnu.bat OPTIONS FILES (Windows)");
System.out.println(" java -jar ~/vnu.jar OPTIONS FILES (any system with Java8+ installed)");
System.out.println("");
System.out.println("...where FILES are the documents to check, and OPTIONS are zero or more of:");
System.out.println("");
System.out.println(" --errors-only --Werror --exit-zero-always --stdout --asciiquotes");
System.out.println(" --user-agent USER_AGENT --no-langdetect --no-stream --filterfile FILENAME");
System.out.println(" --filterpattern PATTERN --css --skip-non-css --also-check-css --svg");
System.out.println(" --skip-non-svg --also-check-svg --html --skip-non-html");
System.out.println(" --format gnu|xml|json|text --help --verbose --version");
System.out.println("");
System.out.println("For detailed usage information, try the \"--help\" option or see:");
System.out.println("");
System.out.println(" http://validator.github.io/");
System.out.println("");
System.out.println("To read from stdin, use \"-\" as the filename, like this: \"java -jar vnu.jar - \".");
System.out.println("");
System.out.println("To run the checker as a standalone Web-based service, open a new terminal");
System.out.println("window and invoke the checker like this");
System.out.println("");
System.out.println(" java -cp vnu.jar nu.validator.servlet.Main 8888");
System.out.println(" vnu-runtime-image/bin/java nu.validator.servlet.Main 8888");
System.out.println(" vnu-runtime-image\\bin\\java -cp vnu.jar nu.validator.servlet.Main 8888");
System.out.println("");
System.out.println("...then open http://127.0.0.1:8888 in a browser.");
System.out.println("");
System.out.println("After that, to check documents locally using the packaged HTTP client, do this:");
System.out.println("");
System.out.println(" java -cp vnu.jar nu.validator.client.HttpClient FILES");
System.out.println(" vnu-runtime-image/bin/java nu.validator.client.HttpClient FILES");
System.out.println(" vnu-runtime-image\\bin\\java nu.validator.client.HttpClient FILES");
System.out.println("");
otherOut.println("Usage:");
otherOut.println("");
otherOut.println(" vnu-runtime-image/bin/vnu OPTIONS FILES (Linux or macOS)");
otherOut.println(" vnu-runtime-image\\bin\\vnu.bat OPTIONS FILES (Windows)");
otherOut.println(" java -jar ~/vnu.jar OPTIONS FILES (any system with Java8+ installed)");
otherOut.println("");
otherOut.println("...where FILES are the documents to check, and OPTIONS are zero or more of:");
otherOut.println("");
otherOut.println(" --errors-only --Werror --exit-zero-always --stdout --asciiquotes");
otherOut.println(" --user-agent USER_AGENT --no-langdetect --no-stream --filterfile FILENAME");
otherOut.println(" --filterpattern PATTERN --css --skip-non-css --also-check-css --svg");
otherOut.println(" --skip-non-svg --also-check-svg --html --skip-non-html");
otherOut.println(" --format gnu|xml|json|text --help --verbose --version");
otherOut.println("");
otherOut.println("For detailed usage information, try the \"--help\" option or see:");
otherOut.println("");
otherOut.println(" http://validator.github.io/");
otherOut.println("");
otherOut.println("To read from stdin, use \"-\" as the filename, like this: \"java -jar vnu.jar - \".");
otherOut.println("");
otherOut.println("To run the checker as a standalone Web-based service, open a new terminal");
otherOut.println("window and invoke the checker like this");
otherOut.println("");
otherOut.println(" java -cp vnu.jar nu.validator.servlet.Main 8888");
otherOut.println(" vnu-runtime-image/bin/java nu.validator.servlet.Main 8888");
otherOut.println(" vnu-runtime-image\\bin\\java -cp vnu.jar nu.validator.servlet.Main 8888");
otherOut.println("");
otherOut.println("...then open http://127.0.0.1:8888 in a browser.");
otherOut.println("");
otherOut.println("After that, to check documents locally using the packaged HTTP client, do this:");
otherOut.println("");
otherOut.println(" java -cp vnu.jar nu.validator.client.HttpClient FILES");
otherOut.println(" vnu-runtime-image/bin/java nu.validator.client.HttpClient FILES");
otherOut.println(" vnu-runtime-image\\bin\\java nu.validator.client.HttpClient FILES");
otherOut.println("");
}

private static void help() {
try (InputStream help = SimpleCommandLineValidator.class.getClassLoader().getResourceAsStream(
"nu/validator/localentities/files/cli-help")) {
System.out.println("");
otherOut.println("");
for (int b = help.read(); b != -1; b = help.read()) {
System.out.write(b);
otherOut.write(b);
}
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down

0 comments on commit 1ce0b83

Please sign in to comment.