diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 7fbb32b..b71d5c2 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -14,6 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - run: corepack enable + - uses: oven-sh/setup-bun@v1 - uses: actions/setup-node@v3 with: node-version: 18 @@ -21,6 +22,7 @@ jobs: - run: pnpm install - name: Fix lint issues run: pnpm run lint:fix && pnpm vitest run --update + - run: git checkout HEAD test/fixtures/bun - uses: autofix-ci/action@8caa572fd27b0019a65e4c695447089c8d3138b9 with: commit-message: "chore: apply automated lint fixes" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29ef7b1..00f8f71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,8 @@ jobs: steps: - uses: actions/checkout@v3 - run: corepack enable + - uses: oven-sh/setup-bun@v1 + if: ${{ matrix.os != 'windows-latest' }} - uses: actions/setup-node@v3 with: node-version: 18 diff --git a/README.md b/README.md index d19bad1..815be21 100644 --- a/README.md +++ b/README.md @@ -11,31 +11,31 @@ ## What does **nypm** do? -✅ Supports **npm, yarn and pnpm** out of the box with a unified API +✅ Supports **npm, yarn, pnpm and bun** out of the box with a unified API ✅ Provides an **API interface** to interact with package managers ✅ **Autodetects** project's package manager using package.json and known lockfiles -✅ **Auto-installs and use exactly expected version** of package manager using [nodejs/corepack](https://github.com/nodejs/corepack) +✅ **Auto-installs and use exactly expected version** of supported package managers using [nodejs/corepack](https://github.com/nodejs/corepack) ✅ **Minimal** implementation nypm, detects package manager type and version and converts command into package manager CLI arguments. It then uses corepack to execute package manager's command (and download it if necessary). ``` - +------------------------------------+ - | nypm | - +------------------------------------+ - +------------------------------------+ - | Corepack | - +------------------------------------+ - +---------+ +---------+ +---------+ - | npm | | yarn | | pnpm | - +---------+ +---------+ +---------+ - +------------------------------------+ - | Node.js project | - +------------------------------------+ + +------------------------------------------------+ + | nypm | + +------------------------------------------------+ + +-----------------------------------+ + | Corepack | + +-----------------------------------+ + +---------+ +---------+ +---------+ +---------+ + | npm | | yarn | | pnpm | | bun | + +---------+ +---------+ +---------+ +---------+ + +------------------------------------------------+ + | Node.js project | + +------------------------------------------------+ ``` ## CLI Usage @@ -55,6 +55,9 @@ pnpm install nypm # yarn yarn add nypm + +# bun +bun install nypm ``` Import: diff --git a/package.json b/package.json index c5d230f..fe0cf5b 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "jiti": "^1.19.1", "pathe": "^1.1.1", "prettier": "^3.0.2", + "std-env": "^3.4.3", "typescript": "^5.1.6", "unbuild": "^1.2.1", "vitest": "^0.34.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f5fd78..056801e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,6 +40,9 @@ devDependencies: prettier: specifier: ^3.0.2 version: 3.0.2 + std-env: + specifier: ^3.4.3 + version: 3.4.3 typescript: specifier: ^5.1.6 version: 5.1.6 @@ -1062,7 +1065,7 @@ packages: istanbul-reports: 3.1.6 magic-string: 0.30.2 picocolors: 1.0.0 - std-env: 3.3.3 + std-env: 3.4.3 test-exclude: 6.0.0 v8-to-istanbul: 9.1.0 vitest: 0.34.1 @@ -1419,7 +1422,7 @@ packages: pkg-types: 1.0.3 scule: 1.0.0 semver: 7.5.4 - std-env: 3.3.3 + std-env: 3.4.3 yaml: 2.3.1 transitivePeerDependencies: - supports-color @@ -3618,8 +3621,8 @@ packages: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true - /std-env@3.3.3: - resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} + /std-env@3.4.3: + resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==} dev: true /string.prototype.trim@1.2.7: @@ -4071,7 +4074,7 @@ packages: magic-string: 0.30.2 pathe: 1.1.1 picocolors: 1.0.0 - std-env: 3.3.3 + std-env: 3.4.3 strip-literal: 1.3.0 tinybench: 2.5.0 tinypool: 0.7.0 diff --git a/src/_utils.ts b/src/_utils.ts index 49d1444..7b9803e 100644 --- a/src/_utils.ts +++ b/src/_utils.ts @@ -35,7 +35,9 @@ export async function executeCommand( // work around issue with segmentation fault when using corepack with npm // on ubuntu-latest const execaArgs: [string, string[]] = - command === "npm" ? [command, args] : ["corepack", [command, ...args]]; + command === "npm" || command === "bun" + ? [command, args] + : ["corepack", [command, ...args]]; await execa(execaArgs[0], execaArgs[1], { cwd: resolve(options.cwd || process.cwd()), @@ -102,6 +104,10 @@ export function getWorkspaceArgs( return ["-F", options.workspace]; } + case "bun": { + return []; + } + case "yarn": { return ["workspace", options.workspace]; } diff --git a/src/package-manager.ts b/src/package-manager.ts index 95bb01e..52fde92 100644 --- a/src/package-manager.ts +++ b/src/package-manager.ts @@ -35,6 +35,11 @@ const _packageManagers: PackageManager[] = [ lockFile: "pnpm-lock.yaml", files: ["pnpm-workspace.yaml"], }, + { + name: "bun", + command: "bun", + lockFile: "bun.lockb", + }, { name: "yarn", command: "yarn", diff --git a/src/types.ts b/src/types.ts index 3b19f2c..561b6d3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -export type PackageManagerName = "npm" | "yarn" | "pnpm"; +export type PackageManagerName = "npm" | "yarn" | "pnpm" | "bun"; export type PackageManager = { name: PackageManagerName; diff --git a/test/fixtures/bun/bun.lockb b/test/fixtures/bun/bun.lockb new file mode 100755 index 0000000..bf3ed0b Binary files /dev/null and b/test/fixtures/bun/bun.lockb differ diff --git a/test/fixtures/bun/package.json b/test/fixtures/bun/package.json new file mode 100644 index 0000000..1850cc0 --- /dev/null +++ b/test/fixtures/bun/package.json @@ -0,0 +1,8 @@ +{ + "name": "fixture-bun", + "version": "0.0.0", + "private": true, + "workspaces": [ + "packages/*" + ] +} diff --git a/test/fixtures/bun/packages/workspace-a/package.json b/test/fixtures/bun/packages/workspace-a/package.json new file mode 100644 index 0000000..d5988e4 --- /dev/null +++ b/test/fixtures/bun/packages/workspace-a/package.json @@ -0,0 +1,8 @@ +{ + "name": "fixture-bun/workspace-a", + "private": true, + "version": "0.0.0", + "devDependencies": { + "ufo": "^1.1.1" + } +} diff --git a/test/index.test.ts b/test/index.test.ts index 32f1677..f1b5a1e 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,5 +1,6 @@ import { fileURLToPath } from "node:url"; import { expect, it, describe, vi } from "vitest"; +import { isWindows } from "std-env"; import { installDependencies, addDependency, @@ -32,6 +33,10 @@ const fixtures = [ name: "pnpm", packageManager: "pnpm", }, + { + name: "bun", + packageManager: "bun", + }, { name: "yarn-classic", packageManager: "yarn", @@ -123,6 +128,11 @@ describe("detectPackageManager", () => { describe("api", () => { for (const fixture of fixtures) { + // bun is not yet supported on Windows + if (isWindows && fixture.name === "bun") { + continue; + } + describe(fixture.name, () => { const fixtureDirectory = resolveFixtureDirectory(fixture.name);