Leon's Blogging

Coding blogging for hackers.

Golang - Module

| Comments

go module 是 1.11 版本出的新功能,先介紹之前使用套件的方式

先下載一個套件

1
2
3
go get -u github.com/appleboy/com/random
// -u 如果檔案已經存在,有更新的話就會更新
// 下載後會存在 $GOPATH/src/github.com/appleboy/com/random

新增檔案 $GOPATH/src/testgomod/main.go

1
2
3
4
5
6
7
8
9
10
11
12
// $GOPATH/src/testgomod/main.go
package main

import (
  "fmt"

  "github.com/appleboy/com/random"
)

func main() {
  fmt.Println(random.String(10))
}

問題

  • 套件無法分版本,因為都是 $GOPATH/src/github.com/appleboy/com/random
  • 專案必須要在 $GOPATH 底下才的 work

govendor

以前都是用 govendor 套件來處理

1
go get -u github.com/kardianos/govendor

在原本的專案底下執行 govendor init

1
2
3
4
5
// 會出現新的 vendor 資料夾
.
├── main.go
└── vendor
    └── vendor.json

在執行 govendor fetch github.com/appleboy/com/random

1
2
3
4
5
6
7
8
9
10
11
12
// 後面可以加上版號 govendor fetch github.com/appleboy/com/random@1.0
// 會產生對應的檔案在 vendor 裡面
.
├── main.go
└── vendor
    ├── github.com
       └── appleboy
           └── com
               ├── LICENSE
               └── random
                   └── random.go
    └── vendor.json

套件相關資訊都會記錄在 vendor.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// $GOPATH/src/testgomod/vendor/vendor.json

{
  "comment": "",
  "ignore": "test",
  "package": [
      {
          "checksumSHA1": "ZPkL/ha7+FVjS65ZmmlDGH8d12A=",
          "path": "github.com/appleboy/com/random",
          "revision": "c0b5901f9622d5256343198ed54af65af5d08cff",
          "revisionTime": "2018-04-10T03:06:38Z"
      }
  ],
  "rootPath": "testgomod"
}

問題

  • 專案必須要在 $GOPATH 底下才的 work

Go module

golang 在版本1.11 新出的功能,初始化專案時必須加上 export GO111MODULE=on 原本預設是 auto 就是 disable

在原本有用 govendor 專案底下執行,就會自動複製產生

1
2
3
go mod init
// go: creating new go.mod: module testgomod
// go: copying requirements from vendor/vendor.json

如果是新專案則是

1
go mod init <packname>

多出一個 go.mod

1
2
3
4
5
6
// go.mod
// 記錄使用哪個套件,版本,sha1
module testgomod

// 新專案就不會有這條
require github.com/appleboy/com v0.0.0-20180410030638-c0b5901f9622

接著 import 的地方如果有需要下載的 package,執行以下指令就會自動去抓取

1
2
3
4
5
go mod download
// or
go run main.go
// or
go build -v -o main .

會產生 go.sum

1
2
3
// go.sum
github.com/appleboy/com v0.0.0-20180410030638-c0b5901f9622 h1:ozHD8HTq7ivv8vTJRCAzjA4wEA8BMGekxMDZrFdqz5M=
github.com/appleboy/com v0.0.0-20180410030638-c0b5901f9622/go.mod h1:rtwjPnHClMOJw4K5oW3ASx9BCPCJ1SDbFbzJjY4Ebqw=

實際上會存取在 $GOPATH/pkg/mod/

這時候可以嘗試將 govendor 的資料夾刪除,並改 module 成 auto

1
2
rm -rf vendor
export GO111MODULE=auto

1
2
3
4
5
go run main.go
// or
go build -v -o main .
// -o output
// -v print the names of packages as they are compiled.

會發現建立不了,再試著將 module 改成 on 去跑

1
export GO111MODULE=on
1
2
3
4
5
go run main.go
// or
go build -v -o main .

// 就不依賴 goverdor,專案也不一定要在 $GOPATH 底下

好處

  • 不需在 $GOPATH 底下才能建立專案
  • 可以切換不同版本

清除

清除 pkg 底下內容

1
go clean -i -x -modcache

指令

1
2
3
4
5
6
7
8
go download    download modules to local cache
go edit        edit go.mod from tools or scripts
go graph       print module requirement graph
go init        initialize new module in current directory
go tidy        add missing and remove unused modules
go vendor      make vendored copy of dependencies
go verify      verify dependencies have expected content
go why         explain why packages or modules are needed

參考文件

Comments