2015-09-18 16 views
5

コードブロックから現在のGOPATHを取得するにはどうすればよいですか?コードから現在のGOPATHを取得する方法

runtimeGOROOTを持っています

// GOROOT returns the root of the Go tree. 
// It uses the GOROOT environment variable, if set, 
// or else the root used during the Go build. 
func GOROOT() string { 
    s := gogetenv("GOROOT") 
    if s != "" { 
     return s 
    } 
    return defaultGoroot 
} 

私はGOROOTGOPATHに置き換えられた機能を作ることができるが、このためのbuildinがありますか?

答えて

10

使用os.Getenv

ドキュメントから:

のgetenvは キーで指定された環境変数の値を取得します。値が返されます。変数が でない場合は空になります。

例:

package main 

import (
    "fmt" 
    "os" 
    ) 

func main() { 
    fmt.Println(os.Getenv("GOPATH")) 
} 

ゴー1.8+の更新

ゴー1.8 GO /ビルドを経由して輸出し、デフォルトのGOPATHがあります

package main 

import (
    "fmt" 
    "go/build" 
    "os" 
) 

func main() { 
    gopath := os.Getenv("GOPATH") 
    if gopath == "" { 
     gopath = build.Default.GOPATH 
    } 
    fmt.Println(gopath) 
} 
+4

go 1.8では、GOPATH env varはオプションです。ユーザーがそれを持っていない場合はどうなりますか?既定値を取得する方法はありますか? Go実行時にはgopathを取得する方法があるはずだから、Go自身がそれを把握できるようにする必要があります。 – tothemario

+0

@tothemario Go 1.8以降の有効な 'GOPATH'をどうやって得ることができるかを私は公表しました。しかし、理想的には、ランタイムはユーザーの 'GOPATH'を取得する方法を提供するべきであると私は同意します。 – tmh

+1

@tothemarioは、Go 1.8のデフォルトのgoパス実装のコードを使って答えを更新しました。 – codefreak

1

ゴー1.8ので、そこにされますa :

環境変数GOPATHは、 ワークスペースの場所を指定します。デフォルトでは、ホーム ディレクトリ内のgoというディレクトリになります。そのため、UNIXでは$HOME/go、プラン9では$home/go、Windowsでは %USERPROFILE%\go(通常はC:\Users\YourName\go)です。

つまり、GOPATHという環境変数は、特に何も設定されていないことを意味します。

あなたはまだ値を取得するために os.Getenvを使用することができますが、場合には、あなたが mitchellh/go-homedirを使用して、たとえば、代わりにplattform固有のデフォルト値を使用することを確認する必要があります設定されていない

package main 

import (
     "fmt" 
     "log" 
     "os" 

     "github.com/mitchellh/go-homedir" 
) 

func main() { 
     p, err := gopath() 
     if err != nil { 
       log.Fatalf("Error finding GOPATH: %v", err) 
     } 

     fmt.Println(p) 
} 

func gopath() (string, error) { 
     s := os.Getenv("GOPATH") 
     if s != "" { 
       return s, nil 
     } 
     return homedir.Expand("~/go") 
} 
+0

これは少し残酷です。 Goのソースコードからコードを使用して、デフォルトのパスを得ることができます。 https://github.com/golang/go/blob/go1.8/src/go/build/build.go#L260-L277 – codefreak

+0

@codefreak確かに簡単な方法があり、あなたの答えも有効です。 'go-homedir'について私が気に入っているのは、疑わしいときにホームディレクトリを見つけるための複数の方法を試行し、すべてが失敗すると実際にはエラーを返すということです。したがって、このコードのユーザーは意味のあるエラーメッセージを返すことができます。空の文字列を返すだけの場合は、空であるかどうかをチェックする必要があります。彼らはそれを怠ると、予期せぬ動作や奇妙なエラーが生じることがあります。 – tmh

+0

問題のポイントは、GOPATHを見つけることです。ホームディレクトリではありません。 go-homedirはホームディレクトリを見つけるのに最適です。しかし、Go自身がdefaultGOPATH関数を使用する場合、Goのコード自体が処理しないエッジケースの世話をするのは何ですか?とにかく、ユーザーに最も好きなものを決めることができます:) – codefreak

4

go/buildパッケージを使用する必要があります。

package main 

import (
    "fmt" 
    "go/build" 
) 

func main() { 
    fmt.Println(build.Default.GOPATH) 
} 
0

私は現在、私が取り組んでいることについてこれを乱していました。予想していたよりも迷惑でした。結局、これは私が(厳密なテストではなく)様々なテストで私のために働いていたようです。複数のパスがGOPATHに上場されている場合、私は私が1つの以上のパスが記載されている必要がありますいくつかの疑いがある、とgo getは、ソースを置く場所を最初は私が推測する(だろうと、唯一の第一のパスを使用することにしました

goPath := strings.Split(os.Getenv("GOPATH"), string(os.PathListSeparator)) 
if len(goPath) == 0 { 
    goPath = append(goPath, build.Default.GOPATH) 
} else if goPath[0] == "" { 
    goPath[0] = build.Default.GOPATH 
} 

注意)。このコードでは、パスが有効かどうかについても考慮していません。

また、GOPATHを取得した後にファイルパスを構築するには、path/filepath.Join()ではなくpath.Join()を使用する必要があります。前者は、最初の引数に\が含まれていればウィンドウに\を使用し、他の引数には/を使用します。ウィンドウはパスを受け入れることができますが、私のPATHとGOPATHのような環境変数はすべて、通常のウィンドウで書かれています。 path.Join()が使用され、無効なパスが生成されます。

関連する問題