Share
Embed
Java→Kotlinの移行率を算出するコマンドラインツールをKotlinで実装してみた話.pdf
- コマンドラインツールをKotlinで実装してみた話です
- 2018.12.20 Kotlin愛好会で発表したスライドです
yu mitsuhori
December 20, 2018
Transcript
36 slides
-
自己紹介 三堀 裕 Android Developer 女性向けのヘルスケアアプリを担当してます。 Twitter: @1013Youmeee GitHub: https://github.com/youmitsu
Qiita: https://qiita.com/youmeee -
本日のアジェンダ 1. 経緯 2. デモ 3. 実装方法 a. 環境構築 b.
実装 c. jarの実行 4. まとめ -
環境準備 1. File > New > Projectを押下 2. 左メニューからGradleを選択後、Kotlinのチェックを入れる 3.
そのまま必要項目を入力してプロジェクトを作成する ↑2の選択画面 3の 作成されるプロジェクト → -
実装①:言語情報を保持するオブジェクトの作成 /** * 言語の情報を保持するクラス * */ data class Language( val
name: String, //言語名 val extension: String //拡張子 ){ override fun toString() = name } -
各言語のファイルリスト、移行元/先情報のクラス /** * 言語のlistを保持するクラス */ class SourceList( val language: Language,
val isReplaceTarget: Boolean, val list: MutableList<File> = mutableListOf()) { fun add(file: File){ list.add(file) } } -
Main.kt(SourceListの初期化) val javaList = SourceList(Language("Java", "java"), false) val kotlinList =
SourceList(Language("Kotlin", "kt"), true) SourceListを初期化する 移行元がfalse, 移行先がtrue -
ignoreファイルを読み取るためのReaderクラスの作成 class IgnoreFileReader(ignoreFilePath: String, private val cd: String) { private
var fileReader: FileReader? = null var files: List<File> = mutableListOf() init { try { fileReader = FileReader(ignoreFilePath) } catch(e: FileNotFoundException) { } } fun read() { fileReader?.let { val filesStr = it.readLines() files = filesStr.map { File("$cd/$it") } } } } -
Main.kt(ignoreファイル読み込み) val homeDir = System.getProperty("user.home") ?: "" val cd =
File(".").absoluteFile.parent val ignoreFileReader = IgnoreFileReader("$homeDir/.krsignore", cd) ignoreFileReader.read() .krsignoreファイルを参照して、プロジェクトのルートディレクトリ から初期化したFileオブジェクトを渡す -
実装③:ディレクトリ探索用のクラス class SearchHandler( private val path: String, private val langList:
Array<SourceList>, private val ignoreDirList: List<File>) { lateinit var result: Result fun execute() { var sizeAll = 0 val rootDir = File(path) rootDir.walkTopDown() .filter { isNotIgnoreFile(it) }.forEach { file -> langList.map { langList -> if(isTargetFile(file, langList.language.extension)){ langList.add(file) println(file) sizeAll++ } } } result = Result(langList, sizeAll) } private fun isTargetFile(file: File, extension: String): Boolean = file.extension == extension /** * 対象外ファイルを無視する */ private fun isNotIgnoreFile(file: File): Boolean = ignoreDirList.none { file.startsWith(it) } } -
Main.kt(探索処理及び結果表示) val handler = SearchHandler(cd, arrayOf(javaList, kotlinList), ignoreFileReader.files) handler.execute() val
logger = ResultLogger(handler.result) logger.log() 画面表示についての説明は割愛します -
最終的なmain.kt fun main(args: Array<String>) { val homeDir = System.getProperty("user.home") ?:
"" val cd = File(".").absoluteFile.parent val javaList = SourceList(Language("Java", "java"), false) val kotlinList = SourceList(Language("Kotlin", "kt"), true) val ignoreFileReader = IgnoreFileReader("$homeDir/.krsignore", cd) ignoreFileReader.read() val handler = SearchHandler(cd, arrayOf(javaList, kotlinList), ignoreFileReader.files) handler.execute() val logger = ResultLogger(handler.result) logger.log() } -
jarをビルド task packJar(type: Jar) { manifest { attributes 'Main-Class': 'jp.co.youmeee.app.MainKt'
} from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar } $ ./gradlew packJar 1. jarファイル生成のtaskを書いてあげて、 2. gradlew wrapperでタスク実行 3. build/libs配下にjarができる -
build.gradle buildscript { ext.kotlin_version = '1.2.10' repositories { mavenCentral() }
dependencies { classpath "org.jetbrains.kotlin: kotlin-gradle-plugin:$kotlin_version" } } plugins { id 'org.jetbrains.kotlin.jvm' version '1.1.51' id 'com.github.johnrengelman.shadow' version '2.0.1' } apply plugin: 'application' apply plugin: 'java' group 'jp.co.youmeee' version '1.2' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" testCompile group: 'junit', name: 'junit', version: '4.12' compile 'org.slf4j:slf4j-api:1.7.25' compile 'org.slf4j:jcl-over-slf4j:1.7.25' compile 'org.slf4j:jul-to-slf4j:1.7.25' compile 'ch.qos.logback:logback-classic:1.2.3' } task packJar(type: Jar) { manifest { attributes 'Main-Class': 'jp.co.youmeee.app.MainKt' } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar } -
build.gradle.kts buildscript { val kotlinVersion = "1.2.10" repositories { mavenCentral()
} dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin: $kotlinVersion") } } group = "jp.co.youmeee" version = "1.2" plugins { java application `kotlin-dsl` id("org.jetbrains.kotlin.jvm") version "1.1.51" id("com.github.johnrengelman.shadow") version "2.0.1" } java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } repositories { mavenCentral() } dependencies { val kotlinVersion = "1.2.10" compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") testCompile(group = "junit", name = "junit", version = "4.12") compile ("org.slf4j:slf4j-api:1.7.25") compile("org.slf4j:jcl-over-slf4j:1.7.25") compile("org.slf4j:jul-to-slf4j:1.7.25") compile("ch.qos.logback:logback-classic:1.2.3") } task("packJar", type = Jar::class) { archiveName = "krs.jar" manifest { attributes["Main-Class"] = "jp.co.youmeee.app.MainKt" } from(configurations.runtime.map({ if (it.isDirectory) it else zipTree(it) })) with(tasks["jar"] as CopySpec) } -
参考資料 ・Migrating build logic from Groovy to Kotlin https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/ ・JVMベースのコマンドラインツールをHomebrewで配布する
https://int128.hatenablog.com/entry/2015/02/27/220907