diff --git a/README.md b/README.md index 17a13987..e08142d8 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Options: -t, --extensionType # ts, js, colortheme, language, snippets, keymap... --extensionId # Id of the extension --extensionDescription # Description of the extension - --pkgManager # 'npm', 'yarn' or 'pnpm' + --pkgManager # 'npm', 'yarn', 'pnpm' or 'bun' --bundle # 'webpack', 'esbuild'. Bundle the extension with webpack or esbuild --gitInit # Initialize a git repo diff --git a/generators/app/index.js b/generators/app/index.js index 184d23d7..3dbcb556 100644 --- a/generators/app/index.js +++ b/generators/app/index.js @@ -43,7 +43,7 @@ export default class extends Generator { this.option('extensionId', { type: String, description: 'Id of the extension' }); this.option('extensionDescription', { type: String, description: 'Description of the extension' }); - this.option('pkgManager', { type: String, description: `'npm', 'yarn' or 'pnpm'` }); + this.option('pkgManager', { type: String, description: `'npm', 'yarn', 'pnpm' or 'bun` }); this.option('bundler', { type: String, description: `Bundle the extension: 'webpack', 'esbuild'` }); this.option('gitInit', { type: Boolean, description: `Initialize a git repo` }); diff --git a/generators/app/prompts.js b/generators/app/prompts.js index a138b7cc..4bfd637a 100644 --- a/generators/app/prompts.js +++ b/generators/app/prompts.js @@ -123,7 +123,7 @@ export function askForGit(generator, extensionConfig) { */ export function askForPackageManager(generator, extensionConfig) { const pkgManager = generator.options['pkgManager']; - if (pkgManager === 'npm' || pkgManager === 'yarn' || pkgManager === 'pnpm') { + if (pkgManager === 'npm' || pkgManager === 'yarn' || pkgManager === 'pnpm' || pkgManager === 'bun') { extensionConfig.pkgManager = pkgManager; return Promise.resolve(); } @@ -150,6 +150,10 @@ export function askForPackageManager(generator, extensionConfig) { { name: 'pnpm', value: 'pnpm' + }, + { + name: 'bun', + value: 'bun' } ] }).then(pckgManagerAnswer => { diff --git a/test/test.mjs b/test/test.mjs index 294a51c8..2b75863c 100644 --- a/test/test.mjs +++ b/test/test.mjs @@ -840,6 +840,86 @@ describe('test code generator', function () { } }); + it('command-ts with bun', async () => { + this.timeout(10000); + + const runResult = await helpers.run(appLocation).withAnswers({ + type: 'ext-command-ts', + name: 'testCom', + displayName: 'Test Com', + description: 'My TestCom', + gitInit: false, + pkgManager: 'bun', + bundler: 'unbundled', + openWith: 'skip' + }); // Mock the prompt answers + + + try { + const expectedPackageJSON = { + "name": "testCom", + "displayName": 'Test Com', + "description": "My TestCom", + "version": "0.0.1", + "engines": { + "vscode": engineVersion + }, + "activationEvents": [], + "devDependencies": devDependencies([ + "@types/vscode", + "@types/mocha", + "@types/node", + "eslint", + "@typescript-eslint/parser", + "@typescript-eslint/eslint-plugin", + "typescript", + "@vscode/test-cli", + "@vscode/test-electron" + ]), + "main": "./out/extension.js", + "scripts": { + "vscode:prepublish": "bun run compile", + "compile": "tsc -p ./", + "lint": "eslint src --ext ts", + "watch": "tsc -watch -p ./", + "pretest": "bun run compile && bun run lint", + "test": "vscode-test" + }, + "categories": [ + "Other" + ], + "contributes": { + "commands": [{ + "command": "testCom.helloWorld", + "title": "Hello World" + }] + } + }; + const expectedTsConfig = { + "compilerOptions": { + "module": "Node16", + "target": "ES2022", + "outDir": "out", + "lib": [ + "ES2022" + ], + "sourceMap": true, + "rootDir": "src", + "strict": true + } + }; + + assertFiles(runResult, 'testCom', ['src/extension.ts', 'src/test/extension.test.ts', 'tsconfig.json', '.eslintrc.json', '.vscode-test.mjs', '.vscode/extensions.json', '.npmrc']); + + runResult.assertJsonFileContent('testCom/package.json', expectedPackageJSON); + + const tsconfigBody = JSON.parse(stripComments(runResult.fs.read('testCom/tsconfig.json'))); + runResult.assertObjectContent(tsconfigBody, expectedTsConfig); + } finally { + cleanup(runResult); + } + }); + it('command-ts with webpack', async () => { this.timeout(10000); @@ -980,6 +1060,76 @@ describe('test code generator', function () { } }); + it('command-ts with webpack + bun', async () => { + this.timeout(10000); + + const runResult = await helpers.run(appLocation).withAnswers({ + type: 'ext-command-ts', + name: 'testCom', + displayName: 'Test Com', + description: 'My TestCom', + gitInit: true, + pkgManager: 'bun', + bundler: 'webpack', + openWith: 'skip' + }); // Mock the prompt answers + + + try { + const expectedPackageJSON = { + "name": "testCom", + "displayName": 'Test Com', + "description": "My TestCom", + "version": "0.0.1", + "engines": { + "vscode": engineVersion + }, + "activationEvents": [], + "devDependencies": devDependencies([ + "@types/vscode", + "@types/mocha", + "@types/node", + "@typescript-eslint/parser", + "@typescript-eslint/eslint-plugin", + "eslint", + "typescript", + "@vscode/test-cli", + "@vscode/test-electron", + "webpack", + "webpack-cli", + "ts-loader" + ]), + "main": "./dist/extension.js", + "scripts": { + "vscode:prepublish": "bun run package", + "compile": "webpack", + "watch": "webpack --watch", + "package": "webpack --mode production --devtool hidden-source-map", + "compile-tests": "tsc -p . --outDir out", + "watch-tests": "tsc -p . -w --outDir out", + "lint": "eslint src --ext ts", + "pretest": "bun run compile-tests && bun run compile && bun run lint", + "test": "vscode-test" + }, + "categories": [ + "Other" + ], + "contributes": { + "commands": [{ + "command": "testCom.helloWorld", + "title": "Hello World" + }] + } + }; + + assertFiles(runResult, 'testCom', ['src/extension.ts', 'src/test/extension.test.ts', 'tsconfig.json', '.npmrc', 'webpack.config.js']); + + runResult.assertJsonFileContent('testCom/package.json', expectedPackageJSON); + } finally { + cleanup(runResult); + } + }); + it('command-ts with esbuild + yarn', async () => { this.timeout(10000); @@ -1170,6 +1320,65 @@ describe('test code generator', function () { } }); + it('command-js with bun', async () => { + this.timeout(10000); + + const runResult = await helpers.run(appLocation).withAnswers({ + type: 'ext-command-js', + name: 'testCom', + displayName: 'Test Com', + description: 'My TestCom', + checkJavaScript: false, + gitInit: false, + pkgManager: 'bun', + openWith: 'skip' + }); // Mock the prompt answers + + + try { + const expectedPackageJSON = { + "name": "testCom", + "displayName": 'Test Com', + "description": "My TestCom", + "version": "0.0.1", + "engines": { + "vscode": engineVersion + }, + "activationEvents": [], + "devDependencies": devDependencies([ + "@types/vscode", + "@types/mocha", + "@types/node", + "eslint", + "typescript", + "@vscode/test-cli", + "@vscode/test-electron" + ]), + "main": "./extension.js", + "scripts": { + "lint": "eslint .", + "pretest": "bun run lint", + "test": "vscode-test" + }, + "categories": [ + "Other" + ], + "contributes": { + "commands": [{ + "command": "testCom.helloWorld", + "title": "Hello World" + }] + } + }; + + assertFiles(runResult, 'testCom', ['extension.js', 'test/extension.test.js', 'jsconfig.json', '.npmrc']); + + runResult.assertJsonFileContent('testCom/package.json', expectedPackageJSON); + } finally { + cleanup(runResult); + } + }); + it('command-js with check JS', async () => { this.timeout(10000); @@ -1374,6 +1583,51 @@ describe('test code generator', function () { } }); + it('language pack with bun', async () => { + const runResult = await helpers.run(appLocation).withAnswers({ + type: 'ext-localization', + name: "vscode-language-pack-ru", + displayName: "Russian Language Pack", + description: "Language pack extension for Russian", + lpLanguageId: 'ru', + lpLanguageName: 'Russian', + lpLocalizedLanguageName: 'русский', + pkgManager: 'bun', + openWith: 'skip' + }); + + try { + const expectedPackageJSON = { + "name": "vscode-language-pack-ru", + "displayName": "Russian Language Pack", + "description": "Language pack extension for Russian", + "version": "0.0.1", + "engines": { + "vscode": engineVersion + }, + "categories": [ + "Language Packs" + ], + "contributes": { + "localizations": [{ + "languageId": "ru", + "languageName": "Russian", + "localizedLanguageName": "русский" + }] + }, + "scripts": { + "update": "cd ../vscode && bun run update-localization-extension ru" + } + }; + + assertFiles(runResult, 'vscode-language-pack-ru', []); + + runResult.assertJsonFileContent('vscode-language-pack-ru/package.json', expectedPackageJSON); + } finally { + cleanup(runResult); + } + }); + it('command-web', async () => { this.timeout(10000); @@ -1516,6 +1770,78 @@ describe('test code generator', function () { } }); + it('command-web with bun', async () => { + this.timeout(10000); + + const runResult = await helpers.run(appLocation).withAnswers({ + type: 'ext-command-web', + name: 'testCom', + displayName: 'Test Com', + description: 'My TestCom', + gitInit: true, + pkgManager: 'bun', + bundler: 'webpack', + openWith: 'skip' + }); // Mock the prompt answers + + + try { + const expectedPackageJSON = { + "name": "testCom", + "displayName": 'Test Com', + "description": "My TestCom", + "version": "0.0.1", + "engines": { + "vscode": engineVersion + }, + "activationEvents": [], + "devDependencies": devDependencies([ + "@types/vscode", + "@types/mocha", + "@types/webpack-env", + "eslint", + "@typescript-eslint/parser", + "@typescript-eslint/eslint-plugin", + "assert", + "mocha", + "process", + "typescript", + "ts-loader", + "vscode-test-web", + "webpack", + "webpack-cli" + ]), + "browser": "./dist/web/extension.js", + "scripts": { + "test": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. --extensionTestsPath=dist/web/test/suite/index.js", + "pretest": "bun run compile-web", + "vscode:prepublish": "bun run package-web", + "compile-web": "webpack", + "watch-web": "webpack --watch", + "package-web": "webpack --mode production --devtool hidden-source-map", + "lint": "eslint src --ext ts", + "run-in-browser": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. ." + }, + "categories": [ + "Other" + ], + "contributes": { + "commands": [{ + "command": "testCom.helloWorld", + "title": "Hello World" + }] + } + }; + + assertFiles(runResult, 'testCom', ['src/web/extension.ts', 'webpack.config.js', 'src/web/test/suite/extension.test.ts', 'src/web/test/suite/index.ts', 'tsconfig.json', '.npmrc']); + + runResult.assertJsonFileContent('testCom/package.json', expectedPackageJSON); + } finally { + cleanup(runResult); + } + }); + + it('command-web-esbuild with yarn', async () => { this.timeout(10000); @@ -1753,3 +2079,86 @@ describe('test code generator', function () { } }) }); + +it('sample notebook renderer with bun', async () => { + + const runResult = await helpers.run(appLocation).withAnswers({ + type: 'ext-notebook-renderer', + name: 'json-renderer-ext', + displayName: 'Cool JSON Renderer Extension', + description: '', + rendererId: 'json-renderer', + rendererDisplayName: 'JSON Renderer', + gitInit: true, + pkgManager: 'bun', + bundler: 'webpack', + openWith: 'skip' + }); + + try { + + + const expectedPackageJSON = { + "name": "json-renderer-ext", + "displayName": "Cool JSON Renderer Extension", + "description": "", + "version": "0.0.1", + "engines": { + "vscode": engineVersion + }, + "keywords": [ + "notebookRenderer" + ], + "categories": [ + "Other" + ], + "activationEvents": [], + "main": "./out/extension/extension.js", + "contributes": { + "notebookRenderer": [ + { + "entrypoint": "./out/client/index.js", + "id": "json-renderer", + "displayName": "JSON Renderer", + "mimeTypes": ["x-application/custom-json-output"] + } + ] + }, + "scripts": { + "vscode:prepublish": "bun run compile", + "compile": "webpack --mode production", + "lint": "eslint src --ext ts", + "watch": "webpack --mode development --watch", + "pretest": "webpack --mode development && bun run lint", + "test": "vscode-test" + }, + "devDependencies": devDependencies([ + "@types/mocha", + "@types/node", + "@types/vscode", + "@types/webpack-env", + "@typescript-eslint/eslint-plugin", + "@typescript-eslint/parser", + "@types/vscode-notebook-renderer", + "css-loader", + "eslint", + "fork-ts-checker-webpack-plugin", + "style-loader", + "ts-loader", + "typescript", + "vscode-notebook-error-overlay", + "@vscode/test-cli", + "@vscode/test-electron", + "util", + "webpack", + "webpack-cli", + ]) + }; + + assertFiles(runResult, 'json-renderer-ext', ['webpack.config.js', '.gitignore', '.eslintrc.json', '.vscode-test.mjs', '.npmrc']); + + runResult.assertJsonFileContent('json-renderer-ext/package.json', expectedPackageJSON); + } finally { + cleanup(runResult); + } +})