From 779738c5fe52fa3822922ec3bafffa09cac28015 Mon Sep 17 00:00:00 2001 From: Mat Mannion Date: Fri, 22 Feb 2019 16:23:50 +0000 Subject: [PATCH 1/2] Replace deprecated interfaces with their replacements for Bitbucket 6 --- .../bitbucket/hook/MirrorRepositoryHook.java | 49 +++++++++++------- .../hook/MirrorRepositoryHookTest.java | 51 +++++++++++++------ 2 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java b/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java index e6c8a7d..5f0dbd9 100644 --- a/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java +++ b/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java @@ -1,9 +1,10 @@ package com.englishtown.bitbucket.hook; -import com.atlassian.bitbucket.hook.repository.AsyncPostReceiveRepositoryHook; -import com.atlassian.bitbucket.hook.repository.RepositoryHookContext; +import com.atlassian.bitbucket.hook.repository.PostRepositoryHook; +import com.atlassian.bitbucket.hook.repository.PostRepositoryHookContext; +import com.atlassian.bitbucket.hook.repository.RepositoryHookRequest; +import com.atlassian.bitbucket.hook.repository.StandardRepositoryHookTrigger; import com.atlassian.bitbucket.i18n.I18nService; -import com.atlassian.bitbucket.repository.RefChange; import com.atlassian.bitbucket.repository.Repository; import com.atlassian.bitbucket.repository.RepositoryService; import com.atlassian.bitbucket.scm.CommandExitHandler; @@ -11,9 +12,12 @@ import com.atlassian.bitbucket.scm.DefaultCommandExitHandler; import com.atlassian.bitbucket.scm.ScmCommandBuilder; import com.atlassian.bitbucket.scm.ScmService; import com.atlassian.bitbucket.scm.git.command.GitScmCommandBuilder; -import com.atlassian.bitbucket.setting.RepositorySettingsValidator; +import com.atlassian.bitbucket.scope.RepositoryScope; +import com.atlassian.bitbucket.scope.Scope; +import com.atlassian.bitbucket.scope.ScopeVisitor; import com.atlassian.bitbucket.setting.Settings; import com.atlassian.bitbucket.setting.SettingsValidationErrors; +import com.atlassian.bitbucket.setting.SettingsValidator; import com.atlassian.sal.api.pluginsettings.PluginSettings; import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory; import com.google.common.base.Strings; @@ -24,11 +28,14 @@ import javax.annotation.Nonnull; import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, RepositorySettingsValidator { +public class MirrorRepositoryHook implements PostRepositoryHook, SettingsValidator { protected static class MirrorSettings { String mirrorRepoUrl; @@ -96,21 +103,19 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep * Despite being asynchronous, the user who initiated this change is still available from * * @param context the context which the hook is being run with - * @param refChanges the refs that have just been updated + * @param request the repository hook request */ @Override - public void postReceive( - @Nonnull RepositoryHookContext context, - @Nonnull Collection refChanges) { + public void postUpdate(@Nonnull PostRepositoryHookContext context, @Nonnull RepositoryHookRequest request) { + if (request.getTrigger() == StandardRepositoryHookTrigger.REPO_PUSH) { + logger.debug("MirrorRepositoryHook: postReceive started."); - logger.debug("MirrorRepositoryHook: postReceive started."); + List mirrorSettings = getMirrorSettings(context.getSettings()); - List mirrorSettings = getMirrorSettings(context.getSettings()); - - for (MirrorSettings settings : mirrorSettings) { - runMirrorCommand(settings, context.getRepository()); + for (MirrorSettings settings : mirrorSettings) { + runMirrorCommand(settings, request.getRepository()); + } } - } void runMirrorCommand(MirrorSettings settings, final Repository repository) { @@ -212,13 +217,13 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep * * @param settings to be validated * @param errors callback for reporting validation errors. - * @param repository the context {@code Repository} the settings will be associated with + * @param scope the scope the settings will be associated with */ @Override public void validate( @Nonnull Settings settings, @Nonnull SettingsValidationErrors errors, - @Nonnull Repository repository) { + @Nonnull Scope scope) { try { boolean ok = true; @@ -236,7 +241,13 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep if (ok) { updateSettings(mirrorSettings, settings); for (MirrorSettings ms : mirrorSettings) { - runMirrorCommand(ms, repository); + scope.accept(new ScopeVisitor() { + @Override + public Void visit(@Nonnull RepositoryScope scope) { + runMirrorCommand(ms, scope.getRepository()); + return null; + } + }); } } diff --git a/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java b/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java index 98a0442..f8b0417 100644 --- a/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java +++ b/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java @@ -1,6 +1,9 @@ package com.englishtown.bitbucket.hook; -import com.atlassian.bitbucket.hook.repository.RepositoryHookContext; +import com.atlassian.bitbucket.hook.repository.PostRepositoryHookContext; +import com.atlassian.bitbucket.hook.repository.RepositoryHookRequest; +import com.atlassian.bitbucket.hook.repository.RepositoryHookTrigger; +import com.atlassian.bitbucket.hook.repository.StandardRepositoryHookTrigger; import com.atlassian.bitbucket.i18n.I18nService; import com.atlassian.bitbucket.repository.Repository; import com.atlassian.bitbucket.repository.RepositoryService; @@ -10,6 +13,7 @@ import com.atlassian.bitbucket.scm.CommandOutputHandler; import com.atlassian.bitbucket.scm.ScmService; import com.atlassian.bitbucket.scm.git.command.GitCommand; import com.atlassian.bitbucket.scm.git.command.GitScmCommandBuilder; +import com.atlassian.bitbucket.scope.Scope; import com.atlassian.bitbucket.setting.Settings; import com.atlassian.bitbucket.setting.SettingsValidationErrors; import com.atlassian.sal.api.pluginsettings.PluginSettings; @@ -24,7 +28,6 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; @@ -96,16 +99,25 @@ public class MirrorRepositoryHookTest { Repository repo = mock(Repository.class); - hook.postReceive(buildContext(repo), new ArrayList<>()); + hook.postUpdate(buildContext(), buildRequest(StandardRepositoryHookTrigger.REPO_PUSH, repo)); verifyExecutor(); } + @Test + public void testUnwantedEventsIgnored() { + Repository repo = mock(Repository.class); + + hook.postUpdate(buildContext(), buildRequest(StandardRepositoryHookTrigger.BRANCH_CREATE, repo)); + + verify(executor, never()).submit(ArgumentMatchers.any()); + } + @Test public void testEmptyRepositoriesNotMirrored() { Repository repo = mock(Repository.class); when(repositoryService.isEmpty(repo)).thenReturn(true); - hook.postReceive(buildContext(repo), new ArrayList<>()); + hook.postUpdate(buildContext(), buildRequest(StandardRepositoryHookTrigger.REPO_PUSH, repo)); verify(executor, never()).submit(ArgumentMatchers.any()); } @@ -214,16 +226,17 @@ public class MirrorRepositoryHookTest { .thenReturn("+refs/heads/master:refs/heads/master") .thenReturn(""); - Repository repo = mock(Repository.class); + Scope scope = mock(Scope.class); + SettingsValidationErrors errors; errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, times(1)).addFormError(anyString()); verify(errors, never()).addFieldError(anyString(), anyString()); errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, never()).addFormError(anyString()); verify(errors).addFieldError(eq(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL + "0"), anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_USERNAME + "0"), anyString()); @@ -231,52 +244,58 @@ public class MirrorRepositoryHookTest { verify(errors).addFieldError(eq(MirrorRepositoryHook.SETTING_REFSPEC + "0"), anyString()); errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, never()).addFormError(anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL + "0"), anyString()); verify(errors).addFieldError(eq(MirrorRepositoryHook.SETTING_USERNAME + "0"), anyString()); verify(errors).addFieldError(eq(MirrorRepositoryHook.SETTING_PASSWORD + "0"), anyString()); errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, never()).addFormError(anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL + "0"), anyString()); verify(errors, never()).addFieldError(anyString(), anyString()); errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, never()).addFormError(anyString()); verify(errors).addFieldError(eq(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL + "0"), anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_USERNAME + "0"), anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_PASSWORD + "0"), anyString()); errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, never()).addFormError(anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL + "0"), anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_USERNAME + "0"), anyString()); verify(errors, never()).addFieldError(eq(MirrorRepositoryHook.SETTING_PASSWORD + "0"), anyString()); errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, never()).addFormError(anyString()); verify(errors, never()).addFieldError(anyString(), anyString()); errors = mock(SettingsValidationErrors.class); - hook.validate(settings, errors, repo); + hook.validate(settings, errors, scope); verify(errors, never()).addFormError(anyString()); verify(errors, never()).addFieldError(anyString(), anyString()); } - private RepositoryHookContext buildContext(Repository repo) { - RepositoryHookContext context = mock(RepositoryHookContext.class); + private PostRepositoryHookContext buildContext() { + PostRepositoryHookContext context = mock(PostRepositoryHookContext.class); Settings settings = defaultSettings(); when(context.getSettings()).thenReturn(settings); - when(context.getRepository()).thenReturn(repo); return context; } + private RepositoryHookRequest buildRequest(RepositoryHookTrigger trigger, Repository repo) { + RepositoryHookRequest request = mock(RepositoryHookRequest.class); + when(request.getTrigger()).thenReturn(trigger); + when(request.getRepository()).thenReturn(repo); + return request; + } + private Settings defaultSettings() { Map map = new HashMap(); map.put(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL, ""); From 2a50e355870b9c028b012edaa5267aa6a7b6d612 Mon Sep 17 00:00:00 2001 From: Mat Mannion Date: Sat, 2 Mar 2019 09:38:35 +0000 Subject: [PATCH 2/2] Trigger repository mirroring on more events --- .../bitbucket/hook/MirrorRepositoryHook.java | 16 +++++++++++----- .../bitbucket/hook/MirrorRepositoryHookTest.java | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java b/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java index 5f0dbd9..f4075d1 100644 --- a/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java +++ b/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java @@ -1,9 +1,6 @@ package com.englishtown.bitbucket.hook; -import com.atlassian.bitbucket.hook.repository.PostRepositoryHook; -import com.atlassian.bitbucket.hook.repository.PostRepositoryHookContext; -import com.atlassian.bitbucket.hook.repository.RepositoryHookRequest; -import com.atlassian.bitbucket.hook.repository.StandardRepositoryHookTrigger; +import com.atlassian.bitbucket.hook.repository.*; import com.atlassian.bitbucket.i18n.I18nService; import com.atlassian.bitbucket.repository.Repository; import com.atlassian.bitbucket.repository.RepositoryService; @@ -21,6 +18,7 @@ import com.atlassian.bitbucket.setting.SettingsValidator; import com.atlassian.sal.api.pluginsettings.PluginSettings; import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,6 +57,14 @@ public class MirrorRepositoryHook implements PostRepositoryHook TRIGGERS_TO_IGNORE = + ImmutableSet.of( + StandardRepositoryHookTrigger.UNKNOWN + ); + private final ScmService scmService; private final I18nService i18nService; private final ScheduledExecutorService executor; @@ -107,7 +113,7 @@ public class MirrorRepositoryHook implements PostRepositoryHook mirrorSettings = getMirrorSettings(context.getSettings()); diff --git a/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java b/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java index f8b0417..7c749f7 100644 --- a/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java +++ b/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java @@ -107,7 +107,7 @@ public class MirrorRepositoryHookTest { public void testUnwantedEventsIgnored() { Repository repo = mock(Repository.class); - hook.postUpdate(buildContext(), buildRequest(StandardRepositoryHookTrigger.BRANCH_CREATE, repo)); + hook.postUpdate(buildContext(), buildRequest(StandardRepositoryHookTrigger.UNKNOWN, repo)); verify(executor, never()).submit(ArgumentMatchers.any()); }