diff --git a/application/src/main/java/run/halo/app/theme/finders/PluginFinder.java b/application/src/main/java/run/halo/app/theme/finders/PluginFinder.java index 67339bb644..c113d39a4c 100644 --- a/application/src/main/java/run/halo/app/theme/finders/PluginFinder.java +++ b/application/src/main/java/run/halo/app/theme/finders/PluginFinder.java @@ -9,4 +9,6 @@ public interface PluginFinder { boolean available(String pluginName); + + boolean available(String pluginName, String requiresVersion); } diff --git a/application/src/main/java/run/halo/app/theme/finders/impl/PluginFinderImpl.java b/application/src/main/java/run/halo/app/theme/finders/impl/PluginFinderImpl.java index f275683a57..0426b40536 100644 --- a/application/src/main/java/run/halo/app/theme/finders/impl/PluginFinderImpl.java +++ b/application/src/main/java/run/halo/app/theme/finders/impl/PluginFinderImpl.java @@ -2,9 +2,10 @@ import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; +import org.pf4j.PluginManager; import org.pf4j.PluginState; import org.pf4j.PluginWrapper; -import run.halo.app.plugin.HaloPluginManager; +import org.springframework.util.Assert; import run.halo.app.theme.finders.Finder; import run.halo.app.theme.finders.PluginFinder; @@ -17,17 +18,29 @@ @Finder("pluginFinder") @AllArgsConstructor public class PluginFinderImpl implements PluginFinder { - private final HaloPluginManager haloPluginManager; + private final PluginManager pluginManager; @Override public boolean available(String pluginName) { if (StringUtils.isBlank(pluginName)) { return false; } - PluginWrapper pluginWrapper = haloPluginManager.getPlugin(pluginName); + PluginWrapper pluginWrapper = pluginManager.getPlugin(pluginName); if (pluginWrapper == null) { return false; } return PluginState.STARTED.equals(pluginWrapper.getPluginState()); } + + @Override + public boolean available(String pluginName, String requiresVersion) { + Assert.notNull(requiresVersion, "Requires version must not be null."); + if (!this.available(pluginName)) { + return false; + } + var pluginWrapper = pluginManager.getPlugin(pluginName); + var pluginVersion = pluginWrapper.getDescriptor().getVersion(); + return pluginManager.getVersionManager() + .checkVersionConstraint(pluginVersion, requiresVersion); + } } diff --git a/application/src/test/java/run/halo/app/theme/finders/impl/PluginFinderImplTest.java b/application/src/test/java/run/halo/app/theme/finders/impl/PluginFinderImplTest.java index aba947ef26..4ae4cec7a4 100644 --- a/application/src/test/java/run/halo/app/theme/finders/impl/PluginFinderImplTest.java +++ b/application/src/test/java/run/halo/app/theme/finders/impl/PluginFinderImplTest.java @@ -1,7 +1,9 @@ package run.halo.app.theme.finders.impl; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.junit.jupiter.api.Test; @@ -10,6 +12,8 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.pf4j.DefaultVersionManager; +import org.pf4j.PluginDescriptor; import org.pf4j.PluginState; import org.pf4j.PluginWrapper; import run.halo.app.plugin.HaloPluginManager; @@ -47,4 +51,39 @@ void available() { available = pluginFinder.available("fake-plugin"); assertThat(available).isTrue(); } + + @Test + void availableWithVersionTest() { + when(haloPluginManager.getVersionManager()).thenReturn(new DefaultVersionManager()); + + assertThatThrownBy(() -> pluginFinder.available("fake-plugin", null)) + .isInstanceOf(IllegalArgumentException.class); + + boolean available = pluginFinder.available("fake-plugin", "1.0.0"); + assertThat(available).isFalse(); + + PluginWrapper mockPluginWrapper = Mockito.mock(PluginWrapper.class); + when(haloPluginManager.getPlugin(eq("fake-plugin"))) + .thenReturn(mockPluginWrapper); + + when(mockPluginWrapper.getPluginState()).thenReturn(PluginState.STARTED); + var descriptor = mock(PluginDescriptor.class); + when(mockPluginWrapper.getDescriptor()).thenReturn(descriptor); + when(descriptor.getVersion()).thenReturn("1.0.0"); + + available = pluginFinder.available("fake-plugin", "1.0.0"); + assertThat(available).isTrue(); + + available = pluginFinder.available("fake-plugin", ">=1.0.0"); + assertThat(available).isTrue(); + + available = pluginFinder.available("fake-plugin", "<2.0.0"); + assertThat(available).isTrue(); + + available = pluginFinder.available("fake-plugin", "2.0.0"); + assertThat(available).isFalse(); + + available = pluginFinder.available("fake-plugin", "<1.0.0"); + assertThat(available).isFalse(); + } } \ No newline at end of file