Go毎日一庫のgodotenv

10960 ワード

概要
twelve-factorアプリケーションは、環境変数に構成を格納することを推奨する.開発環境から生産環境に切り替える際に修正する必要があるものは、コードから環境変数に抽出されます.しかし,実際の開発では,同じマシンで複数のプロジェクトを実行すると,設定環境変数が衝突しやすく,実用的ではない.godotenvライブラリは、.envファイルから構成を読み出し、プログラムの環境変数に格納する.コードで読み取りができるのはとても便利です.godotenvは、Rubyのオープンソースプロジェクトdotenvに由来する.
クイック使用
サードパーティ製ライブラリをインストールする必要があります.
$ go get github.com/joho/godotenv

使用後:
package main

import (
  "fmt"
  "log"
  "os"

  "github.com/joho/godotenv"
)

func main() {
  err := godotenv.Load()
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println("name: ", os.Getenv("name"))
  fmt.Println("age: ", os.Getenv("age"))
}

次に、実行可能プログラムと同じディレクトリの下に.envファイルを追加します.
name = dj
age = 18

プログラムを実行し、出力:
name:  dj
age:  18

見ることができて、使うのはとても便利です.デフォルトでは、godotenvはプロジェクトルートディレクトリの.envファイルを読み込みます.ファイルにはkey = valueのフォーマットが使用され、行ごとにキー値のペアがあります.godotenv.Load()を呼び出すとロードされ、os.Getenv("key")を直接呼び出すことができます.os.Getenvは、環境変数を読み込むために使用されます.
package main

import (
  "fmt"
  "os"
)

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

高度な機能
自動ロード
プログラマーの優れた伝統--怠け者があれば、Loadの方法さえ自分で呼び出したくないかもしれません.大丈夫、godotenvはあなたに怠け者の権力をあげます!github.com/joho/godotenv/autoloadをインポートすると、構成が自動的に読み込まれます.
package main

import (
  "fmt"
  "os"

  _ "github.com/joho/godotenv/autoload"
)

func main() {
  fmt.Println("name: ", os.Getenv("name"))
  fmt.Println("age: ", os.Getenv("age"))
}

なお、コードにはgodotenvライブラリが明示的に使用されていないため、空のインポートを使用する必要があります.すなわち、インポート時にパケット名に_を追加する必要があります.autoloadパッケージのソースコードを見て、実はライブラリがLoadメソッドを呼び出したのです.
// src/github.com/joho/godotenv/autoload/autoload.go
package autoload

/*
    You can just read the .env file on import just by doing

        import _ "github.com/joho/godotenv/autoload"

    And bob's your mother's brother
*/

import "github.com/joho/godotenv"

func init() {
  godotenv.Load()
}

注釈をよく見ると、プログラマーの悪趣味!
カスタムファイルのロード
デフォルトでは、プロジェクトルートディレクトリの.envファイルがロードされます.もちろん、任意の名前のファイルをロードできます.ファイルも.envを接尾辞にする必要はありません.
package main

import (
  "fmt"
  "log"
  "os"

  "github.com/joho/godotenv"
)

func main() {
  err := godotenv.Load("common", "dev.env")
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println("name: ", os.Getenv("name"))
  fmt.Println("version: ", os.Getenv("version"))
  fmt.Println("database: ", os.Getenv("database"))
}
commonファイル内容:
name = awesome web
version = 0.0.1
dev.env :
database = sqlite
production.env :
database = mysql

自分で実行して結果を見ましょう.
注意:Loadは複数のファイル名をパラメータとして受信し、ファイル名が入力されない場合は.envファイルの内容をデフォルトで読み込みます.複数のファイルに同じキーがある場合は、先に表示された優先順位が、後で表示されたものは有効ではありません.だから、上から出力されたdatabaseは何ですか?
コメント.envファイルに注釈を追加することができ、注釈は、行が終了するまで#で開始する.
# app name
name = awesome web
# current version
version = 0.0.1

YAML .envファイルはYAML形式を使用することもできます.
name: awesome web
version: 0.0.1
package main

import (
  "fmt"
  "os"

  _ "github.com/joho/godotenv/autoload"
)

func main() {
  fmt.Println("name: ", os.Getenv("name"))
  fmt.Println("version: ", os.Getenv("version"))
}

環境変数を保存しないgodotenvは、.envファイルの内容を環境変数に保存しないことを許可し、godotenv.Read()を使用してmap[string]stringを返し、直接使用することができます.
package main

import (
  "fmt"
  "log"

  "github.com/joho/godotenv"
)

func main() {
  var myEnv map[string]string
  myEnv, err := godotenv.Read()
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println("name: ", myEnv["name"])
  fmt.Println("version: ", myEnv["version"])
}

ダイレクト操作map、シンプルダイレクト!
データソース
ファイルの読み取りに加えて、構成をio.Readerstringから読み込むこともできます.
package main

import (
  "fmt"
  "log"

  "github.com/joho/godotenv"
)

func main() {
  content := `
name: awesome web
version: 0.0.1
  `
  myEnv, err := godotenv.Unmarshal(content)
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println("name: ", myEnv["name"])
  fmt.Println("version: ", myEnv["version"])
}
io.Readerインタフェースを実現すれば、データソースとして使用できます.ファイル(os.File)、ネットワーク(net.Conn)、bytes.Bufferなど多くのソースから読み取ることができます.
package main

