bash 在每个项目的基础上自动定义 GOPATH

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17780754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:59:18  来源:igfitidea点击:

Automatically defining GOPATH on a per project basis

bashgo.bash-profile

提问by Daniel Nill

For every project I create I have to do export GOPATH={path_to_project}every time i cd into the project dir. There has to be an easier way. Isn't there some way I can create a .bashrc or .bash_profile file for a given directory to define the GOPATH for that project?

对于我创建的每个项目,我export GOPATH={path_to_project}每次进入项目目录时都必须做。必须有更简单的方法。有没有什么方法可以为给定目录创建 .bashrc 或 .bash_profile 文件来定义该项目的 GOPATH ?

For example, I have two go projects A and B. If I have a singular GOPATH that isn't redefined when I move between projects then binaries for both projects will be stored in the same place. More importantly, binaries for third party libraries will be stored in the same place so I have no way of maintaining multiple versions of the same library on a per project basis.

例如,我有两个 go 项目 A 和 B。如果我有一个在项目之间移动时没有重新定义的单一 GOPATH,那么两个项目的二进制文件将存储在同一个地方。更重要的是,第三方库的二进制文件将存储在同一位置,因此我无法在每个项目的基础上维护同一库的多个版本。

However, if I am able to define GOPATH on a per project basis then all binaries and third party libraries a project dependent. This seems to be the common way of handling package management in most other language environments (ruby rbenv, python vertiualenv, etc.)

但是,如果我能够在每个项目的基础上定义 GOPATH,那么所有二进制文件和第三方库都依赖于项目。这似乎是大多数其他语言环境(ruby rbenv、python vertiualenv 等)中处理包管理的常用方法

回答by VonC

(Q2 2018: Note that with the vgo (now "module") project, GOPATHmight end up being deprecated in favor of a project-based workflow. That would avoid the manual project-based GOPATHI was proposing below, two years ago)

(2018 年第 2 季度:请注意,对于vgo(现在为“模块”)项目GOPATH最终可能会被弃用,以支持基于项目的工作流程。这将避免GOPATH我两年前在下面提出的基于手动项目的项目)

With Go 1.11 (August 2018), GOPATHcan be optional, with modules.

使用 Go 1.11(2018 年 8 月),GOPATH可以是可选的,带有模块



You have a similar idea expressed in Manage multiple GOPATH dirs with ease, by Herbert Fischer (hgfischer), for a Linux/Unix environment (base on the questionalready mention in the comments above):

您在管理多个 GOPATH 目录轻松 中表达了类似的想法,作者Herbert Fischer ( hgfischer),针对 Linux/Unix 环境(基于上面评论中已经提到的问题):

Just include the following snippet in your ~/.bashrc(or ~/.bash_profile) and reload your shell environment with source ~/.bashrc.
This snippet will create a shell function that will override the builtin command cdwith a customized one that scans the entered directory, and every other above, for a file named .gopath.

只需在您的~/.bashrc(或~/.bash_profile)中包含以下代码片段,然后使用source ~/.bashrc.
此代码段将创建一个 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
}

Now you just need to create a .gopathfile in every directory you want as your GOPATHand every time you enter this directory, the redefined cdfunction will set the GOPATHof your current environment to this directory.

现在您只需要.gopath在您想要的每个目录中创建一个文件作为您的文件,GOPATH并且每次您进入该目录时,重新定义的cd函数都会将GOPATH您当前的环境设置为该目录。



Update 2017: if you don't want to modify your environment, you can still use one GOPATHper project, by opening the srcfolder of that project in Visual Studio Code (vscode, which is a multi-platform IDE), combined with the extension "Go for Visual Studio Code".

2017 年更新:如果你不想修改你的环境,你仍然可以GOPATH为每个项目使用一个,通过src在 Visual Studio Code 中打开该项目的文件夹(vscode,这是一个多平台 IDE),结合扩展“选择 Visual Studio Code”。

In that IDE, you can:

