나는 Go 프로젝트를 전부 Linux 에서 터미널로 붙어서 vim 으로 개발한다. 재작년부터 크고 작게 사용하던 모듈들이 있었는데, 당시만 해도 Go 자체의 표준 패키지 매니저가 확정이 안되서 기본 프로젝트 레이아웃에 맞게 $GOPATH/src 하위에서 사용했었다. 그리고 사실 그 방식에 꽤나 적응해서 다른 프로젝트들도 $GOPATH/src 하위에 두어서 사용했고, 지금까지도 꽤나 만족한다.

재작년 당시 Go 커뮤니티에서 사용하는 가장 많이 사용되던 패키지 매니저 중에 glide 가 있었고, 뒤이어 dep 도 나왔었지만 표준이 아니었을뿐더러 모든 사내 Go 프로젝트를 내가 홀로 개발해서 😢 나는 굳이 적용을 안 시키고 있었다 (어차피 빌드 배포도 내가 하니까… 😭).

그러다 작년 어느 시점에 표준 패키지 매니저 시스템인 Go Module의 전신인 vgo 가 등장했다. go 1.10 에서 파생되서 별도의 프로젝트가 나왔었던 것으로 기억한다. 눈여겨 보고 있었고, go 1.11 이 릴리즈 되자 go 자체에 정식으로 합쳐서 나왔었다. 근데 GOPATH 경로 내부에 있는 프로젝트는 적용이 안된다는 것이다! 자세한 글은 Go Blog - Using Go Modules 를 읽어보면 확인할 수 있다.

As of Go 1.11, the go command enables the use of modules when the current directory or any parent directory has a go.mod, provided the directory is outside $GOPATH/src. ( Inside $GOPATH/src, for compatibility, the go command still runs in the old GOPATH mode, even if a go.mod is found. See the go command documentation for details.) Starting in Go 1.13, module mode will be the default for all development.

결국 기존에 GOPATH 기반으로 만들어놓은 프로젝트는 그냥 계속 두었다. 버전 1.13 까지… 그리고 올해 초, 드디어 go 1.13 이 릴리즈 되었다! 🎉

Go Blog - Go 1.13 is released

그래서 이번 기회에 트렌드에 맞게 GOPATH 기반 프로젝트들을 Go Module 기반으로 업데이트 하게 되었다. 신규 개발자에게 Go 도 시키려고 했고 말이다 😄😆


사내 시스템으로 Gitea 를 구축해놓았기에 Gitea 를 기준으로 작성한다.

1. go.mod 파일 생성

kesuskim@local:~/dev/go/src/git.kesuskim.com/project-groups/project$ go mod init
go: creating new go.mod: module git.kesuskim.com/project-groups/project

2. private repo 연결

2-1. git 설정

Go Module 에서는 기본적으로 git 을 이용하여 https 로 clone 을 시도하기 때문에, private repo 를 연결하기 위해서는 우리가 git 설정을 수정해주어야한다.

아마 Windows 의 경우에는 한 번 이상 해당 repo에 접근한 적이 있다면 Windows 자체의 Credential Manager 에서 처리가 될 것으로 생각한다. 확실하지는 않음. 아래는 Linux / macOS 에 해당하는 방법!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# $HOME/.gitconfig

# SSH 로 연결할 경우
[url "ssh://[email protected]:"]
  insteadOf = https://git.kesuskim.com

# HTTPS 로 연결할 경우; Personal Access Token
[url "https://[email protected]"]
  insteadOf = https://git.kesuskim.com

# HTTPS 로 연결할 경우; Basic Authentication
[url "https://username:[email protected]"]
  insteadOf = https://git.kesuskim.com

Personal Access Token 은 Gitea 의 경우에 https://<GITEA-URL>/user/settings/applications 경로에 존재하고, Github은 Settings/Developer settings/Personal access tokens 에 있다.

Gitea Personal Access Token

Github Personal Access Token

2-2. GOPRIVATE 환경변수 지정

private repo 로 사용하는 Go repository 들의 목록을 GOPRIVATE 환경변수에 지정한다. 아래처럼 go env -w 을 써도 되고, bashrc 에 등록하거나 .profile 에 등록해도 된다.

kesuskim@local:~/dev/go/src/git.kesuskim.com/project-groups/project$ go env -w GOPRIVATE=git.kesuskim.com/go-projects/*,git.kesuskim.com/external-projects/*

csv 형태로 환경변수를 지정해주면, 해당 경로들은 public 하게 checksum 체크를 따로 하지 않고 Go 커맨드라인에서 직접 접근한다 (관련 링크).

특이하게도 여기서는 Shell 스타일의 Glob 을 따른다 (다른 go cmd 에서는 … 쓰면서! 관련 Russ Cox comment)

3. vendor/ 디렉토리 다운로드 받기 [Optional]

vendor 디렉토리도 같이 git 으로 관리해서 이후 개발자가 환경설정에 덜 고통스럽도록 하고자 mod 에 등록된 패키지를 받을 수 있다.

kesuskim@local:~/dev/go/src/git.kesuskim.com/project-groups/project$ go mod vendor
go: downloading github.com/lib/pq v1.2.0
go: downloading github.com/joho/godotenv v1.3.0
go: downloading gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
go: downloading github.com/pkg/errors v0.8.1
go: downloading golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
go: downloading git.kesuskim.com/project-groups/project v0.0.0-20190801023312-0203d097ae63
go: downloading github.com/CloudyKit/jet v2.1.2+incompatible
go: downloading git.kesuskim.com/go-projects/go-logger v0.0.0-20190521054713-276faa66e7b6
go: extracting git.kesuskim.com/go-projects/go-logger v0.0.0-20190521054713-276faa66e7b6
go: downloading gopkg.in/go-playground/validator.v9 v9.29.1
go: extracting git.kesuskim.com/project-groups/project v0.0.0-20190801023312-0203d097ae63
go: downloading github.com/go-redis/redis v6.15.5+incompatible
go: downloading gopkg.in/natefinch/lumberjack.v2 v2.0.0
go: extracting gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
go: extracting github.com/lib/pq v1.2.0
...

kesuskim@local:~/dev/go/src/git.kesuskim.com/project-groups/project$ git add vendor/
kesuskim@local:~/dev/go/src/git.kesuskim.com/project-groups/project$ git commit -m "add vendor directory"


etc. GOPROXY

Go 1.13 부터는 GOPROXY 라는 개념을 기본적으로 사용한다고 한다. 뭔가 하니 Go 패키지들의 CDN 같은 개념. 이전에는 Github 에서 직접 받아왔다면, 이제는 GOPROXY 에서 먼저 받아온다는 것. GOPRIVATE 환경변수처럼 GOPROXY 환경변수에 설정된 값을 csv 형태로, direct (직접 접근; 대개 Github) 를 fallback 으로 붙어있다.

kesuskim@local:~/dev/go/src/git.kesuskim.com/project-groups/project$ go env | grep GOPROXY
GOPROXY="https://proxy.golang.org,direct"

https://proxy.golang.org 는 Google 에서 운영하는 Global Go Proxy 서버로, 들어가보면 간략하게 설명이 나와있다.

좀 찾아보니 직접 사설 Go Proxy 서버를 운영할 수도 있는 것 같다.

https://goproxy.io

굳이 아직은 필요 없어서 해보진 않았지만, https://github.com/goproxyio/goproxy 의 바이너리를 동작시킨 후에 GOPROXY 환경변수를 설정하면 private npm 을 운영하는 것 마냥 private Go Proxy 서버를 운영할 수 있을 것으로 보인다.