From a6a4eb731990b57b33bbe3449db73b5998215ea6 Mon Sep 17 00:00:00 2001 From: Tunatroll Date: Sat, 7 Mar 2026 09:30:25 -0700 Subject: [PATCH 1/2] Add grand-flip-out plugin with IP warning Added grand-flip-out plugin with repository details and warning. --- plugins/grand-flip-out | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 plugins/grand-flip-out diff --git a/plugins/grand-flip-out b/plugins/grand-flip-out new file mode 100644 index 000000000000..d68fcc708b2a --- /dev/null +++ b/plugins/grand-flip-out @@ -0,0 +1,3 @@ +repository=https://github.com/Tunatroll/grand-flip-out.git +commit=1d2649de4cb8cdac32a771b6e6fcb9396e32fdc1 +warning=This plugin submits your IP address to a 3rd-party server not controlled or verified by RuneLite developers. From 34930feb96b5f990b4fb43814b204e681f910d5f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 19 May 2026 10:15:12 +0000 Subject: [PATCH 2/2] Add descriptor validation regression tests Co-authored-by: Tunatroll --- .../runelite/pluginhub/packager/Plugin.java | 2 +- .../pluginhub/packager/PluginTest.java | 60 +++++++++++++++++-- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java b/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java index 44e629910f83..73f9d120d130 100644 --- a/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java +++ b/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java @@ -248,7 +248,7 @@ public Plugin(File pluginCommitDescriptor) throws IOException, DisabledPluginExc } commit = (String) cd.remove("commit"); - if (!COMMIT_TEST.matcher(commit).matches()) + if (Strings.isNullOrEmpty(commit) || !COMMIT_TEST.matcher(commit).matches()) { throw PluginBuildException.of(internalName, "commit must be a full 40 character sha1sum") .withFileLine(pluginCommitDescriptor, "commit=" + commit); diff --git a/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java b/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java index 3aa33c51ff22..ca75cff7c7bb 100644 --- a/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java +++ b/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java @@ -38,6 +38,9 @@ @Slf4j public class PluginTest { + private static final String VALID_REPOSITORY = "https://github.com/runelite/example-plugin.git"; + private static final String VALID_COMMIT = "0000000000000000000000000000000000000000"; + @Test public void testInternalNameChecks() throws IOException, DisabledPluginException { @@ -59,7 +62,7 @@ public void testCommitMustBeComplete() throws DisabledPluginException, IOExcepti try { newPlugin("test", "" + - "repository=https://github.com/runelite/example-plugin.git\n" + + "repository=" + VALID_REPOSITORY + "\n" + "commit=2357276b"); Assert.fail(); } @@ -70,6 +73,41 @@ public void testCommitMustBeComplete() throws DisabledPluginException, IOExcepti } } + @Test + public void testCommitMustBePresent() throws DisabledPluginException, IOException + { + PluginBuildException e = assertNewPluginFails("test", "repository=" + VALID_REPOSITORY + "\n"); + assertContains(e.getMessage(), "commit must be a full 40 character sha1sum"); + assertContains(e.getHelpText(), "commit=null"); + } + + @Test + public void testRepositoryMustBePresent() throws DisabledPluginException, IOException + { + PluginBuildException e = assertNewPluginFails("test", "commit=" + VALID_COMMIT + "\n"); + assertContains(e.getMessage(), "repository is missing"); + assertContains(e.getHelpText(), "in file"); + } + + @Test + public void testRepositoryMustBeGithubCloneUrl() throws DisabledPluginException, IOException + { + PluginBuildException ssh = assertNewPluginFails("test", "" + + "repository=git@github.com:runelite/example-plugin.git\n" + + "commit=" + VALID_COMMIT + "\n"); + assertContains(ssh.getHelpText(), "repositories must be https clone urls"); + + PluginBuildException wrongHost = assertNewPluginFails("test", "" + + "repository=https://gitlab.com/runelite/example-plugin.git\n" + + "commit=" + VALID_COMMIT + "\n"); + assertContains(wrongHost.getHelpText(), "repositories must be hosted on GitHub.com"); + + PluginBuildException missingGitSuffix = assertNewPluginFails("test", "" + + "repository=https://github.com/runelite/example-plugin\n" + + "commit=" + VALID_COMMIT + "\n"); + assertContains(missingGitSuffix.getHelpText(), "repository must be a clone url"); + } + @Test public void testExamplePluginCompiles() throws DisabledPluginException, PluginBuildException, IOException, InterruptedException { @@ -198,8 +236,8 @@ private static Plugin createExamplePlugin(String name) throws DisabledPluginExce private static Plugin createExamplePlugin(String name, String packageName) throws DisabledPluginException, PluginBuildException, IOException, InterruptedException { Plugin p = newPlugin(name, "" + - "repository=https://github.com/runelite/example-plugin.git\n" + - "commit=0000000000000000000000000000000000000000"); + "repository=" + VALID_REPOSITORY + "\n" + + "commit=" + VALID_COMMIT); Assert.assertEquals(0, new ProcessBuilder( new File("./create_new_plugin.py").getAbsolutePath(), @@ -216,7 +254,21 @@ private static Plugin createExamplePlugin(String name, String packageName) throw return p; } - private void assertContains(String haystack, String needle) + private static PluginBuildException assertNewPluginFails(String name, String desc) throws DisabledPluginException, IOException + { + try (Plugin ignored = newPlugin(name, desc)) + { + Assert.fail(); + return null; + } + catch (PluginBuildException e) + { + log.info("ok: ", e); + return e; + } + } + + private static void assertContains(String haystack, String needle) { Assert.assertTrue(haystack, haystack.contains(needle)); }