diff --git a/.ado/build.yml b/.ado/build.yml new file mode 100644 index 00000000..eb85d473 --- /dev/null +++ b/.ado/build.yml @@ -0,0 +1,51 @@ +name: $(Rev:r) + +trigger: + branches: + include: + - '*' + exclude: + - master + +pr: + branches: + include: + - '*' + +jobs: +- job: 'Build' + displayName: 'Build for testing' + + pool: 'MC-Build-1ES-Azure-Pipeline-Linux' + container: adoptopenjdk/openjdk8:latest + + workspace: + clean: all + + steps: + - task: Gradle@2 + displayName: Build and Test + inputs: + workingDirectory: '' + gradleWrapperFile: 'gradlew' + gradleOptions: '-Xmx3072m' + options: '-PbuildNumber=0' + javaHomeOption: 'JDKVersion' + jdkUserInputPath: '/usr/java/openjdk-8' + testResultsFiles: '**/TEST-*.xml' + tasks: 'build test publish' + + # This is a workaround for ComponentGovernanceComponentDetection@0 not recognizing the generated `.pom` file(s) + - task: Bash@3 + displayName: Copy pom for component governance + inputs: + targetType: 'inline' + script: | + pompath=`find build/repo -name *.pom` + cp "${pompath}" build/pom.xml + + - task: ComponentGovernanceComponentDetection@0 + inputs: + scanType: 'Register' + verbosity: 'Verbose' + alertWarningLevel: 'High' diff --git a/.ado/release.yml b/.ado/release.yml new file mode 100644 index 00000000..b4c334ad --- /dev/null +++ b/.ado/release.yml @@ -0,0 +1,87 @@ +name: $(Rev:r) + +trigger: + branches: + include: + - master + +pr: none + +variables: + rConnection: 'mc-java-sc' + storageAccount: 'librariesminecraftnet' + storageAccountContainer: 'librariesminecraftnet' + keyVault: 'mc-java-vault' + +jobs: +- job: 'Build' + displayName: 'Build for release' + + pool: 'MC-Build-1ES-Azure-Pipeline-Linux' + container: adoptopenjdk/openjdk8:latest + + workspace: + clean: all + + steps: + - task: Gradle@2 + displayName: Build and Test + inputs: + workingDirectory: '' + gradleWrapperFile: 'gradlew' + gradleOptions: '-Xmx3072m' + options: '-PbuildNumber=$(Build.BuildNumber)' + javaHomeOption: 'JDKVersion' + jdkUserInputPath: '/usr/java/openjdk-8' + testResultsFiles: '**/TEST-*.xml' + tasks: 'build test publish report' + + # This is a workaround for ComponentGovernanceComponentDetection@0 not recognizing the generated `.pom` file(s) + - task: Bash@3 + displayName: Copy pom for component governance + inputs: + targetType: 'inline' + script: | + pompath=`find build/repo -name *.pom` + cp "${pompath}" build/pom.xml + + - task: ComponentGovernanceComponentDetection@0 + inputs: + scanType: 'Register' + verbosity: 'Verbose' + alertWarningLevel: 'High' + + - publish: 'build/repo/' + artifact: repo + +- job: 'Publish' + displayName: 'Publish release' + dependsOn: Build + condition: eq(variables['Build.SourceBranch'], 'refs/heads/master') + + pool: 'MC-Build-1ES-Azure-Pipeline-Linux' + + workspace: + clean: all + + steps: + - download: current + artifact: repo + + - task: AzureKeyVault@1 + displayName: 'Fetching secrets' + name: secrets + inputs: + azureSubscription: '$(rConnection)' + KeyVaultName: '$(keyVault)' + SecretsFilter: 'access-key-prod-librariesminecraftnet' + RunAsPreJob: false + + - task: AzureCLI@2 + displayName: Azure CLI + inputs: + azureSubscription: '$(rConnection)' + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az storage blob upload-batch -s '$(Pipeline.Workspace)/repo' -d $(storageAccountContainer) --account-name $(storageAccount) --account-key $(access-key-prod-librariesminecraftnet) diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml new file mode 100644 index 00000000..de2dee69 --- /dev/null +++ b/.github/workflows/pr-check.yml @@ -0,0 +1,22 @@ +name: pr-check + +on: [ pull_request ] + +jobs: + build: + name: Build and test + runs-on: ubuntu-latest + container: + image: adoptopenjdk/openjdk8:latest + + steps: + - uses: actions/checkout@v3 + - name: Build with Gradle + uses: gradle/gradle-build-action@v2 + with: + arguments: build test + - name: Publish Test Report + uses: mikepenz/action-junit-report@v3 + if: always() + with: + report_paths: '**/build/test-results/test/TEST-*.xml' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e71a43f5..00000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -sudo: false -dist: trusty -language: java - -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ - -jdk: - - oraclejdk8 - -script: - - ./gradlew check --info -S --parallel \ No newline at end of file diff --git a/build.gradle b/build.gradle index 5614d587..56af6689 100644 --- a/build.gradle +++ b/build.gradle @@ -78,7 +78,7 @@ publishing { task report { doLast { - println "##teamcity[buildNumber '${project.version}']" + println "##vso[build.updatebuildnumber]${project.version}" } } diff --git a/gradle.properties b/gradle.properties index 8dee0e07..7b2a236a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -majorMinor: 1.0 \ No newline at end of file +majorMinor: 1.1 diff --git a/src/main/java/com/mojang/brigadier/CommandDispatcher.java b/src/main/java/com/mojang/brigadier/CommandDispatcher.java index 14d2a7ed..8becbf3a 100644 --- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java +++ b/src/main/java/com/mojang/brigadier/CommandDispatcher.java @@ -230,7 +230,6 @@ public int execute(final ParseResults parse) throws CommandSyntaxException { if (child != null) { forked |= context.isForked(); if (child.hasNodes()) { - foundCommand = true; final RedirectModifier modifier = context.getRedirectModifier(); if (modifier == null) { if (next == null) { @@ -247,6 +246,8 @@ public int execute(final ParseResults parse) throws CommandSyntaxException { for (final S source : results) { next.add(child.copyFor(source)); } + } else { + foundCommand = true; } } catch (final CommandSyntaxException ex) { consumer.onCommandComplete(context, false, 0); diff --git a/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java b/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java index 6667bd22..61b471fd 100644 --- a/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java +++ b/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java @@ -4,15 +4,16 @@ package com.mojang.brigadier; import com.google.common.collect.Lists; +import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContextBuilder; import com.mojang.brigadier.context.StringRange; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.tree.ArgumentCommandNode; -import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.tree.ArgumentCommandNode; +import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.LiteralCommandNode; import org.junit.Before; import org.junit.Test; @@ -20,6 +21,11 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal; import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument; @@ -39,10 +45,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Collection; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - @RunWith(MockitoJUnitRunner.class) public class CommandDispatcherTest { private CommandDispatcher subject; @@ -423,6 +425,37 @@ public void testExecuteRedirected() throws Exception { verify(command).run(argThat(hasProperty("source", is(source2)))); } + @Test + public void testIncompleteRedirectShouldThrow() { + final LiteralCommandNode foo = subject.register(literal("foo") + .then(literal("bar") + .then(argument("value", integer()).executes(context -> IntegerArgumentType.getInteger(context, "value")))) + .then(literal("awa").executes(context -> 2))); + final LiteralCommandNode baz = subject.register(literal("baz").redirect(foo)); + try { + int result = subject.execute("baz bar", source); + fail("Should have thrown an exception"); + } catch (CommandSyntaxException e) { + assertThat(e.getType(), is(CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand())); + } + } + + @Test + public void testRedirectModifierEmptyResult() { + final LiteralCommandNode foo = subject.register(literal("foo") + .then(literal("bar") + .then(argument("value", integer()).executes(context -> IntegerArgumentType.getInteger(context, "value")))) + .then(literal("awa").executes(context -> 2))); + final RedirectModifier emptyModifier = context -> Collections.emptyList(); + final LiteralCommandNode baz = subject.register(literal("baz").fork(foo, emptyModifier)); + try { + int result = subject.execute("baz bar 100", source); + assertThat(result, is(0)); // No commands executed, so result is 0 + } catch (CommandSyntaxException e) { + fail("Should not throw an exception"); + } + } + @Test public void testExecuteOrphanedSubcommand() throws Exception { subject.register(literal("foo").then(