diff --git a/.github/workflows/files/languageParameterTest.zip b/.github/workflows/files/languageParameterTest.zip new file mode 100644 index 0000000000..66267c0148 Binary files /dev/null and b/.github/workflows/files/languageParameterTest.zip differ diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index e246a7bb7a..497874474c 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -63,16 +63,22 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] dataset: [ - {zip: "progpedia.zip", name: "progpedia", folder: "ACCEPTED", language: "java", cliArgs: "-bc base"}, - {zip: "fileSingleRoot.zip", name: "fileSingleRoot", folder: "fileSingleRoot", language: "java", cliArgs: ""}, - {zip: "folderSingleRoot.zip", name: "folderSingleRoot", folder: "folderSingleRoot", language: "java", cliArgs: ""}, - {zip: "fileMultiRoot.zip", name: "fileMultiRoot", folder: "f0", language: "java", cliArgs: "--new f1"}, - {zip: "folderMultiRoot.zip", name: "folderMultiRoot", folder: "f0", language: "java", cliArgs: "--new f1"}, - {zip: "mixedMultiRoot.zip", name: "mixedBaseFile", folder: "f0", language: "java", cliArgs: "--new f1"}, - {zip: "mixedMultiRoot.zip", name: "mixedBaseFolder", folder: "f1", language: "java", cliArgs: "--new f0"}, - {zip: "cpp.zip", name: "cpp", folder: "./cpp", language: "cpp", cliArgs: ""}, - {zip: "csharp.zip", name: "csharp", folder: "./csharp", language: "csharp", cliArgs: ""}, - {zip: "python.zip", name: "python", folder: "./python", language: "python3", cliArgs: ""} + # Test multiple ways of giving code directories + {zip: "progpedia.zip", name: "progpedia", folder: "ACCEPTED", cliArgs: "-l java -bc base"}, + {zip: "fileSingleRoot.zip", name: "fileSingleRoot", folder: "fileSingleRoot", cliArgs: "-l java"}, + {zip: "folderSingleRoot.zip", name: "folderSingleRoot", folder: "folderSingleRoot", cliArgs: "-l java"}, + {zip: "fileMultiRoot.zip", name: "fileMultiRoot", folder: "f0", cliArgs: "-l java --new f1"}, + {zip: "folderMultiRoot.zip", name: "folderMultiRoot", folder: "f0", cliArgs: "-l java --new f1"}, + {zip: "mixedMultiRoot.zip", name: "mixedBaseFile", folder: "f0", cliArgs: "-l java --new f1"}, + {zip: "mixedMultiRoot.zip", name: "mixedBaseFolder", folder: "f1", cliArgs: "-l java --new f0"}, + # Test that different languages work + {zip: "cpp.zip", name: "cpp", folder: "./cpp", cliArgs: "-l cpp"}, + {zip: "csharp.zip", name: "csharp", folder: "./csharp", cliArgs: "-l csharp"}, + {zip: "python.zip", name: "python", folder: "./python", cliArgs: "-l python3"}, + # Test multiple varients of giving JPlag the language + {zip: "languageParameterTest.zip", name: "languageParameterTest1", folder: "languageParameterTest", cliArgs: "-l java -t 1"}, {zip: "languageParameterTest.zip", name: "languageParameterTest2", folder: "languageParameterTest", cliArgs: "-t 1 -l java"}, + {zip: "languageParameterTest.zip", name: "languageParameterTest3", folder: "languageParameterTest", cliArgs: "java -t 1"}, + {zip: "languageParameterTest.zip", name: "languageParameterTest4", folder: "languageParameterTest", cliArgs: "-t 1 java"} ] steps: @@ -102,7 +108,7 @@ jobs: - name: Run JPlag run: | - java -jar jplag.jar ${{ matrix.dataset.folder }} -l ${{ matrix.dataset.language }} -r ${{ matrix.dataset.name }}-report ${{ matrix.dataset.cliArgs }} + java -jar jplag.jar ${{ matrix.dataset.folder }} -r ${{ matrix.dataset.name }}-report ${{ matrix.dataset.cliArgs }} - name: Upload result uses: actions/upload-artifact@v6 diff --git a/cli/src/main/java/de/jplag/cli/JPlagOptionsBuilder.java b/cli/src/main/java/de/jplag/cli/JPlagOptionsBuilder.java index 206e38915a..e7426bbeb0 100644 --- a/cli/src/main/java/de/jplag/cli/JPlagOptionsBuilder.java +++ b/cli/src/main/java/de/jplag/cli/JPlagOptionsBuilder.java @@ -43,7 +43,6 @@ public JPlagOptions buildOptions() throws CliException { Set oldSubmissionDirectories = Set.of(this.cliOptions.oldDirectories); List suffixes = List.of(this.cliOptions.advanced.suffixes); submissionDirectories.addAll(List.of(this.cliOptions.newDirectories)); - submissionDirectories.addAll(this.cliInputHandler.getSubcommandSubmissionDirectories()); JPlagOptions jPlagOptions = initializeJPlagOptions(submissionDirectories, oldSubmissionDirectories, suffixes); diff --git a/cli/src/main/java/de/jplag/cli/picocli/CliInputHandler.java b/cli/src/main/java/de/jplag/cli/picocli/CliInputHandler.java index bbe837cee2..c6d785384f 100644 --- a/cli/src/main/java/de/jplag/cli/picocli/CliInputHandler.java +++ b/cli/src/main/java/de/jplag/cli/picocli/CliInputHandler.java @@ -9,7 +9,6 @@ import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Random; import java.util.stream.Collectors; @@ -78,7 +77,9 @@ private CommandLine buildCommandLine() { }).collect(Collectors.joining(System.lineSeparator())) + System.lineSeparator()); cli.getHelpSectionMap().put(SECTION_KEY_COMMAND_LIST_HEADING, help -> "Languages:" + System.lineSeparator()); - buildSubcommands().forEach(cli::addSubcommand); + for (CommandLine.Model.CommandSpec subcommand : buildSubcommands()) { + cli.addSubcommand(subcommand).setHelpFactory(new HelpFactory()); + } cli.getHelpSectionMap().put(SECTION_KEY_SYNOPSIS, help -> help.synopsis(help.synopsisHeadingLength()) + generateDescription()); cli.getHelpSectionMap().put(SECTION_KEY_DESCRIPTION_HEADING, help -> OPTION_LIST_HEADING); @@ -95,14 +96,24 @@ private List buildSubcommands() { command.addOption(CommandLine.Model.OptionSpec.builder(option.getNameAsUnixParameter()).type(option.getType().getJavaType()) .description(option.getDescription()).build()); } - command.mixinStandardHelpOptions(true); - command.addPositional( - CommandLine.Model.PositionalParamSpec.builder().type(List.class).auxiliaryTypes(File.class).hidden(true).required(false).build()); + command.addMixin("root", buildRootParametersForSubcommands()); return command; }).toList(); } + private CommandLine.Model.CommandSpec buildRootParametersForSubcommands() { + CommandLine.Model.CommandSpec originalOptions = CommandLine.Model.CommandSpec.forAnnotatedObject(this.options); + CommandLine.Model.CommandSpec hiddenOptions = CommandLine.Model.CommandSpec.create(); + originalOptions.options().forEach(option -> { + hiddenOptions.addOption(CommandLine.Model.OptionSpec.builder(option).hidden(true).required(false).build()); + }); + originalOptions.positionalParameters().forEach(parameter -> { + hiddenOptions.addPositional(CommandLine.Model.PositionalParamSpec.builder(parameter).hidden(true).required(false).build()); + }); + return hiddenOptions; + } + /** * Parses the cli parameters and prints the usage help if requested. * @return true, if the usage help has been requested. In this case the program should stop. @@ -160,16 +171,6 @@ public Language getSelectedLanguage() throws CliException { return language; } - /** - * @return The submission directories configured for the subcommand, if one has been given. - */ - public List getSubcommandSubmissionDirectories() { - if (this.parseResult.subcommand() != null && this.parseResult.subcommand().hasMatchedPositional(0)) { - return this.parseResult.subcommand().matchedPositional(0).getValue(); - } - return Collections.emptyList(); - } - private String generateDescription() { var randomDescription = DESCRIPTIONS[RANDOM.nextInt(DESCRIPTIONS.length)]; return String.format(DESCRIPTION_PATTERN, randomDescription, CREDITS); diff --git a/report-viewer/report-viewer/tests/e2e/OpenComparisonTest.spec.ts b/report-viewer/report-viewer/tests/e2e/OpenComparisonTest.spec.ts index e7886c8de4..a614a6a213 100644 --- a/report-viewer/report-viewer/tests/e2e/OpenComparisonTest.spec.ts +++ b/report-viewer/report-viewer/tests/e2e/OpenComparisonTest.spec.ts @@ -56,6 +56,15 @@ const testSets: DataSet[] = [ } ] +// Add the tests for each language parameter test +for (let i = 1; i <= 4; i++) { + testSets.push({ + datasetName: `languageParameterTest${i}-report.jplag`, + firstSubmissionName: '1.java', + secondSubmissionName: '2.java' + }) +} + for (const testSet of testSets) { test(`Can open ${testSet.datasetName}`, async ({ page }) => { await uploadFile(testSet.datasetName, page)