Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for Bun #108

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- run: npm i -g npm@8
- run: npm i -g yarn@1
- run: npm i -g pnpm@7
# https://github.com/oven-sh/bun/issues/43
- run: npm i -g bun@1
if: matrix.os != 'windows-latest'
- run: npm ci
- run: npx playwright install-deps
- run: npm run build
Expand Down
82 changes: 50 additions & 32 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"prepublish": "npm run build"
},
"devDependencies": {
"@playwright/test": "^1.38.1",
"@types/node": "^16.11.11",
"@playwright/test": "^1.41.0-alpha-1704968142000",
"@types/node": "^18.19.6",
"ansi-colors": "^4.1.1",
"enquirer": "^2.3.6",
"esbuild": "^0.14.25",
Expand Down
14 changes: 13 additions & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import { defineConfig } from '@playwright/test';
import type { TestFixtures } from './tests/baseFixtures';

export default defineConfig<TestFixtures>({
const config = defineConfig<TestFixtures>({
timeout: 120 * 1000,
testDir: './tests',
reporter: 'list',
Expand All @@ -42,3 +42,15 @@ export default defineConfig<TestFixtures>({
},
]
});

// https://github.com/oven-sh/bun/issues/43
if (process.platform !== 'win32') {
config.projects?.push({
name: 'bun',
use: {
packageManager: 'bun'
}
})
}

export default config;
31 changes: 31 additions & 0 deletions src/packageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,43 @@ class PNPM implements PackageManager {
}
}

class Bun implements PackageManager {
name = 'Bun'
cli = 'bun'

init(): string {
return 'bun init -y'
}

npx(command: string, args: string): string {
return `bun --bun x ${command} ${args}`
}

ci(): string {
return 'bun install'
}

installDevDependency(name: string): string {
return `bun install --dev ${name}`
}

runPlaywrightTest(args: string): string {
return this.npx('playwright', `test${args ? (' ' + args) : ''}`);
}

run(script: string): string {
return `bun run ${script}`;
}
}

export function determinePackageManager(rootDir: string): PackageManager {
if (process.env.npm_config_user_agent) {
if (process.env.npm_config_user_agent.includes('yarn'))
return new Yarn();
if (process.env.npm_config_user_agent.includes('pnpm'))
return new PNPM(fs.existsSync(path.resolve(rootDir, 'pnpm-workspace.yaml')));
if (process.env.npm_config_user_agent.includes('bun'))
return new Bun();
return new NPM();
}
return new NPM();
Expand Down
22 changes: 20 additions & 2 deletions tests/baseFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import path from 'path';
import fs from 'fs';
import type { PromptOptions } from '../src/generator';

export type PackageManager = 'npm' | 'pnpm' | 'yarn';
export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';

export type TestFixtures = {
packageManager: PackageManager;
Expand Down Expand Up @@ -82,14 +82,27 @@ export const test = base.extend<TestFixtures>({
cwd: dir,
env: {
...process.env,
'npm_config_user_agent': packageManager === 'yarn' ? 'yarn' : packageManager === 'pnpm' ? 'pnpm/0.0.0' : undefined,
'npm_config_user_agent': packageManagerToNpmConfigUserAgent(packageManager),
'TEST_OPTIONS': JSON.stringify(options),
},
});
});
},
});

function packageManagerToNpmConfigUserAgent(packageManager: PackageManager): string {
switch (packageManager) {
case 'npm':
return 'npm/10.2.4 node/v20.11.0 linux x64 workspaces/false'
case 'yarn':
return 'yarn/1.22.21 npm/? node/v20.11.0 linux x64';
case 'pnpm':
return 'pnpm/8.14.1 npm/? node/v20.11.0 linux x64';
case 'bun':
return 'bun/1.0.22 npm/? node/v20.8.0 linux x64'
}
}

export function assertLockFilesExist(dir: string, packageManager: PackageManager) {
expect(fs.existsSync(path.join(dir, 'package.json'))).toBeTruthy();
if (packageManager === 'npm')
Expand All @@ -98,6 +111,8 @@ export function assertLockFilesExist(dir: string, packageManager: PackageManager
expect(fs.existsSync(path.join(dir, 'yarn.lock'))).toBeTruthy();
else if (packageManager === 'pnpm')
expect(fs.existsSync(path.join(dir, 'pnpm-lock.yaml'))).toBeTruthy();
else if (packageManager === 'bun')
expect(fs.existsSync(path.join(dir, 'bun.lockb'))).toBeTruthy();
}

export function packageManagerToNpxCommand(packageManager: PackageManager): string {
Expand All @@ -108,7 +123,10 @@ export function packageManagerToNpxCommand(packageManager: PackageManager): stri
return 'yarn';
case 'pnpm':
return 'pnpm dlx';
case 'bun':
return 'bun --bun x';
}
throw new Error(`Unsupported package manager: ${packageManager}!`);
}

export const expect = test.expect;
4 changes: 4 additions & 0 deletions tests/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ test('should generate a project in the current directory', async ({ run, dir, pa
expect(stdout).toContain('pnpm init'); // pnpm command outputs name in different case, hence we are not testing the whole string
expect(stdout).toContain('Installing Playwright Test (pnpm add --save-dev @playwright/test)…');
expect(stdout).toContain('Installing Types (pnpm add --save-dev @types/node)…');
} else if (packageManager === 'bun') {
expect(stdout).toContain('Initializing Bun project (bun init -y)…');
expect(stdout).toContain('Installing Playwright Test (bun install --dev @playwright/test)…');
expect(stdout).toContain('Installing Types (bun install --dev @types/node)…');
}
expect(stdout).toContain('npx playwright install' + process.platform === 'linux' ? ' --with-deps' : '');
});
Expand Down