Skip to content

Commit

Permalink
#8: Suggest installing EF Core tools if not installed
Browse files Browse the repository at this point in the history
  • Loading branch information
seclerp committed Nov 30, 2021
1 parent e798f38 commit d95dee8
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package me.seclerp.rider.plugins.efcore

object KnownNotificationGroups {
val efCore = "EF Core Notifications Group"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.jetbrains.rider.util.idea.getService
import me.seclerp.rider.plugins.efcore.clients.MigrationsClient
import me.seclerp.rider.plugins.efcore.dialogs.AddMigrationDialogWrapper
import me.seclerp.rider.plugins.efcore.commands.executeCommandUnderProgress

class AddMigrationAction : BaseEfCoreAction() {
override fun actionPerformed(actionEvent: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
package me.seclerp.rider.plugins.efcore.actions

import com.intellij.ide.SaveAndSyncHandler
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.progress.runBackgroundableTask
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFileManager
import me.seclerp.rider.plugins.efcore.rd.RiderEfCoreModel
import me.seclerp.rider.plugins.efcore.rd.riderEfCoreModel
import com.jetbrains.rider.projectView.solution
import me.seclerp.rider.plugins.efcore.commands.CliCommandResult
import me.seclerp.rider.plugins.efcore.dialogs.BaseEfCoreDialogWrapper
import me.seclerp.rider.plugins.efcore.commands.CommonOptions

Expand All @@ -32,28 +23,6 @@ abstract class BaseEfCoreAction: AnAction() {
dialog.noBuild
)

protected fun executeCommandUnderProgress(project: Project, taskTitle: String, succeedText: String, what: (Unit) -> CliCommandResult) {
runBackgroundableTask(taskTitle, project, false) {
val result = what(Unit)
if (result.succeeded) {
NotificationGroupManager.getInstance().getNotificationGroup("EF Core Notifications Group")
.createNotification(succeedText, NotificationType.INFORMATION)
.notify(project)
} else {
NotificationGroupManager.getInstance().getNotificationGroup("EF Core Notifications Group")
.createNotification(
"EF Core command failed",
"Command: ${result.command}\n\nOutput:\n${result.output}\n\nExit code: ${result.exitCode}",
NotificationType.ERROR)
.notify(project)
}

ApplicationManager.getApplication().invokeAndWait {
refreshSolution()
}
}
}

protected fun getEfCoreRiderModel(actionEvent: AnActionEvent): RiderEfCoreModel {
// TODO: Validate

Expand All @@ -73,10 +42,4 @@ abstract class BaseEfCoreAction: AnAction() {
data class DialogBuildParameters(
val model: RiderEfCoreModel,
val currentDotnetProjectName: String)

private fun refreshSolution() {
FileDocumentManager.getInstance().saveAllDocuments()
SaveAndSyncHandler.getInstance().refreshOpenFiles()
VirtualFileManager.getInstance().refreshWithoutFileWatcher(true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.jetbrains.rider.util.idea.getService
import me.seclerp.rider.plugins.efcore.clients.DatabaseClient
import me.seclerp.rider.plugins.efcore.dialogs.DropDatabaseDialogWrapper
import me.seclerp.rider.plugins.efcore.commands.executeCommandUnderProgress

class DropDatabaseAction : BaseEfCoreAction() {
override fun actionPerformed(actionEvent: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package me.seclerp.rider.plugins.efcore.actions

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.components.service
import me.seclerp.rider.plugins.efcore.clients.ManagementClient
import me.seclerp.rider.plugins.efcore.commands.executeCommandUnderProgress

class InstallEfCoreAction : AnAction("Fix") {
override fun actionPerformed(actionEvent: AnActionEvent) {
executeCommandUnderProgress(
actionEvent.project!!,
"Installing EF Core global tools...",
"EF Core global tools has been successfully installed",
false
) {
val managementClient = actionEvent.project!!.service<ManagementClient>()
managementClient.installEfCoreTools()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.jetbrains.rider.util.idea.getService
import me.seclerp.rider.plugins.efcore.clients.MigrationsClient
import me.seclerp.rider.plugins.efcore.dialogs.RemoveLastMigrationDialogWrapper
import me.seclerp.rider.plugins.efcore.commands.executeCommandUnderProgress

class RemoveLastMigrationAction : BaseEfCoreAction() {
override fun actionPerformed(actionEvent: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.jetbrains.rider.util.idea.getService
import me.seclerp.rider.plugins.efcore.clients.DatabaseClient
import me.seclerp.rider.plugins.efcore.dialogs.UpdateDatabaseDialogWrapper
import me.seclerp.rider.plugins.efcore.commands.executeCommandUnderProgress

class UpdateDatabaseAction : BaseEfCoreAction() {
override fun actionPerformed(actionEvent: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.seclerp.rider.plugins.efcore.clients

import com.intellij.openapi.components.Service
import me.seclerp.rider.plugins.efcore.commands.CliCommand
import me.seclerp.rider.plugins.efcore.commands.CliCommandResult

@Service
class ManagementClient : BaseEfCoreClient() {
fun getEfCoreVersion(): String? {
val command = CliCommand("dotnet ef --version")
val result = command.execute()

return if (result.succeeded)
result.output
else
null
}

fun installEfCoreTools(): CliCommandResult {
val command = CliCommand("dotnet tool install --global dotnet-ef")
return command.execute()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package me.seclerp.rider.plugins.efcore.commands

import com.intellij.ide.SaveAndSyncHandler
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.progress.runBackgroundableTask
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFileManager
import me.seclerp.rider.plugins.efcore.KnownNotificationGroups

fun executeCommandUnderProgress(
project: Project, taskTitle: String, succeedText: String, shouldRefreshSolution: Boolean = true,
what: (Unit) -> CliCommandResult
) {
runBackgroundableTask(taskTitle, project, false) {
val result = what(Unit)
if (result.succeeded) {
NotificationGroupManager.getInstance().getNotificationGroup(KnownNotificationGroups.efCore)
.createNotification(succeedText, NotificationType.INFORMATION)
.notify(project)
} else {
NotificationGroupManager.getInstance().getNotificationGroup(KnownNotificationGroups.efCore)
.createNotification(
"EF Core command failed",
"Command: ${result.command}\n\nOutput:\n${result.output}\n\nError:${result.error}\n\nExit code: ${result.exitCode}",
NotificationType.ERROR)
.notify(project)
}

if (shouldRefreshSolution) {
ApplicationManager.getApplication().invokeAndWait {
refreshSolution()
}
}
}
}

private fun refreshSolution() {
FileDocumentManager.getInstance().saveAllDocuments()
SaveAndSyncHandler.getInstance().refreshOpenFiles()
VirtualFileManager.getInstance().refreshWithoutFileWatcher(true)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package me.seclerp.rider.plugins.efcore.startup

import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupActivity
import com.jetbrains.rider.projectView.solution
import me.seclerp.rider.plugins.efcore.KnownNotificationGroups
import me.seclerp.rider.plugins.efcore.actions.InstallEfCoreAction
import me.seclerp.rider.plugins.efcore.clients.ManagementClient
import me.seclerp.rider.plugins.efcore.rd.StartupProjectInfo
import me.seclerp.rider.plugins.efcore.rd.riderEfCoreModel

class EfCoreStartupActivity : StartupActivity, DumbAware {
override fun runActivity(intellijProject: Project) {
var efCoreStartupProjects: List<StartupProjectInfo>? = null
ApplicationManager.getApplication().invokeAndWait {
efCoreStartupProjects = intellijProject.solution.riderEfCoreModel.getAvailableStartupProjects.sync(Unit)
}

if (efCoreStartupProjects?.isEmpty() != false) {
return
}

val efCoreChecker = intellijProject.service<ManagementClient>()
val version = efCoreChecker.getEfCoreVersion()

if (version == null) {
NotificationGroupManager.getInstance().getNotificationGroup(KnownNotificationGroups.efCore)
.createNotification("EF Core tools are not installed", "These tools are required to execute EF Core commands", NotificationType.WARNING)
.addAction(InstallEfCoreAction())
.notify(intellijProject)
}
}
}
1 change: 1 addition & 0 deletions src/rider/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<extensions defaultExtensionNs="com.intellij">
<applicationConfigurable groupId="language" instance="me.seclerp.rider.plugins.efcore.SampleOptionsPage" id="SampleOptionsPage" />
<notificationGroup id="EF Core Notifications Group" displayType="BALLOON"/>
<postStartupActivity implementation="me.seclerp.rider.plugins.efcore.startup.EfCoreStartupActivity" />
</extensions>

<actions>
Expand Down

0 comments on commit d95dee8

Please sign in to comment.