Go로 간단한 프로젝트를 하려고 보니 처음 신경 쓰이는 건 의존성 관리를 어떻게 하는가였다. PackageManagementTools 문서에 패키지 관리 도구가 정리되어 있다.
dep, is an official experiment for the dependency tool. It is currently being implemented, in pre-alpha state and should be used with caution as "Lots of functionality is knowingly missing or broken".
여러 도구가 있지만 dep을 공식 의존성 관리 도구로 언급하고 있다. 아직 실험적으로 구현 중이지만 공식이라고 하니 그냥 dep을 쓰기로 했다. dep 저장소를 보면 프로덕션에서 사용해도 문제없다고 하니(dep is safe for production use.)아직 Go로 뭔가 큰 걸 만들 건 아니지만 써도 괜찮을 것 같다.
dep 설치
dpe은 go 1.8 이상의 버전이 필요하다고 한다. 현재 최신 버전이 1.10이니 나한테는 영향은 없을 것 같다. go get
으로 설치해도 되지만(go get -u github.com/golang/dep/cmd/dep
) 소스 파일까지는 필요 없을 것 같아서 저장소에 안내된 대로 Homebrew로 설치했다.
$ brew install dep
==> Installing dependencies for dep: go
==> Installing dep dependency: go
==> Downloading https://homebrew.bintray.com/bottles/go-1.10.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring go-1.10.high_sierra.bottle.tar.gz
==> Caveats
A valid GOPATH is required to use the `go get` command.
If $GOPATH is not specified, $HOME/go will be used by default:
https://golang.org/doc/code.html#GOPATH
You may wish to add the GOROOT-based install location to your PATH:
export PATH=$PATH:/usr/local/opt/go/libexec/bin
==> Summary
/usr/local/Cellar/go/1.10: 8,150 files, 336.9MB
==> Installing dep
==> Downloading https://homebrew.bintray.com/bottles/dep-0.4.1_1.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring dep-0.4.1_1.high_sierra.bottle.tar.gz
/usr/local/Cellar/dep/0.4.1_1: 7 files, 8.8MB
dep
으로 버전을 출력해 볼 수 있으면 잘 설치된 것이다.
$ dep version
dep:
version : v0.4.1
build date : 2018-01-27
git hash : 37d9ea0
go version : go1.9.3
go compiler : gc
platform : darwin/amd64
새 버전으로 업그레이드하려면 brew upgrade dep
명령어를 사용하면 된다.
dep으로 의존성 관리하기
go get
이 이미 있고 goimports
등을 사용하려고 tools를 설치할 때는 go get
으로 설치했다. go get
으로 설치하면 $GOPATH/src
아래 소스코드가 들어가는데 이 아래 있으면 로컬에서 import
로 불러서 사용할 수 있으므로 go get
으로 의존성을 설치해서 사용할 수도 있다.(Go 개발자들이 정확히 어떻게 쓰는지는 아직 잘 모르지만...)
하지만 소스 코드에 import
구문이 있다고 하더라도 go get
으로 설치해서 사용하면 본인은 괜찮지만 다른 사람은 의존성을 일일이 찾아서 설치해야 해서 협업하기만 어려우므로 프로젝트의 의존성은 dep
같은 도구가 적합하다고 생각한다.
새 프로젝트에서 dep으로 의존성을 관리하는 방법은 dep 문서에 잘 나와 잇다. 처음에 dep
으로 의존성을 관리하려면 초기화를 해야 한다.
$ dep init
초기화를 하면 아래처럼 2개의 파일과 1개의 디렉터리가 생성된다.
├── Gopkg.lock
├── Gopkg.toml
└── vendor/
Gopkg.toml
Gopkg.toml
은 초기화할 때 생성되는 파일로 dep
의 동작을 감시하는 여러 규칙을 담고 있다고 한다.
- 의존성 규칙:
constraints
,overrides
로 사용자가 적용할 의존성의 버전과 어디서 가져와야 하는지를 지정한다. - 패키지 그래프 규칙:
required
,ignored
로 임포트 경로를 추가하거나 제외해서 임포트 그래프를 조작할 수 있다. metadata
: 사용자가 정의한 키-값의 맵으로 dep은 무시할 것이다.prune
: 어떤 파일과 디렉터리가 불필요하다고 판단할지 설정해서vendor/
에서 자동으로 제거한다.
아래는 dep init
했을 때 생긴 Gopkg.toml
의 내용이다.
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
[prune]
go-tests = true
unused-packages = true
Gopkg.lock
프로젝트의 의존성 그래프의 스냅숏을 가진 파일이다. 이 파일은 dep ensure
할 때 변경된다.
아래는 생성된 Gopkg.lock
파일의 내용이다.
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "ab4fef131ee828e96ba67d31a7d690bd5f2f42040c6766b1b12fe856f87e0ff7"
solver-name = "gps-cdcl"
solver-version = 1
의존성 추가
웹 프레임워크로 gin을 사용하기 위해 dep ensure
로 의존성을 추가해 보자. ensure
가 프로젝트에 의존성을 설치하는 명령어고 새로운 의존성을 추가하려면 dep ensure -add
를 사용해야 한다.
$ dep ensure -add github.com/gin-gonic/gin
no dirs contained any Go code
현재는 Go 코드를 전혀 작성하지 않아서 오류가 난다. 여기선 Go 코드는 중요하지 않으므로 다음 내용으로 main.go
파일을 만들자.
package main
다시 gin
을 추가해 보자.
$ dep ensure -add github.com/gin-gonic/gin
Fetching sources...
"github.com/gin-gonic/gin" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/.
If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/.
아까와 달리 추가되었다. 안내 문구를 보면 아직 github.com/gin-gonic/gin
를 아직 임포트 한 곳이 없어서 Gopkg.lock
와 vender/
에는 추가되었지만 임포트하지 않고 dep ensure
를 실행하면 지워질 것이라고 한다.
Gopkg.toml
파일을 보면 하단에 gin
이 추가된 것을 볼 수 있다.
[[constraint]]
name = "github.com/gin-gonic/gin"
version = "1.2.0"
Gopkg.lock
파일은 아래처럼 의존성의 자세한 정보가 추가되고 [solve-meta]
의 inputs-digest
정보가 변경되게 된다.
[[projects]]
name = "github.com/gin-gonic/gin"
packages = [
".",
"binding",
"render"
]
revision = "d459835d2b077e44f7c9b453505ee29881d5d12d"
version = "v1.2"
dep 관련 파일 버전 관리
위에서 보았듯이 dep이 생성한 파일은 Gopkg.toml
, Gopkg.lock
와 vender
디렉터리다. 좀 찾아봤는데 Gopkg.toml
, Gopkg.lock
는 둘 다 커밋하는 것 같다. Gopkg.lock
가 꼭 필요한지는 확인 안해 봤지만 npm
을 생각해 보면 package-lock.json
과 같은 역할을 하는 거로 보인다. 내 취향으로는 프로덕션에서 서비스하기 전까지는 lock 파일을 저장소에서 관리하는 편은 아니지만 요즘 추세는 lock 파일도 보통 넣는 것 같고 해서 dep에서도 두 파일을 모두 Git에 넣기로 했다.
vender
디렉터리의 경우 딱 봐도 Git에서 관리할 필요가 없어 보이는데 dep의 FAQ 문서를 보면 이 디렉터리를 커밋해서 관리할 때의 장단점이 나와 있다. 말이 장단점이지 그냥 의존성 파일을 다 저장소에 관리할지 말지의 얘기라서 관례대로 나는 vender
디렉터리는 git에서 제외했다.
의존성 설치
프로젝트를 협업하는 경우 Gopkg.toml
, Gopkg.lock
를 가진 저장소를 받아서 의존성을 설치해서 개발해야 한다.
$ dep ensure
이때는 dep ensure
만 실행해야 한다. 참고로 여기서는 dep
만 설명하고 있지만, 앞에서 살펴본 대로 go 소스코드에서 import "github.com/gin-gonic/gin"
처럼 임포트하고 있지 않다면 이 의존성이 지워지게 된다.
옆 사무실 케이독 입니다 좋은 글 잘 보고 갑니다 :D
옆 사무실 케이독 입니다 좋은 글 잘 보고 갑니다 :D
앗 안녕하세요. 여기서도 뵙네요.