在该 IDE 中,您可以:

  • keep your global unique GOPATHin a setting called go.toolsGopath.
  • infer your current GOPATHwith a setting called go.inferGopath
  • 保持你的全球唯一GOPATH一个名为设置go.toolsGopath
  • GOPATH使用名为的设置推断您的当前go.inferGopath

vscode user settings

vscode 用户设置

That way, VSCode will install a collection of tools in your global GOPATH(for you to use outside VSCode as well).
See "Go tools that the Go extension depends on": godep, golint, guru, godoc, ...

这样,VSCode 将在您的全局中安装一组工具GOPATH(供您在 VSCode 之外使用)。
请参阅“ Go 扩展依赖的 Go 工具”:godep, golint, guru, godoc, ...

And yet, your GOPATHfor your project will be the parent folder of src:

然而,您GOPATH的项目将是 src 的父文件夹:

local GOPATH

本地GOPATH

That works when you compile/install your project from the IDE.
If you want to do it from the command line, the original answer above would still apply.

当您从 IDE 编译/安装项目时,这会起作用。
如果您想从命令行执行此操作,则上面的原始答案仍然适用。

回答by Brent

You can use a tool like autoenvto set up a script that is automatically executed when you cdinto a particular directory.

您可以使用像autoenv这样的工具来设置一个脚本,当您cd进入特定目录时该脚本会自动执行。

For your purposes, an example /happy/go/path/yay/.envfile might look like:

出于您的目的,示例/happy/go/path/yay/.env文件可能如下所示:

export GOPATH="/happy/go/path/yay"
export PATH="$GOPATH/bin:$PATH"

回答by joshlf

I would write a script which can infer the proper GOPATH from the current directory, and then alias the gocommand to first call this script. For example, a very simple implementation:

我会编写一个脚本,它可以从当前目录中推断出正确的 GOPATH,然后将go命令别名为首先调用这个脚本。例如,一个非常简单的实现:

#!/bin/bash
# infer-gopath.sh

pwd

And then, in .bash_aliases (or wherever you keep your aliases):

然后,在 .bash_aliases (或任何你保留别名的地方):

alias go='GOPATH=$(infer-gopath.sh) go'

This sets GOPATHto whatever infer-gopath.shoutputs just for the invocation of the gocommand, so it won't have any lasting effect on your shell.

这将设置GOPATHinfer-gopath.sh仅用于调用go命令的任何输出,因此它不会对您的 shell 产生任何持久影响。

回答by joshlf

I know this is not very clever but I find that if I simply go to the base directory of the go project where I have the src, pkg and bin folders I can simply type:

我知道这不是很聪明,但我发现如果我只是转到 go 项目的基本目录,在那里我有 src、pkg 和 bin 文件夹,我可以简单地输入:

export GOPATH=$(pwd)

and thats it all good!

就是这样!

回答by rici

My impression is that the gotool actively discourages "maintaining multiple versions of the same library on a per project basis" for the precise reason that experience has shown that that strategy doesn't work on large codebases (such as Google's). There has been quite a lot of discussion about package versioning on golang-nuts: (search the list), and it seems that the discussion is still open, as indicated by Ian Lance Taylor in this June 6, 2013 interview(search for the word "versioning").

我的印象是该go工具积极反对“在每个项目的基础上维护同一库的多个版本”,原因是经验表明该策略不适用于大型代码库(例如 Google 的)。关于 golang-nuts 上的包版本控制已经有很多讨论:(搜索列表),而且似乎讨论仍然是开放的,正如 Ian Lance Taylor 在2013 年 6 月 6 日的采访中所指出的(搜索词“版本控制”)。

The gopackaging system is designed to allow every project to have its own directory structure; the only restriction is that they all need to be children of (some) directory in GOPATH. This has the advantage that it interacts well with version control systems, as long as the VCS master always builds. In the blog interview referenced above, ILT suggests:

