問題解決 child_process execSync /bin/sh: pnpm: command not found

問題解決 child_process execSync /bin/sh: pnpm: command not found
Photo by Towfiqu barbhuiya / Unsplash

Context

我在執行 child_process.execSync 時,使用了下方程式碼去跑 db migration 並且指定了環境變數 DATABASE_URL 去執行 schema refresh & seed

execSync('pnpm -F backend db:reset && pnpm -F backend seed', {
    env: { DATABASE_URL: databaseUrl },
})

本人是使用 Windows 作業系統,這行指令在我電腦中執行的很順暢,所以就開開心心的把這行程式推上 Github 了。

不料沒多久,一位使用 Mac 的同事就對我說這行程式沒辦法跑啊,一直寫說 pnpm command not found

我循思這不太可能啊,每個人都有裝了 pnpm 才對,為何這時候又冒出了這個錯誤?不會又是 Mac 的鍋吧...😂

source: https://www.igtsolutions.com/information-technology/breaking-down-barriers-navigating-the-tester-vs-developer-dynamics/

Problem

我不斷地在網路上衝浪,直到找到這篇 Stack Overflow,裡面有一段程式碼可以幫助我們 debug

const { execSync } = require('child_process')
console.log(process.env.ComSpec);// verify what terminal is used

try {
    // success command
    const resNpmVersion = execSync("npm -v");
    console.log("success", resNpmVersion.toString());

    // failed command, the result is printed in the catch block
    const resHelp = execSync("HELP");
} catch (error) {
    console.log(error.message);
    console.log("error", error.stdout.toString());
}

於是我把這段程式碼交給他,說道你把 npm 改成 pnpm 看看能不能執行?

過了一段時間後,他說:可以耶!我的版本是 9.x.x ...

我驚訝到,為什麼這樣可以執行??

Solution

於是我看了一下差異問道

是不是指定環境變數的問題呢?把 process.env 也放進去會如何呢?
execSync('pnpm -F backend db:reset && pnpm -F backend seed', {
    env: { ...process.env, DATABASE_URL: databaseUrl },
})

it's works!果真就能夠執行了!

後來找到了一篇文章 使用child_process时注意环境变量 寫道:

呼叫 child_process.execSync時,若指定了env,切記一定要把繼承來的process.env帶上。 否則最重要的PATH環境變數就可能這麼被忽略了,導致子 Process 要呼叫 shell 指令時,發生各種找不到命令的奇怪錯誤。

官方文件中也寫道:

The command lookup is performed using the options.env.PATH environment variable if env is in the options object. Otherwise, process.env.PATH is used. If options.env is set without PATH, lookup on Unix is performed on a default search path search of /usr/bin:/bin (see your operating system's manual for execvpe/execvp), on Windows the current processes environment variable PATH is used. On Windows, environment variables are case-insensitive. Node.js lexicographically sorts the env keys and uses the first one that case-insensitively matches. Only first (in lexicographic order) entry will be passed to the subprocess. This might lead to issues on Windows when passing objects to the env option that have multiple variants of the same key, such as PATH and Path.

結論:下參數之前要先讀 spec 啊...

Read more

UV python 操作筆記

UV python 操作筆記

前陣子看到了 uv 這個 python 套件、專案管理器,使用了之後發現簡直快、輕便又好上手,下方是我常使用的指令集 (持續更新中): 查看 python 版本清單 uv python list 💡已安裝的旁邊會顯示 python 安裝目錄位址 安裝 python 版本 # latest uv python install # specific version uv python install <version number> 初始化 uv 專案資料夾。 uv init <project name> 💡預設會自動產生 git repository、.python-version、pyproject.toml

By GXiang
ts-rest 的 API 測試手法(1)

ts-rest 的 API 測試手法(1)

今天與朋友討論到 ts-rest 撰寫 API test 的時候可以用 Zod 的 safeParse().success 判斷 API Response 的 schema 正不正確。 Sample Code: const { body, status } = client.users.create({ body: createUserPayload(), }) expect( userContract.create.responses[201].safeParse(body) .success, ).toBe(true) 這樣做確實會減少許多傳統需要手動添加 expect.any(Type)...等等的型別驗證,如果只是單純驗證型別,確實透過 ts-rest 合約搭配的 Zod 的 safeParse 安全型別驗證就能夠減少用 expect.

By GXiang
把 MixerBox 歌單匯入到 Spotify

把 MixerBox 歌單匯入到 Spotify

本文由 個人medium文章 同步 筆者最近從 MixerBox 跳槽到 Spotify,但因為 Spotify 推薦的歌單不符合我的口味,又想把 MixerBox 歌單直接無痛移轉到 Spotify,網路上爬文許久,雖然有看到 Jerry 大大分享的這篇文章,但似乎已經沒辦法使用,既然沒有現成的解決方案,那我們就只好動動自己的小腦袋了🧠 貼心體醒:接下來的內容並不會要求撰寫/查看任何程式🙂 使用工具:瀏覽器, Visual Studio Code 筆者在目前看到的平台歌單轉移工具 TuneMyMusic 中,我發現了一個可能性,在第一步選擇歌曲來源時,有一個選項叫做「任意文本」。 點了之後才發現,原來可以利用歌名加上換行分隔作為清單進行匯入!那事情就簡單多了,我們只要能拿到自己播放清單中的歌曲文字列表就可以直接匯入。 接下來我們來到 MixerBox Web 版頁面,點擊「我的音樂庫」,可以看到自己的歌單。 點擊你想要的歌單後,所有歌曲都會呈現在頁面上。 那麼接下來的問題是:

By GXiang
Jest, Testcontainers 如何不重新建立 container 情況下執行 e2e 測試?

Jest, Testcontainers 如何不重新建立 container 情況下執行 e2e 測試?

前言 前不久才研究 Testcontainers 如何套用在 jest e2e 測試環節中,不過這方面進展不錯,目前在每次執行 e2e 測試時都能啟動新的 MySQL 容器並且套用 Primsa 的 migration,用起來真香啊。 但是仍存在一個令我困擾的問題,就是在每一次跑測試時都會 Recreate 一次 Testcontainers,我在想可不可以像過往一樣就把 DB Container 開著,在跑測試時直接用就好。 解決方案 Testcontainers Node.js 官方文件提到: Enabling container re-use means that Testcontainers will not start a new container if a Testcontainers managed container with

By GXiang