Golang中如何使用`go get`安装时指定不同的可执行文件名?
Golang中如何使用go get安装时指定不同的可执行文件名?
在使用 go get 安装时,是否可以使用不同的可执行文件名称?
我知道 go build 有一个 -o 标志可以使用,但对于我的软件包的用户来说呢。
背景是公司仓库强制要求 Git 仓库的命名规范。
类似于 git.company.com/pkg/GoPkg-Name
但这会破坏 go get 的使用。
go: git.company.com/pkg/GoPkg-MyTool.git upgrade => v0.0.0-20210121150345-6241afcc3125
go get: git.company.com/pkg/GoPkg-MyTool.git@v0.0.0-20210121150345-6241afcc3125: parsing go.mod:
module declares its path as: git.company.com/pkg/mytool
but was required as: git.company.com/pkg/GoPkg-MyTool.git
如果能够使用 go get 并让它将工具安装为 mytool,而无需经过更多手动步骤(例如 mv GoPkg-MyTool mytool),那就太好了。
更多关于Golang中如何使用`go get`安装时指定不同的可执行文件名?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
go mod replace … 请自行搜索。
更多关于Golang中如何使用`go get`安装时指定不同的可执行文件名?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
h3adache:
我99%确定你没有阅读。
我100%确定你没有阅读。
你引用的资料日期是2017年3月9日。而关于Go模块的首次公开提及直到2018年2月20日才出现。
我 99% 确定你没看,不过没关系。
如何构建名称不同于 Go 语言包的可执行文件
标签: go, build, package, naming-conventions
看来对于 go get 来说,没有方法可以做到这一点。
我只能接受让人们手动重命名,或者直接分发二进制文件了。
提醒一下正在尝试此操作的人。
不要像我一样,试图通过 mod replace 让它工作,这行不通,只会让你抓耳挠腮。
请采用 https://github.com/bazelbuild/buildtools 所使用的方法,将你的工具放入以工具命名的子目录中。
我犯了一个错误,试图让我的仓库名称与工具名称相同。
这种方法对公共和私有仓库都有效,唯一的例外是对于私有仓库,你必须添加 .git 后缀。
因此,在我上面的例子中,你可以在实际工具所在的位置创建一个 mytool 子目录,用户可以通过以下方式安装它:
go get git.company.com/pkg/GoPkg-MyTool.git/mytool
在Go模块系统中,go get安装的可执行文件名由模块路径的最后一个元素决定,但可以通过在go.mod文件中使用replace指令结合自定义构建来解决。以下是具体方案:
方案1:使用replace指令(推荐)
在用户项目的go.mod中添加replace指令,将不符合规范的路径映射到正确的模块路径:
// 用户项目的go.mod
module myproject
go 1.21
require (
git.company.com/pkg/mytool v0.1.0
)
replace git.company.com/pkg/mytool => git.company.com/pkg/GoPkg-MyTool.git v0.1.0
然后用户可以通过以下方式安装:
# 安装到$GOPATH/bin
go install git.company.com/pkg/mytool@latest
# 或者安装到当前目录
go install git.company.com/pkg/mytool@latest
方案2:包维护者提供安装脚本
包维护者可以在仓库中提供安装脚本:
#!/bin/bash
# install.sh
set -e
# 临时目录
TMP_DIR=$(mktemp -d)
cd "$TMP_DIR"
# 克隆仓库
git clone https://git.company.com/pkg/GoPkg-MyTool.git
cd GoPkg-MyTool
# 构建并安装为mytool
go build -o mytool ./cmd/mytool
sudo mv mytool /usr/local/bin/
# 清理
cd /
rm -rf "$TMP_DIR"
方案3:使用go install的@version语法
用户可以直接指定版本安装:
# 安装特定版本
go install git.company.com/pkg/GoPkg-MyTool.git/cmd/mytool@v0.1.0
# 安装最新版本
go install git.company.com/pkg/GoPkg-MyTool.git/cmd/mytool@latest
方案4:包内使用build tags控制输出名称
包维护者可以在main.go中添加构建约束:
//go:build rename
// +build rename
package main
import (
"fmt"
"os"
)
func main() {
// 程序逻辑
fmt.Println("Running as mytool")
}
然后用户可以通过构建标签控制输出名称:
go build -tags rename -o mytool .
方案5:使用go generate
包维护者可以在代码中添加go generate指令:
//go:generate sh -c "go build -o mytool ."
用户执行:
go generate ./...
实际示例
假设包结构如下:
GoPkg-MyTool/
├── cmd/
│ └── mytool/
│ └── main.go
├── go.mod
└── README.md
go.mod内容:
module git.company.com/pkg/mytool
go 1.21
用户安装时使用:
# 方法1:使用完整路径
go install git.company.com/pkg/GoPkg-MyTool.git/cmd/mytool@latest
# 方法2:配置replace后
echo 'replace git.company.com/pkg/mytool => git.company.com/pkg/GoPkg-MyTool.git v0.1.0' >> go.mod
go install git.company.com/pkg/mytool@latest
安装后,可执行文件将命名为mytool(来自cmd/mytool目录名),而不是GoPkg-MyTool。

