diff --git a/build.gradle b/build.gradle index 9e0a2177..4c0bcc3e 100644 --- a/build.gradle +++ b/build.gradle @@ -49,3 +49,20 @@ subprojects { useJUnitPlatform() } } + +def toolCoreProject = project(':dap-tool-core') + +tasks.register('validateMcpToolNames', JavaExec) { + group = 'verification' + description = 'Checks duplicate @McpFunction names across all Tool modules before packaging.' + dependsOn toolCoreProject.tasks.named('classes') + classpath = toolCoreProject.sourceSets.main.runtimeClasspath + mainClass.set('io.shinhanlife.dap.lib.validation.McpToolNameValidationRunner') + args rootProject.projectDir.absolutePath +} + +subprojects { + tasks.matching { it.name == 'bootJar' }.configureEach { + dependsOn rootProject.tasks.named('validateMcpToolNames') + } +} \ No newline at end of file diff --git a/dap-tool-core/src/main/java/io/shinhanlife/dap/lib/validation/McpToolNameValidationRunner.java b/dap-tool-core/src/main/java/io/shinhanlife/dap/lib/validation/McpToolNameValidationRunner.java new file mode 100644 index 00000000..414843e3 --- /dev/null +++ b/dap-tool-core/src/main/java/io/shinhanlife/dap/lib/validation/McpToolNameValidationRunner.java @@ -0,0 +1,21 @@ +package io.shinhanlife.dap.lib.validation; + +import java.nio.file.Path; + +/** Gradle entry point for validating unique MCP Tool names before packaging. */ +public final class McpToolNameValidationRunner { + + private McpToolNameValidationRunner() { + } + + public static void main(String[] args) { + if (args.length != 1) { + throw new IllegalArgumentException("Usage: McpToolNameValidationRunner "); + } + validate(Path.of(args[0])); + } + + static void validate(Path projectRoot) { + McpToolNameValidator.assertUnique(projectRoot); + } +} \ No newline at end of file diff --git a/dap-tool-core/src/test/java/io/shinhanlife/dap/lib/validation/McpToolNameValidatorTest.java b/dap-tool-core/src/test/java/io/shinhanlife/dap/lib/validation/McpToolNameValidatorTest.java index 60089dce..1f357748 100644 --- a/dap-tool-core/src/test/java/io/shinhanlife/dap/lib/validation/McpToolNameValidatorTest.java +++ b/dap-tool-core/src/test/java/io/shinhanlife/dap/lib/validation/McpToolNameValidatorTest.java @@ -42,6 +42,15 @@ class McpToolNameValidatorTest { assertTrue(exception.getMessage().contains("dap-tool-second")); } + @Test + void validationRunnerRejectsDuplicateMcpFunctionNamesBeforePackaging() throws IOException { + writeToolSource("dap-tool-first", "FirstTool.java", "first", "send_sms"); + writeToolSource("dap-tool-second", "SecondTool.java", "second", "send_sms"); + + assertThrows(IllegalStateException.class, + () -> McpToolNameValidationRunner.validate(temporaryRoot)); + } + @Test void acceptsCurrentProjectToolNames() { assertDoesNotThrow(() -> McpToolNameValidator.assertUnique(findProjectRoot()));