import (
    "bytes"
    "fmt"
    "log"
    "os"

    "github.com/joho/godotenv"
)

func main() {
  file, _ := os.OpenFile(".env", os.O_RDONLY, 0666)
  myEnv, err := godotenv.Parse(file)
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println("name: ", myEnv["name"])
  fmt.Println("version: ", myEnv["version"])

  buf := &bytes.Buffer{}
  buf.WriteString("name: awesome web @buffer")
  buf.Write([]byte{'
'}) buf.WriteString("version: 0.0.1") myEnv, err = godotenv.Parse(buf) if err != nil { log.Fatal(err) } fmt.Println("name: ", myEnv["name"]) fmt.Println("version: ", myEnv["version"]) }

なお、文字列から読み取る方法とio.Readerから読み取る方法は異なる.前者はUnmarshal、後者はParseである..envファイルの生成
プログラムによって.envファイルの内容を生成することができ、直接ファイルに書き込むことができます.
package main

import (
  "bytes"
  "log"

  "github.com/joho/godotenv"
)

func main() {
  buf := &bytes.Buffer{}
  buf.WriteString("name = awesome web")
  buf.WriteByte('
') buf.WriteString("version = 0.0.1") env, err := godotenv.Parse(buf) if err != nil { log.Fatal(err) } err = godotenv.Write(env, "./.env") if err != nil { log.Fatal(err) } }

生成された.envファイルを表示します.
name="awesome web"
version="0.0.1"

文字列を返すこともできます.
package main

import (
  "bytes"
  "fmt"
  "log"

  "github.com/joho/godotenv"
)

func main() {
  buf := &bytes.Buffer{}
  buf.WriteString("name = awesome web")
  buf.WriteByte('
') buf.WriteString("version = 0.0.1") env, err := godotenv.Parse(buf) if err != nil { log.Fatal(err) } content, err := godotenv.Marshal(env) if err != nil { log.Fatal(err) } fmt.Println(content) }

コマンドラインモードgodotenvは、コマンドラインのモードも提供する.
$ godotenv -f ./.env command args
go getgodotenvがインストールされている間に、godotenvはすでに$GOPATH/binディレクトリにインストールされていました.私は$GOPATH/binをシステムPATHに追加することに慣れているので、godotenvコマンドは直接使用できます.
コマンドラインモードとは、指定ファイルを読み出し(-fで指定しない場合は.envファイルを使用)、環境変数を設定し、その後のプログラムを実行することである.
簡単にプログラムを書いて検証します.
package main

import (
  "fmt"
  "os"
)

func main() {
  fmt.Println(os.Getenv("name"))
  fmt.Println(os.Getenv("version"))
}
godotenvを使用して実行します.
$ godotenv -f ./.env go run main.go

出力:
awesome web
0.0.1

複数の環境
実際には、APP_ENV環境変数の値に基づいて異なるファイルがロードされます.
package main

import (
    "fmt"
    "log"
    "os"

    "github.com/joho/godotenv"
)

func main() {
    env := os.Getenv("GODAILYLIB_ENV")
    if env == "" {
        env = "development"
    }

    err := godotenv.Load(".env." + env)
    if err != nil {
        log.Fatal(err)
    }

    err = godotenv.Load()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("name: ", os.Getenv("name"))
    fmt.Println("version: ", os.Getenv("version"))
    fmt.Println("database: ", os.Getenv("database"))
}

環境変数GODAILYLIB_ENVを読み込み、対応する.env.+envを読み込み、デフォルトの.envファイルを読み込みます.
前述したように、先に読み取った優先順位.開発/テスト/本番環境で変更が必要な場合は、対応する.envファイルでもう一度構成すれば、デフォルトの.env.development/.env.test/.env.productionファイルで基礎情報とデフォルトの値を構成できます..envファイル内容:
name = awesome web
version = 0.0.1
database = file
.env.development :
database = sqlite3
.env.production :
database = mysql

プログラムの実行:
#        
$ go run main.go
name:  awesome web
version:  0.0.1
database:  sqlite3

#        
$ GODAILYLIB_ENV=production go run main.go
name:  awesome web
version:  0.0.1
database:  mysql

一点のソースgodotenvファイルの内容を読み取り、os.Getenvを使用してアクセスできる理由:
// src/github.com/joho/godotenv/godotenv.go
func loadFile(filename string, overload bool) error {
    envMap, err := readFile(filename)
    if err != nil {
        return err
    }

    currentEnv := map[string]bool{}
    rawEnv := os.Environ()
    for _, rawEnvLine := range rawEnv {
        key := strings.Split(rawEnvLine, "=")[0]
        currentEnv[key] = true
    }

    for key, value := range envMap {
        if !currentEnv[key] || overload {
            os.Setenv(key, value)
        }
    }

    return nil
}
godotenvos.Setenvを呼び出してキー値ペアを環境変数に設定したからです.
まとめgodotenvライブラリの基礎と高度な使い方を紹介しました.godotenvのソースコードも比較的読みやすく、時間があり、興味のある子供靴は見てみることをお勧めします~
リファレンス
  • godotenv GitHub倉庫:https://github.com/joho/godotenv
  • わたし
    私のブログ
    私の微信の公衆番号【GoUpUp】に注目することを歓迎して、共に勉強して、いっしょに進歩します~
    本文はブログの1文の多発プラットフォームから
    OpenWriteリリース!