我无法理解创建具有本地包的go项目的工作流程。
假设我创建了一个新项目,使用 git 进行版本控制,它有一个 main.go 文件和一个 tools.go 文件,这些文件将在包实用程序中。所以我有一个目录结构,如下所示:
/myproject/
main.go
utils/
tools.go
main.go 看起来像这样:
package main
import "./utils"
func main() {
utils.DoSomthing()
}
tools.go看起来像这样:
package utils;
func DoSomething() {
}
一切都在本地运行良好,使用 go build 和 go run。但是这是托管在 github 上的,我希望能够让其他人使用 go get 命令来安装它。因此,必须将本地包导入更改为使用格式"github.com/user/project/utils",该格式有效,除了现在我有两个源代码副本,真正的问题是带有 git 历史记录的副本有一个使用下载副本的导入。因此,如果我正在使用 git 历史记录的副本,对 tools.go 所做的任何更改都不会被注意到,因为它将使用下载的副本。
所以我想知道是否有人可以解释在同一项目中使用 go get、版本控制和包导入的正确方法。
我刚刚写了一个简短的分步指南,介绍如何使用新的 go 工具和 github.com。您可能会发现它很有用:
1. 设置你的GOPATH
您可以将环境变量GOPATH
设置为您喜欢的任何目录。如果您有较大的项目,则为每个项目创建一个不同的GOPATH可能是个好主意。我会特别推荐这种方法进行部署,这样更新项目 A 的库不会破坏项目 B,这可能需要同一库的早期版本。
另请注意,您可以将 GOPATH 设置为目录列表,由冒号分隔。因此,您可能有一个包含所有常用包的 GOPATH,并且每个项目都有单独的 GOPATH,其中包含附加包或现有包的不同版本。
但是,除非您同时处理许多不同的 Go 项目,否则在本地只有一个 GOPATH 可能就足够了。因此,让我们创建一个:
mkdir $HOME/gopath
然后,您需要设置两个环境变量来告诉 go 工具在哪里可以找到现有的 Go 软件包以及应该在哪里安装新的软件包。最好将以下两行添加到您的~/.bashrc
或~/.profile
中(之后不要忘记重新加载您的 .bashrc)。
export GOPATH="$HOME/gopath"
export PATH="$GOPATH/bin:$PATH"
2. 创建一个新项目
如果要创建一个稍后托管在 github.com 的新 Go 项目,则应在 $GOPATH/src/github.com/myname/myproject
下创建此项目。路径必须与 github.com 存储库的 URL 匹配,因为 go 工具将遵循相同的约定。因此,让我们创建项目根目录并在那里初始化一个新的 git 存储库:
mkdir -p $GOPATH/src/github.com/myname/myproject
cd $GOPATH/src/github.com/myname/myproject
git init
因为我不喜欢键入这么长的路径,所以我通常会在我的主文件夹中为我当前正在处理的项目创建符号链接:
ln -s $GOPATH/src/github.com/myname/myproject ~/myproject
3. 编写应用程序
开始编码,不要忘记git add
和git commit
文件。此外,不要对子包使用相对导入(如 import "./utils"
)。它们目前没有文档,根本不应该使用,因为它们不能与 go 工具一起使用。请改用github.com/myname/myproject/utils
等导入。
4. 发布项目
在 github.com 创建一个新的存储库,上传您的 SSH 公钥(如果您之前没有这样做过),并将您的更改推送到远程存储库:
git remote add origin git@github.com:myname/myproject.git
git push origin master
5. 继续处理您的项目
如果您在 .bashrc 中设置了 GOPATH,并且您在主文件夹中创建了指向项目的符号链接,您只需键入cd myproject/
并在那里编辑一些文件即可。之后,您可以使用git commit -a
提交更改,并通过执行git push
将它们发送到 github.com。
您可能不想要源的两个副本。 按照如何编写 Go 代码,你应该有一个进行 Go 开发的路径,比如说"godev",下面是一个"src"目录,下面是你的"github.com/user/project"和"github.com/user/project/utils"。 (我同意,这似乎有点僵化,但向我们解释的优势是无需制作文件。 抛弃我的项目,这是你将做你的工作的地方。
你至少会将 GOPATH 设置为 godev,但你可能希望你的 GOPATH 从不属于你的外部包的路径开始。 例如,我使用的GOPATH是<my place on the file system>/goext:<my place on the file system>/godev
。
你是对的,你在main.go中的导入现在应该读作"github.com/user/project/utils。
不要担心go get或任何go命令覆盖你的文件或搞砸版本控制。 通过GOPATH,他们可以看到你在哪里工作,他们知道版本控制是如何工作的。
如果你想把你的代码保存在本地版本仓库中,只需把你的代码放在GOPATH中。
GOPATH 接受多条路径。例如。在 Linux 上
GOPATH=$HOME/go:$HOME/prj/foo
因此,您可以去获取安装在 $HOME/go/src/...而且,你可以用$HOME/prj/foo/src控制你的代码。
参考: go help gopath
说应该使用绝对路径来构造项目结构和导入:
import "github.com/user/utils"
但这可能会限制单个存储库 (GitHub) 中的项目。 我想使用相对路径改为:
import "./utils"
我没有找到一种方法,我在这里提出一个问题:如果 GO 项目包将托管在不同的存储库(github & sourceForge)
在不同的帖子和 Go 文档中寻找这个答案后,Go 1.11 发布了一种处理包的新方法,并且正在使用 Go 模块。
在此处阅读有关 Go 模块的整个系列文章。
Go 模块还负责版本控制