英文:
Go, go get, go install, local packages, and version control
问题
我对创建一个具有本地包的Go项目的工作流程感到困惑。
假设我创建了一个新项目,使用git进行版本控制,其中包含一个main.go文件和一个位于utils包中的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、版本控制和包导入的正确方法。
英文:
I am having trouble understanding the workflow for creating a go project that has local packages.
Say I create a new project, using git for version control, which has a main.go file and a tools.go file which will be in package utils. So I have a directory structure such as this:
/myproject/
main.go
utils/
tools.go
main.go looks like this:
package main
import "./utils"
func main() {
utils.DoSomthing()
}
and tools.go looks like this:
package utils;
func DoSomething() {
}
Everything works just fine locally, using go build and go run. But this is being hosted on github, and I'd like to be able to have others use the go get command to install it. So the local package import must be changed to use the format "github.com/user/project/utils", which works, except now I have two copies of the source code, and the real problem is that the copy with the git history has an import that makes use of the downloaded copy. So if I'm working on the copy with the git history, any changes made to tools.go will go unnoticed, because it will be using the downloaded copy.
So I'm wondering if someone can explain the right way of using go get, version control, and package imports within the same project.
答案1
得分: 97
我刚刚写了一个关于如何使用新的go工具和github.com的简短的逐步指南。你可能会觉得有用:
1. 设置你的GOPATH
你可以将环境变量GOPATH
设置为任何你喜欢的目录。如果你有较大的项目,为每个项目创建一个不同的GOPATH可能是一个好主意。我特别推荐这种方法用于部署,这样为项目A更新一个库不会破坏项目B,而项目B可能需要一个早期版本的同一个库。
还要注意,你可以将GOPATH设置为由冒号分隔的目录列表。所以你可以有一个包含所有常用包的GOPATH,以及每个项目的单独GOPATH,其中包含额外的包或不同版本的现有包。
但是,除非你同时在很多不同的Go项目上工作,否则只有一个本地GOPATH可能就足够了。所以,让我们创建一个:
mkdir $HOME/gopath
然后你需要设置两个环境变量,告诉go工具它可以在哪里找到现有的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 repo的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公钥,请上传你的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。
英文:
I've just written a short step-by-step guide on how I am using the new go tool and github.com. You might find it useful:
1. Setup your GOPATH
You can set the environment variable GOPATH
to any directory you like. If you have larger projects, it's probably a good idea to create a different GOPATH for each of them. I would recommend this approach especially for the deployment, so that updating a library for project A doesn't break project B which might require an earlier version of the very same library.
Also note that you can set your GOPATH to a list of directories, delimited by colons. So you might have a GOPATH containing all commonly used packages, and separate GOPATHS for each project with additonal packages or different versions of existing packages.
But unless your are working on a lot of different Go projects simultaneously, its probably enough to have just a single GOPATH locally. So, let's create one:
mkdir $HOME/gopath
Then you need to set two environment variables to tell the go tool where it can find existing Go packages and where it should install new ones. It's probably best to add the following two lines to your ~/.bashrc
or ~/.profile
(and do not forget to reload your .bashrc afterwards).
export GOPATH="$HOME/gopath"
export PATH="$GOPATH/bin:$PATH"
2. Create a new project
If you want to create a new Go project which should be hosted at github.com later, you should create this project under $GOPATH/src/github.com/myname/myproject
. It's important that the path matches the URL of the github.com repo, because the go tool will follow the same convention. So, let's create the project root and initialize a new git repository there:
mkdir -p $GOPATH/src/github.com/myname/myproject
cd $GOPATH/src/github.com/myname/myproject
git init
Because I do not like to type such long paths, I normally create symbolic links for the projects I am currently working on in my home folder:
ln -s $GOPATH/src/github.com/myname/myproject ~/myproject
3. Write your application
Start coding and don't forget to git add
and git commit
your files. Also, do not use relative imports like import "./utils"
for sub-packages. They are currently undocumented and shouldn't be used at all, because they won't work with the go tool. Use imports like github.com/myname/myproject/utils
instead.
4. Publish your project
Create a new repository at github.com, upload your SSH public key if you haven't done that before and push your changes to the remote repository:
git remote add origin git@github.com:myname/myproject.git
git push origin master
5. Continue working on your project
If you have set the GOPATH in your .bashrc and if you have created a symlink to your project in your home folder, you can just type cd myproject/
and edit some files there. Afterwards, you can commit the changes using git commit -a
and send them to github.com by doing a git push
.
答案2
得分: 10
你可能不想要两份源代码的副本。根据如何编写Go代码,你应该有一个用于Go开发的路径,比如说"godev",在这个路径下,有一个"src"目录,然后在这个目录下,有你的"github.com/user/project"和"github.com/user/project/utils"。(我同意,这似乎有点死板,但我们被告知的好处是摆脱了make文件。)放弃myproject,这就是你将要进行工作的地方。
你的GOPATH至少应该设置为godev,但你可能希望你的GOPATH以一个不属于你的外部包的路径开始。例如,我使用的GOPATH是<文件系统上的位置>/goext:<文件系统上的位置>/godev
。
你是对的,你在main.go中的导入现在应该写成"github.com/user/project/utils"。
不用担心go get或任何go命令会覆盖你的文件或破坏版本控制。通过GOPATH,它们知道你正在工作的位置,也知道版本控制是如何工作的。
英文:
You probably don't want two copies of the source. Following How to Write Go Code, you should have a path where you do your Go development, lets say "godev", and under that, a "src" directory, and under that, your "github.com/user/project" and "github.com/user/project/utils". (I agree, it seems a little rigid, but the advantage explained to us is freedom from make files.) Ditch the myproject, this is where you will do your work.
You will have GOPATH set to godev at least, but you will probably want your GOPATH to start with a path for external packages that are not yours. For example the GOPATH I use is <my place on the file system>/goext:<my place on the file system>/godev
.
You are right that your import in main.go should now read "github.com/user/project/utils.
Don't worry about go get or any of the go commands overwriting your files or messing up version control. Through GOPATH, they see where you are working and they know how version control works.
答案3
得分: 8
如果你想将你的代码保存在本地版本库中,只需将你的代码放在GOPATH中。
GOPATH可以接受多个路径。
例如,在Linux上:
GOPATH=$HOME/go:$HOME/prj/foo
这样,你可以在$HOME/go/src/...中安装第三方包。
同时,你可以将你的代码保存在$HOME/prj/foo/src中。
参考:go help gopath
英文:
If you want to keep your code in local version repository, just put your code in GOPATH.
GOPATH accepts multiple paths.
eg. on linux
GOPATH=$HOME/go:$HOME/prj/foo
So, you could go get 3rd party packages installed in $HOME/go/src/...
And, you could keep your code controlled in $HOME/prj/foo/src.
ref: go help gopath
答案4
得分: -2
很多人说应该使用绝对路径来构建项目结构和导入:
import "github.com/user/utils"
但是这可能会限制你的项目只能在一个仓库(github)中。我想使用相对路径代替:
import "./utils"
我还没有找到实现这一点的方法,我在这里提出了一个问题:
https://stackoverflow.com/questions/51413252/how-to-oraganize-go-project-packages-if-it-will-hosted-on-different-reposgithub
英文:
lot of people say should use absolutlly path to construct project struct and import :
import "github.com/user/utils"
but this may limit your project within a single repo (github). I would like to use
relative path instead :
import "./utils"
I havn't find a way to do that, I raise a question here:
https://stackoverflow.com/questions/51413252/how-to-oraganize-go-project-packages-if-it-will-hosted-on-different-reposgithub
答案5
得分: -4
After looking for this answer in different posts and Go documentation, with Go 1.11 there has been released a new approach to handle packages and is using Go Modules.
Read the whole post series about Go Modules here.
Go Modules also takes care of version control as well.
英文:
After looking for this answer in different posts and Go documentation, with Go 1.11 there has been released a new approach to handle packages and is using Go Modules.
Read the whole post series about Go Modules here.
Go Modules also takes care of version control as well
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论