顯示具有 Go 標籤的文章。 顯示所有文章
顯示具有 Go 標籤的文章。 顯示所有文章

2023年12月1日 星期五

如何解決在 WSL 安裝 GVM 後,無法使用 "code ." 開啟 VS Code 的問題。

 一、前言

前陣子有鑑於今年都沒有參加什麼 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" 是什麼意思了?怎麼會這樣?於是我開始做以下檢查

  1. 在 Windows 用 Git Bash 可否使用 "code ." => 可以
  2. 重新安裝 VS Code 的 WSL extension 後,在 WSL 嘗試使用 "code ." => 不可以
  3. 重新安裝 VS Code 後,在 WSL 嘗試使用 "code ." => 不可以
  4. 將 gvm 移除後,在 WSL 嘗試使用 "code ." => 不可以
  5. 將 gvm 安裝後,於 .bashrc 所加入的
    [[ -s "/home/cyli/.gvm/scripts/gvm" ]] && source "/home/cyli/.gvm/scripts/gvm"
    註解掉後,在 WSL 嘗試使用 "code ." => 可以,但變成找不到 Go。

四、深入整個安裝流程

1. gvm-installer

執行了 gvm-installer,然後寫進 bash
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

執行 gvm-default
export GVM_ROOT=/home/cyli/.gvm
. $GVM_ROOT/scripts/gvm-default

3.  $GVM_ROOT/script/gvm-default

重設各種變數,並且修改 PATH,最後執行 $GVM_ROOT/environments/default(如果存在), $GVM_ROOT/scripts/env/gvm 與 $GVM_ROOT/scripts/env/cd
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)"

五、Walkaround

最終,我嘗試在 .bashrc 裡,再次設定 VS Code 的 PATH,結果就解決了。至於會不會有其他跟 VS Code 有一樣的狀況,可能要等之後遇到再說。
不過有個特別的現象是,因為 Windows 裡會有檔案的名稱含有空白,在我的 WSL 會用 ":" 取代,我有嘗試加入一樣的路徑,但結果不行,最後是加入含有跳脫的版本。

六、後記

我有嘗試在保哥的文章底下留言詢問,不過我推測並不會有通知,所以保哥並沒有回應。而我也到了 Go程式語言 (Golang Taiwan, Gopher Taipei) 的 Facebook 社團去求教,不過看起來大家都不太推 gvm,頂多是推 goenv,但我還是覺得可能可以堅持一下,雖然結果也不算有根本解決,不過至少可以讓我舒服開發了。

四、References