-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Feat: Add integrity check to cli #13848
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
Merged
Merged
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
812fa4b
extend CheckIntegrity
palukku 82723a6
add check integrity to jabkit
palukku da299eb
replace writer
palukku ce3a15d
Merge branch 'main' into add-integrity-check-to-cli
palukku efebec9
fix imports
palukku c49f597
fix format
palukku 805cc42
add separator character handling
palukku 2d8c404
remove exception
palukku 2e5b4e2
adapt languages
palukku fd0d992
fix language tests
palukku 228838c
fix language tests 2
palukku 743765d
change field ranges in BibtexParser
palukku 244217c
re-add CygWinPathConverter
palukku 8fc9fd6
fix modernizer
palukku 483b3f0
fix modernizer2
palukku c0bf69b
move fieldranges to parser
palukku cf7924a
added changelog entry
palukku 4b9ac21
change HashMap to IdentityHashMap
palukku 764c5ba
remove line
palukku 58180f7
remove unused import
palukku 10231e0
add IntegrityCheckResultWriter
palukku f92d8f6
address comments
palukku 58aee67
add immutable Map#of
palukku fef7e2e
updated option handling and fix check
palukku eff8e17
remove test output
palukku 4bd013e
add comment on constructor handling the writer and close
palukku File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 104 additions & 8 deletions
112
jabkit/src/main/java/org/jabref/cli/CheckIntegrity.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,133 @@ | ||
| package org.jabref.cli; | ||
|
|
||
| import java.nio.file.Path; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Locale; | ||
| import java.util.Map; | ||
| import java.util.Optional; | ||
| import java.util.concurrent.Callable; | ||
|
|
||
| import org.jabref.cli.converter.CygWinPathConverter; | ||
| import org.jabref.logic.importer.ParserResult; | ||
| import org.jabref.logic.integrity.IntegrityCheck; | ||
| import org.jabref.logic.integrity.IntegrityMessage; | ||
| import org.jabref.logic.journals.JournalAbbreviationLoader; | ||
| import org.jabref.logic.l10n.Localization; | ||
| import org.jabref.model.database.BibDatabaseContext; | ||
| import org.jabref.model.entry.field.Field; | ||
| import org.jabref.model.entry.field.InternalField; | ||
|
|
||
| import picocli.CommandLine; | ||
|
|
||
| import static picocli.CommandLine.Command; | ||
| import static picocli.CommandLine.Mixin; | ||
| import static picocli.CommandLine.Option; | ||
| import static picocli.CommandLine.Parameters; | ||
|
|
||
| @Command(name = "check-integrity", description = "Check integrity of the database.") | ||
| class CheckIntegrity implements Runnable { | ||
| class CheckIntegrity implements Callable<Integer> { | ||
|
|
||
| @CommandLine.ParentCommand | ||
| private ArgumentProcessor argumentProcessor; | ||
|
|
||
| @Mixin | ||
| private ArgumentProcessor.SharedOptions sharedOptions = new ArgumentProcessor.SharedOptions(); | ||
|
|
||
| @Parameters(index = "0", converter = CygWinPathConverter.class, description = "BibTeX file to check", arity = "0..1") | ||
| @Parameters(converter = CygWinPathConverter.class, description = "BibTeX file to check", arity = "1") | ||
| private Path inputFile; | ||
|
|
||
| @Option(names = {"--input"}, converter = CygWinPathConverter.class, description = "Input BibTeX file") | ||
| private Path inputOption; | ||
| @Option(names = {"--output-format"}, description = "Output format: errorformat, txt or csv", defaultValue = "errorformat") | ||
| private String outputFormat; | ||
|
|
||
| @Option(names = {"--output-format"}, description = "Output format: txt or csv") | ||
| private String outputFormat = "txt"; // FixMe: Default value? | ||
| @Option(names = {"--allow-integer-edition"}, description = "Allows Integer edition: true or false", defaultValue = "true") | ||
palukku marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| private boolean allowIntegerEdition = true; | ||
|
|
||
| @Override | ||
| public void run() { | ||
| public Integer call() { | ||
| Optional<ParserResult> parserResult = ArgumentProcessor.importFile( | ||
| inputFile, | ||
| "bibtex", | ||
| argumentProcessor.cliPreferences, | ||
| sharedOptions.porcelain); | ||
| if (parserResult.isEmpty()) { | ||
| System.out.println(Localization.lang("Unable to open file '%0'.", inputFile)); | ||
| return 2; | ||
palukku marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| if (parserResult.get().isInvalid()) { | ||
| System.out.println(Localization.lang("Input file '%0' is invalid and could not be parsed.", inputFile)); | ||
| return 2; | ||
palukku marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| if (!sharedOptions.porcelain) { | ||
| System.out.println(Localization.lang("Checking integrity of '%0'.", inputFile)); | ||
| System.out.flush(); | ||
| } | ||
|
|
||
| // TODO: Implement integrity checking | ||
| BibDatabaseContext databaseContext = parserResult.get().getDatabaseContext(); | ||
|
|
||
| IntegrityCheck integrityCheck = new IntegrityCheck( | ||
| databaseContext, | ||
| argumentProcessor.cliPreferences.getFilePreferences(), | ||
| argumentProcessor.cliPreferences.getCitationKeyPatternPreferences(), | ||
| JournalAbbreviationLoader.loadRepository(argumentProcessor.cliPreferences.getJournalAbbreviationPreferences()), | ||
| allowIntegerEdition | ||
| ); | ||
|
|
||
| List<IntegrityMessage> messages = databaseContext.getEntries().stream() | ||
| .flatMap(entry -> { | ||
| if (!sharedOptions.porcelain) { | ||
| System.out.println(Localization.lang("Checking integrity of '%0'.", entry.getCitationKey().orElse(""))); | ||
| } | ||
| return integrityCheck.checkEntry(entry).stream(); | ||
| }) | ||
| .toList(); | ||
|
|
||
| return switch (outputFormat.toLowerCase(Locale.ROOT)) { | ||
| case "errorformat" -> | ||
| outputErrorFormat(messages, parserResult.get()); | ||
| case "txt" -> | ||
| outputTxt(messages); | ||
| case "csv" -> | ||
| outputCsv(messages); | ||
| default -> { | ||
| System.out.println(Localization.lang("Unknown output format '%0'.", outputFormat)); | ||
| yield 3; | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| private int outputCsv(List<IntegrityMessage> messages) { | ||
| System.out.println("Citation Key,Field,Message"); | ||
Siedlerchr marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| for (IntegrityMessage message : messages) { | ||
palukku marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| String citationKey = message.entry().getCitationKey().orElse(""); | ||
| String field = message.field() != null ? message.field().getDisplayName() : ""; | ||
| String msg = message.message().replace("\"", "\\\""); | ||
| if (msg.contains(",")) { | ||
| msg = "\"" + msg + "\""; | ||
| } | ||
| System.out.printf("%s,%s,%s%n", citationKey, field, msg); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| private int outputTxt(List<IntegrityMessage> messages) { | ||
| messages.forEach(System.out::println); | ||
| return 0; | ||
| } | ||
|
|
||
| private int outputErrorFormat(List<IntegrityMessage> messages, ParserResult parserResult) { | ||
| for (IntegrityMessage message : messages) { | ||
| Map<Field, ParserResult.Range> fieldRangeMap = parserResult.getFieldRanges().getOrDefault(message.entry(), new HashMap<>()); | ||
| ParserResult.Range fieldRange = fieldRangeMap.getOrDefault(message.field(), fieldRangeMap.getOrDefault(InternalField.KEY_FIELD, parserResult.getArticleRanges().getOrDefault(message.entry(), ParserResult.Range.getNullRange()))); | ||
|
|
||
| System.out.printf("%s:%d:%d: %s\n".formatted( | ||
| inputFile, | ||
| fieldRange.startLine(), | ||
| fieldRange.startColumn(), | ||
| message.message())); | ||
| } | ||
| return 0; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.