はじめに
Qiita初投稿になります。6年程会社でプログラマとして仕事をし、今はフリーランスでAndroidアプリを中心にJava/Kotlinでゴリゴリ開発してます。今回、Androidアプリで使っているライブラリの表示をする必要がありまして、以前採用させていただいたクックパッドさんの license-tools-plugin
を使おうとしたのですが、プラグイン自体のアップデートやIDE(Android Studio)の更新もあり、すんなり導入することができませんでした。公式が クックパッド開発者ブログ で解説していますが、導入方法とハマったポイントを少し長いですが共有します。間違いや補足などがあればコメントにて教えてください。
開発環境
- PC: MacBook Air (11-inch, Early 2014)
- OS: macOS Mojave 10.14.3
- IDE: Android Studio 3.3.2
license-tools-pluginとは
クックパッドさんが開発したGradleの神プラグインです。プロジェクトで使用しているライブラリのライセンスをYAMLで管理、HTMLもしくはJSONに一覧を出力してくれます。ライセンスの追記漏れもチェックしてくれる優れものです。GitHubのリポジトリは こちら です。
導入
Gradleのプラグインなので、プロジェクトルート直下の build.gradle
に追記します。記事執筆時の最新バージョンは 1.7.0
でした。
buildscript {
...
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.cookpad.android.licensetools:license-tools-plugin:1.7.0' // 追加
}
}
アプリ内で使用する為に、app直下の build.gradle
の冒頭に追記をします。
apply plugin: 'com.cookpad.android.licensetools' // 追加
動作する為に JDK8
以上が必須とのことなので、こちらも build.gradle
に互換性を追記しておきます。 JDK8
はAndroid Studio 3.3.2であれば、ビルトインとしてあらかじめ用意されているはずです。
android {
...
// 追加
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
全ての追記が終わったら Sync Project
を行い、エラーが出ていなければOKです。
使い方
ライブラリの依存関係を確認
ライブラリの依存関係を確認します。今回はデモの為に、Androidアプリの開発でよく使うものを追加しました。
dependencies {
// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Android Support Library
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
// Square
implementation 'com.squareup.moshi:moshi:1.8.0'
implementation 'com.squareup.moshi:moshi-kotlin:1.8.0'
implementation 'com.squareup:otto:1.3.8'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
// ReactiveX
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.7'
}
ライセンス情報の作成
依存関係の記述が終わったら、Android Studioのサイドバーにある Gradle > [project-name] > :app > Tasks > verification
から、 checkLicenses
タスクを実行します。コンソールにライセンス情報の一覧が出力されるので、app直下に licenses.yml
を作成して内容をコピペします。
- artifact: android.arch.core:common:+
name: Android Arch-Common
copyrightHolder: #COPYRIGHT_HOLDER#
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://developer.android.com/topic/libraries/architecture/index.html
- artifact: com.squareup.okhttp3:okhttp:+
name: OkHttp
copyrightHolder: #COPYRIGHT_HOLDER#
license: #LICENSE#
- artifact: org.jetbrains.kotlin:kotlin-stdlib:+
name: org.jetbrains.kotlin:kotlin-stdlib
copyrightHolder: #COPYRIGHT_HOLDER#
license: The Apache License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://kotlinlang.org/
- artifact: com.squareup.okio:okio:+
name: Okio
copyrightHolder: #COPYRIGHT_HOLDER#
license: #LICENSE#
- artifact: com.android.support:support-annotations:+
name: Android Support Library Annotations
copyrightHolder: #COPYRIGHT_HOLDER#
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: http://developer.android.com/tools/extras/support-library.html
- artifact: com.android.support:design:+
name: Material Components for Android
copyrightHolder: #COPYRIGHT_HOLDER#
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: http://developer.android.com/tools/extras/support-library.html
- artifact: com.android.support:support-core-utils:+
name: Android Support Library core utils
copyrightHolder: #COPYRIGHT_HOLDER#
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: http://developer.android.com/tools/extras/support-library.html
- artifact: com.android.support:interpolator:+
name: Android Support Library Interpolators
copyrightHolder: #COPYRIGHT_HOLDER#
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: http://developer.android.com/tools/extras/support-library.html
# 以下、長いので省略
ライセンス情報の編集
その後 licenses.yaml
の情報を編集していきます。具体的には #COPYRIGHT_HOLDER#
や #LICENSE#
と言ったプレースホルダ部分を編集します。例えば
- artifact: com.android.support:appcompat-v7:+
name: Android AppCompat Library v7
copyrightHolder: #COPYRIGHT_HOLDER#
license: #LICENSE#
- artifact: com.squareup.retrofit2:retrofit:+
name: Retrofit
copyrightHolder: #COPYRIGHT_HOLDER#
license: #LICENSE#
- artifact: io.reactivex.rxjava2:rxjava:+
name: RxJava
copyrightHolder: #COPYRIGHT_HOLDER#
license: #LICENSE#
のような一覧が出力された場合は
- artifact: com.android.support:appcompat-v7:+
name: Android AppCompat Library v7
copyrightHolder: The Android Open Source Project
license: The Apache License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://developer.android.com/topic/libraries/support-library/
- artifact: com.squareup.retrofit2:retrofit:+
name: Retrofit
copyrightHolder: Square, Inc.
license: The Apache License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/square/retrofit/
- artifact: io.reactivex.rxjava2:rxjava:+
name: RxJava
copyrightHolder: RxJava Contributors
license: The Apache License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/reactivex/rxjava/
となります。基本的にGitHubの情報を元に調べ編集していきます。Android Open Source Project(AOSP)は ここ にライセンスに関する内容が記載されています。全ての情報の編集が終わったら、再度 checkLicenses
タスクを実行し、エラーが発生しなければOKです。
ライセンス情報の表示
最後に Gradle > [project-name] > :app > Tasks > other
から、 generateLicensePage
タスクを実行し、出力されたHTMLファイルをアプリ内の WebView
に読み込ませます。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
webView.loadUrl("file:///android_asset/licenses.html")
}
ハマったこと
checkLicensesタスクが失敗する
checkLicenses
タスクを実行した際に missing libraries in licenses.yml
というエラーで失敗してしまう。初回実行時には licenses.yaml
が存在しないので、コンソールに表示されたライセンスの情報一覧をコピペして作成すればいいのですが、2回目以降であれば不足している情報がコンソールに出力されていますので、YAMLファイルに追記します。また、使用しているライブラリが、内部的に別のライブラリに依存している場合(例えば appcompat-v7
は内部的に support-annotations
や support-compat
に依存している)、その関係性も監視対象になります。そういったライブラリは
- artifact: com.android.support:appcompat-v7:+
name: Android AppCompat Library v7
copyrightHolder: The Android Open Source Project
license: The Apache License, Version 2.0
- artifact: com.android.support:support-annotations:+
skip: true
- artifact: com.android.support:support-compat:+
skip: true
と記述することで、一覧から除外することができます。また、グループ一式で除外する場合は
- artifact: com.android.support:+:+
skip: true
の様にワイルドカードで指定したり、
licenseTools {
ignoredGroups = ['com.android.support']
}
の様に記述することで可能となります。
generateLicensePageタスクが失敗する
コンソールでエラーの内容を確認すると checkLicenses
タスクでコケていることがほとんどかと思います。 checkLicensesタスクが失敗する を参考に解決します。
必要な項目が不足している
licenses.yaml
に必要な項目が不足している場合にも、プラグインのタスクが失敗します。必須項目は以下の通りです。
- artifact
- name
- copyrightHolder/ author/ authors/ noticeのうちどれか1つ
オプションとして付与できる項目は
- year
- skip
- forceGenerate
などがあります。詳しくは公式の GitHubリポジトリ を参照してください。
最終的な着地点
ここまでのハマった箇所を踏まえて、デモ用のアプリとしてGitHubに demo-licenses をアップしておきます。参考になるかわかりませんが、躓いていらっしゃる方の助けに少しでもなれたらなと思います。表示させないライセンスについてですが、最終的には ignoredGroups
と skip
を併用することで解決しました。 ignoredGroups
は、名前の通り使用しているライブラリの groupId
のみにしか対応しておらず artifactId
では除外できませんでした。 groupId
+ artifactId
でもプラグインの監視対象から除外できれば良いのになぁ。
まとめ
結果的に調べたりなんなりで作業自体のコストはかかってしまいましたが、1から全て自前で実装するよりは遥かに良いです。今後、同様な実装が発生した場合にはこの記事を参考にスピーディに対応したいですね。また、先ほどの groupId
+ artifactId
で除外するPull Requestなどを本家に出してみたいと思っています。ライセンスの表示は、Androidアプリを開発していく上で必要なことではありますが、開発が進むにつれて管理が億劫になったり、時間を割くことが難しいかもしれません。そんな痒いところに手が届くようなライブラリを開発してくださったクックパッド様には感謝しかないです
どうでも良い話
ライセンスの綴りとして license と licence があります。大きな違いとして、イギリスでは動詞の場合に『license』名詞の場合に『licence』を使い分けますが、アメリカでは特に区別をせず日常的に『license』が使われるみたいです。結構タイプミスするので気をつけたいです。