Golang where to set GO111MODULE

Hi Vtitans,
Do Golang có bước chuyển đổi lớn về cách quản lý dependencies (từ Go 11), rất nhiều project, library, framework và đặc biệt là documentation không cập nhật hoàn chỉnh ngay được, dẫn đến nhiều khi anh em coder phải loay hoay cả tiếng đồng hồ không xong một task được estimate là ... 5 phút.

Trong bài viết này mình không giải thích Go module, có lẽ là dịp khác khi có nhiều thời gian hơn, cũng không solve một task cụ thể như thường lệ. Chỉ trả lời câu hỏi là: nếu trong một guide troubleshoot bạn được bảo là "set GO111MODULE", thì bạn set nó ở đâu?

Mình viết tỉ mỉ cho những bạn chưa rành shell, do đó là nhu cầu của team mình. Nếu bạn đã rành nhưng đang rảnh, cứ đọc thêm chút nhé.

Trước hết, hãy nhìn go env

Hãy mở terminal và gõ lệnh go env. Bạn sẽ thấy tất cả biến môi trường của Go được list ra, trích đoạn như sau:

# go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/chautran/Library/Caches/go-build"
GOENV="/Users/chautran/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/chautran/go/pkg/mod"

Ngay dòng đầu bạn thấy GO111MODULE được list ra. Nếu bạn muốn xem một biến cụ thể thôi thì thêm tên của nó, ví dụ như sau:

go env GO111MODULE

Thứ hai, hãy hiểu go env

Go env show ra tập biến "effective" - nghĩa là giá trị của nó không phản ánh nó được lấy ra từ đâu hay tính toán như thế nào, mà phản ánh chính xác trạng thái môi trường mà các task, ví dụ lệnh build, chạy trong đó.

Cụ thể hơn là:

  1. Khi muốn tìm hiểu chắc chắn và tin cậy một biến đang có giá trị như thế nào khi thực hiện task, hãy dùng lệnh go env thay vì kiểm tra các file settings.
  2. Lệnh go env sẽ trả kết quả khác nhau tại những session hay tại các folder khác nhau, tuỳ thuộc vào biến. Ví dụ biến GOMOD, khi bạn chạy tại lệnh tại root folder của một module (là nơi chứa file go.mod), biến này sẽ có giá trị là path của file.
  3. Khi cần kiểm tra tại sao task trong VS Code có vẻ như lỗi, không giống như khi chạy lệnh go trực tiếp, thì hãy mở terminal trong VS Code và chạy go env từ đó.

Set GO111MODULE như một biến OS

Nói OS cho dễ hiểu, có 3 kiểu:

  1. Gõ lệnh export trong terminal. Biến chỉ có giá trị trong session đó, nghĩa là bạn mở tab mới thì nó khác.
  2. Viết lệnh export trong .bashrc hay .bash_profile (tuỳ thuộc vào OS của bạn). Effective khi một session được init. Bạn phải mở lại terminal (hoặc chạy lệnh gì đó để reload các file trên).
  3. Set trực tiếp trước câu lệnh, chỉ có giá trị cho câu lệnh đó.

Form của chúng như sau:

# 1
export GO111MODULE=on
# 2 ~/.bashrc hoặc ~/.bash_profile hoặc ~/.profile hoặc else
export GO111MODULE=on
# 3
GO111MODULE=on some_command

Set GO111MODULE bằng go env

Tại và chỉ tại một session mà OS không set, go env cho phép bạn set với chỉ thị -w:

go env -w GO111MODULE=on
# Unset
go env -u GO111MODULE

Giống như cách 2 là ghi ra file, giá trị set bằng cách này là permanent nên hãy làm vậy nếu bạn muốn không phải gõ lệnh nhiều lần. Ghi ra đâu? Bạn để ý trong output của go env có một cái path tên là GOENV đó. Bạn có thể ghi trực tiếp file này, có thể xoá bỏ file này.

Ai override ai?

Câu hỏi này quan trọng với DevOps, hay chính xác hơn là các anh chàng viết script để build, package, deploy vv. Mà đã được làm việc đấy rồi thì tự trả lời đi =))))

Với một team code cụ thể đang dùng Windows và VS Code, có 3 bổ sung:

  1. Trong Windows, lệnh set tương đương lệnh export. Biến môi trường là ... biến môi trường =)))
  2. Nên đảm bảo là lệnh go env trong terminal của VS Code trả kết quả giống như khi chạy trong GitBash. Phương pháp đạt được điều này là cách 2 (biến môi trường permanent) + tránh settings trong VS Code.
  3. Trong VS Code, chỉ nên mở đúng folder có chứa go.mod file. Mở nhiều Window nếu cần làm việc với nhiều module, project hay branch.

Điều 3 quan trọng bạn nhé, nếu không thì lại vò đầu bứt tai đấy =)))
Thân, from Châu D9

Leave a Reply

Your email address will not be published. Required fields are marked *