go.mod 中 license 字段非法且会被自动删除,真正起作用的是根目录的 LICENSE 或 LICENSE.md 文件;import 路径必须与 go.mod 的 module 声明严格一致;go list -json 的 License 字段不可靠,需人工核对文件内容。

Go module 的 go.mod 里 license 字段没用,别白填
Go 官方工具链(go list、go mod graph)完全不读取 go.mod 中的 license 字段,它甚至不是 Go module 的合法字段——填了会被 go mod tidy 自动删掉。真正起作用的是项目根目录下的 LICENSE 或 LICENSE.md 文件,且文件名必须全大写或带标准后缀(.md / .txt),否则 go list -json 返回的 License 字段为空。
- GitHub 和 pkg.go.dev 都依赖文件系统中真实存在的
LICENSE文件来识别协议,不是靠解析go.mod - 如果用
MIT等常见协议,建议直接用curl -s https://raw.githubusercontent.com/spdx/license-list-data/master/text/MIT.txt > LICENSE下载官方原文,避免手写漏掉“above copyright notice”等关键句 - 双协议(如 MIT/Apache-2.0)要合并进一个
LICENSE文件,并在首行注明:SPDX-License-Identifier: MIT OR Apache-2.0
README.md 里 import path 必须和 go.mod module 值一致
用户复制粘贴 import 语句失败,90% 是因为 README 写的路径和 go.mod 第一行的 module 声明不一致。Go 不允许 import 路径与 module 名不同,也不支持重定向。
- 检查方式:运行
go list -m,输出必须和 README 里的import "xxx"完全匹配(包括大小写、斜杠方向) - 常见坑:
github.com/username/repo和github.com/username/repo/v2是两个独立 module,v2+ 必须在go.mod中声明为module github.com/username/repo/v2,且 import 时也必须带/v2 - 如果项目支持多版本(如 v1/v2 并存),README 每个版本的示例 import 要分开写清楚,不能只写主干路径
go list -json 输出的 License 字段不可信,得看文件内容
go list -json 返回的 License 字段只是启发式猜测(比如扫描文件头注释里的 “MIT” 字样),不是权威来源。实际合规审查时,它可能把代码里某行注释误判为许可证,也可能漏掉嵌套子模块的独立 LICENSE 文件。
- 运行
go list -json -m all | jq -r '.License'看到空或乱码?先确认根目录是否存在LICENSE,再检查是否被.gitignore忽略了 - 子模块(如
/cmd/foo)若含独立 LICENSE,go list不会自动合并,需人工核对;Go module 机制本身不递归管理子目录许可证 - CI 中建议加一步校验:
test -f LICENSE || (echo "ERROR: missing LICENSE file" >&2; exit 1)
README 里不要写 “go get github.com/xxx/yyy”
go get 在 Go 1.16+ 默认只用于包安装(go install),且已弃用直接拉取未带版本的 main 包。现在用户要装 CLI 工具,正确命令是 go install github.com/xxx/yyy@latest,否则会报错 go get: installing executables with 'go get' in module mode is deprecated。
立即学习“go语言免费学习笔记(深入)”;
- 如果项目提供二进制发布(GitHub Releases),README 优先推荐
curl | sh或brew install,比 go install 更稳定 - 必须用 go install 时,明确写出版本标签:
go install github.com/xxx/yyy@v1.2.3,避免@latest导致 CI 缓存污染 - 别在 README 里教用户
go get -u—— 它会升级所有依赖,大概率破坏兼容性










