Bash 基于每个项目自动定义GOPATH
对于我创建的每个项目,每次我将cd放入项目目录时,我都必须执行Bash 基于每个项目自动定义GOPATH,bash,go,Bash,Go,对于我创建的每个项目,每次我将cd放入项目目录时,我都必须执行export GOPATH={path_to_project}。必须有一个更简单的方法。我是否有办法为给定目录创建一个.bashrc或.bash_概要文件来定义该项目的GOPATH 例如,我有两个go项目A和B。如果我有一个在项目之间移动时未重新定义的单一GOPATH,则两个项目的二进制文件将存储在同一位置。更重要的是,第三方库的二进制文件将存储在同一个位置,因此我无法在每个项目的基础上维护同一库的多个版本 然而,如果我能够在每个项目
export GOPATH={path_to_project}
。必须有一个更简单的方法。我是否有办法为给定目录创建一个.bashrc或.bash_概要文件来定义该项目的GOPATH
例如,我有两个go项目A和B。如果我有一个在项目之间移动时未重新定义的单一GOPATH,则两个项目的二进制文件将存储在同一位置。更重要的是,第三方库的二进制文件将存储在同一个位置,因此我无法在每个项目的基础上维护同一库的多个版本
然而,如果我能够在每个项目的基础上定义GOPATH,那么所有二进制文件和第三方库都依赖于项目。这似乎是大多数其他语言环境(ruby rbenv、python vertiualenv等)中处理包管理的常用方法。我将编写一个脚本,从当前目录推断正确的GOPATH,然后别名
go
命令来首先调用此脚本。例如,一个非常简单的实现:
#!/bin/bash
# infer-gopath.sh
pwd
然后,在.bash_别名中(或保留别名的任何地方):
这将
GOPATH
设置为推断GOPATH.sh
输出的任何内容,仅用于调用go
命令,因此它不会对shell产生任何持久的影响。我的印象是go
工具积极地阻止“在每个项目的基础上维护同一库的多个版本”正因为如此,经验表明,这种策略在大型代码库(如谷歌)上不起作用。关于golang nuts上的包版本控制有很多讨论:(),正如Ian Lance Taylor在本文(搜索“版本控制”一词)中所指出的,讨论似乎仍然没有结束
go
打包系统旨在允许每个项目都有自己的目录结构;唯一的限制是它们都必须是GOPATH
中(某些)目录的子目录。这样做的好处是,只要VCS主机始终构建,它就可以与版本控制系统很好地交互。在上面提到的博客采访中,ILT建议:
我们在内部所做的是获取导入代码的快照,并不时更新该快照。这样,如果API发生更改,我们的代码库就不会意外中断
用“我的其他库”代替“导入的代码”,这似乎是一种可能性;您可以有两个go
目录,即production和development;对于开发,您可以将开发目录放在路径的第一位,这样开发二进制文件和库就不会污染生产目录。我不知道这是否足够
如果您真的想为每个项目单独设置一个GOPATH
,我建议如下:
1) 使每个项目的GOPATH
在名为go
的目录中结束(或类似目录)
2) 使用类似于以下shell函数(几乎完全未经测试)的函数推导出GOPATH
:
然后,您可以使用gopath
而不是go
,只要当前工作目录位于项目存储库中的某个位置。(更复杂的可能性可能包括使用显式提供的项目路径(如果有)来推断GOPATH
)您可以使用类似的工具来设置脚本,当您将cd
放入特定目录时,脚本会自动执行
出于您的目的,示例/happy/go/path/yay/.env
文件可能如下所示:
export GOPATH="/happy/go/path/yay"
export PATH="$GOPATH/bin:$PATH"
我喜欢的勇气,但我不喜欢(a)只为go
命令设置GOPATH
(我在vim插件等中使用它),也不喜欢(b)必须记住键入GOPATH
,而不是go
:)
这就是我最终添加到我的~/.bash\u配置文件中的内容:
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
))"
}
(我还写了上述内容,并额外讨论了一些要求)(2018年第二季度:
请注意,GOPATH
可能会被弃用,转而支持基于项目的工作流。这将避免两年前我在下面提出的手动基于项目的GOPATH)
Go 1.11(2018年8月)的规定
对于Linux/Unix环境,您也有类似的想法(基于上面评论中已经提到的):
只需在~/.bashrc
(或~/.bash_配置文件
)中包含以下代码片段,并使用源代码~/.bashrc
重新加载shell环境即可
此代码段将创建一个shell函数,该函数将使用一个自定义的函数覆盖内置命令cd
,该函数扫描输入的目录,并每隔一段扫描一个名为.gopath
的文件
现在,您只需在每个目录中创建一个.gopath
文件作为您的gopath
,每次进入该目录时,重定义的cd
函数将当前环境的gopath
设置为此目录
2017年更新:如果您不想修改您的环境,您仍然可以通过在Visual Studio code(,这是一个多平台IDE)中打开该项目的src
文件夹,并结合扩展名“”,为每个项目使用一个GOPATH
在该IDE中,您可以:
- 将全局唯一的
GOPATH
保存在名为go.toolsGopath
的设置中
- 使用名为
go.inferGopath
这样,VSCode将在您的全局路径中安装一组工具(供您在VSCode外部使用)。
参见“:godep
,golint
,guru
,godoc
,”
然而,你的
export GOPATH="/happy/go/path/yay"
export PATH="$GOPATH/bin:$PATH"
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
))"
}
cd () {
builtin cd "$@"
cdir=$PWD
while [ "$cdir" != "/" ]; do
if [ -e "$cdir/.gopath" ]; then
export GOPATH=$cdir
break
fi
cdir=$(dirname "$cdir")
done
}
#!/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
export GOPATH=$(pwd)