안드로이드 스튜디오(203.7717.56)용 File Templates 플러그인 개발환경 구축 가이드
(https://plugins.jetbrains.com/docs/intellij/templates.html)
안드로이드 스튜디오(IDE)등을 사용하여 소프트웨어를 개발 하면서, 동일한 기본 파일구조와 공통의 코드들을 반복적으로 생성 및 작성 해야만 할 때가 있습니다. 그래서 안드로이드 스튜디오에는 '파일 생성 템플릿'(File Templates : IDE-File-New-Activity,Fragment등 탬플릿선택)이라는 기본 코드와 주석등이 작성된 파일을 생성해주는 기능이 있습니다.
기본 안드로이드'파일생성 템플릿'외에 자신의 프로젝트구조나 스타일에 맞게 사용하고 싶은 '커스텀 템플릿'을 직접 플러그인형태로 추가 개발하여서, 아주 쉽게(?) 프로젝트에 사용할 수 있습니다.
(직접 만든 플러그인을 Intellij Plugin MarketPlace에 배포 및 공유도 가능합니다.)
Intellij IDE Plugin 개발환경은 레퍼런스 문서를 보니 3가지 유형이 있었습니다.
1) IntelliJ Platform Plugin Template
2) Building Plugins with Gradle
3) Using DevKit
이중에 IntelliJ Platform Plugin Template 프로젝트로 플러그인 개발 환경을 선택하였고, 다음과 같이 Github의 Use This Template를 사용하여 프로젝트 리포지토리를 생성하고 Android Studio에서 Clone(다운로드)합니다.
(1) Use This Template - IntelliJ Platform Plugin Tempalte in Github
(2) Clone from Github My Repository in Android Studio
.
├── .github/ GitHub Actions workflows and Dependabot configuration files
├── .run/ Predefined Run/Debug Configurations
├── gradle
│ └── wrapper/ Gradle Wrapper
├── build/ Output build directory
├── src Plugin sources
│ └── main
│ ├── kotlin/ Kotlin source files
│ └── resources/ Resources - plugin.xml, icons, messages
│ └── test
│ ├── kotlin/ Kotlin test files
│ └── testData/ Test data used by tests
├── .gitignore Git ignoring rules
├── build.gradle.kts Gradle configuration
├── CHANGELOG.md Full change history
├── gradle.properties Gradle configuration properties
├── gradlew *nix Gradle Wrapper binary
├── gradlew.bat Windows Gradle Wrapper binary
├── LICENSE License, MIT by default
├── qodana.yml Qodana configuration file
├── README.md README
└── settings.gradle.kts Gradle project settings
# IntelliJ Platform Artifacts Repositories
# -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html
pluginGroup = com.github.ridsync.androidmvvmtemplate
pluginName = android-mvvm-devoks-plugin # 플러그인 명
pluginVersion = 0.7.0 # 플러그인 버젼
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild = 203
pluginUntilBuild = 212.*
# Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl
# See https://jb.gg/intellij-platform-builds-list for available build versions.
pluginVerifierIdeVersions = 2020.3.4, 2021.1.3, 2021.2.1
platformType = IC # 플랫폼 유형(커뮤니티,Ultimate,PhpStorm등의 타입선언)
platformVersion = 2020.3.4 # IDE 플랫폼 버젼 (중요)
platformDownloadSources = false
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins = android, org.jetbrains.android, org.jetbrains.kotlin, java, com.intellij.java
# Java language level used to compile sources and to generate the files for - Java 11 is required since 2020.3
javaVersion = 11
gradleVersion = 7.2
# Opt-out flag for bundling Kotlin standard library.
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.
# suppress inspection "UnusedProperty"
kotlin.stdlib.default.dependency = false
# 스튜디오 설치 경로 속성(in MacOS)
StudioCompilePath = /Applications/Android Studio.app/Contents
StudioRunPath = /Applications/Android Studio.app/Contents
(2) build.gradle.kts (기본 옵션에 추가된 빌드설정 요약.)
intellij {
```
// localPath 설정 (안드로이드 스튜디오 경로)
localPath.set(properties("StudioRunPath"))
}
tasks {
```
instrumentCode {
compilerVersion.set("203.7717.56") // 현재 사용중인 Android Studio Version
}
}
```
// 기타 patch, Signing, Publishing등의 옵션
(3) src/main/resource/META-INF/plugin.xml
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin>
<id>androidmvvmtemplate</id>
<name>android-mvvm-plugin-template</name>
<vendor>ridsync</vendor>
<depends>org.jetbrains.android</depends>
<depends>com.intellij.modules.androidstudio</depends>
<extensions defaultExtensionNs="com.android.tools.idea.wizard.template">
<wizardTemplateProvider implementation="com.github.ridsync.wizard.WizardTemplateProviderImpl" />
</extensions>
<!-- 아래 클래스들은 불필요해서 주석처리 함 (미사용) -->
<!-- <extensions defaultExtensionNs="com.intellij">-->
<!-- <applicationService serviceImplementation="com.github.ridsync.androidmvvmtemplate.services.MyApplicationService"/>-->
<!-- <projectService serviceImplementation="com.github.ridsync.androidmvvmtemplate.services.MyProjectService"/>-->
<!-- </extensions>-->
<!-- <applicationListeners>-->
<!-- <listener class="com.github.ridsync.androidmvvmtemplate.listeners.MyProjectManagerListener"-->
<!-- topic="com.intellij.openapi.project.ProjectManagerListener"/>-->
<!-- </applicationListeners>-->
</idea-plugin>
(4) src/main/kotlin/.../WizardTemplateProviderImpl.kt
class WizardTemplateProviderImpl : WizardTemplateProvider() {
// 템플릿 프로바이더 구현 클래스 - 직접 커스텀한 템플릿(mvvmWizardTemplate.Class)를 생성 및 반환하는 역할
override fun getTemplates(): List<Template> = listOf(mvvmWizardTemplate)
}
(5) src/main/kotlin/.../mvvmWizardTemplate.kt
// TemplateBuilder를 통해 실제 Custom Template의 UI,위젯,파일처리등을 정의하는 클래스
name = "Android MVVM Creator (Project)"
description = "Creates a new Fragment/ViewModel with layout file."
minApi = MIN_SDK
category = Category.Other // Check other categories
formFactor = FormFactor.Mobile
(6) src/main/kotlin/.../mvvmWizardRecipe.kt
// 파람을 통해 전달받은 ModuleTemplateData의 File정보로
// 최종 생성할 파일의 저장위치,파일명등을 정의 및 생성처리하는 클래스
val (projectData, srcOut, resOut) = moduleData
addAllKotlinDependencies(moduleData)
val format = SimpleDateFormat("yyyy/MM/dd")
val date = format.format(Date())
val path = srcOut.absolutePath.replace("java","kotlin") // 현 프로젝트에서는 kotlin dir을 사용하므로 replace처리 함.
val srcKotlinDir = File(path)
// Fragment Template String Save
save(
someFragment(date, defaultPackage, newFilePackage, entityName, layoutName, projectData),
srcKotlinDir.resolve("${entityName}Fragment.kt")
)
// ViewModel Template String Save
save(someFragmentViewModel(date, defaultPackage, newFilePackage, entityName, layoutName, projectData),
srcKotlinDir.resolve("${entityName}ViewModel.kt"))
// Layout(XML) Template String Save
save(someFragmentLayout(defaultPackage, newFilePackage, entityName),
resOut.resolve("layout/$layoutName.xml")
)
(7) src/main/kotlin/.../FragmentAndLayout.kt
// 실제 생성할 파일들의 코드(String)를 생성하는 각 메소드
fun someFragment(
date: String,
defaultPackage: String,
newFilePackage: String,
entityName: String,
layoutName: String,
projectData: ProjectTemplateData
): String {
val databindingName = "Fragment${entityName.toLowerCase().toCamelCase()}Binding"
return """package $newFilePackage
import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import dagger.hilt.android.AndroidEntryPoint
import ${defaultPackage}.presentation.base.BaseAppBarFragment
import ${defaultPackage}.databinding.${databindingName}
import ${defaultPackage}.R
/**
* Created by user on ${date}.
* Description :
*/
@AndroidEntryPoint
class ${entityName}Fragment : BaseAppBarFragment<${databindingName}>(R.layout.${layoutName.toLowerCase()}) {
private val viewModel by viewModels<${entityName}ViewModel>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.fragment = this
binding.viewModel = viewModel
super.onViewCreated(view, savedInstanceState)
}
override fun onInitViews() {}
override fun onSubscribeVm() {}
override fun onSetToolBarViews() {}
}
"""
}
빌드 및 테스트
플러그인 설치 (jar)
플러그인 사용
안드로이드 스튜디오 타겟 버젼을 맞추기 위한 템플릿 프로젝트의 초기 환경설정시에 프로젝트 빌드가 안되는 현상이 발생하였습니다. 그래서 Github Issue에서 오류 로그를 찾아 확인해보니, instrunmentCode의 옵션을 추가하여 해당 플랫폼 버젼에 맞는 리포지토리로부터 libarary 다운로드받고 나서야 빌드가 정상적으로 진행되었습니다.
(참고: https://github.com/JetBrains/gradle-intellij-plugin/issues/369#issuecomment-893311439 )
플러그인을 통한 파일 생성시마다, 파일생성은 문제없으나 Gradle Sync가 동작하는 현상이 조금 있기는 한데 원인은 잘 모르겠습니다; (정상은 아닌듯...),
추가적으로, 선택한 프롬프트(?)의 폴더위치로 파일생성 경로를 자동 입력되게 하는 방법도 좋을것 같아서, File Template 관련 레퍼런스 문서가 추가되면 개선 해보려고 합니다.
그리고, 시간이 된다면, 마켓플레이스에 개발자가 쓸만한 멋진 플러그인을 한번 만들고 배포해보면 좋겠습니다.
Completion
https://github.com/ridsync/android-mvvm-devoks-plugin
https://plugins.jetbrains.com/docs/intellij/welcome.html
https://github.com/JetBrains/gradle-intellij-plugin
https://steewsc.medium.com/template-plugin-for-android-studio-4-1-92dcbc689d39