Mavenで依存しているライブラリのライセンス累計を作成します。
下記のように「ライセンス名 ライブラリ個数」の行がライセンス種別数分作られるイメージ。
BSD 4
ASL2 43
MIT 5
開発中のクローズドなソースにGPLやAGPLなどのライセンスが含まれていないか分かるようにしておきます。
環境
- Maven 3.5.2
- Java 9
- grep、sed、cut、awkコマンドが使えるターミナル
license-audio-maven-pluginインストール
Maven標準プラグインにはライブラリ名とライセンスを一覧表示する機能が有りません。ライセンス監査用のMavenプラグイン「license-audit-maven-plugin」を使用してライセンス一覧を表示させます。
このプラグイン単体でもライセンス違反を警告することが出来ますが、表示形式をカスタマイズしたいので今回はライセンス一覧を出す為に使用します。
githubからzipをダウンロードして解凍、解凍ディレクトリに入り、mvn clean installしてローカルmvnリポジトリにインストールすれば準備完了。
ライセンスサマリを表示
pom.xmlがある適当なMavenプロジェクトにターミナルで入り、reportゴールに-Dformat=summaryオプションを指定するとライセンスサマリが表示される。
$ mvn org.heneveld.maven:license-audit-maven-plugin:report -Dformat=summary
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- license-audit-maven-plugin:1.0-SNAPSHOT:report (default-cli) @ demo ---
[INFO] com.example:demo:0.0.1-SNAPSHOT: ASL2
[INFO] +-org.springframework.boot:spring-boot-starter-web:2.1.6.RELEASE (compile): ASL2
[INFO] | +-org.springframework.boot:spring-boot-starter:2.1.6.RELEASE (compile): ASL2
[INFO] | | +-org.springframework.boot:spring-boot:2.1.6.RELEASE (compile): ASL2
[INFO] | | | +-org.springframework:spring-core:5.1.8.RELEASE (compile, reported below): ASL2
[INFO] | | | +-org.springframework:spring-context:5.1.8.RELEASE (compile, reported below): ASL2
[INFO] | | | +-ch.qos.logback:logback-classic:1.2.3 (compile, optional, reported below): EPL1; LGPL
[INFO] | | | +-com.fasterxml.jackson.core:jackson-databind:2.9.9 (compile, optional, reported below): ASL2
[INFO] | | | +-org.apache.logging.log4j:log4j-api:2.11.2 (compile, optional, reported below): ASL2
(snip)
[INFO] +-org.bouncycastle:bcprov-jdk15on:1.62 (compile, no dependencies): Bouncy Castle Licence
[INFO] org.slf4j:slf4j-api:1.7.26 (unknown, no dependencies): MIT
[INFO] com.fasterxml:classmate:1.4.0 (unknown, no dependencies): ASL2
[INFO] commons-codec:commons-codec:1.11 (unknown, no dependencies): ASL2
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.449 s
[INFO] Finished at: 2019-08-18T19:41:58+09:00
[INFO] Final Memory: 44M/565M
[INFO] ------------------------------------------------------------------------
不要部分削除、ライブラリ名:ライセンス名を抽出
awk、cut、grep、sedで必要部分のみ抽出。「EPL1 GPL」のように選択式になっているものは空白を削除して連結しています。
後に違反ライセンスとしてGPLを禁止ワードにした場合「GPLに完全一致しなければ選択式なのでOK」にする為です。
$ mvn org.heneveld.maven:license-audit-maven-plugin:report \
-Dformat=summary \
| awk '/Scanning/,/BUILD SUCCESS/' \
| cut -d ":" -f 2,4 \
| grep -v "[INFO]" \
| grep -v "^\s*$" \
| sed -e 's/;//g' -e 's/ //g'
// 実行結果
demo: ASL2
spring-boot-starter-web: ASL2
spring-boot-starter: ASL2
spring-boot: ASL2
spring-core: ASL2
spring-beans: ASL2
(snip)
spring-beans: ASL2
slf4j-api: MIT
重複を削除
spring-beansのような複数ライブラリから芋づる式に依存されるものが複数表示されてしまうので、awkの連想配列を使用してライブラリ名でユニークにする。(sort | uniqでも可)
$ mvn org.heneveld.maven:license-audit-maven-plugin:report \
-Dformat=summary \
| awk '/Scanning/,/BUILD SUCCESS/' \
| cut -d ":" -f 2,4 \
| grep -v "[INFO]" \
| grep -v "^\s*$" \
| sed -e 's/;//g' -e 's/ //g'
| awk '!a[$1]++'
// 実行結果
demo: ASL2
spring-boot-starter-web: ASL2
spring-boot-starter: ASL2
spring-boot: ASL2
spring-core: ASL2
spring-beans: ASL2
(snip)
slf4j-api: MIT
集計
ライブラリ名:ライセンス名の行がユニークになったのでawkでライセンス名をキーにして集計。
$ mvn org.heneveld.maven:license-audit-maven-plugin:report \
-Dformat=summary \
| awk '/Scanning/,/BUILD SUCCESS/' \
| cut -d ":" -f 2,4 \
| grep -v "[INFO]" \
| grep -v "^\s*$" \
| sed -e 's/;//g' -e 's/ //g' \
| awk '!a[$1]++' \
| awk -F : '{ sum[$2]++; } END { for (key in sum) { print(key, " ", sum[key]) }}'
// 実行結果
BSD 1
EPL1LGPL 2
BouncyCastleLicence 1
<unknown> 1
<notloaded> 5
ASL2 43
EclipsePublicLicense-v2.0 1
CDDL+GPLv2withclasspathexception 1
まとめ
ライセンス毎のライブラリ数がサマリとして出せました。
同じライセンスでもEPLだったりEclipsePublicLicenseだったり揺れがあったりしてちょっと嫌な感じだったりしますが、CI実行してチャットなりに送信しておけば、万が一AGPLのような縛りのきついライセンスが含まれたりしても直ぐ気付けます。