これは、なにをしたくて書いたもの?
こちらのエントリで、Goで書いたアプリケーションに含まれるモジュールなどがわかるだろうか?という確認をしました。
go tool nmコマンドで、Goの実行可能ファイルの定義やシンボルを表示する - CLOVER🍀
次は、使用しているモジュールのライセンスを確認したいな、と。
Goとライセンス
そもそも、Goのライセンスは?というと、BSDライセンスです。
Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.
https://github.com/golang/go/blob/master/LICENSE
・ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
・ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
・ Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
なので、再頒布にあたってはライセンスファイルのコピーが必要だ、ということになります。
Every program that you distribute to a third party in binary form, yes. Technically it should have a copy of the LICENSE file, not just a reference to it.
Standard library licensing question · Issue #19893 · golang/go · GitHub
Goってアプリケーションをビルドするとシングルバイナリになりますし、こういうところも気をつけないとですね。
Chromeも、以下で使用しているライブラリのライセンスを確認できるようです。知らなかった…。
chrome://credits/
で、Goプロジェクトで使っているモジュールのライセンスを調べるには、このあたりを使えばよさそうです。
GitHub - google/go-licenses: Reports on the licenses used by a Go package and its dependencies.
GitHub - ribice/glice: Go license and dependency checker
ライセンスファイルをまとめたファイルを作るには、こちら。
GitHub - Songmu/gocredits: creates CREDITS file from LICENSE files of dependencies
いくつか試してみましょう。
環境とサンプルプログラム
今回の環境は、こちらです。
$ go version go version go1.15.6 linux/amd64
モジュールの作成。
$ go mod init view-licenses go: creating new go.mod: module view-licenses
依存モジュールは、こちら。
go.mod
module view-licenses go 1.15 require ( github.com/google/uuid v1.1.4 // indirect github.com/labstack/echo/v4 v4.1.17 // indirect )
go.sum
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/google/uuid v1.1.4 h1:0ecGp3skIrHWPNGPJDaBIghfA6Sp7Ruo2Io8eLKzWm0= github.com/google/uuid v1.1.4/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/labstack/echo v1.4.4 h1:1bEiBNeGSUKxcPDGfZ/7IgdhJJZx8wV/pICJh4W2NJI= github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= github.com/labstack/echo/v4 v4.1.17 h1:PQIBaRplyRy3OjwILGkPg89JRtH2x5bssi59G2EL3fo= github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 h1:DvY3Zkh7KabQE/kfzMvYvKirSiguP9Q/veMtkYyf0o8= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
サンプルプログラムとしては、こちらを用意。
main.go
package main import ( "github.com/google/uuid" "github.com/labstack/echo/v4" "net/http" ) func main() { e := echo.New() e.GET("/", func(c echo.Context) error { uuid4, _ := uuid.NewRandom() return c.String(http.StatusOK, "UUID v4 = "+uuid4.String()) }) e.Logger.Fatal(e.Start(":1323")) }
ビルドもしておきます。
$ go build $ ./view-licenses # 動作確認のため
このGoプロジェクトを対象に、依存プロジェクトのライセンスを解析してみましょう。
google/go-licenses
まずは、こちらを使ってみましょう。
GitHub - google/go-licenses: Reports on the licenses used by a Go package and its dependencies.
依存ライブラリを分析し、ライセンスに関するレポートを出力できます。また、ソースコード、ライセンスファイル、ソースコードを
まとめることも可能なようです。
インストール。
# Goプロジェクト外で実行 $ GO111MODULE=on go get github.com/google/go-licenses
今回取得したバージョン。
go: downloading github.com/google/go-licenses v0.0.0-20201026145851-73411c8fa237 go: github.com/google/go-licenses upgrade => v0.0.0-20201026145851-73411c8fa237
ヘルプの表示。
$ go-licenses help Usage: licenses [command] Available Commands: check Checks whether licenses for a package are not Forbidden. csv Prints all licenses that apply to a Go package and its dependencies help Help about any command save Saves licenses, copyright notices and source code, as required by a Go package's dependencies, to a directory. Flags: --alsologtostderr log to standard error as well as files --confidence_threshold float Minimum confidence required in order to positively identify a license. (default 0.9) -h, --help help for licenses --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) --log_dir string If non-empty, write log files in this directory --logtostderr log to standard error instead of files --stderrthreshold severity logs at or above this threshold go to stderr (default 2) -v, --v Level log level for V logs --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging Use "licenses [command] --help" for more information about a command.
csv
コマンドを使うと、レポート表示ができます。
このツールに関しては自プロジェクトにLICENSE
があった状態で実行した方が良さそうだったので、LICENSE
ファイルを
作成しておきました。まずはMITライセンスにしています。
この状態で、プロジェクト内で以下のコマンドを実行。
$ go-licenses csv . E0113 00:09:20.566415 19924 csv.go:84] Error discovering URL for "$HOME/go/pkg/mod/golang.org/x/net@v0.0.0-20200822124328-c89045814202/LICENSE": - unsupported package host "golang.org" for "golang.org/x/net" E0113 00:09:20.574686 19924 csv.go:84] Error discovering URL for "$HOME/go/pkg/mod/golang.org/x/text@v0.3.3/LICENSE": - unsupported package host "golang.org" for "golang.org/x/text" E0113 00:09:20.583300 19924 csv.go:84] Error discovering URL for "/path/to/view-licenses/LICENSE": - cannot determine URL for "view-licenses" package E0113 00:09:20.626889 19924 csv.go:84] Error discovering URL for "$HOME/go/pkg/mod/golang.org/x/sys@v0.0.0-20200826173525-f9321e4c35a6/LICENSE": - unsupported package host "golang.org" for "golang.org/x/sys" E0113 00:09:20.641393 19924 csv.go:84] Error discovering URL for "$HOME/go/pkg/mod/golang.org/x/crypto@v0.0.0-20200820211705-5c72a883971a/LICENSE": - unsupported package host "golang.org" for "golang.org/x/crypto/acme" golang.org/x/net,Unknown,BSD-3-Clause golang.org/x/text,Unknown,BSD-3-Clause view-licenses,Unknown,MIT github.com/google/uuid,https://github.com/google/uuid/blob/master/LICENSE,BSD-3-Clause github.com/mattn/go-colorable,https://github.com/mattn/go-colorable/blob/master/LICENSE,MIT github.com/mattn/go-isatty,https://github.com/mattn/go-isatty/blob/master/LICENSE,MIT github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/master/LICENSE,MIT github.com/labstack/echo/v4,https://github.com/labstack/echo/blob/master/v4/LICENSE,MIT github.com/labstack/gommon,https://github.com/labstack/gommon/blob/master/LICENSE,MIT golang.org/x/sys,Unknown,BSD-3-Clause github.com/valyala/bytebufferpool,https://github.com/valyala/bytebufferpool/blob/master/LICENSE,MIT golang.org/x/crypto/acme,Unknown,BSD-3-Clause
バイナリファイルを指定してもOKのようです。今回は、すべて.
指定で行うことにします。
### go-licenses csv [バイナリファイル] $ go-licenses csv view-licenses
結果の一部がエラーになっていますが、理由はこれっぽいですね…。
URLs may not be available if the library is not checked out as a Git repository (e.g. as is the case when Go Modules are enabled).
少なくとも、このあたりを見るとライセンスの確認はできます。
golang.org/x/net,Unknown,BSD-3-Clause golang.org/x/text,Unknown,BSD-3-Clause view-licenses,Unknown,MIT github.com/google/uuid,https://github.com/google/uuid/blob/master/LICENSE,BSD-3-Clause github.com/mattn/go-colorable,https://github.com/mattn/go-colorable/blob/master/LICENSE,MIT github.com/mattn/go-isatty,https://github.com/mattn/go-isatty/blob/master/LICENSE,MIT github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/master/LICENSE,MIT github.com/labstack/echo/v4,https://github.com/labstack/echo/blob/master/v4/LICENSE,MIT github.com/labstack/gommon,https://github.com/labstack/gommon/blob/master/LICENSE,MIT golang.org/x/sys,Unknown,BSD-3-Clause github.com/valyala/bytebufferpool,https://github.com/valyala/bytebufferpool/blob/master/LICENSE,MIT golang.org/x/crypto/acme,Unknown,BSD-3-Clause
過不足は、go tool nm
コマンドで確認すると良いかな、と。
続いてはsave
です。こちらで、ライセンスファイルを収集することができます。
--save_path
オプションが必須で、ライセンスファイルの出力先を指定します。
$ go-licenses save . --save_path licenses
結果は、こんな感じになります。
$ find licenses -type f licenses/golang.org/x/text/LICENSE licenses/golang.org/x/crypto/acme/LICENSE licenses/golang.org/x/net/LICENSE licenses/golang.org/x/sys/LICENSE licenses/view-licenses/LICENSE licenses/github.com/mattn/go-colorable/LICENSE licenses/github.com/mattn/go-isatty/LICENSE licenses/github.com/google/uuid/LICENSE licenses/github.com/labstack/gommon/LICENSE licenses/github.com/labstack/echo/v4/LICENSE licenses/github.com/valyala/fasttemplate/LICENSE licenses/github.com/valyala/bytebufferpool/LICENSE
最後はcheck
。ライセンスの分類によって禁止されていないものがないかを確認します。
Checking for forbidden licenses
具体的には、ここで"禁止"と定められたリストです。
ライセンスのテキストから、ライセンスの種類を判別できるモジュールを使用しています。
GitHub - google/licenseclassifier: A License Classifier
これ、なんで"禁止"になってるかは、確認しとかないとですね…。
今回のプロジェクトの状態で実行すると、なにも出ません。
$ go-licenses check .
試しに、手元のLICENSE
ファイルの内容をAGPL 3.0にして再実行。
$ go-licenses check . Forbidden license type AGPL-3.0 for library view-licenses
こうなりました、なるほど。
自プロジェクトのライセンスは、MITライセンスに戻しておきます。
mitchellh/golicense
次は、こちら。
こちらは、ビルドされたGoのバイナリファイルを解析して、依存関係やライセンスを出力できるツールです。
インストール。
# Goプロジェクト外で実行 $ GO111MODULE=on go get github.com/mitchellh/golicense
今回使うバージョン。
go: downloading github.com/mitchellh/golicense v0.2.0 go: github.com/mitchellh/golicense upgrade => v0.2.0
ヘルプ。
$ golicense -h Usage of golicense: -license look up and verify license. If false, dependencies are printed without licenses. (default true) -out-xlsx string save report in Excel XLSX format to the given path -plain plain terminal output, no colors or live updates -verbose additional logging to terminal, requires -plain
実行してみます。こちらは、コマンドの引数に解析対象のバイナリファイルを指定する必要があります。
### golicense [バイナリファイル] $ golicense view-licenses
結果は、こちら。
github.com/valyala/bytebufferpool MIT License github.com/labstack/echo MIT License github.com/labstack/gommon MIT License github.com/mattn/go-isatty MIT License github.com/valyala/fasttemplate MIT License github.com/mattn/go-colorable MIT License github.com/google/uuid BSD 3-Clause "New" or "Revised" License golang.org/x/net BSD 3-Clause "New" or "Revised" License golang.org/x/text BSD 3-Clause "New" or "Revised" License golang.org/x/sys BSD 3-Clause "New" or "Revised" License golang.org/x/crypto BSD 3-Clause "New" or "Revised" License
解析したバイナリ自身の情報は入っていませんね。
あとはライセンスの許可、拒否を設定したり
Excel形式での出力も可能なようです。
制限事項の記載はありますが、使用しているモジュールのライセンスが途中で変わった時に問題になるかも…ってところですね。
つまりこのツールは、GitHubへのアクセスを行います。
ribice/glice
$GOPATH
内のものでないと解析できないようなので、今回はパスしました。
GitHub - ribice/glice: Go license and dependency checker
Songmu/gocredits
最後は、こちら。
GitHub - Songmu/gocredits: creates CREDITS file from LICENSE files of dependencies
依存モジュールのライセンスをまとめてファイル出力するツールです。
インストール。
# Goプロジェクト外で実行 $ GO111MODULE=on go get github.com/Songmu/gocredits/cmd/gocredits
今回使用するバージョン。
go: downloading github.com/Songmu/gocredits v0.2.0 go: found github.com/Songmu/gocredits/cmd/gocredits in github.com/Songmu/gocredits v0.2.0
ヘルプ。
$ gocredits -h Usage of gocredits (v0.2.0 rev:HEAD): -f string format -json data to be printed in JSON format -skip-missing skip when gocredits can't find the license -version display version -w write result to CREDITS file instead of stdout
Goプロジェクト内で、以下のコマンドを実行すると、ライセンスファイル(がまとまったもの)が出力されます。
$ gocredits
ファイルとしてまとめるには、次のどちらかの方法を使います。-w
の場合はファイル名はCREDITS
固定になります。
$ gocredits > CREDITS $ gocredits -w
https://github.com/Songmu/gocredits/blob/v0.2.0/gocredits.go#L77
できあがったファイルは、ライセンスファイルが結合した状態になっています。
また、JSON形式で出力したり
$ gocredits -json
出力フォーマットを-f
で指定することもできます。
デフォルトのフォーマットはこちらで、text/template
を使っています。
https://github.com/Songmu/gocredits/blob/v0.2.0/gocredits.go#L21-L28
とまあ、こんなところで。
まとめ
Goプロジェクトで、依存モジュールのライセンスを調べたり、まとめたりできるツールを調べてみました。
このあたりを使って、ちゃんとライセンスを把握していきたいものですねぇ。