Skip to content

Latest commit

 

History

History
189 lines (147 loc) · 5.04 KB

package_viper.md

File metadata and controls

189 lines (147 loc) · 5.04 KB

Package Viper

viper

환경 설정 파일들을 다루기 위해 Viper Package 를 사용한다.

Table of Contents

viper Basic

viper 은 유명한 configuration 패키지로써 많은 Go 프로젝트들 내에서 사용되었다.

  • Hugo : 정적 사이트 생성기

  • Notary : Docker 이미지 위변조 방지 툴

  • RexRay : Docker 와 Mesos 의 Container 스토리지 오케스트레이션 엔진

    viper-project

env variable

환경 변수는 실행 환경 정보의 값을 지니고 있다.
Go 에서 env variable 을 관리하기 위해 자주 사용되는 패키지들은 세가지가 있다.

  1. os package
  2. godotenv package
  3. viper package

이 중 viper package 에 대해 알아보자.

Install

go get github.com/spf13/viper

기본 사용법

Instance
viper 인스턴스 생성하기
viper.New()

Set File & Path
config 파일과 경로를 설정하기 위해서 SetConfigFile 이라는 메서드를 사용한다.
viper.SetConfigFile(".env")

  • Viper 는 env 파일 외에 다양한 파일들을 지원한다.
    • HCL
    • TOML
    • JSON
    • YAML
    • etc..

Read Config File
viper 에서 config 파일을 읽어들이는 메서드는 두 가지가 있다.

  1. ReadConfig()

    • yaml
    • json
  2. ReadInConfig()

    • byte buffer

↑ return to TOC

viper 코드 열어보기

viper.ReadConfig

Configuration 파일을 읽어들인다.

func (v *Viper) ReadConfig(in io.Reader) error {
    v.config = make(map[string]interface{})
    return v.unmarshalReader(in, v.config)
}
  • key 가 파일내에 존재하지 않을 때 해당 key 는 nil 값으로 설정된다.

↑ return to TOC

viper.ReadInConfig

미리 설정해둔 경로로 가서 디스크나 키-값 스토리지에 있는 config 파일을 찾아 읽어들인다.

  • 설정된 경로의 예)
    viper.AddConfigPath(currentdir())
func (v *Viper) ReadInConfig() error {
	jww.INFO.Println("Attempting to read in config file")
	filename, err := v.getConfigFile()
	if err != nil {
		return err
	}

	if !stringInSlice(v.getConfigType(), SupportedExts) {
		return UnsupportedConfigError(v.getConfigType())
	}

	jww.DEBUG.Println("Reading file: ", filename)
	file, err := afero.ReadFile(v.fs, filename)
	if err != nil {
		return err
	}

	config := make(map[string]interface{})

	err = v.unmarshalReader(bytes.NewReader(file), config)
	if err != nil {
		return err
	}

	v.config = config
	return nil
}

↑ return to TOC

viper.WriteConfig

현재의 viper configuration 을 파일에 쓴다. 파일이 작성되는 위치는 미리 지정해둔 경로이다.
만약 경로가 설정되 있지 않다면 err 를 리턴한다.

func (v *Viper) WriteConfig() error {
	filename, err := v.getConfigFile()
	if err != nil {
		return err
	}
	return v.writeConfig(filename, true)
}

↑ return to TOC

viper.SafeWriteConfig

SafeWriteConfig 는 해당 경로에 config 파일이 존재하지 않을시에만 파일을 작성한다.
그로인해 덮어쓰기가 발생하지 않는다. 안전한 파일 작성이 가능하다.

func (v *Viper) SafeWriteConfig() error {
	if len(v.configPaths) < 1 {
		return errors.New("missing configuration for 'configPath'")
	}
	return v.SafeWriteConfigAs(filepath.Join(v.configPaths[0], v.configName+"."+v.configType))
}

↑ return to TOC

viper.Set

Set을 통해 직접 config 의 key 와 value 를 설정

func (v *Viper) Set(key string, value interface{}) {
	key = v.realKey(strings.ToLower(key))
	value = toCaseInsensitiveValue(value)

	path := strings.Split(key, v.keyDelim)
	lastKey := strings.ToLower(path[len(path)-1])
	deepestMap := deepSearch(v.override, path[0:len(path)-1])

	deepestMap[lastKey] = value
}
  • Key 는 case-insensitive

↑ return to TOC

viper.MergeInConfig

새 config 파일과 기존에 존재하는 config 파일을 합병시킨다.

func (v *Viper) MergeInConfig() error {
	jww.INFO.Println("Attempting to merge in config file")
	filename, err := v.getConfigFile()
	if err != nil {
		return err
	}

	if !stringInSlice(v.getConfigType(), SupportedExts) {
		return UnsupportedConfigError(v.getConfigType())
	}

	file, err := afero.ReadFile(v.fs, filename)
	if err != nil {
		return err
	}

	return v.MergeConfig(bytes.NewReader(file))
}

↑ return to TOC