読者です 読者をやめる 読者になる 読者になる

元Web系エンジニアのごはんブログ

JavaとかKotlinとかのごはん関係のブログです。

KotlinプロジェクトをTravis CIで回し、カバレッジをCoverallsで見る

github.com


Travis CIを回していたのですが、Kotlinでカバレッジを取ることができそうだったのでどうせならCoverallsで見られるようにしようと試行錯誤した記録です(結果だけまとめますが)。

Travis CI

まずTravis CIは簡単なのでざっくりと説明しますが、私は次のように「.travis.yml」ファイルを作成しました。sudoとかいるのか正直あまり良くわかっていませんが、こんな感じに書いています。

language: java
sudo: false
jdk:
    - oraclejdk7
script:
    - ./gradlew test

GitHubにpushする前にTravis CIの方でCIを回したいプロジェクトを選択します。

f:id:webarata3:20160605142021p:plain

そして、GitHubにそのプロジェクトをpushすると自動的にTravis CIで指定したコマンドが動きます。

テストが通りうまく行けば次のように緑の画面になります。

f:id:webarata3:20160605142030p:plain

また、よくGitHubにはってある次のようなバッチも

f:id:webarata3:20160605142040p:plain

次の場所をクリックしてMarkdownを選択することで簡単に作ることができます。

f:id:webarata3:20160605142047p:plain

Travis CIはこんな感じでできます。

Coveralls

Coverallsは少し苦労しました。基本的にはJaCoCoでカバレッジのレポートを作成し、それをCoverallsに送るだけになりますがいろいろとハマりどころがありました。

まずローカル環境でカバレッジを取ります。カバレッジにはJaCoCoを用いました。JaCoCoのGradleの設定は次の通りになります。

apply plugin: 'jacoco'

jacocoTestReport {
  reports {
    xml.enabled true
    csv.enabled false
    html.enabled true
  }
}

この設定の場合、XMLとHTMLでカバレッジの結果を出力します。設定後、

$ ./gradlew test jacocoTestReport

とすると、テストとカバレッジのレポートが作成されます。JaCoCOは必ずtestの後か、testと一緒に行ってください。

ここで、実は少しハマったのですが、JaCoCOのタスクがSKIPPEDとなりカバレッジレポートが作成されないことがありました。わたしの場合には、buildディレクトリーを削除することで無事動作するようになりました。

さて、次にCoverallsの設定になりますが、設定する際にはCoverallsでトークンを取得する必要があります。まずは、カバレッジを見たいプロジェクトを設定します。

f:id:webarata3:20160605142103p:plain

そうすると、次のような画面になりトークンが表示されます(写真ではぼかしています)。

f:id:webarata3:20160605142111p:plain

このトークンの設定を先に行います。このトークンはGitHub上にアップしないとCoverallsが動きませんが、だれでもトークンを見ることができる状況になってしまいます。それを防ぐためにTravisのツールを用いてトークンを暗号化します。

これに関しては
次のサイトを参考にしました。

qiita.com

まずtravisのモジュールをダウンロードします。

$ sudo gem install travis

そして、このツールを用いてトークンを暗号化します。

$ travis encrypt COVERALLS_TOKEN=トークンをここに書く

そうすると標準出力にずらっと次のように暗号化された文字列が表示されます。

  secure: "Gj9nNmjtg8Zk /* 省略 */ F/0="

この文字列を複写して「.coveralls.yml」ファイルを作成します。secureの項目に作成した暗号化文字列をコピーします。

env:
  global:
    - secure: Gj9nNmjtg8Zk /* 省略 */ F/0=

最後に、JaCoCoのレポートをCoverallsに送信するためのGradleのモジュールを導入します。build.gradleを抜粋します。

buildscript {
    ext.kotlin_version = '1.0.0-beta-2423'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.4.0'
    }
}

apply plugin: 'com.github.kt3k.coveralls'

coveralls {
  sourceDirs = files(sourceSets.main.allSource.srcDirs).files.absolutePath
}

重要なのは最後の3行の設定で、これがないとソースファイルが無いぞ!的なエラーで怒られます。

これで、最後に「.travis.yml」の設定をしてGItHubにpushすると終了になります。

language: java
sudo: false
jdk:
    - oraclejdk7
script:
    - ./gradlew test

after_success:
    - ./gradlew jacocoTestReport coveralls

今回はafter_successでカバレッジ作成、Coverallsに送信をしています。

成功すると次のような感じにカバレッジのレポートを見ることができます。

f:id:webarata3:20160605142131p:plain

Travis CIと同様に次の場所をクリックすることでバッチ用のMarkdownを取得できます。

f:id:webarata3:20160605142140p:plain

おまけ

今回、Coverallsへのレポートの送信がうまくいかず何度もGitHubにpushしまくったのですが、最後の方にローカルでCoverallsに送信する方法がわかり、それで行っていました。

参考にしたのは次のサイトです。

http://ksoichiro.blogspot.jp/2014/05/androidgradle-jacoco.html

例を挙げると、次のようなコマンドでできます。

COVERALLS_REPO_TOKEN=トークン ./gradlew coveralls

まとめ

疲れた。

GitHubページを独自ドメインにする(ムームードメイン)

## 古い記事のため、画像と内容が一部あっていません。適宜読み替えてご覧ください。

GitHubページを独自ドメインにできるという記事を見ました。

qiita.com

ドメインをメールにしか使用していないため、せっかくなので設定してみることにしました。

持っているドメインarata.linkでメールにしか使用していません。このドメインサブドメイン(www.arata.link)をGitHubページに設定してみました。

