Skip to content

Commit

Permalink
Normalize ArC subclasses when getting the overriding options
Browse files Browse the repository at this point in the history
Fixes #352
  • Loading branch information
gsmet committed Sep 6, 2022
1 parent 6eb338a commit c741d0d
Show file tree
Hide file tree
Showing 11 changed files with 2,073 additions and 1 deletion.
Expand Up @@ -28,6 +28,8 @@

import io.quarkiverse.githubapp.command.airline.runtime.util.Commandline;
import io.quarkiverse.githubapp.command.airline.runtime.util.Reactions;
import io.quarkus.arc.ClientProxy;
import io.quarkus.arc.Subclass;

public abstract class AbstractCommandDispatcher<C> {

Expand Down Expand Up @@ -80,7 +82,7 @@ protected Optional<CommandExecutionContext<C>> getCommand(GHEventPayload.IssueCo
ParseResult<C> parseResult = cli.parseWithResult(commandLine);

if (parseResult.wasSuccessful()) {
String commandClassName = parseResult.getCommand().getClass().getName();
String commandClassName = normalizeCommandClass(parseResult.getCommand().getClass()).getName();

CommandConfig commandConfig = commandConfigs.getOrDefault(commandClassName,
cliConfig.getDefaultCommandConfig());
Expand Down Expand Up @@ -111,6 +113,17 @@ protected Optional<CommandExecutionContext<C>> getCommand(GHEventPayload.IssueCo
return Optional.empty();
}

private static Class<?> normalizeCommandClass(Class<?> commandClass) {
if (Subclass.class.isAssignableFrom(commandClass)) {
return commandClass.getSuperclass();
}
if (ClientProxy.class.isAssignableFrom(commandClass)) {
return commandClass.getSuperclass();
}

return commandClass;
}

private boolean matches(String cli) {
for (String alias : cliConfig.getAliases()) {
if (alias.equals(cli)) {
Expand Down
@@ -0,0 +1,111 @@
package io.quarkiverse.githubapp.it.command.airline;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.io.IOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InterceptorBinding;
import javax.interceptor.InvocationContext;

import org.kohsuke.github.GHEventPayload;
import org.kohsuke.github.GHEventPayload.IssueComment;

import com.github.rvesse.airline.annotations.Cli;
import com.github.rvesse.airline.annotations.Command;

import io.quarkiverse.githubapp.command.airline.CliOptions;
import io.quarkiverse.githubapp.command.airline.CommandOptions;
import io.quarkiverse.githubapp.command.airline.CommandOptions.CommandScope;
import io.quarkiverse.githubapp.it.command.airline.ArcSubclassesCli.TestApplicationScopedCommand1;
import io.quarkiverse.githubapp.it.command.airline.ArcSubclassesCli.TestApplicationScopedCommand2;
import io.quarkiverse.githubapp.it.command.airline.ArcSubclassesCli.TestSubclassCommand1;
import io.quarkiverse.githubapp.it.command.airline.ArcSubclassesCli.TestSubclassCommand2;
import io.quarkiverse.githubapp.it.command.airline.DefaultCommandOptionsCli.TestCommand;

@Cli(name = "@arc", commands = { TestApplicationScopedCommand1.class, TestApplicationScopedCommand2.class,
TestSubclassCommand1.class, TestSubclassCommand2.class })
@CliOptions(defaultCommandOptions = @CommandOptions(scope = CommandScope.ISSUES))
public class ArcSubclassesCli {

@Command(name = "application-scoped-command1")
@ApplicationScoped
static class TestApplicationScopedCommand1 implements TestCommand {

@Override
public void run(IssueComment issueCommentPayload) throws IOException {
issueCommentPayload.getIssue().comment("hello from @arc application-scoped-command1");
}
}

@Command(name = "application-scoped-command2")
@CommandOptions(scope = CommandScope.ISSUES_AND_PULL_REQUESTS)
@ApplicationScoped
static class TestApplicationScopedCommand2 implements TestCommand {

@Override
public void run(IssueComment issueCommentPayload) throws IOException {
issueCommentPayload.getIssue().comment("hello from @arc application-scoped-command2");
}
}

// we add an interceptor to generate a `_Subclass`
@Command(name = "subclass-command1")
@DoNothing
static class TestSubclassCommand1 implements TestCommand {

@Override
public void run(IssueComment issueCommentPayload) throws IOException {
issueCommentPayload.getIssue().comment("hello from @arc subclass-command1");
}
}

// we add an interceptor to generate a `_Subclass`
@Command(name = "subclass-command2")
@CommandOptions(scope = CommandScope.ISSUES_AND_PULL_REQUESTS)
@DoNothing
static class TestSubclassCommand2 implements TestCommand {

@Override
public void run(IssueComment issueCommentPayload) throws IOException {
issueCommentPayload.getIssue().comment("hello from @arc subclass-command2");
}
}

public interface DefaultCommand {

void run(GHEventPayload.IssueComment issueCommentPayload) throws IOException;
}

@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
@InterceptorBinding
public @interface DoNothing {
}

@DoNothing
@Priority(2020)
@Interceptor
public static class LoggingInterceptor {

@AroundInvoke
Object logInvocation(InvocationContext context) {
// do nothing specific, we just want an interceptor

try {
return context.proceed();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
@@ -0,0 +1,88 @@
package io.quarkiverse.githubapp.it.command.airline;

import static io.quarkiverse.githubapp.it.command.airline.util.CommandTestUtils.verifyCommandExecution;
import static io.quarkiverse.githubapp.testing.GitHubAppTesting.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import java.io.IOException;

import org.junit.jupiter.api.Test;
import org.kohsuke.github.GHEvent;
import org.kohsuke.github.ReactionContent;

import io.quarkiverse.githubapp.testing.GitHubAppTest;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
@GitHubAppTest
public class ArcSubclassesCliTest {

@Test
void testApplicationScopedScopeIssues() throws IOException {
when().payloadFromClasspath("/issue-comment-arc-application-scoped-command1-issue.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verify(mocks.issueComment(1093016219))
.createReaction(ReactionContent.ROCKET);
verify(mocks.issue(1168785554))
.comment("hello from @arc application-scoped-command1");
verify(mocks.issueComment(1093016219))
.createReaction(ReactionContent.PLUS_ONE);
verifyNoMoreInteractions(mocks.ghObjects());
});
when().payloadFromClasspath("/issue-comment-arc-application-scoped-command1-pr.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verifyNoMoreInteractions(mocks.ghObjects());
});
}

@Test
void testApplicationScopedScopeIssuesAndPullRequests() throws IOException {
when().payloadFromClasspath("/issue-comment-arc-application-scoped-command2-issue.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verifyCommandExecution(mocks, "hello from @arc application-scoped-command2");
});
when().payloadFromClasspath("/issue-comment-arc-application-scoped-command2-pr.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verifyCommandExecution(mocks, "hello from @arc application-scoped-command2");
});
}

@Test
void testSubclassScopeIssues() throws IOException {
when().payloadFromClasspath("/issue-comment-arc-subclass-command1-issue.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verify(mocks.issueComment(1093016219))
.createReaction(ReactionContent.ROCKET);
verify(mocks.issue(1168785554))
.comment("hello from @arc subclass-command1");
verify(mocks.issueComment(1093016219))
.createReaction(ReactionContent.PLUS_ONE);
verifyNoMoreInteractions(mocks.ghObjects());
});
when().payloadFromClasspath("/issue-comment-arc-subclass-command1-pr.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verifyNoMoreInteractions(mocks.ghObjects());
});
}

@Test
void testSubclassScopeIssuesAndPullRequests() throws IOException {
when().payloadFromClasspath("/issue-comment-arc-subclass-command2-issue.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verifyCommandExecution(mocks, "hello from @arc subclass-command2");
});
when().payloadFromClasspath("/issue-comment-arc-subclass-command2-pr.json")
.event(GHEvent.ISSUE_COMMENT)
.then().github(mocks -> {
verifyCommandExecution(mocks, "hello from @arc subclass-command2");
});
}
}

0 comments on commit c741d0d

Please sign in to comment.