web-dev-qa-db-ja.com

プロジェクトごとにGOPATHを自動的に定義する

私が作成するすべてのプロジェクトについて、私はexport GOPATH={path_to_project}プロジェクトディレクトリにcdするたび。より簡単な方法が必要です。特定のディレクトリの.bashrcまたは.bash_profileファイルを作成して、そのプロジェクトのGOPATHを定義する方法はありませんか?

たとえば、2つのgoプロジェクトAとBがあります。プロジェクト間を移動するときに再定義されない単一のGOPATHがある場合、両方のプロジェクトのバイナリが同じ場所に保存されます。さらに重要なことに、サードパーティのライブラリのバイナリは同じ場所に保存されるため、プロジェクトごとに同じライブラリの複数のバージョンを維持する方法はありません。

ただし、プロジェクトごとにGOPATHを定義できる場合、すべてのバイナリとサードパーティのライブラリはプロジェクトに依存します。これは、他のほとんどの言語環境(Ruby rbenv、python vertiualenvなど)でパッケージ管理を処理する一般的な方法のようです。

28
Daniel Nill

(2018年第2四半期: vgo(現在は「モジュール」)プロジェクト を使用すると、GOPATHがプロジェクトベースのワークフローのために廃止される可能性があることに注意してください。手動プロジェクトを回避できます。ベースのGOPATH私は2年前に以下を提案しました)

Go 1.11(2018年8月)では、 GOPATHはオプションで、modules を使用できます。


複数のGOPATHディレクトリを簡単に管理するHerbert Fischer(hgfischer 、Linux/Unix環境の場合( に基づく質問 上記のコメントですでに言及されている):

~/.bashrc(または~/.bash_profile)に次のスニペットを含め、シェル環境をsource ~/.bashrcでリロードするだけです。
このスニペットは、ビルトインコマンド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関数が現在の環境のGOPATHをこのディレクトリに設定します。


2017年更新:環境を変更したくない場合でも、プロジェクトごとにGOPATHフォルダーをVisual Studio Code( vscode で開くことにより、プロジェクトごとに1つのsrcを使用できます。これはマルチプラットフォームIDEであり、 " Go for Visual Studio Code "と組み合わされます。

そのIDEでは、次のことができます。

  • グローバルで一意のGOPATHgo.toolsGopathという設定で保持します。
  • go.inferGopathという設定で現在のGOPATHを推測します

vscode user settings

このようにして、VSCodeはツールのコレクションをグローバルGOPATHにインストールします(VSCodeの外部でも使用できます)。
Go拡張機能が依存するGoツール 」を参照:godepgolintgurugodoc、...

ただし、プロジェクトのGOPATHはsrcの親フォルダーになります。

local GOPATH

これは、IDEからプロジェクトをコンパイル/インストールするときに機能します。
コマンドラインから実行する場合でも、上記の元の回答が適用されます。

20
VonC

autoenv のようなツールを使用して、特定のディレクトリにcdしたときに自動的に実行されるスクリプトを設定できます。

あなたの目的のために、例/happy/go/path/yay/.envファイルは次のようになります。

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

現在のディレクトリから適切なGOPATHを推測できるスクリプトを作成し、goコマンドにエイリアスを付けて、最初にこのスクリプトを呼び出します。たとえば、非常に単純な実装:

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

pwd

そして、.bash_aliases(またはエイリアスを保持する場所)で:

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

これはGOPATHを何にでも設定しますinfer-gopath.shgoコマンドの呼び出しについてのみ出力するため、シェルに永続的な影響を与えることはありません。

5
joshlf

私はこれがあまり賢くないことを知っていますが、src、pkg、binフォルダーがあるgoプロジェクトのベースディレクトリに単純に移動すると、次のように入力できます。

export GOPATH=$(pwd)

それでいいのです!

3
user2855262

私の印象は、goツールは「同じライブラリの複数のバージョンをプロジェクトごとに維持する」ことを積極的に推奨していないということです。これは、その戦略が大きなコードベース(Googleの)。 golang-nutsでのパッケージのバージョン管理については非常に多くの議論がありました:( リストを検索 )、これについてはIan Lance Taylorが指摘しているように、議論はまだ開かれているようです 2013年6月6日のインタビュー (「バージョン管理」という単語を検索)。

goパッケージングシステムは、すべてのプロジェクトが独自のディレクトリ構造を持つことができるように設計されています。唯一の制限は、それらすべてがGOPATHの(一部の)ディレクトリの子である必要があることです。これには、VCSマスターが常にビルドされている限り、バージョン管理システムと適切に相互作用するという利点があります。上記のブログのインタビューで、ILTは次のことを提案しています。

私たちが内部で行うことは、インポートされたコードのスナップショットを取り、そのスナップショットを時々更新することです。これにより、APIが変更されても、コードベースが予期せず壊れることはありません。

「インポートされたコード」を「自分の他のライブラリ」に置き換えると、可能性があるようです。 2つのgoディレクトリ、本番環境と開発環境を持つことができます。開発の場合、開発バイナリとライブラリが本番ディレクトリを汚染しないように、開発ディレクトリをパスの最初に置くことができます。それで十分かわかりません。

プロジェクトごとに個別のGOPATHが本当に必要な場合は、次のことをお勧めします。

1)すべてのプロジェクトのGOPATHgo(またはそのようなもの)という名前のディレクトリで終了する

2)次のシェル関数(ほとんど完全にテストされていない)のようなものを使用してGOPATHを推定します。

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

次に、現在の作業ディレクトリがプロジェクトのリポジトリ内にある限り、gopathの代わりにgoを使用できます。 (より洗練された可能性としては、明示的に提供されたプロジェクトパスがあれば、それを使用してGOPATHを推定することが挙げられます。)

3
rici

コメントはできませんが、@ joshlfからの回答を構築するために:::

エイリアスgoGOPATHの先頭に追加する-この方法では、追加のファイルを処理/作成する必要はありません。

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

乾杯

1
lukeed

私はGolangの初心者ですが、これを行う最善の方法は、各プロジェクトでシェルスクリプトを作成し、プロジェクトをビルド/実行して、このスクリプトをプロジェクトのルートに配置することです:)

#!/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

このスクリプトは、プロジェクトのルートではないディレクトリから実行した場合でも機能します。

0
Alexander Mills

私は 上記のgopath()の答え の根性が好きですが、(a)GOPATHgoコマンドに対してのみ設定するのは好きではありません(私はそれは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
    ))"
}

(私はまた、要件の少し余分な議論で上記を書きました このブログ投稿で

0
el_bhs