From d7d3b4a502c7f589d67f12ae3b482853890eaffd Mon Sep 17 00:00:00 2001 From: opazenha Date: Thu, 20 Nov 2025 12:22:57 +0000 Subject: [PATCH 1/6] refactor(jabkit): improve usage footer generation and add export format support Extract option checking logic into helper method and use Map to track command options. Add constants for footer labels and implement support for export format footers alongside existing input and output formats. --- .../org/jabref/toolkit/JabKitLauncher.java | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java index 27d4457ba89..b0338d70b23 100644 --- a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java +++ b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java @@ -7,6 +7,7 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -104,26 +105,41 @@ public static void main(String[] args) { } } + private static boolean hasCommandOption(CommandLine.Model.CommandSpec commandSpec, String optionName) { + return commandSpec.options().stream() + .anyMatch(opt -> Arrays.asList(opt.names()).contains(optionName)); + } + private static void applyUsageFooters(CommandLine commandLine, List> inputFormats, List> outputFormats, Set fetchers) { + + final String INPUT_FOOTER_LABEL = "Available import formats:"; + final String OUTPUT_FOOTER_LABEL = "Available output formats:"; + final String EXPORT_FOOTER_LABEL = "Available export formats:"; + String inputFooter = "\n" - + Localization.lang("Available import formats:") + "\n" + + INPUT_FOOTER_LABEL + "\n" + StringUtil.alignStringTable(inputFormats); String outputFooter = "\n" - + Localization.lang("Available export formats:") + "\n" + + OUTPUT_FOOTER_LABEL + "\n" + + StringUtil.alignStringTable(outputFormats); + String exportFooter = "\n" + + EXPORT_FOOTER_LABEL + "\n" + StringUtil.alignStringTable(outputFormats); commandLine.getSubcommands().values().forEach(subCommand -> { - boolean hasInputOption = subCommand.getCommandSpec().options().stream() - .anyMatch(opt -> Arrays.asList(opt.names()).contains("--input-format")); - boolean hasOutputOption = subCommand.getCommandSpec().options().stream() - .anyMatch(opt -> Arrays.asList(opt.names()).contains("--output-format")); + Map hasOptions = Map.of( + "input", hasCommandOption(subCommand.getCommandSpec(), "--input-format"), + "output", hasCommandOption(subCommand.getCommandSpec(), "--output-format"), + "export", hasCommandOption(subCommand.getCommandSpec(), "--export-format") + ); String footerText = ""; - footerText += hasInputOption ? inputFooter : ""; - footerText += hasOutputOption ? outputFooter : ""; + footerText += hasOptions.get("input") ? inputFooter : ""; + footerText += hasOptions.get("output") ? outputFooter : ""; + footerText += hasOptions.get("export") ? exportFooter : ""; subCommand.getCommandSpec().usageMessage().footer(footerText); }); From d7586387a9166c1c8263e06670785dc4f7e45185 Mon Sep 17 00:00:00 2001 From: opazenha Date: Thu, 20 Nov 2025 12:28:00 +0000 Subject: [PATCH 2/6] refactor(jabkit): reorganize method order and add documentation Move hasCommandOption method below applyUsageFooters for better logical grouping and add comprehensive JavaDoc documentation to explain the usage footer application functionality. --- .../java/org/jabref/toolkit/JabKitLauncher.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java index b0338d70b23..1eafe6c4ac4 100644 --- a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java +++ b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java @@ -105,11 +105,10 @@ public static void main(String[] args) { } } - private static boolean hasCommandOption(CommandLine.Model.CommandSpec commandSpec, String optionName) { - return commandSpec.options().stream() - .anyMatch(opt -> Arrays.asList(opt.names()).contains(optionName)); - } - + /** + * Applies appropriate usage footers to each subcommand based on their supported options. + * Distinguishes between input formats, output formats, and export formats. + */ private static void applyUsageFooters(CommandLine commandLine, List> inputFormats, List> outputFormats, @@ -151,6 +150,11 @@ private static void applyUsageFooters(CommandLine commandLine, .collect(Collectors.joining(", "))); } + private static boolean hasCommandOption(CommandLine.Model.CommandSpec commandSpec, String optionName) { + return commandSpec.options().stream() + .anyMatch(opt -> Arrays.asList(opt.names()).contains(optionName)); + } + /// This needs to be called as early as possible. After the first log writing, it /// is not possible to alter the log configuration programmatically anymore. public static void initLogging(String[] args) { From 12139fbd37e6404ee69c6194895d1ec933a810ef Mon Sep 17 00:00:00 2001 From: opazenha Date: Wed, 26 Nov 2025 09:28:44 +0000 Subject: [PATCH 3/6] refactor(jabkit): skip redundant format footers for check-consistency command --- .../src/main/java/org/jabref/toolkit/JabKitLauncher.java | 9 ++++++--- .../java/org/jabref/toolkit/commands/JabKitTest.java | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java index 1eafe6c4ac4..304e0f5c226 100644 --- a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java +++ b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java @@ -136,9 +136,12 @@ private static void applyUsageFooters(CommandLine commandLine, ); String footerText = ""; - footerText += hasOptions.get("input") ? inputFooter : ""; - footerText += hasOptions.get("output") ? outputFooter : ""; - footerText += hasOptions.get("export") ? exportFooter : ""; + // Skip format footers for check-consistency since formats are already documented in option description + if (!"check-consistency".equals(subCommand.getCommandSpec().name())) { + footerText += hasOptions.get("input") ? inputFooter : ""; + footerText += hasOptions.get("output") ? outputFooter : ""; + footerText += hasOptions.get("export") ? exportFooter : ""; + } subCommand.getCommandSpec().usageMessage().footer(footerText); }); diff --git a/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java b/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java index 5ccf2cb7a03..33ac4264866 100644 --- a/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java +++ b/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.api.io.TempDir; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; From 057e0fde5bf9bf8e042683687a011de9015db206 Mon Sep 17 00:00:00 2001 From: opazenha Date: Wed, 26 Nov 2025 09:31:23 +0000 Subject: [PATCH 4/6] refactor(jabkit): improve CLI output formatting and code organization --- jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java b/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java index 33ac4264866..5ccf2cb7a03 100644 --- a/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java +++ b/jabkit/src/test/java/org/jabref/toolkit/commands/JabKitTest.java @@ -23,7 +23,6 @@ import org.junit.jupiter.api.io.TempDir; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; From f9273d59531c057257b501f05e9c643186099c04 Mon Sep 17 00:00:00 2001 From: opazenha Date: Wed, 26 Nov 2025 15:07:35 +0000 Subject: [PATCH 5/6] fix: use localization for format labels in jabkit - Replace hardcoded strings with Localization.lang() calls - Add missing 'Available output formats:' localization key - Fixes failing LocalizationConsistencyTest --- .../org/jabref/toolkit/JabKitLauncher.java | 6 +++--- .../main/resources/l10n/JabRef_en.properties | 1 + pr_description.md | 21 +++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 pr_description.md diff --git a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java index 304e0f5c226..59c4b3c9a97 100644 --- a/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java +++ b/jabkit/src/main/java/org/jabref/toolkit/JabKitLauncher.java @@ -114,9 +114,9 @@ private static void applyUsageFooters(CommandLine commandLine, List> outputFormats, Set fetchers) { - final String INPUT_FOOTER_LABEL = "Available import formats:"; - final String OUTPUT_FOOTER_LABEL = "Available output formats:"; - final String EXPORT_FOOTER_LABEL = "Available export formats:"; + final String INPUT_FOOTER_LABEL = Localization.lang("Available import formats:"); + final String OUTPUT_FOOTER_LABEL = Localization.lang("Available output formats:"); + final String EXPORT_FOOTER_LABEL = Localization.lang("Available export formats:"); String inputFooter = "\n" + INPUT_FOOTER_LABEL + "\n" diff --git a/jablib/src/main/resources/l10n/JabRef_en.properties b/jablib/src/main/resources/l10n/JabRef_en.properties index 8c94453fd4b..4d59ad2602b 100644 --- a/jablib/src/main/resources/l10n/JabRef_en.properties +++ b/jablib/src/main/resources/l10n/JabRef_en.properties @@ -3301,6 +3301,7 @@ Continue\ walkthrough=Continue walkthrough # CommandLine Available\ export\ formats\:=Available export formats: Available\ import\ formats\:=Available import formats: +Available\ output\ formats\:=Available output formats: Cannot\ embed\ metadata\ on\ any\ linked\ files\ of\ %s.\ Make\ sure\ there\ is\ at\ least\ one\ linked\ file\ and\ the\ path\ is\ correct.=Cannot embed metadata on any linked files of %s. Make sure there is at least one linked file and the path is correct. Cannot\ write\ XMP\ metadata\ on\ any\ linked\ files\ of\ %0.\ Make\ sure\ there\ is\ at\ least\ one\ linked\ file\ and\ the\ path\ is\ correct.=Cannot write XMP metadata on any linked files of %0. Make sure there is at least one linked file and the path is correct. Checking\ consistency\ of\ '%0'.=Checking consistency of '%0'. diff --git a/pr_description.md b/pr_description.md new file mode 100644 index 00000000000..5faa39ca115 --- /dev/null +++ b/pr_description.md @@ -0,0 +1,21 @@ +Closes #13275 + +Refactored jabkit CLI to improve output formatting and code organization. Changes include clearing unused imports, skipping redundant format footers for check-consistency command, reorganizing method order, adding documentation, and improving usage footer generation with export format support. + +### Steps to test + +1. Build the project: `./gradlew build` +2. Run jabkit commands to verify output formatting: + - `./gradlew :jabkit-cli:run --args="check-consistency"` + - `./gradlew :jabkit-cli:run --args="export --help"` +3. Verify that redundant footers are no longer displayed +4. Check that usage information is properly formatted + +### Mandatory checks + +- [x] I own the copyright of the code submitted and I license it under the [MIT license](https://github.com/JabRef/jabref/blob/main/LICENSE) +- [x] I manually tested my changes in running JabRef (always required) +- [/] I added JUnit tests for changes (if applicable) +- [/] I added screenshots in the PR description (if change is visible to the user) +- [/] I described the change in `CHANGELOG.md` in a way that is understandable for the average user (if change is visible to the user) +- [/] I checked the [user documentation](https://docs.jabref.org/): Is the information available and up to date? If not, I created an issue at or, even better, I submitted a pull request updating file(s) in . \ No newline at end of file From 4c2b3f3531513c8a27782f9c331c56f67c7a6dfe Mon Sep 17 00:00:00 2001 From: opazenha Date: Wed, 26 Nov 2025 15:22:45 +0000 Subject: [PATCH 6/6] refactor(jabkit): remove temporary support markdown file. --- pr_description.md | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 pr_description.md diff --git a/pr_description.md b/pr_description.md deleted file mode 100644 index 5faa39ca115..00000000000 --- a/pr_description.md +++ /dev/null @@ -1,21 +0,0 @@ -Closes #13275 - -Refactored jabkit CLI to improve output formatting and code organization. Changes include clearing unused imports, skipping redundant format footers for check-consistency command, reorganizing method order, adding documentation, and improving usage footer generation with export format support. - -### Steps to test - -1. Build the project: `./gradlew build` -2. Run jabkit commands to verify output formatting: - - `./gradlew :jabkit-cli:run --args="check-consistency"` - - `./gradlew :jabkit-cli:run --args="export --help"` -3. Verify that redundant footers are no longer displayed -4. Check that usage information is properly formatted - -### Mandatory checks - -- [x] I own the copyright of the code submitted and I license it under the [MIT license](https://github.com/JabRef/jabref/blob/main/LICENSE) -- [x] I manually tested my changes in running JabRef (always required) -- [/] I added JUnit tests for changes (if applicable) -- [/] I added screenshots in the PR description (if change is visible to the user) -- [/] I described the change in `CHANGELOG.md` in a way that is understandable for the average user (if change is visible to the user) -- [/] I checked the [user documentation](https://docs.jabref.org/): Is the information available and up to date? If not, I created an issue at or, even better, I submitted a pull request updating file(s) in . \ No newline at end of file