@@ -7,9 +7,17 @@ import com.intellij.openapi.progress.ProgressManager
7
7
import com.intellij.openapi.progress.Task
8
8
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator
9
9
import com.intellij.openapi.project.Project
10
- import io.projectenv.core.commons.process.ProcessEnvironmentHelper.getPathVariableName
10
+ import io.projectenv.core.cli.ToolSupportHelper
11
+ import io.projectenv.core.cli.configuration.ProjectEnvConfiguration
12
+ import io.projectenv.core.cli.configuration.toml.TomlConfigurationFactory
13
+ import io.projectenv.core.cli.index.DefaultToolsIndexManager
14
+ import io.projectenv.core.cli.installer.DefaultLocalToolInstallationManager
11
15
import io.projectenv.core.commons.process.ProcessHelper
12
16
import io.projectenv.core.commons.process.ProcessResult
17
+ import io.projectenv.core.toolsupport.spi.ImmutableToolSupportContext
18
+ import io.projectenv.core.toolsupport.spi.ToolInfo
19
+ import io.projectenv.core.toolsupport.spi.ToolSupport
20
+ import io.projectenv.core.toolsupport.spi.ToolSupportContext
13
21
import io.projectenv.intellijplugin.listeners.ProjectEnvTopics
14
22
import io.projectenv.intellijplugin.notifications.ProjectEnvNotificationGroup
15
23
import io.projectenv.intellijplugin.services.ProjectEnvCliResolverService
@@ -18,6 +26,7 @@ import io.projectenv.intellijplugin.services.ProjectEnvService
18
26
import io.projectenv.intellijplugin.toolinfo.ToolInfoParser
19
27
import io.projectenv.intellijplugin.toolinfo.ToolInfos
20
28
import java.io.File
29
+ import java.util.ServiceLoader
21
30
22
31
class ProjectEnvServiceImpl (val project : Project ) : ProjectEnvService {
23
32
@@ -26,29 +35,24 @@ class ProjectEnvServiceImpl(val project: Project) : ProjectEnvService {
26
35
override fun refreshProjectEnv (sync : Boolean ) {
27
36
val configurationFile = project.service<ProjectEnvConfigFileResolverService >().resolveConfig() ? : return
28
37
29
- val projectEnvCliExecutable = project.service<ProjectEnvCliResolverService >().resolveCli()
30
- if (projectEnvCliExecutable == null ) {
31
- handleMissingCli()
32
- return
33
- }
34
-
35
38
runProcess(" Installing Project-Env" , sync) {
36
- val result = executeProjectEnvCli(projectEnvCliExecutable, configurationFile)
37
- if (isSuccessfulCliExecution(result)) {
38
- handleSuccessfulCliExecution(result)
39
- } else {
40
- handleCliExecutionFailure(result)
39
+ try {
40
+ val projectEnvCliExecutable = project.service<ProjectEnvCliResolverService >().resolveCli()
41
+
42
+ val toolInfos = if (projectEnvCliExecutable != null ) {
43
+ executeProjectEnvCliExecutable(projectEnvCliExecutable, configurationFile)
44
+ } else {
45
+ executeEmbeddedProjectEnvCli(configurationFile)
46
+ }
47
+
48
+ project.messageBus.syncPublisher(ProjectEnvTopics .TOOLS_TOPIC ).toolsUpdated(toolInfos)
49
+ } catch (e: Exception ) {
50
+ ProjectEnvNotificationGroup .createNotification(e.message.orEmpty(), NotificationType .WARNING )
51
+ .notify(project)
41
52
}
42
53
}
43
54
}
44
55
45
- private fun handleMissingCli () {
46
- ProjectEnvNotificationGroup .createNotification(
47
- " Could not resolve Project-Env CLI. Please make sure that the CLI is installed and on ${getPathVariableName()} ." ,
48
- NotificationType .WARNING
49
- ).notify(project)
50
- }
51
-
52
56
private fun runProcess (title : String , sync : Boolean , runnable : Runnable ) {
53
57
if (sync) {
54
58
ProgressManager .getInstance().runProcessWithProgressSynchronously(runnable, title, false , project)
@@ -64,7 +68,7 @@ class ProjectEnvServiceImpl(val project: Project) : ProjectEnvService {
64
68
}
65
69
}
66
70
67
- private fun executeProjectEnvCli (projectEnvCliExecutable : File , configurationFile : File ): ProcessResult {
71
+ private fun executeProjectEnvCliExecutable (projectEnvCliExecutable : File , configurationFile : File ): ToolInfos {
68
72
val processBuilder = ProcessBuilder ()
69
73
.command(
70
74
projectEnvCliExecutable.canonicalPath,
@@ -75,30 +79,62 @@ class ProjectEnvServiceImpl(val project: Project) : ProjectEnvService {
75
79
)
76
80
.directory(projectRoot)
77
81
78
- return ProcessHelper .executeProcess(processBuilder, true , true )
82
+ val result = ProcessHelper .executeProcess(processBuilder, true , true )
83
+ if (isSuccessfulCliExecution(result)) {
84
+ return ToolInfoParser .fromJson(result.stdOutput.get())
85
+ } else {
86
+ throw Exception (" Failed to execute Project-Env CLI. See process output for more details:\n ${result.errOutput.get()} " )
87
+ }
79
88
}
80
89
81
90
private fun isSuccessfulCliExecution (result : ProcessResult ): Boolean {
82
91
return result.exitCode == 0
83
92
}
84
93
85
- private fun handleSuccessfulCliExecution (result : ProcessResult ) {
86
- val toolDetails = parseRawToolDetails(result)
94
+ private fun executeEmbeddedProjectEnvCli (configurationFile : File ): ToolInfos {
95
+ val configuration: ProjectEnvConfiguration = TomlConfigurationFactory .fromFile(configurationFile)
96
+ val toolSupportContext = createToolSupportContext(configuration)
87
97
88
- project.messageBus.syncPublisher(ProjectEnvTopics .TOOLS_TOPIC ).toolsUpdated(toolDetails)
98
+ val toolInstallationInfos = LinkedHashMap <String , List <ToolInfo >>()
99
+ for (toolSupport in ServiceLoader .load(ToolSupport ::class .java, ToolSupport ::class .java.classLoader)) {
100
+ val toolInfos: List <ToolInfo > = installOrUpdateTool(toolSupport, configuration, toolSupportContext)
101
+ if (toolInfos.isNotEmpty()) {
102
+ toolInstallationInfos[toolSupport.toolIdentifier] = toolInfos
103
+ }
104
+ }
105
+
106
+ return ToolInfos (toolInstallationInfos)
89
107
}
90
108
91
- private fun parseRawToolDetails (result : ProcessResult ): ToolInfos {
92
- return ToolInfoParser .fromJson(result.stdOutput.get())
109
+ private fun <T > installOrUpdateTool (
110
+ toolSupport : ToolSupport <T >,
111
+ configuration : ProjectEnvConfiguration ,
112
+ toolSupportContext : ToolSupportContext
113
+ ): List <ToolInfo > {
114
+ val toolSupportConfigurationClass = ToolSupportHelper .getToolSupportConfigurationClass(toolSupport)
115
+ val toolConfigurations =
116
+ configuration.getToolConfigurations(toolSupport.toolIdentifier, toolSupportConfigurationClass)
117
+ if (toolConfigurations.isEmpty()) {
118
+ return emptyList()
119
+ }
120
+
121
+ val toolInfos = ArrayList <ToolInfo >()
122
+ for (toolConfiguration in toolConfigurations) {
123
+ toolInfos.add(toolSupport.prepareTool(toolConfiguration, toolSupportContext))
124
+ }
125
+ return toolInfos
93
126
}
94
127
95
- private fun handleCliExecutionFailure (result : ProcessResult ) {
96
- ProjectEnvNotificationGroup
97
- .createNotification(
98
- " Failed to execute Project-Env CLI. See process output for more details:\n ${result.errOutput.get()} " ,
99
- NotificationType .WARNING
100
- )
101
- .notify(project)
128
+ private fun createToolSupportContext (configuration : ProjectEnvConfiguration ): ToolSupportContext {
129
+ val toolsDirectory = File (projectRoot, configuration.toolsDirectory)
130
+ val localToolInstallationManager = DefaultLocalToolInstallationManager (toolsDirectory)
131
+ val toolsIndexManager = DefaultToolsIndexManager (toolsDirectory)
132
+
133
+ return ImmutableToolSupportContext .builder()
134
+ .projectRoot(projectRoot)
135
+ .localToolInstallationManager(localToolInstallationManager)
136
+ .toolsIndexManager(toolsIndexManager)
137
+ .build()
102
138
}
103
139
104
140
override fun dispose () {
0 commit comments