Help us understand the problem. What is going on with this article?

あの素晴らしいlicense-tools-pluginをもう一度

:cooking: はじめに

Qiita初投稿になります。6年程会社でプログラマとして仕事をし、今はフリーランスでAndroidアプリを中心にJava/Kotlinでゴリゴリ開発してます。今回、Androidアプリで使っているライブラリの表示をする必要がありまして、以前採用させていただいたクックパッドさんの license-tools-plugin を使おうとしたのですが、プラグイン自体のアップデートやIDE(Android Studio)の更新もあり、すんなり導入することができませんでした。公式が クックパッド開発者ブログ で解説していますが、導入方法とハマったポイントを少し長いですが共有します。間違いや補足などがあればコメントにて教えてください。

:cooking: 開発環境

  • PC: MacBook Air (11-inch, Early 2014)
  • OS: macOS Mojave 10.14.3
  • IDE: Android Studio 3.3.2

:cooking: license-tools-pluginとは

クックパッドさんが開発したGradleの神プラグインです。プロジェクトで使用しているライブラリのライセンスをYAMLで管理、HTMLもしくはJSONに一覧を出力してくれます。ライセンスの追記漏れもチェックしてくれる優れものです。GitHubのリポジトリは こちら です。

:cooking: 導入

Gradleのプラグインなので、プロジェクトルート直下の build.gradle に追記します。記事執筆時の最新バージョンは 1.7.0 でした。

build.gradle[root]
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 の冒頭に追記をします。

build.gradle[app]
apply plugin: 'com.cookpad.android.licensetools' // 追加

動作する為に JDK8 以上が必須とのことなので、こちらも build.gradle に互換性を追記しておきます。 JDK8 はAndroid Studio 3.3.2であれば、ビルトインとしてあらかじめ用意されているはずです。

build.gradle[app]
android {
    ...

    // 追加
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

全ての追記が終わったら Sync Project を行い、エラーが出ていなければOKです。

:cooking: 使い方

ライブラリの依存関係を確認

ライブラリの依存関係を確認します。今回はデモの為に、Androidアプリの開発でよく使うものを追加しました。

build.gradle[app]
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 を作成して内容をコピペします。

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# と言ったプレースホルダ部分を編集します。例えば

licenses.yaml
- 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#

のような一覧が出力された場合は

licenses.yaml
- 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 に読み込ませます。

MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    webView.loadUrl("file:///android_asset/licenses.html")
}

screen.gif

:cooking: ハマったこと

checkLicensesタスクが失敗する

checkLicenses タスクを実行した際に missing libraries in licenses.yml というエラーで失敗してしまう。初回実行時には licenses.yaml が存在しないので、コンソールに表示されたライセンスの情報一覧をコピペして作成すればいいのですが、2回目以降であれば不足している情報がコンソールに出力されていますので、YAMLファイルに追記します。また、使用しているライブラリが、内部的に別のライブラリに依存している場合(例えば appcompat-v7 は内部的に support-annotationssupport-compat に依存している)、その関係性も監視対象になります。そういったライブラリは

licenses.yaml
- 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

と記述することで、一覧から除外することができます。また、グループ一式で除外する場合は

licenses.yaml
- artifact: com.android.support:+:+
  skip: true

の様にワイルドカードで指定したり、

build.gradle[app]
licenseTools {
    ignoredGroups = ['com.android.support']
}

の様に記述することで可能となります。

generateLicensePageタスクが失敗する

コンソールでエラーの内容を確認すると checkLicenses タスクでコケていることがほとんどかと思います。 checkLicensesタスクが失敗する を参考に解決します。

必要な項目が不足している

licenses.yaml に必要な項目が不足している場合にも、プラグインのタスクが失敗します。必須項目は以下の通りです。

  • artifact
  • name
  • copyrightHolder/ author/ authors/ noticeのうちどれか1つ

オプションとして付与できる項目は

  • year
  • skip
  • forceGenerate

などがあります。詳しくは公式の GitHubリポジトリ を参照してください。

:cooking: 最終的な着地点

ここまでのハマった箇所を踏まえて、デモ用のアプリとしてGitHubに demo-licenses をアップしておきます。参考になるかわかりませんが、躓いていらっしゃる方の助けに少しでもなれたらなと思います。表示させないライセンスについてですが、最終的には ignoredGroupsskip を併用することで解決しました。 ignoredGroups は、名前の通り使用しているライブラリの groupId のみにしか対応しておらず artifactId では除外できませんでした。 groupId + artifactId でもプラグインの監視対象から除外できれば良いのになぁ。

:cooking: まとめ

結果的に調べたりなんなりで作業自体のコストはかかってしまいましたが、1から全て自前で実装するよりは遥かに良いです。今後、同様な実装が発生した場合にはこの記事を参考にスピーディに対応したいですね。また、先ほどの groupId + artifactId で除外するPull Requestなどを本家に出してみたいと思っています。ライセンスの表示は、Androidアプリを開発していく上で必要なことではありますが、開発が進むにつれて管理が億劫になったり、時間を割くことが難しいかもしれません。そんな痒いところに手が届くようなライブラリを開発してくださったクックパッド様には感謝しかないです :pray:

:cooking: どうでも良い話

ライセンスの綴りとして licenselicence があります。大きな違いとして、イギリスでは動詞の場合に『license』名詞の場合に『licence』を使い分けますが、アメリカでは特に区別をせず日常的に『license』が使われるみたいです。結構タイプミスするので気をつけたいです。

:cooking: 参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした