diff --git a/README.md b/README.md index e2adeb949..6349ea366 100644 --- a/README.md +++ b/README.md @@ -340,8 +340,12 @@ same major line. Should you need to upgrade to a new major, use an explicit will be taken into account. - `COREPACK_HOME` can be set in order to define where Corepack should install - the package managers. By default it is set to `%LOCALAPPDATA%\node\corepack` - on Windows, and to `$HOME/.cache/node/corepack` everywhere else. + the package managers. Otherwise, Corepack uses `$XDG_CACHE_HOME/node/corepack` + if `XDG_CACHE_HOME` is set. Without either override, it uses + `%LOCALAPPDATA%\node\corepack` on Windows (falling back to + `%USERPROFILE%\AppData\Local\node\corepack` if `LOCALAPPDATA` is unset), and + `$HOME/.cache/node/corepack` everywhere else. `LOCALAPPDATA` is ignored on + non-Windows platforms, including Linux running under WSL. - `COREPACK_ROOT` has no functional impact on Corepack itself; it's automatically being set in your environment by Corepack when it shells out to diff --git a/sources/folderUtils.ts b/sources/folderUtils.ts index 84cde502c..36685b52d 100644 --- a/sources/folderUtils.ts +++ b/sources/folderUtils.ts @@ -16,7 +16,7 @@ export function getCorepackHomeFolder() { process.env.COREPACK_HOME ?? join( process.env.XDG_CACHE_HOME ?? - process.env.LOCALAPPDATA ?? + (process.platform === `win32` ? process.env.LOCALAPPDATA : undefined) ?? join(homedir(), process.platform === `win32` ? `AppData/Local` : `.cache`), `node/corepack`, ) diff --git a/tests/folderUtils.test.ts b/tests/folderUtils.test.ts new file mode 100644 index 000000000..4d42fb553 --- /dev/null +++ b/tests/folderUtils.test.ts @@ -0,0 +1,45 @@ +import {homedir} from 'os'; +import {join} from 'path'; +import process from 'process'; +import {beforeEach, describe, expect, it} from 'vitest'; + +import {getCorepackHomeFolder, getInstallFolder} from '../sources/folderUtils.ts'; + +beforeEach(() => { + delete process.env.COREPACK_HOME; + delete process.env.XDG_CACHE_HOME; + delete process.env.LOCALAPPDATA; +}); + +describe(`cache location`, () => { + const localAppData = join(homedir(), `windows-cache`); + const xdgCacheHome = join(homedir(), `xdg-cache`); + const corepackHome = join(homedir(), `custom-corepack`); + + const cases: Array<{platform: NodeJS.Platform, env: NodeJS.ProcessEnv, expected: string}> = [ + {platform: `linux`, env: {}, expected: join(homedir(), `.cache/node/corepack`)}, + {platform: `linux`, env: {LOCALAPPDATA: localAppData}, expected: join(homedir(), `.cache/node/corepack`)}, + {platform: `darwin`, env: {LOCALAPPDATA: localAppData}, expected: join(homedir(), `.cache/node/corepack`)}, + {platform: `win32`, env: {LOCALAPPDATA: localAppData}, expected: join(localAppData, `node/corepack`)}, + {platform: `win32`, env: {}, expected: join(homedir(), `AppData/Local/node/corepack`)}, + ]; + + for (const platform of [`linux`, `darwin`, `win32`] as const) { + cases.push( + {platform, env: {XDG_CACHE_HOME: xdgCacheHome, LOCALAPPDATA: localAppData}, expected: join(xdgCacheHome, `node/corepack`)}, + {platform, env: {COREPACK_HOME: corepackHome, XDG_CACHE_HOME: xdgCacheHome, LOCALAPPDATA: localAppData}, expected: corepackHome}, + ); + } + + it.each(cases)(`uses $expected on $platform with $env`, ({platform, env, expected}) => { + const descriptor = Object.getOwnPropertyDescriptor(process, `platform`)!; + Object.assign(process.env, env); + Object.defineProperty(process, `platform`, {value: platform}); + try { + expect(getCorepackHomeFolder()).toBe(expected); + expect(getInstallFolder()).toBe(join(expected, `v1`)); + } finally { + Object.defineProperty(process, `platform`, descriptor); + } + }); +});