Skip to content

Commit 927ec8e

Browse files
authored
BugFix: Open SAM Project on creation in Rider 231 (#3683)
* fix opening sam projects * feedback changes * empty commit * feedback changes * feedback changes 2 * added changelog
1 parent 49c40b4 commit 927ec8e

File tree

4 files changed

+204
-80
lines changed

4 files changed

+204
-80
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "Fix threading issue preventing SAM Applications from opening in Rider 2023.1"
4+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.lambda.dotnet
5+
6+
import com.intellij.openapi.module.ModuleManager
7+
import com.intellij.openapi.progress.DumbProgressIndicator
8+
import com.intellij.openapi.progress.ProgressManager
9+
import com.intellij.openapi.project.rootManager
10+
import com.intellij.openapi.util.io.FileUtil
11+
import com.intellij.openapi.vfs.LocalFileSystem
12+
import com.jetbrains.rider.ideaInterop.fileTypes.msbuild.CsprojFileType
13+
import com.jetbrains.rider.projectView.SolutionManager
14+
import com.jetbrains.rider.projectView.actions.projectTemplating.backend.ReSharperTemplatesInteraction
15+
import com.jetbrains.rider.projectView.actions.projectTemplating.impl.ProjectTemplateDialogContext
16+
import com.jetbrains.rider.projectView.actions.projectTemplating.impl.ProjectTemplateTransferableModel
17+
import kotlinx.coroutines.runBlocking
18+
import software.aws.toolkits.resources.message
19+
import java.io.File
20+
21+
class DotNetSamProjectGenerator(
22+
private val context: ProjectTemplateDialogContext,
23+
group: String,
24+
categoryName: String,
25+
model: ProjectTemplateTransferableModel
26+
) : DotNetSamProjectGeneratorRoot(context, group, categoryName, model) {
27+
28+
override fun expand() = Runnable {
29+
val samPanel = getSamPanel()
30+
val generator = getSamGenerator()
31+
val samSettings = samPanel.getNewProjectSettings()
32+
33+
val solutionDirectory = getSolutionDirectory()
34+
?: throw Exception(message("sam.init.error.no.solution.basepath"))
35+
36+
val fileSystem = LocalFileSystem.getInstance()
37+
if (!solutionDirectory.exists()) {
38+
FileUtil.createDirectory(solutionDirectory)
39+
}
40+
41+
val outDirVf = fileSystem.refreshAndFindFileByIoFile(solutionDirectory)
42+
?: throw Exception(message("sam.init.error.no.virtual.file"))
43+
44+
val progressManager = ProgressManager.getInstance()
45+
val samProjectBuilder = generator.createModuleBuilder()
46+
progressManager.runProcessWithProgressSynchronously(
47+
{
48+
samProjectBuilder.runSamInit(
49+
context.project,
50+
projectNameField.text,
51+
samSettings,
52+
null,
53+
outDirVf
54+
)
55+
},
56+
message("sam.init.generating.template"),
57+
false,
58+
null
59+
)
60+
61+
// Create solution file
62+
val projectFiles =
63+
File(solutionDirectory, "src").walk().filter { it.extension == CsprojFileType.defaultExtension } +
64+
File(solutionDirectory, "test").walk().filter { it.extension == CsprojFileType.defaultExtension }
65+
66+
// Get the rest of generated files and copy to "SolutionItems" default folder in project structure
67+
val solutionFiles = solutionDirectory.listFiles()?.filter { it.isFile }?.toList() ?: emptyList()
68+
69+
val solutionFile = ReSharperTemplatesInteraction.createSolution(
70+
name = getSolutionName(),
71+
directory = solutionDirectory,
72+
projectFiles = projectFiles.toList(),
73+
protocolHost = context.protocolHost,
74+
solutionFiles = solutionFiles
75+
) ?: throw Exception(message("sam.init.error.solution.create.fail"))
76+
77+
val project = runBlocking {
78+
SolutionManager.openExistingSolution(
79+
projectToClose = null,
80+
forceOpenInNewFrame = false,
81+
solutionFile = solutionFile,
82+
forceConsiderTrusted = true
83+
)
84+
} ?: return@Runnable
85+
86+
vcsPanel?.createInitializer()?.execute(project)
87+
88+
val modifiableModel = ModuleManager.getInstance(project).modules.firstOrNull()?.rootManager?.modifiableModel ?: return@Runnable
89+
try {
90+
val progressIndicator = if (progressManager.hasProgressIndicator()) progressManager.progressIndicator else DumbProgressIndicator()
91+
92+
samProjectBuilder.runPostSamInit(project, modifiableModel, progressIndicator, samSettings, outDirVf)
93+
} finally {
94+
modifiableModel.dispose()
95+
}
96+
}
97+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.lambda.dotnet
5+
6+
import com.intellij.openapi.module.ModuleManager
7+
import com.intellij.openapi.progress.DumbProgressIndicator
8+
import com.intellij.openapi.progress.ProgressManager
9+
import com.intellij.openapi.project.rootManager
10+
import com.intellij.openapi.util.io.FileUtil
11+
import com.intellij.openapi.vfs.LocalFileSystem
12+
import com.jetbrains.rider.ideaInterop.fileTypes.msbuild.CsprojFileType
13+
import com.jetbrains.rider.projectView.SolutionManager
14+
import com.jetbrains.rider.projectView.actions.projectTemplating.backend.ReSharperTemplatesInteraction
15+
import com.jetbrains.rider.projectView.actions.projectTemplating.impl.ProjectTemplateDialogContext
16+
import com.jetbrains.rider.projectView.actions.projectTemplating.impl.ProjectTemplateTransferableModel
17+
import kotlinx.coroutines.launch
18+
import software.aws.toolkits.jetbrains.core.coroutines.applicationCoroutineScope
19+
import software.aws.toolkits.resources.message
20+
import java.io.File
21+
22+
class DotNetSamProjectGenerator(
23+
private val context: ProjectTemplateDialogContext,
24+
group: String,
25+
categoryName: String,
26+
model: ProjectTemplateTransferableModel
27+
) : DotNetSamProjectGeneratorRoot(context, group, categoryName, model) {
28+
override fun expand() = Runnable {
29+
val samPanel = getSamPanel()
30+
val generator = getSamGenerator()
31+
val samSettings = samPanel.getNewProjectSettings()
32+
33+
val solutionDirectory = getSolutionDirectory()
34+
?: throw Exception(message("sam.init.error.no.solution.basepath"))
35+
36+
val fileSystem = LocalFileSystem.getInstance()
37+
if (!solutionDirectory.exists()) {
38+
FileUtil.createDirectory(solutionDirectory)
39+
}
40+
41+
val outDirVf = fileSystem.refreshAndFindFileByIoFile(solutionDirectory)
42+
?: throw Exception(message("sam.init.error.no.virtual.file"))
43+
44+
val progressManager = ProgressManager.getInstance()
45+
val samProjectBuilder = generator.createModuleBuilder()
46+
progressManager.runProcessWithProgressSynchronously(
47+
{
48+
samProjectBuilder.runSamInit(
49+
context.project,
50+
projectNameField.text,
51+
samSettings,
52+
null,
53+
outDirVf
54+
)
55+
},
56+
message("sam.init.generating.template"),
57+
false,
58+
null
59+
)
60+
61+
// Create solution file
62+
val projectFiles =
63+
File(solutionDirectory, "src").walk().filter { it.extension == CsprojFileType.defaultExtension } +
64+
File(solutionDirectory, "test").walk().filter { it.extension == CsprojFileType.defaultExtension }
65+
66+
// Get the rest of generated files and copy to "SolutionItems" default folder in project structure
67+
val solutionFiles = solutionDirectory.listFiles()?.filter { it.isFile }?.toList() ?: emptyList()
68+
69+
val solutionFile = ReSharperTemplatesInteraction.createSolution(
70+
name = getSolutionName(),
71+
directory = solutionDirectory,
72+
projectFiles = projectFiles.toList(),
73+
protocolHost = context.protocolHost,
74+
solutionFiles = solutionFiles
75+
) ?: throw Exception(message("sam.init.error.solution.create.fail"))
76+
77+
applicationCoroutineScope().launch {
78+
val project =
79+
SolutionManager.openExistingSolution(
80+
projectToClose = null,
81+
forceOpenInNewFrame = false,
82+
solutionFile = solutionFile,
83+
forceConsiderTrusted = true
84+
) ?: return@launch
85+
vcsPanel?.createInitializer()?.execute(project)
86+
87+
val modifiableModel = ModuleManager.getInstance(project).modules.firstOrNull()?.rootManager?.modifiableModel ?: return@launch
88+
try {
89+
val progressIndicator = if (progressManager.hasProgressIndicator()) progressManager.progressIndicator else DumbProgressIndicator()
90+
91+
samProjectBuilder.runPostSamInit(project, modifiableModel, progressIndicator, samSettings, outDirVf)
92+
} finally {
93+
modifiableModel.dispose()
94+
}
95+
}
96+
}
97+
}
Lines changed: 6 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,19 @@
1-
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
1+
// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

44
package software.aws.toolkits.jetbrains.services.lambda.dotnet
55

6-
import com.intellij.openapi.module.ModuleManager
7-
import com.intellij.openapi.progress.DumbProgressIndicator
8-
import com.intellij.openapi.progress.ProgressManager
9-
import com.intellij.openapi.project.rootManager
10-
import com.intellij.openapi.util.io.FileUtil
11-
import com.intellij.openapi.vfs.LocalFileSystem
126
import com.intellij.ui.ColorUtil
137
import com.intellij.ui.components.JBScrollPane
148
import com.intellij.ui.components.JBTabbedPane
159
import com.intellij.util.ui.JBUI
1610
import com.intellij.util.ui.UIUtil
1711
import com.intellij.xml.util.XmlUtil
18-
import com.jetbrains.rider.ideaInterop.fileTypes.msbuild.CsprojFileType
1912
import com.jetbrains.rider.ideaInterop.fileTypes.sln.SolutionFileType
20-
import com.jetbrains.rider.projectView.SolutionManager
2113
import com.jetbrains.rider.projectView.actions.projectTemplating.backend.ReSharperTemplateGeneratorBase
22-
import com.jetbrains.rider.projectView.actions.projectTemplating.backend.ReSharperTemplatesInteraction
2314
import com.jetbrains.rider.projectView.actions.projectTemplating.impl.ProjectTemplateDialogContext
2415
import com.jetbrains.rider.projectView.actions.projectTemplating.impl.ProjectTemplateTransferableModel
2516
import com.jetbrains.rider.ui.themes.RiderTheme
26-
import kotlinx.coroutines.runBlocking
2717
import software.aws.toolkits.jetbrains.services.lambda.BuiltInRuntimeGroups
2818
import software.aws.toolkits.jetbrains.services.lambda.RuntimeGroup
2919
import software.aws.toolkits.jetbrains.services.lambda.wizard.SamInitSelectionPanel
@@ -36,7 +26,7 @@ import javax.swing.JScrollPane
3626
import javax.swing.JTabbedPane
3727
import javax.swing.JTextPane
3828

39-
class DotNetSamProjectGenerator(
29+
abstract class DotNetSamProjectGeneratorRoot(
4030
private val context: ProjectTemplateDialogContext,
4131
group: String,
4232
categoryName: String,
@@ -61,6 +51,10 @@ class DotNetSamProjectGenerator(
6151
wizardUpdateCallback = { validateData() }
6252
)
6353

54+
fun getSamPanel() = samPanel
55+
56+
fun getSamGenerator() = generator
57+
6458
private val projectStructurePanel: JTabbedPane
6559

6660
private val structurePane = JTextPane().apply {
@@ -154,74 +148,6 @@ class DotNetSamProjectGenerator(
154148
validateData()
155149
}
156150

157-
override fun expand() = Runnable {
158-
val samSettings = samPanel.getNewProjectSettings()
159-
160-
val solutionDirectory = getSolutionDirectory()
161-
?: throw Exception(message("sam.init.error.no.solution.basepath"))
162-
163-
val fileSystem = LocalFileSystem.getInstance()
164-
if (!solutionDirectory.exists()) {
165-
FileUtil.createDirectory(solutionDirectory)
166-
}
167-
168-
val outDirVf = fileSystem.refreshAndFindFileByIoFile(solutionDirectory)
169-
?: throw Exception(message("sam.init.error.no.virtual.file"))
170-
171-
val progressManager = ProgressManager.getInstance()
172-
val samProjectBuilder = generator.createModuleBuilder()
173-
progressManager.runProcessWithProgressSynchronously(
174-
{
175-
samProjectBuilder.runSamInit(
176-
context.project,
177-
projectNameField.text,
178-
samSettings,
179-
null,
180-
outDirVf
181-
)
182-
},
183-
message("sam.init.generating.template"),
184-
false,
185-
null
186-
)
187-
188-
// Create solution file
189-
val projectFiles =
190-
File(solutionDirectory, "src").walk().filter { it.extension == CsprojFileType.defaultExtension } +
191-
File(solutionDirectory, "test").walk().filter { it.extension == CsprojFileType.defaultExtension }
192-
193-
// Get the rest of generated files and copy to "SolutionItems" default folder in project structure
194-
val solutionFiles = solutionDirectory.listFiles()?.filter { it.isFile }?.toList() ?: emptyList()
195-
196-
val solutionFile = ReSharperTemplatesInteraction.createSolution(
197-
name = getSolutionName(),
198-
directory = solutionDirectory,
199-
projectFiles = projectFiles.toList(),
200-
protocolHost = context.protocolHost,
201-
solutionFiles = solutionFiles
202-
) ?: throw Exception(message("sam.init.error.solution.create.fail"))
203-
204-
val project = runBlocking {
205-
SolutionManager.openExistingSolution(
206-
projectToClose = null,
207-
forceOpenInNewFrame = false,
208-
solutionFile = solutionFile,
209-
forceConsiderTrusted = true
210-
)
211-
} ?: return@Runnable
212-
213-
vcsPanel?.createInitializer()?.execute(project)
214-
215-
val modifiableModel = ModuleManager.getInstance(project).modules.firstOrNull()?.rootManager?.modifiableModel ?: return@Runnable
216-
try {
217-
val progressIndicator = if (progressManager.hasProgressIndicator()) progressManager.progressIndicator else DumbProgressIndicator()
218-
219-
samProjectBuilder.runPostSamInit(project, modifiableModel, progressIndicator, samSettings, outDirVf)
220-
} finally {
221-
modifiableModel.dispose()
222-
}
223-
}
224-
225151
override fun refreshUI() {
226152
super.refreshUI()
227153
// This restore project name when user change a solution name and switch between templates

0 commit comments

Comments
 (0)