개요

go workspace에 대해서 좀 더 자세히 알아보고 케이스 별로 어떻게 사용하고 관리하는 것이 좋을지에 대해서 알아보겠습니다.

go.work.sum

이전 포스팅에서 한번 언급을 했는데 go work sync 명령어를 이용하면 go.work.sum 파일이 생성됩니다. 이 파일은 현재 workspace에 있는 모듈들의 정보를 가지고 있습니다. 이 파일을 통해서 현재 workspace에 있는 모듈들을 관리하고, 의존성을 관리할 수 있습니다. 하지만 모든 경우에서 go.work.sum 파일이 생기는 것은 아닙니다.

go.work.sum 파일이 생성되는 경우

각 하위 폴더 하위에서 별도의 의존성을 관리하지 않을 때 go.work.sum 파일이 생성됩니다. 만약에 하위 모듈에서 각자 의존성을 관리하고 있다면 go.work.sum 파일이 생성되지 않습니다.

.
├── minus/
│   ├── minus.go
│   └── go.mod
├── plus/
│   ├── plus.go
│   └── go.mod
├── calculator/
│   ├── main.go
│   └── go.mod
├── go.work
└── go.work.sum

하지만 아래의 경우처럼 각 모듈별로 의존성을 관리하는 상황이라면 go.work.sum 파일을 생기지 않습니다.

.
├── minus/
│   ├── minus.go
│   ├── go.sum
│   └── go.mod
├── plus/
│   ├── plus.go
│   ├── go.sum
│   └── go.mod
├── calculator/
│   ├── main.go
│   ├── go.sum
│   └── go.mod
└── go.work

go.work.sum 파일의 역할

go.work.sum 파일은 각 모듈별로 가지고 있던 go.sum 파일을 하나로 합쳐서 관리하는 역할을 합니다. 이 파일을 통해서 모든 모듈의 의존성을 한 번에 관리할 수 있습니다. 하지만 go.work.sum 파일을 생성하는 것은 선택사항이기 때문에 모든 경우에서 생성되는 것은 아닙니다. 위에 언급했듯이 각 모듈별로 의존성을 관리하고 있다면 go.work.sum 파일은 생성되지 않습니다.

go workspace 유용성

위에처럼 각 모듈별로 의존성을 관리하고 있다면 go workspace를 사용하는 것이 큰 의미가 없다고 생각할 수 있지만 그렇지 않습니다. 버전 관리를 독립된 모듈에서 할 수 있게 보장하는 것이지 실제로 golang workspace를 선언함으로써 replace가 아니라 자연스럽게 모듈 간의 상호작용하는 기능을 도와주고 특히 통합 테스트를 하는 환경에서는 go workspace를 사용하는 것이 효율적입니다.

버전 충돌

workspce를 통해서 한 번에 모든 의존성을 관리한다면 버전 충돌에 대한 이슈가 없겠지만 위에 언급했듯이 각 모듈별로 독립성을 위해서 의존성을 각자 관리한다면 버전 충돌에 대한 이슈가 발생할 수 있습니다.

예를 들어서 아래와 같은 의존성이 있다고 가정해 보겠습니다.

  • A 모듈 : D 라이브러리를 1.4 버전을 사용 중
  • B 모듈 : D 라이브러리를 1.2 버전을 사용 중
  • C 모듈 : A, B 모듈을 워크스페이스를 통해서 사용 중

위에 경우에는 C 모듈에서 A 모듈과 B 모듈의 버전 충돌이 발생할 수 있습니다. Golang에서는 이런 경우에 MVS(Minimal Version Selection) 알고리즘을 통해서 버전 충돌을 해결합니다. MVS 알고리즘은 모듈의 의존성을 최소한으로 가져가는 알고리즘으로 의존성을 최소화하고 버전 충돌을 해결하는 알고리즘입니다.

이 경우에는 D 모듈은 MVS 알고리즘에 따라서 1.4 버전을 사용하게 됩니다.

선택한 버전은 보통은 이전 버전에 대한 호환성을 보장해야 하지만 그렇지 않은 경우에는 go.mod 파일에 replace 지시어를 통해서 버전을 변경할 수 있습니다.

정리

이번 포스팅에서는 go workspace에 대해서 좀 더 자세히 알아보았습니다. go workspace를 사용하면 모듈 간의 의존성을 관리하고, 통합 테스트를 하는 환경에서 효율적으로 사용할 수 있습니다. 각 모듈별로 의존성을 관리하는 상황에서도 go workspace는 이미가 있으며 버전 충돌에 대한 이슈가 발생할 수 있지만 Golang에서는 MVS 알고리즘을 통해서 버전 충돌을 해결할 수 있습니다. 혹여나 이전 버전에 대한 호환성을 보장하지 못하는 경우에는 replace 지시어를 사용해서 충돌을 해결할 수도 있습니다.