2015-09-18 27 views
5

Geçerli kod GOPATH kodunu nasıl alabilirim?Güncel GOPATH kodu nasıl alınır

// 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 
} 

Ben GOROOTGOPATH ile yerine geçen bir işlev yapabilir, ama orada bunun için buildin geçerli:

runtime sadece GOROOT sahiptir?

cevap

10

Kullanım Dokümanlar os.Getenv

:

getenv anahtar ile adlandırılmış ortam değişkeninin değerini alır. Değişken mevcut değilse boş olacak olan değeri döndürür.

Örnek:

package main 

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

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

1.8'de, GOPATH env var isteğe bağlıdır. Kullanıcı buna sahip değilse ne olur? Varsayılan olanı almanın bir yolu var mı? Gitme zamanının, Gopath'ı almanın bir yolu olması gerektiğini düşünüyorum. – tothemario

+0

@tothemario Go 1.8'den beri geçerli olan GOPATH'i nasıl alabileceğinizi bir cevap gönderdim. Ancak, ideal olarak çalışma zamanının kullanıcının “GOPATH” 'ını elde etmenin bir yolunu sağlaması gerektiğine katılıyorum. – tmh

+1

@tothemario, Go 1.8'in varsayılan go yolu uygulamasından kodu kullanarak güncellenmiş yanıtı. – codefreak

1

Go 1.8 beri vardır: Go 1.8+

Go 1.8 için

package main 

import (
    "fmt" 
    "os" 
    ) 

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

Güncelleme go/yapı yoluyla ihraç varsayılan GOPATH vardır default GOPATH:

GOPATH ortam değişkeni çalışma alanınızın konumunu belirtir. Bu, varsayılan olarak evinizde dizininin bulunduğu dizine, Unix'te $HOME/go, Plan 9'da $home/go ve Windows'da %USERPROFILE%\go (genellikle C:\Users\YourName\go) dizinini kullanır.

Bu, GOPATH ortam değişkeninin, özellikle herhangi bir şeye ayarlanmadığı anlamına gelir.

Hala değeri elde etmek os.Getenv kullanabilir ancak durumda size mitchellh/go-homedir kullanarak örneğin, yerine plattform özgü varsayılan değer kullanmak emin olmak gerekir ayarlı değil:

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

Bu biraz aşırı. Varsayılan go yolunu almak için Go'nun kendi kaynak kodundan kod kullanabiliriz. Bkz. Https://github.com/golang/go/blob/go1.8/src/go/build/build.go#L260-L277 – codefreak

+0

@codefreak Kesinlikle daha basit yollar vardır ve cevabınız da geçerlidir. 'Go-homedir' ile ilgili hoşuma giden şey şüphe duyduğunda, ev dizinini bulmanın birçok yolunu dener ve eğer başarısız olursa, aslında bir hata döndürür. Bu nedenle bu kodun kullanıcıları anlamlı bir hata mesajı verebilir. Boş bir dizge döndürdüyseniz, kullanıcılar boş olup olmadığını kontrol etmelidir. Bunu ihmal etmeleri halinde, bu durum bazı kenar durumlarında beklenmedik davranışlara veya garip hatalara yol açabilir. – tmh

+0

Soru şu ki, GOPATH'ı bulmak değil, ev dir. go-homedir ev dir bulmak için harika. Ancak Go'nun kendisi varsayılanGOPATH işlevini kullanıyorsa, Go kodunun kendisinin yapacağı kenar durumlarına dikkat etmenin ne önemi yoktur. Neyse, kullanıcıların en çok neye benzediğine karar vermesine izin verin :) – codefreak

4

go/build paketini kullanmalısınız.

package main 

import (
    "fmt" 
    "go/build" 
) 

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

Bugün üzerinde çalıştığım bir şey için uğraşıyordum ve beklediğimden daha sinir bozucuydu. Sonunda, bu benim yaptığım çeşitli testlerde benim için işe yaramış görünüyordu ('titiz' testleri değil). Birden yolları GOPATH listelenen eğer ben 1'den fazla yol listelenen olacak birkaç şüpheli ve go get kaynağını koyar nerede birinci sanırım (olurdu, sadece 1 yolunu kullanmaya karar

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 
} 

Not). Bu kod, yolların geçerli olup olmadığını da dikkate almaz.

Ayrıca, GOPATH'ı aldıktan sonra bir dosya yolu oluşturmak için path/filepath.Join()'u path.Join() kullanmam gerektiğine dikkat edin. Birincisi, ilk argümanın \, ve/veya diğerleri için \ windows'ları kullanır. Pencereler görünüşe göre yolları kabul etse de, tüm PATH ve GOPATH benzeri çevresel değişkenler pencerelerin normalleriyle yazılır. path.Join() kullanılmış/geçersiz bir yol üretiyor.

İlgili konular