Skip to content

Commit

Permalink
feat: support custom column widths in cli (#4616)
Browse files Browse the repository at this point in the history
Allow column width to be explicitly specified in tabular cli output, e.g.: 
ksql> SET CLI COLUMN-WIDTH 10

Given a customized value, subsequent renderings of output use the setting.

The default behavior, in which column width is determined based on the terminal width and column count, can be re-enabled using:
ksql> SET CLI COLUMN-WIDTH 0
  • Loading branch information
colinhicks committed Feb 27, 2020
1 parent 7cc19a0 commit cb66e05
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
public class CliConfig extends AbstractConfig {

public static final String WRAP_CONFIG = "WRAP";
public static final String COLUMN_WIDTH_CONFIG = "COLUMN-WIDTH";

private static final ConfigDef CONFIG_DEF = new ConfigDef()
.define(
Expand All @@ -37,6 +38,15 @@ public class CliConfig extends AbstractConfig {
Importance.MEDIUM,
"A value of 'OFF' will clip lines to ensure that query results do not exceed the "
+ "terminal width (i.e. each row will appear on a single line)."
)
.define(
COLUMN_WIDTH_CONFIG,
Type.INT,
0,
ConfigValidators.zeroOrPositive(),
Importance.MEDIUM,
"The width in characters of each column in tabular output. A value of '0' indicates "
+ "column width should be based on terminal width and number of columns."
);

public CliConfig(final Map<?, ?> originals) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ private void printRowHeader(final LogicalSchema schema) {
case JSON:
break;
case TABULAR:
writer().println(TabularRow.createHeader(getWidth(), schema));
writer().println(TabularRow.createHeader(getWidth(), schema, config));
break;
default:
throw new RuntimeException(String.format(
Expand Down
28 changes: 20 additions & 8 deletions ksql-cli/src/main/java/io/confluent/ksql/util/TabularRow.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ public final class TabularRow {
private static final String CLIPPED = "...";
private static final int MIN_CELL_WIDTH = 5;

private final int width;
private final int cellWidth;
private final List<String> columns;
private final boolean isHeader;
private final boolean shouldWrap;

public static TabularRow createHeader(final int width, final LogicalSchema schema) {
public static TabularRow createHeader(
final int width,
final LogicalSchema schema,
final CliConfig config
) {
final List<String> headings = schema.columns().stream()
.map(Column::name)
.map(ColumnName::name)
Expand All @@ -49,7 +53,7 @@ public static TabularRow createHeader(final int width, final LogicalSchema schem
width,
headings,
true,
true
config
);
}

Expand All @@ -62,20 +66,29 @@ public static TabularRow createRow(
width,
value.values().stream().map(Objects::toString).collect(Collectors.toList()),
false,
config.getString(CliConfig.WRAP_CONFIG).equalsIgnoreCase(OnOff.ON.toString())
config
);
}

private TabularRow(
final int width,
final List<String> columns,
final boolean isHeader,
final boolean shouldWrap
final CliConfig config
) {
this.columns = ImmutableList.copyOf(Objects.requireNonNull(columns, "columns"));
this.width = width;
this.isHeader = isHeader;
this.shouldWrap = shouldWrap;
this.shouldWrap = isHeader
|| config.getString(CliConfig.WRAP_CONFIG).equalsIgnoreCase(OnOff.ON.toString());

final int configCellWidth = config.getInt(CliConfig.COLUMN_WIDTH_CONFIG);
if (configCellWidth > 0) {
this.cellWidth = configCellWidth;
} else if (!columns.isEmpty()) {
this.cellWidth = Math.max(width / columns.size() - 2, MIN_CELL_WIDTH);
} else {
cellWidth = MIN_CELL_WIDTH;
}
}

@Override
Expand All @@ -84,7 +97,6 @@ public String toString() {
return "";
}

final int cellWidth = Math.max(width / columns.size() - 2, MIN_CELL_WIDTH);
final StringBuilder builder = new StringBuilder();

if (isHeader) {
Expand Down
37 changes: 32 additions & 5 deletions ksql-cli/src/test/java/io/confluent/ksql/util/TabularRowTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void shouldFormatHeader() {
.build();

// When:
final String formatted = TabularRow.createHeader(20, schema).toString();
final String formatted = TabularRow.createHeader(20, schema, config).toString();

// Then:
assertThat(formatted, is(""
Expand All @@ -67,7 +67,7 @@ public void shouldMultilineFormatHeader() {
.build();

// When:
final String formatted = TabularRow.createHeader(20, schema).toString();
final String formatted = TabularRow.createHeader(20, schema, config).toString();

// Then:
assertThat(formatted, is(""
Expand Down Expand Up @@ -169,7 +169,7 @@ public void shouldFormatNoColumnsHeader() {
.build();

// When:
final String formatted = TabularRow.createHeader(20, schema).toString();
final String formatted = TabularRow.createHeader(20, schema, config).toString();

// Then:
assertThat(formatted, isEmptyString());
Expand All @@ -186,7 +186,7 @@ public void shouldFormatMoreColumnsThanWidth() {
.build();

// When:
final String formatted = TabularRow.createHeader(3, schema).toString();
final String formatted = TabularRow.createHeader(3, schema, config).toString();

// Then:
assertThat(formatted,
Expand All @@ -196,11 +196,38 @@ public void shouldFormatMoreColumnsThanWidth() {
+ "+-----+-----+-----+"));
}

@Test
public void shouldFormatCustomColumnWidth() {
// Given:
givenCustomColumnWidth(10);

final LogicalSchema schema = LogicalSchema.builder()
.noImplicitColumns()
.keyColumn(ColumnName.of("foo"), SqlTypes.BIGINT)
.valueColumn(ColumnName.of("bar"), SqlTypes.STRING)
.valueColumn(ColumnName.of("baz"), SqlTypes.DOUBLE)
.build();

// When:
final String formatted = TabularRow.createHeader(999, schema, config).toString();

// Then:
assertThat(formatted,
is(""
+ "+----------+----------+----------+\n"
+ "|foo |bar |baz |\n"
+ "+----------+----------+----------+"));
}

private void givenWrappingEnabled() {
when(config.getString(CliConfig.WRAP_CONFIG)).thenReturn(OnOff.ON.toString());
}

private void givenWrappingDisabled() {
when(config.getString(CliConfig.WRAP_CONFIG)).thenReturn("Not ON");
}
}

private void givenCustomColumnWidth(int width) {
when(config.getInt(CliConfig.COLUMN_WIDTH_CONFIG)).thenReturn(width);
}
}

0 comments on commit cb66e05

Please sign in to comment.