golang 에서의 패키지 관리

go lang에서는 패키지 관리가 까다롭다. 제일 큰 문제가 되는것은 version pinnig을 지원할 수단이 적다는 것인데, 이때문에 수많은 관리 툴들이 난무한다.

개인적으로는 golang 에서 vendor 폴더를 version pinning 용도로 사용하는데, git 에서 submodule 로 관리하면 딱 들어 맞는 형식이다. 다만 git submodule은 디자인이 딱 실수 하기 좋게끔 짜여져 있다는 것이 문제이다. 또한 go get 은 git 뿐만아니라 다른 저장소도 사용할수 있는데, submodule은 git에 디펜던시가 존재한다.

그나마 가장 괜찮은 툴은 glide 같은 툴이다. 추가적인 파일에 패키지 버전 정보를 기록한다음 명령어 한번으로 vendor 폴더에 인스톨 하게끔 한다1. 이 방식이 가장 네이티브에 가까운 방식이라고 할수 있겠다.

Vendor

vendor folder 를 제대로 쓰기 위해서는 반드시 gopath 내부여야 한다.(1.7.5 에서 확인) https://github.com/golang/go/issues/14566

vendor 시에 가장 큰문제는 vendor folder 안에 있는 type이 패키지를 넘어다닐경우 type mismatch 가 날수 있다는 것이다. 이것은 일종의 버그 인데 이미 보고는 되어 있으나 훨씬 나중에야 고쳐질듯 하다. https://github.com/golang/go/issues/18827

vendoring안에 있는 type은 한 패키지 이상에서 쓰지 않도록 주의하거나, type alias를 활용해서 회피할수 있다.

예를 들면 다음과 같이 작성하고

// datatypes/datatypes.go

package datatypes

import "github.com/moby/moby/daemon/logger"

// because vendor issue, https://github.com/golang/go/issues/18827

type Info = logger.Info
type Capability = logger.Capability
type ReadConfig = logger.ReadConfig

이 타입을 사용할떄 github.com/moby/moby/daemon/logger을 import 하여 사용하는 대신 datatypes 패키지(내가만든)를 사용하여 사용하면 이 타입에러가 발생하지 않게 된다.


  1. 마치 npm을 연상케 한다.