Skip to content
This repository was archived by the owner on Jul 6, 2023. It is now read-only.

Commit 93f794d

Browse files
committed
automatically select output format when terminal is interactive or not
New help text (note `--format`): ``` usage: cypher-shell [-h] [-a ADDRESS] [-u USERNAME] [-p PASSWORD] [--encryption {true,false}] [--format {auto,verbose,plain}] [--debug] [--non-interactive] [-v] [--fail-fast | --fail-at-end] [cypher] A command line shell where you can execute Cypher against an instance of Neo4j. By default the shell is interactive but you can use it for scripting by passing cypher directly on the command line or by piping a file with cypher statements (requires Powershell on Windows). example of piping a file: cat some-cypher.txt | cypher-shell positional arguments: cypher an optional string of cypher to execute and then exit optional arguments: -h, --help show this help message and exit --fail-fast exit and report failure on first error when reading from file (this is the default behavior) --fail-at-end exit and report failures at end of input when reading from file --format {auto,verbose,plain} desired output format, verbose displays results in tabular format and prints statistics, plain displays data with minimal formatting (default: auto) --debug print additional debug information (default: false) --non-interactive force non-interactive mode, only useful if auto- detection fails (like on Windows) (default: false) -v, --version print version of cypher-shell and exit (default: false) connection arguments: -a ADDRESS, --address ADDRESS address and port to connect to (default: bolt: //localhost:7687) -u USERNAME, --username USERNAME username to connect as. Can also be specified using environment variable NEO4J_USERNAME (default: ) -p PASSWORD, --password PASSWORD password to connect with. Can also be specified using environment variable NEO4J_PASSWORD (default: ) --encryption {true,false} whether the connection to Neo4j should be encrypted; must be consistent with Neo4j's configuration (default: true) ```
1 parent 8a422e9 commit 93f794d

File tree

5 files changed

+46
-8
lines changed

5 files changed

+46
-8
lines changed

cypher-shell/src/main/java/org/neo4j/shell/ShellRunner.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.IOException;
1313

1414
import static org.fusesource.jansi.internal.CLibrary.STDIN_FILENO;
15+
import static org.fusesource.jansi.internal.CLibrary.STDOUT_FILENO;
1516
import static org.fusesource.jansi.internal.CLibrary.isatty;
1617
import static org.neo4j.shell.system.Utils.isWindows;
1718

@@ -74,7 +75,7 @@ static boolean shouldBeInteractive(@Nonnull CliArgs cliArgs) {
7475
* Checks if STDIN is a TTY. In case TTY checking is not possible (lack of libc), then the check falls back to
7576
* the built in Java {@link System#console()} which checks if EITHER STDIN or STDOUT has been redirected.
7677
*
77-
* @return true if the shell reading from an interactive terminal, false otherwise (e.g., we are reading from a
78+
* @return true if the shell is reading from an interactive terminal, false otherwise (e.g., we are reading from a
7879
* file).
7980
*/
8081
static boolean isInputInteractive() {
@@ -91,4 +92,26 @@ static boolean isInputInteractive() {
9192
return System.console() != null;
9293
}
9394
}
95+
96+
/**
97+
* Checks if STDOUT is a TTY. In case TTY checking is not possible (lack of libc), then the check falls back to
98+
* the built in Java {@link System#console()} which checks if EITHER STDIN or STDOUT has been redirected.
99+
*
100+
* @return true if the shell is outputting to an interactive terminal, false otherwise (e.g., we are outputting
101+
* to a file)
102+
*/
103+
static boolean isOutputInteractive() {
104+
if (isWindows()) {
105+
// Input will never be a TTY on windows and it isatty seems to be able to block forever on Windows so avoid
106+
// calling it.
107+
return System.console() != null;
108+
}
109+
try {
110+
return 1 == isatty(STDOUT_FILENO);
111+
} catch (Throwable ignored) {
112+
// system is not using libc (like Alpine Linux)
113+
// Fallback to checking stdin OR stdout
114+
return System.console() != null;
115+
}
116+
}
94117
}

cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgHelper.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,13 @@ private static ArgumentParser setupParser()
148148
parser.setDefault("fail-behavior", FAIL_FAST);
149149

150150
parser.addArgument("--format")
151-
.help("desired output format, verbose(default) displays statistics, plain only displays data")
151+
.help("desired output format, verbose displays results in tabular format and prints statistics, " +
152+
"plain displays data with minimal formatting")
152153
.choices(new CollectionArgumentChoice<>(
153-
Format.VERBOSE.name().toLowerCase(), Format.PLAIN.name().toLowerCase()))
154-
.setDefault(Format.VERBOSE.name().toLowerCase());
154+
Format.AUTO.name().toLowerCase(),
155+
Format.VERBOSE.name().toLowerCase(),
156+
Format.PLAIN.name().toLowerCase()))
157+
.setDefault(Format.AUTO.name().toLowerCase());
155158

156159
parser.addArgument("--debug")
157160
.help("print additional debug information")

cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgs.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class CliArgs {
1111
private String username = "";
1212
private String password = "";
1313
private FailBehavior failBehavior = FailBehavior.FAIL_FAST;
14-
private Format format = Format.VERBOSE;
14+
private Format format = Format.AUTO;
1515
private Optional<String> cypher = Optional.empty();
1616
private boolean encryption;
1717
private boolean debugMode;
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
package org.neo4j.shell.cli;
22

3+
import javax.annotation.Nonnull;
4+
5+
import static org.neo4j.shell.ShellRunner.isOutputInteractive;
6+
37
public enum Format {
8+
// Will select depending on if stdout is redirected or not
9+
AUTO,
410
// Intended for human consumption
511
VERBOSE,
612
// Intended for machine consumption (nothing except data is printed
713
PLAIN;
814
// TODO JSON, strictly intended for machine consumption with data formatted in JSON
915

10-
public static Format parse(String format) {
16+
public static Format parse(@Nonnull String format) {
1117
if (format.equalsIgnoreCase(PLAIN.name())) {
1218
return PLAIN;
19+
} else if (format.equalsIgnoreCase( VERBOSE.name() )) {
20+
return VERBOSE;
21+
} else {
22+
return isOutputInteractive() ? VERBOSE : PLAIN;
1323
}
14-
return VERBOSE;
1524
}
1625
}

cypher-shell/src/test/java/org/neo4j/shell/cli/CliArgsTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ public void setFailBehavior() throws Exception {
6161
@Test
6262
public void setFormat() throws Exception {
6363
// default
64-
assertEquals(Format.VERBOSE, cliArgs.getFormat());
64+
assertEquals(Format.AUTO, cliArgs.getFormat());
6565

6666
cliArgs.setFormat(Format.PLAIN);
6767
assertEquals(Format.PLAIN, cliArgs.getFormat());
68+
69+
cliArgs.setFormat(Format.VERBOSE);
70+
assertEquals(Format.VERBOSE, cliArgs.getFormat());
6871
}
6972

7073
@Test

0 commit comments

Comments
 (0)