きっかけ
先日投稿したオープンソースライセンスの記事にちょっと反響があり、Qiitaを始めたばかりの私としてはとても嬉しい体験でした。ありがとうございます。
私自身が開発する時や受託開発で協力会社や外部の方に依頼した際に、オープンソースライセンスについてあまり意識したことがありませんでした。
実際に毎回確認するのは大変ですし、外注などを考えるとライセンス確認の自動化が望ましいと思います。
GitHub Actionsでの確認方法もありますが、プルリク前のcommit時点で分かった方がいいでしょう。
そこで、先日Ruffとmypyをコミット時に実行したpre-commitで一緒にライセンスの確認もしてしまおうと思います。
環境と前提情報
MacBookPro
macOS Sequoia15.0.1
uvで仮想環境を作っています。
python 3.13
pre-commitについては下記記事を参照してください。
pip-licensesとpre-commitの設定
まずは、ライセンスの確認に必要なpip-licensesのインストールをします。
uv add pip-licenses
uv sync # 毎回同期を忘れない!
現在のライセンスはこんな感じ。
$ uv run pip-licenses
Name Version License
PyYAML 6.0.2 MIT License
cfgv 3.4.0 MIT License
distlib 0.3.9 Python Software Foundation License
filelock 3.16.1 The Unlicense (Unlicense)
identify 2.6.1 MIT License
iniconfig 2.0.0 MIT License
nodeenv 1.9.1 BSD License
packaging 24.1 Apache Software License; BSD License
platformdirs 4.3.6 MIT License
pluggy 1.5.0 MIT License
pre_commit 4.0.1 MIT License
pytest 8.3.3 MIT License
virtualenv 20.27.0 MIT License
pip-licensesをインストールし、動作確認もできたのでyamlファイルを書き換え、pre-commit時にライセンス確認をするようにします。
以前、commit時にRuffとmypyをチェックするpre-commitを記載したものがありますが気にしないでください。
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.280
hooks:
- id: ruff
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
hooks:
- id: mypy
args: ["--strict"]
- repo: local
hooks:
- id: check-licenses
name: Check licenses
entry: bash -c 'uv run pip-licenses --from=mixed --format=json | jq ".[] | select(.License | contains(\"GPL\"))" | tee /tmp/gpl_check_output && if [ -s /tmp/gpl_check_output ]; then echo "GPL license found!" && exit 1; else echo "No GPL licenses found" && exit 0; fi'
language: system
types_or: [file] # 何かしらのファイルに変更があった場合は毎回確認
これで基本的に作業は完了です。
GPLライセンスでテストしてみる。
適当にいくつかのGPLライセンスのものを追加しました。
$ uv run pip-licenses
Name Version License
PyQt6 6.7.1 GPL v3
PyQt6-Qt6 6.7.3 LGPL v3
PyQt6_sip 13.8.0 SIP
PyYAML 6.0.2 MIT License
cfgv 3.4.0 MIT License
distlib 0.3.9 Python Software Foundation License
filelock 3.16.1 The Unlicense (Unlicense)
gsl 0.0.3 GNU Affero General Public License v3 or later (AGPLv3+)
identify 2.6.1 MIT License
iniconfig 2.0.0 MIT License
nodeenv 1.9.1 BSD License
packaging 24.1 Apache Software License; BSD License
platformdirs 4.3.6 MIT License
pluggy 1.5.0 MIT License
pre_commit 4.0.1 MIT License
pytest 8.3.3 MIT License
virtualenv 20.27.0 MIT License
実際にcommitしてみます。
$ git commit
ruff.................................................(no files to check)Skipped
mypy.................................................(no files to check)Skipped
Check licenses...........................................................Failed
- hook id: check-licenses
- exit code: 1
{
"License": "GPL v3",
"Name": "PyQt6",
"Version": "6.7.1"
}
{
"License": "LGPL v3",
"Name": "PyQt6-Qt6",
"Version": "6.7.3"
}
{
"License": "GNU Affero General Public License v3 or later (AGPLv3+)",
"Name": "gsl",
"Version": "0.0.3"
}
無事、GPL系のライセンスに対してエラーを出してくれました。
対象するライセンスを増やしたい場合は、|
で繋げて書いてください。
ちなみに部分一致なので、GPLを指定すればLGPLとかも引っかかってきます。
entry: bash -c 'uv run pip-licenses --from=mixed --format=json | jq ".[] | select(.License | contains(\"GPL|AGPL|LGPL\"))" | tee /tmp/gpl_check_output && if [ -s /tmp/gpl_check_output ]; then echo "GPL license found!" && exit 1; else echo "No GPL licenses found" && exit 0; fi'
ということで、ライセンス違反のライブラリを削除します。
$ uv remove PyQt6
Resolved 20 packages in 136ms
Uninstalled 3 packages in 378ms
- pyqt6==6.7.1
- pyqt6-qt6==6.7.3
- pyqt6-sip==13.8.0
MacBook-Pro-3:LearningPythonLab cocolo$ uv remove PyQt6-Qt6
error: The dependency `pyqt6-qt6` could not be found in `dependencies`
MacBook-Pro-3:LearningPythonLab cocolo$ uv remove gsl
Resolved 19 packages in 7ms
Uninstalled 1 package in 3ms
- gsl==0.0.3
MacBook-Pro-3:LearningPythonLab cocolo$ uv sync
Resolved 19 packages in 0.66ms
Audited 17 packages in 0.02ms
MacBook-Pro-3:LearningPythonLab cocolo$ uv run pip-licenses
Name Version License
PyYAML 6.0.2 MIT License
cfgv 3.4.0 MIT License
distlib 0.3.9 Python Software Foundation License
filelock 3.16.1 The Unlicense (Unlicense)
identify 2.6.1 MIT License
iniconfig 2.0.0 MIT License
nodeenv 1.9.1 BSD License
packaging 24.1 Apache Software License; BSD License
platformdirs 4.3.6 MIT License
pluggy 1.5.0 MIT License
pre_commit 4.0.1 MIT License
pytest 8.3.3 MIT License
virtualenv 20.27.0 MIT License
もう一度コミットしてみます。
$ git commit
ruff.....................................................................Passed
mypy.....................................................................Passed
Check licenses...........................................................Passed
無事全てのテストをクリアしました。
まとめ
とりあえず、pre-commitでコミット時にライセンスチェックを行えるようにしました。
実際の運用では、これと合わせてGitHub Actionsも使ってダブルチェック体制を作るのだと思います。
自分が発注者になったりするときは、この辺も気をつけたいですね。