티스토리 뷰
개요
1) Go Modules Wiki 의 일부를 세세히 들여다보자
2) Local Module 이라는 표현이 적절한지는 모르겠으나
Go Modules 기능을 통해 Local Path 에 있는 Module 들을 import 하고 사용할 수 있도록 해보자
참고링크
- Golang Wiki: https://github.com/golang/go/wiki/Modules
- stackoverflow1: http://bit.ly/2VyG3Sr
(참고) Package 와 Module
Module 이 더 큰 개념이다.
관련이 있는 Go Package 들을 모아서 하나의 유닛처럼 버저닝 해주는 것이다.
사용된 각각의 Package 들의 정확한 버전정보들을 기록해 두기에 dependency 관리가 된다.
이번에는 Golang Wiki 의 다음 항목까지만을 따라가 보도록 한다.
Quick Start - Example
$ mkdir -p /tmp/scratchpad/hello |
폴더를 만들고, 들어간다 |
$ go mod init github.com/you/hello go: creating new go.mod: module github.com/you/hello |
$go mod init <모듈명> 을 실행하면 go.mod 파일이 만들어진다. 생성된 파일을 열어보면 module <모듈명> 밖에 없다.
|
$ cat <<EOF > hello.go import ( func main() { |
왼쪽과 같이 hello.go 라는 파일을 작성한다음 |
$ go build Hello, world. |
go build 를 실행하면 go.mod 가 바뀐다. |
$ cat go.mod module github.com/you/hello require rsc.io/quote v1.5.2 |
바로 hello.go 파일에서 import 한 package 가 require 로 들어가있다. |
Quick Start - Daily Workflow
일반적으로는 이렇게 할 것이다.
|
1) .go 에 사용하고픈 package 를 import 해준다.
2) go build 또는 go test 를 먹여주면, 1) 에서 추가한 package dependency 들이 반영됨 - go.mod 가 업데이트 되고 - 추가한 dependency 가 다운로드 된다.
3) 사용하고픈 package 의 정확한 버전이 있다면 - go get 에서 명시하거나 - go.mod 를 직접 edit 하면 된다. |
때때로 쓸만한 기능들은 다음과 같다.
|
빌드시 사용된 module 들의 버전을 확인할 수 있음
The -m flag causes list to list modules instead of packages. |
|
package 들의 minor, patch 가능여부를 확인
The -u flag adds information about available upgrades. When the latest version of a given module is newer than the current one, list -u sets the Module's Update field to information about the newer module. |
|
최신 버전으로 업데이트
The -u flag instructs get to use the network to update the named packages and their dependencies. By default, get uses the network to check out missing packages but does not use it to look for updates to existing packages. |
|
|
|
go.mod 에서 불필요한 것들을 잘라내고, 필요한 것들을 추가한다. 1) 더 이상 필요없는 dependency 들은 삭제 2) 다른 OS, Architecture, Build tag 등을 위해 필요한 것들을 추가 |
|
|
|
|
New Concepts - Modules
모듈은 관련한 패키지들을 모아놓은 것이고, 그 전체를 하나의 유닛으로 버전관리한다.
이를 통해 모듈에 필요한 패키지들의 정확한 버전을 알 수 있다.
여러 모듈을 하나의 repository 에 관리할 수도 있으나, 하나의 저장소에 하나의 모듈을 관리하는 것을 원칙으로 한다.
Repository, Module, Package 의 관계
1) Repository 는 하나 이상의 Go Module 을 가진다.
2) Module 은 하나 이상의 Go Package 를 가진다.
3) Package 는 하나의 directory 안에, 하나 이상의 Go source file 을 가진다.
버전명은 3부분으로 구성된다.
- 기준: https://semver.org/
- v(major).(minor).(patch)
New Concepts - go.mod
1) 모듈은 Go source file 들로 이루어진 트리구조의 디렉토리라 보면 되고
2) 그 트리의 root 에 go.mod 가 있다.
네 가지 directive 가 있다. module, require, replace, exclude
exclude 와 replace 는 현재의 module 에 대해서만 적용이 된다.
예시를 통해서 알아보자.
module github.com/my/thing
require ( |
go.mod 파일이다.
1) 모듈명은 github.com/my/thing 이다. - 이때 module 이 사용되며 module 의 path 를 정의한다.
2) 이때 import 되는 package 들은 이 module path (여기서는 github.com/my/thing) 을 - common prefix 로 공유한다. - 이 둘의 조합으로 package 의 import path 를 결정한다. |
|
좀더 구체적 예를 들어보자.
1) 모듈을 만든다고 하자. 모듈명은 github.com/my/repo 이다.
2) 이 모듈은 두 개의 package 를 가지고 있다. - github.com/my/repo/foo - github.com/my/repo/bar
3) 이 경우에 왼쪽과 같은 디렉토리 구조를 가지게 된다.
4) 이제 누군가가 bar package 만 import 하고 싶다면 - import "github.com/my/repo/bar" 라고 하면 된다. |
When should I use the replace directive?
FAQ 항목의 일부만 추려내어 본다.
The replace directive allows you to supply another import path that might be another module located in VCS (GitHub or elsewhere), or on your local filesystem with a relative or absolute file path. The new import path from the replace directive is used without needing to update the import paths in the actual source code. |
또다른 import path 를 제공할 수 있도록 해준다. - GitHub 등의 인터넷 상의 path 이거나 - local file system 상의 path 이거나. |
One sample use case is if you need to fix or investigate something in a dependency, you can have a local fork and add the something like the following in your top-level go.mod:
|
내가 fork 한 package 의 path 로 redirect 해서 테스트 해볼 수도 있고 |
replace also allows the top-level module control over the exact version used for a dependency, such as:
|
좀더 정확한 버전을 명시하는데 쓸 수도 있다.
|
replace also can be used to inform the go tooling of the relative or absolute on-disk location of modules in a multi-module project, such as:
|
위에 언급했던대로 local file system 로 보낼 수도 있다. |
In general, you have the option of specifying a version to the left of the => in a replace directive, but typically it is less sensitive to change if you omit that (e.g., as done in all of the replace examples above). |
|
Note: for direct dependencies, a require directive is needed even when doing a replace. For example, if foo is a direct dependency, you cannot do replace foo => ../foo without a corresponding require for foo. (If you are not sure what version to use in the require directive, you can often use v0.0.0 such as require foo v0.0.0; see #26241). |
direct dependency 의 경우에는
replace 를 쓸때에도 require 는 써줘야 한다. 버전을 잘 모르겠을때는 v0.0.0 을 먹여주면 된다. |
Can I work entirely outside of VCS on my local filesystem?
FAQ 항목의 일부만 추려내어 본다.
If you want to have multiple inter-related modules on your local disk that you want to edit at the same time, then replace directives are one approach. Here is a sample go.mod that uses a replace with a relative path to point the hello module at the on-disk location of the goodbye module (without relying on any VCS): |
여러 개의 관련있는 모듈들이 local file system 에 있을때에 replace 를 사용해볼 수 있겠다.
아래 예제를 보자. |
module example.com/me/hello
require example.com/me/goodbye v0.0.0 replace example.com/me/goodbye => ../goodbye |
hello 모듈의 go.mod 파일이다.
1) Go source file 에서는 - import "example.com/me/goodbye" 라고 되어 있었을 거고 2) 이걸 replace 를 통해 relative path 인 ../goodbye를 가리키게 한다.
|
As shown in this example, if outside of VCS you can use v0.0.0 as the version in the requiredirective. Note that as mentioned in the prior FAQ, the require directive is needed here. (replace example.com/me/goodbye => ../goodbye does not yet work without a corresponding require example.com/me/goodbye v0.0.0; this might change in the future with #26241). |
1) 버전으로 v0.0.0 을 쓸 수 있다. 2) replace 만으로는 안되고 쌍이 되는 require 가 필요하다. |
실전 예제
- 링크: http://bit.ly/2VyQUf9
|
1) /tmp/playground 라는 폴더가 있고 2) 서브 폴더로 hello, goodbye 가 있으며 3) 각각 go.mod 와 hello.go, goodbye.go 가 있다. |
|
hello 폴더의 go.mod 를 보면
이놈의 모듈명을 example.com/me/hello 라고 해둔걸 알 수 있다. - hello.go 의 package main 뒤에 코멘트로 // import "example.com/me/hello" 라고 해두고 $go mod init 을 치거나 - $go mod init example.com/me/hello 라고 명령하면 이렇게 생성된다.
그리고 require 와 replace 를 이용하여 example.com/me/goodbye 를 import 하기 위한 작업을 해두었다. |
|
실제 hello.go 파일을 보면
import "example.com/me/goodbye:" 라고 import 하고 있다.
goodbye 의 go.mod 에는 모듈명이 module example.com/me/goodbye 라고 되어 있다. |
|
실제 실행결과는 왼쪽과 같다. |
'golang' 카테고리의 다른 글
Dynamic Programming (0) | 2019.05.22 |
---|---|
Go Modules - Local Modules 실전 (1) | 2019.04.10 |
Slack slash command: Verifying requests from Slack: code (0) | 2019.02.25 |
Slack slash command: Verifying requests from Slack (0) | 2019.02.19 |
Golang Channel 의 자명한 이치 (Axioms) (0) | 2019.02.18 |
- Total
- Today
- Yesterday
- strange
- OpenAI
- 노션
- bun
- 독서
- API
- agile
- Gin
- 2023
- notion
- github
- 인텔리제이
- 제이펍
- postgres
- intellij
- websocket
- 체호프
- solid
- JIRA
- Shortcut
- Bug
- 독서후기
- 영화
- golang
- 잡학툰
- 클린 애자일
- ChatGPT
- folklore
- pool
- go
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |