Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consistent console help usage #9944

Merged
merged 13 commits into from
May 24, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve
- We fixed an issue in the preferences 'External file types' tab ignoring a custom application path in the edit dialog. [#9895](https://github.com/JabRef/jabref/issues/9895)
- We fixed an issue in the preferences where custom columns could be added to the entry table with no qualifier. [#9913](https://github.com/JabRef/jabref/issues/9913)
- We fixed an issue where the encoding header in a bib file was not respected when the file contained a BOM (Byte Order Mark). [#9926](https://github.com/JabRef/jabref/issues/9926)
- We fixed an issue where cli help output for import and export format was inconsistent. [koppor#429](https://github.com/koppor/jabref/issues/429)

### Removed

Expand Down
51 changes: 43 additions & 8 deletions src/main/java/org/jabref/cli/JabRefCLI.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.jabref.cli;

import java.util.List;
import java.util.Objects;

import javafx.util.Pair;

import org.jabref.gui.Globals;
import org.jabref.logic.exporter.Exporter;
import org.jabref.logic.exporter.ExporterFactory;
import org.jabref.logic.importer.ImportFormatReader;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.OS;
import org.jabref.model.strings.StringUtil;
import org.jabref.model.util.DummyFileUpdateMonitor;
import org.jabref.preferences.PreferencesService;

Expand All @@ -20,6 +24,7 @@
public class JabRefCLI {
private static final int WIDTH = 100; // Number of characters per line before a line break must be added.
private static final String WRAPPED_LINE_PREFIX = ""; // If a line break is added, this prefix will be inserted at the beginning of the next line
private static final String STRING_TABLE_DELIMITER = " : ";

private final CommandLine cl;
private final List<String> leftOver;
Expand Down Expand Up @@ -161,7 +166,7 @@ public boolean isWriteMetadatatoPdf() {
public String getWriteMetadatatoPdf() {
return cl.hasOption("writeMetadatatoPdf") ? cl.getOptionValue("writeMetadatatoPdf") :
cl.hasOption("writeXMPtoPdf") ? cl.getOptionValue("writeXMPtoPdf") :
cl.hasOption("embeddBibfileInPdf") ? cl.getOptionValue("embeddBibfileInPdf") : null;
cl.hasOption("embeddBibfileInPdf") ? cl.getOptionValue("embeddBibfileInPdf") : null;
}

private static Options getOptions() {
Expand Down Expand Up @@ -292,20 +297,28 @@ public void displayVersion() {

public static void printUsage(PreferencesService preferencesService) {
String header = "";

ImportFormatReader importFormatReader = new ImportFormatReader(
preferencesService.getImporterPreferences(),
preferencesService.getImportFormatPreferences(),
new DummyFileUpdateMonitor());
String importFormats = importFormatReader.getImportFormatList();
String importFormatsList = String.format("%s:%n%s%n", Localization.lang("Available import formats"), importFormats);
List<Pair<String, String>> importFormats = importFormatReader
.getImportFormats().stream()
.map(format -> new Pair<>(format.getName(), format.getId()))
.toList();
String importFormatsIntro = Localization.lang("Available import formats");
String importFormatsList = String.format("%s:%n%s%n", importFormatsIntro, alignStringTable(importFormats));

ExporterFactory exporterFactory = ExporterFactory.create(
preferencesService,
Globals.entryTypesManager,
Globals.journalAbbreviationRepository);
List<Pair<String, String>> exportFormats = exporterFactory
.getExporters().stream()
.map(format -> new Pair<>(format.getName(), format.getId()))
.toList();
String outFormatsIntro = Localization.lang("Available export formats");
String outFormats = wrapStringList(exporterFactory.getExporters().stream().map(Exporter::getId).toList(), outFormatsIntro.length());
String outFormatsList = String.format("%s: %s%n", outFormatsIntro, outFormats);
String outFormatsList = String.format("%s:%n%s%n", outFormatsIntro, alignStringTable(exportFormats));

String footer = '\n' + importFormatsList + outFormatsList + "\nPlease report issues at https://github.com/JabRef/jabref/issues.";

Expand All @@ -321,12 +334,34 @@ public List<String> getLeftOver() {
return leftOver;
}

protected static String alignStringTable(List<Pair<String, String>> table) {
StringBuilder sb = new StringBuilder();

int maxLength = table.stream()
.mapToInt(pair -> Objects.requireNonNullElse(pair.getKey(), "").length())
.max().orElse(0);

for (Pair<String, String> pair : table) {
int padding = Math.max(0, maxLength - pair.getKey().length());
sb.append(WRAPPED_LINE_PREFIX);
sb.append(pair.getKey());

sb.append(StringUtil.repeatSpaces(padding));

sb.append(STRING_TABLE_DELIMITER);
sb.append(pair.getValue());
sb.append(OS.NEWLINE);
}

return sb.toString();
}

/**
* Creates and wraps a multi-line and colon-seperated string from a List of Strings.
*/
protected static String wrapStringList(List<String> list, int firstLineIntroLength) {
protected static String wrapStringList(List<String> list, int firstLineIndentation) {
StringBuilder builder = new StringBuilder();
int lastBreak = -firstLineIntroLength;
int lastBreak = -firstLineIndentation;

for (String line : list) {
if (((builder.length() + 2 + line.length()) - lastBreak) > WIDTH) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/jabref/cli/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class Launcher {

public static void main(String[] args) {
ARGUMENTS = args;

addLogToDisk();
try {
// Init preferences
Expand All @@ -53,7 +54,7 @@ public static void main(String[] args) {
PreferencesMigrations.runMigrations(preferences);

// Early exit in case another instance is already running
if (!handleMultipleAppInstances(args, preferences)) {
if (!handleMultipleAppInstances(ARGUMENTS, preferences)) {
return;
}

Expand All @@ -68,7 +69,7 @@ public static void main(String[] args) {

// Process arguments
ArgumentProcessor argumentProcessor = new ArgumentProcessor(
args, ArgumentProcessor.Mode.INITIAL_START,
ARGUMENTS, ArgumentProcessor.Mode.INITIAL_START,
preferences,
fileUpdateMonitor);
if (argumentProcessor.shouldShutDown()) {
Expand Down
26 changes: 0 additions & 26 deletions src/main/java/org/jabref/logic/importer/ImportFormatReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabases;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.strings.StringUtil;
import org.jabref.model.util.FileUpdateMonitor;

public class ImportFormatReader {
Expand Down Expand Up @@ -137,31 +136,6 @@ public SortedSet<Importer> getImportFormats() {
return new TreeSet<>(this.formats);
}

/**
* Human readable list of all known import formats (name and CLI Id).
* <p>
* <p>List is sorted by importer name.</p>
*
* @return human readable list of all known import formats
*/
public String getImportFormatList() {
StringBuilder sb = new StringBuilder();

for (Importer imFo : getImportFormats()) {
int pad = Math.max(0, 14 - imFo.getName().length());
sb.append(" ");
sb.append(imFo.getName());

sb.append(StringUtil.repeatSpaces(pad));

sb.append(" : ");
sb.append(imFo.getId());
sb.append('\n');
}

return sb.toString();
}

public static class UnknownFormatImport {

public final String format;
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/org/jabref/cli/JabRefCLITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Collections;
import java.util.List;

import javafx.util.Pair;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -143,4 +145,22 @@ void wrapStringList() {

assertEquals(expected, "Available export formats: " + JabRefCLI.wrapStringList(given, 26));
}

@Test
void alignStringTable() {
List<Pair<String, String>> given = List.of(
new Pair<>("Apple", "Slice"),
new Pair<>("Bread", "Loaf"),
new Pair<>("Paper", "Sheet"),
new Pair<>("Country", "County"));

String expected = """
Apple : Slice
Bread : Loaf
Paper : Sheet
Country : County
""";

assertEquals(expected, JabRefCLI.alignStringTable(given));
}
}