一、前言
前陣子有鑑於今年都沒有參加什麼 conference,所以就去高雄參加 MOPCON 2023,剛好遇到 Dcard 的工程師,小聊了一下才知道他們目前正在從 Node.js 轉換到 Golang。之前也有跟一些 hunter 小聊,很多開口第一句就是「你會寫 Go(以下皆以此取代 Golang)嗎?」對那時的我來說,這就是「不屬於我的機會」,直到我發現目前靠 C# 在寫後端的我,能夠找的職缺有限(排除金融與博弈),所以就開啟一探 Go 神秘面紗的契機。
二、安裝環境
因為我是個不喜歡在 Windows 開發程式(排除開發 C# 專案,因為會用到 Visual Studio),又想要 Windows 上的服務,所以移除非必要,大部分非 C# 的專案都會在 WSL 上開發。因此就找到保哥寫的如何在 Windows 平台打造完美的 Go 開發環境 (WSL 2),在「安裝 VSCode 需要的 go modules 與相關工具」之前的內容基本上就是再用中文交代過一次 gvm 在 GitHub 上的說明。
不過有一個小地方在 GitHub 有提到,但文章中漏掉了,那就是當你從來沒有安裝過 Go 的任何版本時,如果你要安裝 Go 1.5+ 以上的版本,你需要安裝 Go 1.4,主要原因是因為 Go 1.5+ 把 C compilers 移除了。
三、我遇到什麼問題
常用 VS Code 的人就知道,可以在 cmd 切換到指定 repo 後,透過 "code ." 在當下路徑開啟 VS Code,在 WSL 上只要設定好也是如此。但正當我準備開心的進入 Go 的世界時,我發現我無法開啟我的 VS Code!
從錯誤來看,它不認識 "code" 是什麼意思了?怎麼會這樣?於是我開始做以下檢查
- 在 Windows 用 Git Bash 可否使用 "code ." => 可以
- 重新安裝 VS Code 的 WSL extension 後,在 WSL 嘗試使用 "code ." => 不可以
- 重新安裝 VS Code 後,在 WSL 嘗試使用 "code ." => 不可以
- 將 gvm 移除後,在 WSL 嘗試使用 "code ." => 不可以
-
將 gvm 安裝後,於 .bashrc 所加入的
[[ -s "/home/cyli/.gvm/scripts/gvm" ]] && source "/home/cyli/.gvm/scripts/gvm"
註解掉後,在 WSL 嘗試使用 "code ." => 可以,但變成找不到 Go。
四、深入整個安裝流程
1. gvm-installer
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
GVM_DEST=${2:-$HOME} GVM_NAME="gvm" [ "$GVM_DEST" = "$HOME" ] && GVM_NAME=".gvm" source_line="[[ -s \"${GVM_DEST}/$GVM_NAME/scripts/gvm\" ]] && source \"${GVM_DEST}/$GVM_NAME/scripts/gvm\"" source_file="${GVM_DEST}/$GVM_NAME/scripts/gvm" if [ -z "$GVM_NO_UPDATE_PROFILE" ] ; then if [ -f "$HOME/.zshrc" ]; then update_profile "$HOME/.zshrc" fi if [ "$(uname)" == "Linux" ]; then update_profile "$HOME/.bashrc" || update_profile "$HOME/.bash_profile" elif [ "$(uname)" == "Darwin" ]; then LOGIN_SHELL=$(finger $(id -u -n) | grep Shell | cut -d : -f 3) echo "macOS detected. User shell is:" $LOGIN_SHELL if [ $LOGIN_SHELL == "/bin/zsh" ]; then # macOS moved to ZSH after macOS Catalina pdate_profile "$HOME/.zshrc" else update_profile "$HOME/.profile" || update_profile "$HOME/.bash_profile" fi fi fi
2. .gvm/script/gvm
export GVM_ROOT=/home/cyli/.gvm . $GVM_ROOT/scripts/gvm-default
3. $GVM_ROOT/script/gvm-default
unset GOROOT unset GOARCH unset GOOS unset GOPATH unset GOBIN unset gvm_go_name unset gvm_pkgset_name mkdir -p "$GVM_ROOT/logs" > /dev/null 2>&1 mkdir -p "$GVM_ROOT/gos" > /dev/null 2>&1 mkdir -p "$GVM_ROOT/archive" > /dev/null 2>&1 mkdir -p "$GVM_ROOT/archive/package" > /dev/null 2>&1 mkdir -p "$GVM_ROOT/environments" > /dev/null 2>&1 export GVM_VERSION=$(cat "$GVM_ROOT/VERSION") export PATH="$GVM_ROOT/bin:$PATH" export GVM_PATH_BACKUP="$PATH" [ -f "$GVM_ROOT/environments/default" ] && . "$GVM_ROOT/environments/default" . "$GVM_ROOT/scripts/env/gvm" . "$GVM_ROOT/scripts/env/cd" && cd .
4. $GVM_ROOT/environments/default
重新設定各種環境變數,包含 PATH。
5. $GVM_ROOT/scripts/env/gvm
設定各種指令的路徑
6. $GVM_ROOT/scripts/env/cd
# Path cleanup # # Sort all paths, place rvm paths first, followed by gvm, followed by the rest. # We do this so that rvm and gvm can live together happily. # # NOTE: Cleanup will also take place everytime 'gvm use' or 'gvm pkgset use' is # executed but we do it now just to call it from some place on login. # export PATH="$(__gvm_munge_path)"