对于我创建的每个项目,每次进入项目目录时我都必须export GOPATH={path_to_project}
。必须有一个更简单的方法。是否有某种方法可以为给定目录创建.bashrc或.bash_profile文件来定义该项目的GOPATH?
例如,我有两个项目A和B.如果我在项目之间移动时没有重新定义的单个GOPATH,那么两个项目的二进制文件将存储在同一个地方。更重要的是,第三方库的二进制文件将存储在同一个地方,因此我无法按项目维护同一个库的多个版本。
但是,如果我能够在每个项目的基础上定义GOPATH,那么所有二进制文件和第三方库都依赖于项目。这似乎是在大多数其他语言环境中处理包管理的常用方法(ruby rbenv,python vertiualenv等)
答案 0 :(得分:20)
(2018年第二季度:
请注意,对于vgo (now "module") project,最终可能会弃用GOPATH
以支持基于项目的工作流。这样可以避免两年前我在下面提出的基于项目的GOPATH
手册。
使用Go 1.11(2018年8月),GOPATH
can be optional, with modules。
对于Linux / Unix环境(基于Manage multiple GOPATH dirs with ease已经在上面的评论中提到),Herbert Fischer (hgfischer
)中the question表达了类似的想法:
只需在
~/.bashrc
(或~/.bash_profile
)中添加以下代码段,然后使用source ~/.bashrc
重新加载您的shell环境。
此代码段将创建一个shell函数,该函数将使用自定义命令覆盖内置命令cd
,该命令扫描输入的目录,以及上面的所有其他命令,以查找名为.gopath
的文件。
cd () {
builtin cd "$@"
cdir=$PWD
while [ "$cdir" != "/" ]; do
if [ -e "$cdir/.gopath" ]; then
export GOPATH=$cdir
break
fi
cdir=$(dirname "$cdir")
done
}
现在您只需要在每个目录中创建一个
.gopath
文件作为GOPATH
,每次进入此目录时,重新定义的cd
函数将设置{{1}当前环境到此目录。
2017年更新:如果您不想修改您的环境,您仍然可以在每个项目中使用一个GOPATH
,方法是在Visual Studio Code中打开该项目的GOPATH
文件夹({ {3}},这是一个多平台的IDE),与扩展" vscode"。
在该IDE中,您可以:
src
保留在名为GOPATH
。go.toolsGopath
GOPATH
这样,VSCode将在您的全球go.inferGopath
中安装一系列工具(您也可以在VSCode外部使用)。
请参阅" ":GOPATH
,godep
,golint
,guru
,...
然而,您项目的godoc
将是src的父文件夹:
Go tools that the Go extension depends on
从IDE编译/安装项目时,这是有效的 如果您想从命令行执行此操作,上面的原始答案仍然适用。
答案 1 :(得分:10)
您可以使用autoenv之类的工具来设置在cd
进入特定目录时自动执行的脚本。
出于您的目的,示例/happy/go/path/yay/.env
文件可能如下所示:
export GOPATH="/happy/go/path/yay"
export PATH="$GOPATH/bin:$PATH"
答案 2 :(得分:5)
我会写一个脚本,它可以从当前目录推断出正确的GOPATH,然后使用go
命令别名来首先调用这个脚本。例如,一个非常简单的实现:
#!/bin/bash
# infer-gopath.sh
pwd
然后,在.bash_aliases中(或者你保留别名的地方):
alias go='GOPATH=$(infer-gopath.sh) go'
这会将GOPATH
设置为仅用于调用infer-gopath.sh
命令的go
输出,因此它不会对您的shell产生任何持久影响。
答案 3 :(得分:3)
我的印象是go
工具主动阻止“在每个项目的基础上维护同一个库的多个版本”,原因在于经验表明该策略不适用于大型代码库(例如作为谷歌的)。关于golang-nuts的包版本化已经进行了很多讨论:( search the list),似乎讨论仍然是开放的,正如Ian Lance Taylor在June 6, 2013 interview所指出的那样(搜索“版本化”这个词。)
go
打包系统旨在允许每个项目都有自己的目录结构;唯一的限制是它们都需要是GOPATH
中(某些)目录的子项。这样做的好处是,只要VCS主站始终构建,它就可以很好地与版本控制系统进行交互。在上面引用的博客访谈中,ILT建议:
我们在内部执行的操作是获取导入代码的快照,并不时更新该快照。这样,如果API发生变化,我们的代码库就不会意外中断。
将“我的其他图书馆”替换为“导入的代码”,这似乎是一种可能性;你可以有两个go
目录,生产和开发;对于开发,您可以将开发目录放在路径的第一位,以便开发二进制文件和库不会污染生产目录。我不知道这是否足够。
如果你真的想为每个项目单独GOPATH
,我建议如下:
1)让每个项目的GOPATH
结束于名为go
的目录(或某些此类目录)
2)使用类似下面的shell函数(几乎完全未经测试)来推导GOPATH
:
gopath() {
GOPATH="$(
( while [[ $PWD != / && $(basename $PWD) != go ]]; do
cd ..
done
if [[ $PWD == / ]]; then
echo $GOPATH
else
echo $PWD
fi
))" go "$@"
}
然后,只要您当前的工作目录位于项目存储库中的某个位置,就可以使用gopath
而不是go
。 (更复杂的可能性可能包括使用明确提供的项目路径(如果有的话)来推导GOPATH
。)
答案 4 :(得分:2)
我知道这不是很聪明但我发现如果我只是去go项目的基本目录,我有src,pkg和bin文件夹,我只需输入:
export GOPATH=$(pwd)
这就好了!
答案 5 :(得分:1)
我无法发表评论,但要从@joshlf :::
中建立答案别名go
通过添加GOPATH
- 我的方法不要求你处理/创建额外的文件:
alias go='GOPATH=$(echo $(pwd)) go'
欢呼声
答案 6 :(得分:0)
我喜欢the gopath() answer above的胆量,但我不喜欢(a)只为GOPATH
命令设置go
(我在vim插件中使用它,等),我也不喜欢(b)必须记住键入gopath
而不是go
:)
这是我最终添加到~/.bash_profile
:
export GOPATH="... a default path ..."
function cd() {
builtin cd $@ &&
export GOPATH="$(
( while [[ $PWD != / && $(basename $PWD) != go ]]; do
cd ..
done
if [[ $PWD == / ]]; then
echo $GOPATH
else
echo $PWD
fi
))"
}
(我还在上面写了一些关于需求in this blog post)
的额外讨论答案 7 :(得分:0)
我是Golang的新手,但最好的方法可能是在每个项目中创建一个shell脚本,构建/运行你的项目,并将这个脚本放在你的项目根目录中:)
#!/usr/bin/env bash
// get absolute path to the directory which contains this script
PROJECT_DIR=$(cd $(dirname $0) && pwd)
// set GOPATH as you wish, then run go build
GOPATH=${GOPATH}:${PROJECT_DIR} && cd ${PROJECT_DIR} && go build
此脚本应该可以工作,即使您从非项目根目录执行它。