Skip to content

Commit ebb3822

Browse files
authored
Portfolio 14314 improvements (#73)
* [MOB-24628] After wizard add dialog for sync if need * [MOB-24628] Fix imports * [MOB-24629] Change dialog cancel button text * [MOB-24631] Show only folders with recipes * [MOB-24631] Fix duplication items after reopen project * [MOB-24631] Add ability to rescan folders with templates without restarting * [MOB-24631] 'help' filed for widgets not required * [MOB-24631] Fix code-style * [MOB-24631] If Geminio config wrong -> show error with settings action * [MOB-24631] Info balloon after templates rescanned * [MOB-24631] Fix parameters and import * [MOB-24629] Fix addGradlePlugin and other modification commands in files (#70) * [MOB-24630] Multi-window support (#71) * [MOB-24722] Update geminio version and changelog (#72) * [MOB-24722] Update geminio version and changelog * [MOB-24722] Up to 1.2.0
1 parent cb0dd94 commit ebb3822

File tree

16 files changed

+421
-181
lines changed

16 files changed

+421
-181
lines changed

plugins/hh-carnival/src/main/kotlin/ru/hh/android/plugin/actions/modules/copy_module/CopyAndroidModuleAction.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import ru.hh.android.plugin.utils.notifyError
3636
import ru.hh.android.plugin.utils.notifyInfo
3737
import ru.hh.plugins.code_modification.BuildGradleModificationService
3838
import ru.hh.plugins.code_modification.SettingsGradleModificationService
39+
import ru.hh.plugins.dialog.sync.showSyncQuestionDialog
3940
import ru.hh.plugins.extensions.openapi.isAndroidLibraryModule
4041
import ru.hh.plugins.models.gradle.BuildGradleDependency
4142
import ru.hh.plugins.models.gradle.BuildGradleDependencyConfiguration
@@ -98,8 +99,7 @@ class CopyAndroidModuleAction : AnAction() {
9899
)
99100
)
100101

101-
SyncProjectAction().actionPerformed(actionData.actionEvent)
102-
102+
project.showSyncQuestionDialog(syncPerformedActionEvent = actionData.actionEvent)
103103
project.notifyInfo("Module \"${newModuleParams.moduleToCopy.name}\" successfully copied!")
104104
}
105105
}

plugins/hh-geminio/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Geminio
22

3+
## [1.2.0]
4+
### Added
5+
- Sync dialog after creating templates
6+
- Display templates folders with recipes only
7+
- Ability to rescan templates folders without restarting
8+
- `help` filed for all widgets not required
9+
- Multi-window support with different projects
10+
11+
### Fixed
12+
- Fixed duplication templates items after reopen project
13+
- Fixed 'addGradlePlugin' and other modification commands in files
14+
315
## [1.1.11]
416
### Added
517
- Support for Android Studio Chipmunk | 2022.2.1

plugins/hh-geminio/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pluginVersion=1.1.11
1+
pluginVersion=1.2.0
22

