Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java→Kotlinの移行率を算出するコマンドラインツールをKotlinで実装してみた話...

yu mitsuhori
December 20, 2018

 Java→Kotlinの移行率を算出するコマンドラインツールをKotlinで実装してみた話.pdf

- コマンドラインツールをKotlinで実装してみた話です
- 2018.12.20 Kotlin愛好会で発表したスライドです

yu mitsuhori

December 20, 2018
Tweet

More Decks by yu mitsuhori

Other Decks in Technology

Transcript

  1. 環境準備 1. File > New > Projectを押下 2. 左メニューからGradleを選択後、Kotlinのチェックを入れる 3.

    そのまま必要項目を入力してプロジェクトを作成する ↑2の選択画面 3の 作成されるプロジェクト →
  2. 実装①:言語情報を保持するオブジェクトの作成 /** * 言語の情報を保持するクラス * */ data class Language( val

    name: String, //言語名 val extension: String //拡張子 ){ override fun toString() = name }
  3. 各言語のファイルリスト、移行元/先情報のクラス /** * 言語のlistを保持するクラス */ class SourceList( val language: Language,

    val isReplaceTarget: Boolean, val list: MutableList<File> = mutableListOf()) { fun add(file: File){ list.add(file) } }
  4. Main.kt(SourceListの初期化) val javaList = SourceList(Language("Java", "java"), false) val kotlinList =

    SourceList(Language("Kotlin", "kt"), true) SourceListを初期化する 移行元がfalse, 移行先がtrue
  5. 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") } } } }
  6. Main.kt(ignoreファイル読み込み) val homeDir = System.getProperty("user.home") ?: "" val cd =

    File(".").absoluteFile.parent val ignoreFileReader = IgnoreFileReader("$homeDir/.krsignore", cd) ignoreFileReader.read() .krsignoreファイルを参照して、プロジェクトのルートディレクトリ から初期化したFileオブジェクトを渡す
  7. 実装③:ディレクトリ探索用のクラス 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) } }
  8. Main.kt(探索処理及び結果表示) val handler = SearchHandler(cd, arrayOf(javaList, kotlinList), ignoreFileReader.files) handler.execute() val

    logger = ResultLogger(handler.result) logger.log() 画面表示についての説明は割愛します
  9. 最終的な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() }
  10. 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ができる
  11. 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 }
  12. 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) }