go包装系统被设计为允许每个项目都有自己的目录结构; 唯一的限制是它们都需要是GOPATH. 这样做的好处是它可以与版本控制系统很好地交互,只要 VCS master 始终构建。在上面提到的博客采访中,ILT 建议:

What we do internally is take a snapshot of the imported code, and update that snapshot from time to time. That way, our code base won't break unexpectedly if the API changes.

我们在内部做的是对导入的代码进行快照,并不时更新该快照。这样,如果 API 更改,我们的代码库不会意外中断。

Substituting "my other libraries" for "the imported code", that seems like a possibility; you could have two godirectories, production and development; for development, you could put the development directory first in the path so that development binaries and libraries don't pollute the production directories. I don't know if that is sufficient.

将“我的其他库”替换为“导入的代码”,这似乎是一种可能性;你可以有两个go目录,生产和开发;对于开发,您可以将开发目录放在路径中的首位,这样开发二进制文件和库就不会污染生产目录。我不知道这是否足够。

If you really want to have a separate GOPATHfor each project, I'd suggest the following:

如果您真的想GOPATH为每个项目单独创建一个,我建议如下:

1) Make every project's GOPATHend at a directory named go(or some such)

1)使每个项目都GOPATH在一个名为go(或类似)的目录中结束

2) Deduce the GOPATHusing the something like the following shell function (almost totally untested):

2)推断GOPATH使用类似于以下shell函数的东西(几乎完全未经测试):

gopath() {
  GOPATH="$(
    ( while [[ $PWD != / && $(basename $PWD) != go ]]; do
        cd ..
      done
      if [[ $PWD == / ]]; then
        echo $GOPATH
      else
        echo $PWD
      fi
    ))" go "$@"
}

Then you can use gopathinstead of goas long as your current working directory is somewhere inside the project's repository. (More sophisticated possibilities might include using the explicitly provided project path, if any, to deduce GOPATH.)

然后您可以使用gopath而不是go只要您当前的工作目录位于项目存储库中的某个位置。(更复杂的可能性可能包括使用明确提供的项目路径(如果有)来推断GOPATH.)

回答by lukeed

I can't comment, but to build off the answer from @joshlf :::

我不能发表评论,但要建立在@joshlf 的答案的基础上 :::

alias goby prepending the GOPATH-- my method doesn't require you deal with/create an extra file:

go通过在前面添加别名GOPATH-- 我的方法不需要您处理/创建额外的文件:

alias go='GOPATH=$(echo $(pwd)) go'

alias go='GOPATH=$(echo $(pwd)) go'

cheers

干杯

回答by Alexander Mills

I'm a Golang newb, but the best way to do this would probably be to create a shell script in each of your projects, to build/run your project, and put this script in your project root :)

我是 Golang 新手,但最好的方法可能是在您的每个项目中创建一个 shell 脚本,以构建/运行您的项目,然后将此脚本放在您的项目根目录中 :)

#!/usr/bin/env bash

// get absolute path to the directory which contains this script
PROJECT_DIR=$(cd $(dirname 
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
    ))"
}
) && pwd) // set GOPATH as you wish, then run go build GOPATH=${GOPATH}:${PROJECT_DIR} && cd ${PROJECT_DIR} && go build

this script should work, even if you execute it from a directory that is not the project root.

即使您从不是项目根目录的目录中执行该脚本,该脚本也应该可以工作。

回答by el_bhs

I like the guts of the gopath() answer above, but I don't like (a) having the GOPATHset only for the gocommand (I use it in vim plugins, etc), nor do I like (b) having to remember to type gopathinstead of go:)

我喜欢上面 gopath() 答案的胆量,但我不喜欢 (a)GOPATH只为go命令设置(我在 vim 插件等中使用它),我也不喜欢 (b) 必须记住键入gopath而不是go:)

This is what I ultimately added to my ~/.bash_profile:

这是我最终添加到我的~/.bash_profile

##代码##

(I also wrote up the above with a little extra discussion of requirements in this blog post)

(我还在这篇博文中对要求进行了一些额外的讨论)