去,去获取,去安装,本地包和版本控制
Posted
技术标签:
【中文标题】去,去获取,去安装,本地包和版本控制【英文标题】:Go, go get, go install, local packages, and version control 【发布时间】:2012-04-25 04:45:47 【问题描述】:我无法理解创建具有本地包的 go 项目的工作流程。
假设我创建了一个新项目,使用 git 进行版本控制,它有一个 main.go 文件和一个 tools.go 文件,它们将在包 utils 中。所以我有一个这样的目录结构:
/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、版本控制和包导入的正确方法。
【问题讨论】:
【参考方案1】:您可能不想要源的两个副本。在How to Write Go Code 之后,您应该有一个进行 Go 开发的路径,比如说“godev”,在它下面是一个“src”目录,在它下面是您的“github.com/user/project”和“github” .com/user/project/utils”。 (我同意,这似乎有点死板,但向我们解释的优点是无需制作文件。)放弃 myproject,这是您将要做的工作。
您至少将 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,他们可以看到您在哪里工作,并且知道版本控制的工作原理。
【讨论】:
我遇到了一个相关问题,并在此处遵循您的指南,但现在出现“导入循环”错误。我的源代码在我刚刚写了一个简短的分步指南,说明我如何使用新的go tool 和github.com。您可能会发现它很有用:
1.设置你的 GOPATH
您可以将环境变量GOPATH
设置为您喜欢的任何目录。如果你有更大的项目,为每个项目创建一个不同的 GOPATH 可能是个好主意。我会特别推荐这种方法用于部署,这样更新项目 A 的库不会破坏项目 B,这可能需要相同库的早期版本。
还请注意,您可以将 GOPATH 设置为目录列表,以冒号分隔。因此,您可能有一个包含所有常用包的 GOPATH,并为每个带有附加包或现有包的不同版本的项目单独的 GOPATH。
但除非你同时处理许多不同的 Go 项目,否则本地只有一个 GOPATH 可能就足够了。所以,让我们创建一个:
mkdir $HOME/gopath
然后你需要设置两个环境变量来告诉go tool它可以在哪里找到现有的Go包以及它应该在哪里安装新的包。最好将以下两行添加到您的~/.bashrc
或~/.profile
(之后不要忘记重新加载您的 .bashrc)。
export GOPATH="$HOME/gopath"
export PATH="$GOPATH/bin:$PATH"
2。创建一个新项目
如果你想创建一个新的 Go 项目,以后应该托管在 github.com,你应该在 $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.发布您的项目
创建一个new repository at 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。
【讨论】:
我最近自己也掌握了这个窍门。我开始做的是拥有一个 GOPATH,并将我的项目符号链接到它们中。这样我就可以轻松构建,但将实际项目保存在他们自己的存储库中。到目前为止,这感觉是一种非常干净的方法。 Github 路径往往很长而且我很懒,所以我在我的 bashrc 中添加了一个别名:alias g="cd /home/me/goroot/src/github.com/me/"
。现在我可以使用简单的 g 命令快捷地访问我的项目。
你如何跟踪你的包使用的外部依赖?
如果我使用 CI 服务器可以应用吗?我假设在每次推送时,CI 都会尝试从 master
分支尝试 go get
本地包,这可能与要测试的版本不同。关于使用 CI 和 go 的任何指示? @tux21b
@tux21b 我可以问你另一个问题,如何将项目托管到不同的 repo 上? ***.com/questions/51413252/…【参考方案3】:
如果您想将代码保存在本地版本存储库中,只需将您的代码放在 GOPATH 中即可。
GOPATH 接受多个路径。 例如。在linux上
GOPATH=$HOME/go:$HOME/prj/foo
所以,您可以在 $HOME/go/src/... 中安装第 3 方软件包 而且,您可以将代码控制在 $HOME/prj/foo/src 中。
参考:go help gopath
【讨论】:
这个!或者索尼娅的回答。【参考方案4】:很多人说应该使用绝对路径来构建项目结构和导入:
import "github.com/user/utils"
但这可能会将您的项目限制在单个 repo (github) 内。我想用 相对路径:
import "./utils"
我还没有找到办法,我在这里提出一个问题: how to oraganize GO project packages if it will hosted on different repos(github & sourceForge)
【讨论】:
【参考方案5】:在不同的帖子和 Go 文档中寻找这个答案后,Go 1.11 发布了一种处理包的新方法,并且正在使用 Go 模块。
阅读有关 Go Modules here 的整个系列文章。
Go Modules 也负责版本控制
【讨论】:
以上是关于去,去获取,去安装,本地包和版本控制的主要内容,如果未能解决你的问题,请参考以下文章