まず、GitHubページを適当に作成します。これは、自分のGitHubアカウントがwebarata3の場合にはwebarata3.github.ioというリポジトリを作ることでそのmasterブランチ(gh-pagesではありません)が、http://webarata3.github.ioとしてWebページになります。作成の際にルートにCNAMEというファイルを作成しその内容は設定する独自ドメイン、今回の場合にはwww.arata.linkとします。

次にムームードメインの設定です。コントロールパネルにログインし、「ドメイン管理」→「ムームDNS」を選択します。表示されたドメインからGitHubに設定したいドメインの「変更」ボタンを押します。

f:id:webarata3:20160605141430p:plain

画面が変わったら、DNSの設定をします。ムームードメインの場合には必ずサブドメインを指定しないといけないので、今回はwwwと設定しています。種別はCNAMEとし、内容をGitHubページのアドレス、今回の場合はwebarata3.github.ioとします。

f:id:webarata3:20160605141438p:plain

設定完了後しばらくしたら、www.arata.linkにアクセスするとwebarata3.github.ioにアクセスされるはずです。今回は設定後すぐにアクセスすることができました。

設定自体は非常に簡単ですが、気をつけることが2つあります。

1つ目は、GitHubページにアクセスしようとしても独自ドメインにリダイレクトされるということです。今回で言うと、webarata3.github.ioにアクセスするとwww.arata.linkに切り替わります。

2つ目は、トップページ以外のGitHubページも独自ドメインに切り替わるということです。例えば、testというリポジトリGItHubページを作った場合、webarata3.github.io/testにアクセスするとwww.arata.link/testにリダイレクトされます。

設定は以上になります。

自分のWebサイトを作ってもファイルの転送が面倒でやめてしまうことも多いですが、GitHubだとローカルで確認しpushするだけなので非常に簡単です(しかも無料!)。独自ドメインを取って、自分のサイトを運営したい人にはおすすめできるのではないでしょうか。静的なページに限りますが。

GitHubをMavenリポジトリにする(GitHub pagesでできなかった)

KExcelAPIを作ったのはいいのですが、jarファイルをダウンロードして使用する方法では使う人が面倒なためオレオレMavenリポジトリを作成することにしました。

当初は、gh-pagesにリポジトリを作成(ただファイルを置くだけ)でやってみたのですが、IntelliJ上のGradleでライブラリーを取得する際に次のようなエラーが出てしまいました。

f:id:webarata3:20160605141214p:plain

これ自体はインデックスを取得できない感じのエラーなので無視して(Disable)も問題ないのですが、上記画面の「Open Repository List」から飛べる設定画面でもエラーが出ています。(Updateしても同じ)

f:id:webarata3:20160605141218p:plain

このエラーメッセージにマウスポインタを合わせるとエラーの内容が出てきますが、これはリポジトリー上に「nexus-maven-repository-index.properties」ファイルが無いために起きているということでした。ですので、このファイルを作成する方法を探したところ、次のページを見つけました。

stackoverflow.com

このサイトの通り、nexus-indexer-3.0.4-cli.jarをダウンロードして、nexus-maven-repository-index.propertiesファイル等を作成しました。ファイルはrepositoryトップに.indexディレクトリーを作成しその中に作ります。

ここまでで作成したファイルをgh-pages上に構築したのですがエラーは消えませんでした。確認(ソースが見つけられなかった)は取れてないのですが、gh-pages上では「.」が先頭のファイルは参照できないため、「.index」以下にあるインデックスファイルが参照できない、ということのようです。(この辺違ったら教えて下さい)

いろいろと試行錯誤していたのですが、GItHubのrawモードをMavenリポジトリとするとインデックスファイルが正しく読めるようになり、IntelliJ上のエラーも消えました。

ということで次の場所にリポジトリーができ、IntelliJ上の警告やエラーも消えてすっきりです。

github.com

KExcelAPIリポジトリーは

repositories {
    maven { url 'https://raw.githubusercontent.com/webarata3/maven/master/repository' }
}

dependencies {
    compile 'link.arata.kexcelapi:kexcelapi:0.1.0'
}

で取得できます。

残念なのは、GitHubページのURLに比べて長くなってしまうことですが、エラーが出るよりはいいかなと思っています。

Kotlin用Apache POIのラッパーライブラリーKExcelAPI 0.1.0をリリースしました

Kotlin用Apache POIのラッパーライブラリーKExcelAPIをリリースしました。

github.com

もともとGroovy用のGExcelAPIというライブラリーがあり、それが便利そうなためKotlin版を作成しました。

コードのイメージは次のようになります。

// 簡単にファイルオープン、クローズ
KExcel.open("file/book1.xlsx").use { workbook ->
    val sheet = workbook.getSheetAt(0)

    // セルの読み込み
    // セル名でのアクセス
    println("""B7=${sheet["B7"].toStr()}""")
    // セルのインデックスでのアクセス [x, y]
    println("B7=${sheet[1, 6].toDouble()}")
    println("B7=${sheet[1, 6].toInt()}")

    // セルの書き込み
    sheet["A1"] = "あいうえお"
    sheet[3, 7] = 123

    // ファイルの書き込みも簡単に
    KExcel.write(workbook, "file/book2.xlsx")
}

B1のようなセル名や、[1, 3]のようなセルのインデックスのどちらでも読み書きできるのが特徴です。書きながらシートへのアクセスも何かしたほうがいいなと思い始めました。。

ということで、まだ0.1.0なのでいろいろ改善していきたいと思います。