diff --git a/src/main/java/com/sourcegraph/cody/actions/GenerateCommitMessageAction.kt b/src/main/java/com/sourcegraph/cody/actions/GenerateCommitMessageAction.kt new file mode 100644 index 0000000000..07e902c52b --- /dev/null +++ b/src/main/java/com/sourcegraph/cody/actions/GenerateCommitMessageAction.kt @@ -0,0 +1,40 @@ +package com.sourcegraph.cody.actions + +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.ui.Messages +import com.sourcegraph.cody.agent.CodyAgentService +import com.sourcegraph.cody.agent.protocol.CommitMessageParams + +class GenerateCommitMessageAction : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + val project = e.project ?: return + val editor = e.getData(CommonDataKeys.EDITOR) ?: return + val document = editor.document + val file = FileDocumentManager.getInstance().getFile(document) ?: return + + val filePath = file.path + val diff = getDiff(filePath) // Implement this method to get the diff of the file + val template = getTemplate() // Implement this method to get the commit message template + + val params = CommitMessageParams(filePath, diff, template) + val result = CodyAgentService().generateCommitMessage(params) + + Messages.showMessageDialog( + project, + "Commit Message: ${result.commitMessage}\n\nPR Title: ${result.prTitle}\n\nPR Description: ${result.prDescription}", + "Generated Commit Message", + Messages.getInformationIcon() + ) + } + + private fun getDiff(filePath: String): String { + // Implement the logic to generate the diff for the given file path + return "" + } + + private fun getTemplate(): String { + // Implement the logic to get the commit message template + return "" + } +} diff --git a/src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt b/src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt new file mode 100644 index 0000000000..dc30e8afee --- /dev/null +++ b/src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt @@ -0,0 +1,27 @@ +package com.sourcegraph.cody.agent + +import com.sourcegraph.cody.agent.protocol.CommitMessageParams +import com.sourcegraph.cody.agent.protocol.CommitMessageResult +import com.google.gson.Gson +import java.net.HttpURLConnection +import java.net.URL + +class CodyAgentClient { + + fun generateCommitMessage(params: CommitMessageParams): CommitMessageResult { + val url = URL("http://localhost:8080/generateCommitMessage") + val connection = url.openConnection() as HttpURLConnection + connection.requestMethod = "POST" + connection.doOutput = true + connection.setRequestProperty("Content-Type", "application/json") + + val jsonInputString = params.toJson() + connection.outputStream.use { os -> + val input = jsonInputString.toByteArray() + os.write(input, 0, input.size) + } + + val response = connection.inputStream.bufferedReader().use { it.readText() } + return Gson().fromJson(response, CommitMessageResult::class.java) + } +} diff --git a/src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt b/src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt new file mode 100644 index 0000000000..7e5c7e5665 --- /dev/null +++ b/src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt @@ -0,0 +1,13 @@ +package com.sourcegraph.cody.agent + +import com.sourcegraph.cody.agent.protocol.CommitMessageParams +import com.sourcegraph.cody.agent.protocol.CommitMessageResult + +class CodyAgentService { + + private val client = CodyAgentClient() + + fun generateCommitMessage(params: CommitMessageParams): CommitMessageResult { + return client.generateCommitMessage(params) + } +} diff --git a/src/main/java/com/sourcegraph/cody/agent/protocol/CommitMessageParams.kt b/src/main/java/com/sourcegraph/cody/agent/protocol/CommitMessageParams.kt new file mode 100644 index 0000000000..0629193414 --- /dev/null +++ b/src/main/java/com/sourcegraph/cody/agent/protocol/CommitMessageParams.kt @@ -0,0 +1,13 @@ +package com.sourcegraph.cody.agent.protocol + +import com.google.gson.Gson + +data class CommitMessageParams( + val filePath: String, + val diff: String, + val template: String +) { + fun toJson(): String { + return Gson().toJson(this) + } +} diff --git a/src/main/java/com/sourcegraph/cody/agent/protocol/CommitMessageResult.kt b/src/main/java/com/sourcegraph/cody/agent/protocol/CommitMessageResult.kt new file mode 100644 index 0000000000..dc820e0127 --- /dev/null +++ b/src/main/java/com/sourcegraph/cody/agent/protocol/CommitMessageResult.kt @@ -0,0 +1,13 @@ +package com.sourcegraph.cody.agent.protocol + +import com.google.gson.Gson + +data class CommitMessageResult( + val commitMessage: String, + val prTitle: String, + val prDescription: String +) { + fun toJson(): String { + return Gson().toJson(this) + } +} diff --git a/src/main/kotlin/com/sourcegraph/cody/config/CodyApplicationSettings.kt b/src/main/kotlin/com/sourcegraph/cody/config/CodyApplicationSettings.kt index 3feba1b399..d757f060a5 100644 --- a/src/main/kotlin/com/sourcegraph/cody/config/CodyApplicationSettings.kt +++ b/src/main/kotlin/com/sourcegraph/cody/config/CodyApplicationSettings.kt @@ -23,6 +23,7 @@ data class CodyApplicationSettings( var isOnboardingGuidanceDismissed: Boolean = false, var shouldAcceptNonTrustedCertificatesAutomatically: Boolean = false, var shouldCheckForUpdates: Boolean = true, + var commitMessageTemplate: String? = null, // P6bf9 ) : PersistentStateComponent { override fun getState(): CodyApplicationSettings = this @@ -44,6 +45,15 @@ data class CodyApplicationSettings( this.shouldAcceptNonTrustedCertificatesAutomatically = state.shouldAcceptNonTrustedCertificatesAutomatically this.shouldCheckForUpdates = state.shouldCheckForUpdates + this.commitMessageTemplate = state.commitMessageTemplate // Pb717 + } + + fun getCommitMessageTemplate(): String? { + return commitMessageTemplate + } + + fun setCommitMessageTemplate(template: String) { + this.commitMessageTemplate = template } companion object { diff --git a/src/main/kotlin/com/sourcegraph/cody/config/ui/CodyConfigurable.kt b/src/main/kotlin/com/sourcegraph/cody/config/ui/CodyConfigurable.kt index 26c848cc6b..4dab9d0dca 100644 --- a/src/main/kotlin/com/sourcegraph/cody/config/ui/CodyConfigurable.kt +++ b/src/main/kotlin/com/sourcegraph/cody/config/ui/CodyConfigurable.kt @@ -104,6 +104,14 @@ class CodyConfigurable(val project: Project) : BoundConfigurable(ConfigUtil.CODY settingsModel::blacklistedLanguageIds.toMutableProperty()) } } + + group("Commit Message Template") { + row { + textField() + .bindText(settingsModel::commitMessageTemplate.toMutableProperty()) + .horizontalAlign(HorizontalAlign.FILL) + } + } } return dialogPanel } @@ -123,6 +131,7 @@ class CodyConfigurable(val project: Project) : BoundConfigurable(ConfigUtil.CODY settingsModel.blacklistedLanguageIds = codyApplicationSettings.blacklistedLanguageIds settingsModel.shouldAcceptNonTrustedCertificatesAutomatically = codyApplicationSettings.shouldAcceptNonTrustedCertificatesAutomatically + settingsModel.commitMessageTemplate = codyApplicationSettings.commitMessageTemplate dialogPanel.reset() } @@ -156,6 +165,7 @@ class CodyConfigurable(val project: Project) : BoundConfigurable(ConfigUtil.CODY codyApplicationSettings.blacklistedLanguageIds = settingsModel.blacklistedLanguageIds codyApplicationSettings.shouldAcceptNonTrustedCertificatesAutomatically = settingsModel.shouldAcceptNonTrustedCertificatesAutomatically + codyApplicationSettings.commitMessageTemplate = settingsModel.commitMessageTemplate publisher.afterAction(context) } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index ccade00bf3..a749611772 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -405,6 +405,14 @@ + + + + + diff --git a/src/test/kotlin/com/sourcegraph/cody/actions/GenerateCommitMessageActionTest.kt b/src/test/kotlin/com/sourcegraph/cody/actions/GenerateCommitMessageActionTest.kt new file mode 100644 index 0000000000..79e922d3b3 --- /dev/null +++ b/src/test/kotlin/com/sourcegraph/cody/actions/GenerateCommitMessageActionTest.kt @@ -0,0 +1,48 @@ +package com.sourcegraph.cody.actions + +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.editor.EditorFactory +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.sourcegraph.cody.agent.CodyAgentService +import com.sourcegraph.cody.agent.protocol.CommitMessageParams +import com.sourcegraph.cody.agent.protocol.CommitMessageResult +import org.junit.Test +import org.mockito.Mockito + +class GenerateCommitMessageActionTest : BasePlatformTestCase() { + + @Test + fun testActionPerformed() { + val project = project + val file = myFixture.configureByText("TestFile.java", "class Test {}").virtualFile + val document = FileDocumentManager.getInstance().getDocument(file)!! + + val editor = EditorFactory.getInstance().createEditor(document, project) + val event = Mockito.mock(AnActionEvent::class.java) + Mockito.`when`(event.project).thenReturn(project) + Mockito.`when`(event.getData(CommonDataKeys.EDITOR)).thenReturn(editor) + + val diff = "diff --git a/TestFile.java b/TestFile.java\nindex 0000000..e69de29" + val template = "feat: " + + val params = CommitMessageParams(file.path, diff, template) + val result = CommitMessageResult("feat: add TestFile", "Add TestFile", "This PR adds TestFile.java") + + val service = Mockito.mock(CodyAgentService::class.java) + Mockito.`when`(service.generateCommitMessage(params)).thenReturn(result) + + WriteCommandAction.runWriteCommandAction(project) { + GenerateCommitMessageAction().actionPerformed(event) + } + + val dialog = Messages.getInstance().getDialog("Generated Commit Message") + assertNotNull(dialog) + assertTrue(dialog.message.contains("feat: add TestFile")) + assertTrue(dialog.message.contains("Add TestFile")) + assertTrue(dialog.message.contains("This PR adds TestFile.java")) + + EditorFactory.getInstance().releaseEditor(editor) + } +} diff --git a/src/test/kotlin/com/sourcegraph/cody/agent/CodyAgentClientTest.kt b/src/test/kotlin/com/sourcegraph/cody/agent/CodyAgentClientTest.kt new file mode 100644 index 0000000000..087c75edb0 --- /dev/null +++ b/src/test/kotlin/com/sourcegraph/cody/agent/CodyAgentClientTest.kt @@ -0,0 +1,34 @@ +package com.sourcegraph.cody.agent + +import com.sourcegraph.cody.agent.protocol.CommitMessageParams +import com.sourcegraph.cody.agent.protocol.CommitMessageResult +import org.junit.Assert.assertEquals +import org.junit.Test + +class CodyAgentClientTest { + + @Test + fun testGenerateCommitMessage() { + val client = CodyAgentClient() + val params = CommitMessageParams( + filePath = "src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt", + diff = "diff --git a/src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt b/src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt\n" + + "index 83db48f..e6b0e5b 100644\n" + + "--- a/src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt\n" + + "+++ b/src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.kt\n" + + "@@ -1,6 +1,6 @@\n" + + " package com.sourcegraph.cody.agent\n" + + "\n" + + " import com.sourcegraph.cody.agent.protocol.CommitMessageParams\n" + + " import com.sourcegraph.cody.agent.protocol.CommitMessageResult\n" + + " import com.google.gson.Gson\n" + + " import java.net.HttpURLConnection\n" + + " import java.net.URL\n", + template = "feat: Implemented new feature" + ) + val result = client.generateCommitMessage(params) + assertEquals("feat: Implemented new feature", result.commitMessage) + assertEquals("Implemented new feature", result.prTitle) + assertEquals("This PR implements a new feature.", result.prDescription) + } +} diff --git a/src/test/kotlin/com/sourcegraph/cody/agent/CodyAgentServiceTest.kt b/src/test/kotlin/com/sourcegraph/cody/agent/CodyAgentServiceTest.kt new file mode 100644 index 0000000000..fffbb44b1d --- /dev/null +++ b/src/test/kotlin/com/sourcegraph/cody/agent/CodyAgentServiceTest.kt @@ -0,0 +1,34 @@ +package com.sourcegraph.cody.agent + +import com.sourcegraph.cody.agent.protocol.CommitMessageParams +import com.sourcegraph.cody.agent.protocol.CommitMessageResult +import org.junit.Assert.assertEquals +import org.junit.Test + +class CodyAgentServiceTest { + + @Test + fun testGenerateCommitMessage() { + val service = CodyAgentService() + val params = CommitMessageParams( + filePath = "src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt", + diff = "diff --git a/src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt b/src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt\n" + + "index 83db48f..e6b0e5b 100644\n" + + "--- a/src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt\n" + + "+++ b/src/main/java/com/sourcegraph/cody/agent/CodyAgentService.kt\n" + + "@@ -1,6 +1,6 @@\n" + + " package com.sourcegraph.cody.agent\n" + + "\n" + + " import com.sourcegraph.cody.agent.protocol.CommitMessageParams\n" + + " import com.sourcegraph.cody.agent.protocol.CommitMessageResult\n" + + " import com.google.gson.Gson\n" + + " import java.net.HttpURLConnection\n" + + " import java.net.URL\n", + template = "feat: Implemented new feature" + ) + val result = service.generateCommitMessage(params) + assertEquals("feat: Implemented new feature", result.commitMessage) + assertEquals("Implemented new feature", result.prTitle) + assertEquals("This PR implements a new feature.", result.prDescription) + } +}