33
pluginGroup=ru.hh.plugins
44
pluginName=hh-geminio
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
package ru.hh.plugins.geminio
2+
3+
import com.intellij.openapi.actionSystem.ActionManager
4+
import com.intellij.openapi.actionSystem.AnAction
5+
import com.intellij.openapi.actionSystem.DefaultActionGroup
6+
import com.intellij.openapi.project.Project
7+
import ru.hh.plugins.extensions.toUnderlines
8+
import ru.hh.plugins.geminio.GeminioConstants.GEMINIO_TEMPLATE_CONFIG_FILE_NAME
9+
import ru.hh.plugins.geminio.actions.RescanTemplatesAction
10+
import ru.hh.plugins.geminio.actions.SetupGeminioConfigAction
11+
import ru.hh.plugins.geminio.actions.module_template.ExecuteGeminioModuleTemplateAction
12+
import ru.hh.plugins.geminio.actions.template.ExecuteGeminioTemplateAction
13+
import ru.hh.plugins.geminio.config.GeminioPluginConfig
14+
import ru.hh.plugins.geminio.config.editor.GeminioPluginSettings
15+
import ru.hh.plugins.geminio.services.balloonError
16+
import java.io.File
17+
18+
internal class ActionsHelper {
19+
20+
private companion object {
21+
const val BASE_ID = "ru.hh.plugins.geminio.actions."
22+
const val NEW_GROUP_ID_SUFFIX = "NewGroup."
23+
const val GENERATE_GROUP_ID_SUFFIX = "GenerateGroup."
24+
25+
const val LOG_DIVIDER = "============"
26+
}
27+
28+
29+
fun createGeminioActions(project: Project) {
30+
val pluginConfig = GeminioPluginSettings.getConfig(project)
31+
val pathToConfig = pluginConfig.configFilePath
32+
val pathToTemplates = project.basePath + pluginConfig.templatesRootDirPath
33+
val pathToModulesTemplates = project.basePath + pluginConfig.modulesTemplatesRootDirPath
34+
35+
println("\tpathToConfig: $pathToConfig")
36+
println("\tpathToTemplates: $pathToTemplates")
37+
println("\tpathToModulesTemplates: $pathToModulesTemplates")
38+
println(LOG_DIVIDER)
39+
println(LOG_DIVIDER)
40+
41+
resetGeminioActions(project)
42+
43+
if (project.isConfigNotValid(pathToConfig, pathToTemplates, pathToModulesTemplates)) {
44+
val error = "Geminio's config is not valid (may be not configured at all) -> no need to create actions"
45+
project.balloonError(message = error, action = SetupGeminioConfigAction())
46+
println("\t$error")
47+
return
48+
}
49+
50+
createActionsForTemplates(
51+
project = project,
52+
pluginConfig = pluginConfig,
53+
rootDirPath = pathToTemplates,
54+
isModulesTemplates = false,
55+
)
56+
57+
createActionsForTemplates(
58+
project = project,
59+
pluginConfig = pluginConfig,
60+
rootDirPath = pathToModulesTemplates,
61+
isModulesTemplates = true,
62+
)
63+
}
64+
65+
fun resetGeminioActions(project: Project) {
66+
val actionManager = ActionManager.getInstance()
67+
val pluginConfig = GeminioPluginSettings.getConfig(project)
68+
actionManager.removeAllActionsFromGroups(pluginConfig, isModulesTemplates = true)
69+
actionManager.removeAllActionsFromGroups(pluginConfig, isModulesTemplates = false)
70+
}
71+
72+
73+
private fun createActionsForTemplates(
74+
project: Project,
75+
pluginConfig: GeminioPluginConfig,
76+
rootDirPath: String,
77+
isModulesTemplates: Boolean,
78+
) {
79+
val actionManager = ActionManager.getInstance()
80+
val bundle = getTemplateActionsBundle(pluginConfig, isModulesTemplates)
81+
val hhNewGroup = actionManager.getAction(bundle.templatesNewGroupId) as DefaultActionGroup
82+
hhNewGroup.templatePresentation.text = bundle.templatesNewGroupName
83+
84+
val hhGenerateGroup = actionManager.getAction(bundle.templatesGenerateGroupId) as DefaultActionGroup
85+
val rootDirectory = File(rootDirPath)
86+
87+
if (rootDirectory.exists().not() || rootDirectory.isDirectory.not()) {
88+
println("Templates directory doesn't exists [path: $rootDirPath, isModulesTemplates: $isModulesTemplates]")
89+
return
90+
}
91+
92+
println("\tTemplates directory exists [path: $rootDirPath, isModulesTemplates: $isModulesTemplates]")
93+
val templatesDirs = rootDirectory.getSubfolderNamesWithRecipes()
94+
95+
println("\tTemplates count: ${templatesDirs.size}")
96+
println(LOG_DIVIDER)
97+
98+
actionManager.addTemplatesActions(
99+
projectName = project.name,
100+
templatesDirs = templatesDirs,
101+
rootDirPath = rootDirPath,
102+
isModulesTemplates = isModulesTemplates,
103+
groups = Groups(hhNewGroup = hhNewGroup, hhGenerateGroup = hhGenerateGroup),
104+
)
105+
106+
actionManager.addRescanActions(
107+
projectName = project.name,
108+
groups = Groups(hhNewGroup = hhNewGroup, hhGenerateGroup = hhGenerateGroup),
109+
)
110+
}
111+
112+
private fun ActionManager.removeAllActionsFromGroups(
113+
pluginConfig: GeminioPluginConfig,
114+
isModulesTemplates: Boolean,
115+
) {
116+
val bundle = getTemplateActionsBundle(pluginConfig, isModulesTemplates)
117+
val hhNewGroup = getAction(bundle.templatesNewGroupId) as DefaultActionGroup
118+
val hhGenerateGroup = getAction(bundle.templatesGenerateGroupId) as DefaultActionGroup
119+
120+
hhNewGroup.removeAll()
121+
hhGenerateGroup.removeAll()
122+
}
123+
124+
private fun createActionForTemplate(
125+
templatesRootDirPath: String,
126+
templateDirName: String,
127+
isModulesTemplates: Boolean,
128+
actionManager: ActionManager,
129+
actionId: String,
130+
): AnAction {
131+
val action = when (isModulesTemplates) {
132+
true -> {
133+
ExecuteGeminioModuleTemplateAction(
134+
actionText = templateDirName,
135+
actionDescription = "Action for executing '$templateDirName'",
136+
geminioRecipePath = getGeminioRecipeFilePath(templatesRootDirPath, templateDirName),
137+
)
138+
}
139+
140+
false -> {
141+
ExecuteGeminioTemplateAction(
142+
actionText = templateDirName,
143+
actionDescription = "Action for executing '$templateDirName'",
144+
geminioRecipePath = getGeminioRecipeFilePath(templatesRootDirPath, templateDirName),
145+
)
146+
}
147+
}
148+
149+
with(actionManager) {
150+
getActionOrStub(actionId)
151+
?.also { replaceAction(actionId, action) }
152+
?: registerAction(actionId, action)
153+
}
154+
155+
return action
156+
}
157+
158+
private fun getGeminioRecipeFilePath(templatesRootDirPath: String, templateDirName: String): String {
159+
return "$templatesRootDirPath/$templateDirName/${GeminioConstants.GEMINIO_TEMPLATE_CONFIG_FILE_NAME}"
160+
}
161+
162+
private fun getTemplateActionsBundle(
163+
pluginConfig: GeminioPluginConfig,
164+
isModulesTemplates: Boolean,
165+
): TemplateActionsBundle = when (isModulesTemplates) {
166+
true -> {
167+
TemplateActionsBundle(
168+
templatesNewGroupId = GeminioConstants.HH_MODULES_TEMPLATES_NEW_GROUP_ID,
169+
templatesGenerateGroupId = GeminioConstants.HH_MODULES_TEMPLATES_GENERATE_GROUP_ID,
170+
templatesNewGroupName = pluginConfig.groupsNames.forNewModulesGroup,
171+
)
172+
}
173+
174+
false -> {
175+
TemplateActionsBundle(
176+
templatesNewGroupId = GeminioConstants.HH_TEMPLATES_NEW_GROUP_ID,
177+
templatesGenerateGroupId = GeminioConstants.HH_TEMPLATES_GENERATE_GROUP_ID,
178+
templatesNewGroupName = pluginConfig.groupsNames.forNewGroup,
179+
)
180+
}
181+
}
182+
183+
private fun ActionManager.addTemplatesActions(
184+
projectName: String,
185+
templatesDirs: List<String>,
186+
rootDirPath: String,
187+
isModulesTemplates: Boolean,
188+
groups: Groups,
189+
) {
190+
templatesDirs.forEach { templateName ->
191+
createActionForTemplate(
192+
templatesRootDirPath = rootDirPath,
193+
templateDirName = templateName,
194+
isModulesTemplates = isModulesTemplates,
195+
actionManager = this,
196+
actionId = BASE_ID + NEW_GROUP_ID_SUFFIX + "$projectName." + templateName.toUnderlines(),
197+
).also(groups.hhNewGroup::add)
198+
199+
createActionForTemplate(
200+
templatesRootDirPath = rootDirPath,
201+
templateDirName = templateName,
202+
isModulesTemplates = isModulesTemplates,
203+
actionManager = this,
204+
actionId = BASE_ID + GENERATE_GROUP_ID_SUFFIX + "$projectName." + templateName.toUnderlines(),
205+
).also(groups.hhGenerateGroup::add)
206+
}
207+
}
208+
209+
private fun ActionManager.addRescanActions(
210+
projectName: String,
211+
groups: Groups,
212+
) {
213+
val actionId = "$BASE_ID$projectName.RescanActionId"
214+
val rescanTemplatesAction = RescanTemplatesAction()
215+
216+
getActionOrStub(actionId)
217+
?.also { replaceAction(actionId, rescanTemplatesAction) }
218+
?: registerAction(actionId, rescanTemplatesAction)
219+
220+
groups.hhNewGroup.add(rescanTemplatesAction)
221+
groups.hhGenerateGroup.add(rescanTemplatesAction)
222+
}
223+
224+
private fun File.getSubfolderNamesWithRecipes(): List<String> {
225+
return listFiles { file, _ -> file.isDirectory }
226+
?.filter { file ->
227+
file.listFiles { _, name -> name == GEMINIO_TEMPLATE_CONFIG_FILE_NAME }.isNullOrEmpty().not()
228+
}
229+
?.map { it.name }
230+
?: emptyList()
231+
}
232+
233+
private fun Project.isConfigNotValid(
234+
pathToConfig: String,
235+
pathToTemplates: String,
236+
pathToModulesTemplates: String,
237+
): Boolean {
238+
return pathToConfig.isBlank() || pathToTemplates == basePath || pathToModulesTemplates == basePath
239+
}
240+
241+
242+
private data class TemplateActionsBundle(
243+
val templatesNewGroupId: String,
244+
val templatesGenerateGroupId: String,
245+
val templatesNewGroupName: String,
246+
)
247+
248+
private data class Groups(
249+
val hhNewGroup: DefaultActionGroup,
250+
val hhGenerateGroup: DefaultActionGroup,
251+
)
252+
253+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package ru.hh.plugins.geminio.actions
2+
3+
import com.intellij.icons.AllIcons
4+
import com.intellij.openapi.actionSystem.AnAction
5+
import com.intellij.openapi.actionSystem.AnActionEvent
6+
import com.intellij.psi.PsiDirectory
7+
import ru.hh.plugins.extensions.getSelectedPsiElement
8+
import ru.hh.plugins.geminio.ActionsHelper
9+
import ru.hh.plugins.geminio.services.balloonInfo
10+
11+
class RescanTemplatesAction : AnAction() {
12+
13+
init {
14+
with(templatePresentation) {
15+
text = "Rescan Templates"
16+
icon = AllIcons.Actions.Refresh
17+
description = "Rescan folder with templates"
18+
isEnabledAndVisible = true
19+
}
20+
}
21+
22+
override fun update(e: AnActionEvent) {
23+
super.update(e)
24+
25+
val selectedPsiElement = e.getSelectedPsiElement()
26+
e.presentation.isEnabledAndVisible =
27+
(e.project == null || selectedPsiElement == null || selectedPsiElement !is PsiDirectory).not()
28+
}
29+
30+
override fun actionPerformed(e: AnActionEvent) {
31+
println("Start executing rescan templates")
32+
e.project?.also(ActionsHelper()::createGeminioActions)
33+
e.project?.balloonInfo(message = "Templates rescanned")
34+
}
35+
36+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package ru.hh.plugins.geminio.actions
2+
3+
import com.intellij.openapi.actionSystem.AnAction
4+
import com.intellij.openapi.actionSystem.AnActionEvent
5+
import com.intellij.openapi.options.ShowSettingsUtil
6+
import ru.hh.plugins.geminio.config.editor.GeminioPluginSettingsSearchableConfigurable
7+
8+
class SetupGeminioConfigAction : AnAction() {
9+
10+
init {
11+
with(templatePresentation) {
12+
text = "Setup Config"
13+
isEnabledAndVisible = true
14+
}
15+
}
16+
17+
override fun actionPerformed(e: AnActionEvent) {
18+
val project = e.project ?: return
19+
ShowSettingsUtil.getInstance()
20+
.editConfigurable(project, GeminioPluginSettingsSearchableConfigurable(project))
21+
}
22+
23+
}

plugins/hh-geminio/src/main/kotlin/ru/hh/plugins/geminio/actions/module_template/ExecuteGeminioModuleTemplateAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package ru.hh.plugins.geminio.actions.module_template
22

3-
import com.android.tools.idea.gradle.actions.SyncProjectAction
43
import com.android.tools.idea.ui.wizard.StudioWizardDialogBuilder
54
import com.android.tools.idea.wizard.model.ModelWizard
65
import com.intellij.openapi.actionSystem.AnAction
@@ -9,6 +8,7 @@ import com.intellij.psi.PsiDirectory
98
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
109
import ru.hh.plugins.code_modification.BuildGradleModificationService
1110
import ru.hh.plugins.code_modification.SettingsGradleModificationService
11+
import ru.hh.plugins.dialog.sync.showSyncQuestionDialog
1212
import ru.hh.plugins.extensions.SPACE
1313
import ru.hh.plugins.extensions.UNDERSCORE
1414
import ru.hh.plugins.extensions.getSelectedPsiElement
@@ -131,8 +131,7 @@ class ExecuteGeminioModuleTemplateAction(
131131
modifyBuildGradle(recipeExecutorModel)
132132
}
133133

134-
SyncProjectAction().actionPerformed(actionEvent)
135-
134+
project.showSyncQuestionDialog(syncPerformedActionEvent = actionEvent)
136135
project.balloonInfo(message = "Finished '$actionText' module template execution")
137136
} catch (ex: Exception) {
138137
ex.printStackTrace()

plugins/hh-geminio/src/main/kotlin/ru/hh/plugins/geminio/config/editor/GeminioPluginSettingsSearchableConfigurable.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ru.hh.plugins.geminio.config.editor
22

33
import com.intellij.openapi.options.SearchableConfigurable
44
import com.intellij.openapi.project.Project
5+
import ru.hh.plugins.geminio.ActionsHelper
56
import javax.swing.JComponent
67

78
class GeminioPluginSettingsSearchableConfigurable(
@@ -33,6 +34,7 @@ class GeminioPluginSettingsSearchableConfigurable(
3334

3435
override fun apply() {
3536
pluginConfigPropertiesEditor?.applyNewConfiguration(pluginConfig)
37+
ActionsHelper().createGeminioActions(project)
3638
}
3739

3840
override fun createComponent(): JComponent? {

0 commit comments

Comments
 (0)