Skip to content

Commit

Permalink
extensionPath options to add additional extensions. Fixes #5
Browse files Browse the repository at this point in the history
  • Loading branch information
aeschli committed Sep 24, 2021
1 parent 49082d4 commit 8ff1e83
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 24 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Changelog

## 0.0.14

* new option `--permission`: Permission granted to the opened browser: e.g. clipboard-read, clipboard-write. See full list of options [here](https://playwright.dev/docs/1.14/emulation#permissions). Argument can be added multiple times.
* new option `--extensionPath` : A path pointing to a folder containing additional extensions to include. Argument can be provided multiple times.
* new option `--permission`: Permission granted to the opened browser: e.g. clipboard-read, clipboard-write. See full list of options [here](https://playwright.dev/docs/1.14/emulation#permissions). Argument can be provided multiple times.
* new option `--hideServerLog`: If set, hides the server log. Defaults to true when an extensionTestsPath is provided, otherwise false.
* close server when browser is closed

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,15 @@ CLI options:
|Option|Argument Description||
|-----|-----|----|
| --browserType | The browser to launch: `chromium` (default), `firefox` or `webkit` |
| --extensionDevelopmentPath | A path pointing to an extension to include. |
| --extensionDevelopmentPath | A path pointing to an extension under development to include. |
| --extensionTestsPath | A path to a test module to run. |
| --version | `insiders` (default), `stable` or `sources`.<br>For sources, also run `yarn web` in a vscode repo |
| --open-devtools| If set, opens the dev tools |
| --headless| If set, hides the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. |
| --hideServerLog| If set, hides the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. |
| --permission| Permission granted to the opened browser: e.g. `clipboard-read`, `clipboard-write`. See [full list of options](https://playwright.dev/docs/api/class-browsercontext#browser-context-grant-permissions). Argument can be added multiple times. |
| --permission| Permission granted to the opened browser: e.g. `clipboard-read`, `clipboard-write`. See [full list of options](https://playwright.dev/docs/api/class-browsercontext#browser-context-grant-permissions). Argument can be provided multiple times. |
| --folder-uri | URI of the workspace to open VS Code on. Ignored when `folderPath` is provided |
| --extensionPath | A path pointing to a folder containing additional extensions to include. Argument can be provided multiple times. |
| folderPath | A local folder to open VS Code on. The folder content will be available as a virtual file system and opened as workspace. |

Corresponding options are available in the API.
Expand Down
51 changes: 44 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ export interface Options {
* Example: [ 'clipboard-read', 'clipboard-write' ]
*/
permissions?: string[];

/**
* Absolute paths pointing to built-in extensions to include.
*/
extensionPaths?: string[];
}

export interface Disposable {
Expand All @@ -110,7 +115,8 @@ export async function runTests(options: Options & { extensionTestsPath: string }
build: await getBuild(options.version),
folderUri: options.folderUri,
folderMountPath: options.folderPath,
hideServerLog: true
hideServerLog: true,
extensionPaths: options.extensionPaths
};

const port = 3000;
Expand Down Expand Up @@ -155,6 +161,7 @@ export async function open(options: Options): Promise<Disposable> {
build: await getBuild(options.version),
folderUri: options.folderUri,
folderMountPath: options.folderPath,
extensionPaths: options.extensionPaths
};

const port = 3000;
Expand Down Expand Up @@ -271,12 +278,37 @@ function valdiatePermissions(permissions: unknown): string[] | undefined {
return permissions;
}

console.log(`Invalid browser type.`);
console.log(`Invalid permission`);
showHelp();
process.exit(-1);
}

async function validatePath(loc: string, isFile?: boolean): Promise<string | undefined> {
async function valdiateExtensionPaths(extensionPaths: unknown): Promise<string[] | undefined> {
if (extensionPaths === undefined) {
return undefined
}
if (!Array.isArray(extensionPaths)) {
extensionPaths = [extensionPaths];
}
if (Array.isArray(extensionPaths)) {
const res: string[] = [];
for (const extensionPath of extensionPaths) {
if (typeof extensionPath === 'string') {
res.push(await validatePath(extensionPath));
} else {
break;
}
}
return res;
}

console.log(`Invalid extensionPath`);
showHelp();
process.exit(-1);
}


async function validatePath(loc: string, isFile?: boolean): Promise<string> {
loc = path.resolve(loc);
if (isFile) {
if (!await fileExists(loc)) {
Expand Down Expand Up @@ -322,29 +354,32 @@ interface CommandLineOptions {
hideServerLog?: boolean;
'folder-uri'?: string;
permission?: string | string[];
extensionPath: string | string[];
}

function showHelp() {
console.log('Usage:');
console.log(` --browserType 'chromium' | 'firefox' | 'webkit': The browser to launch. [Optional, default 'chromium']`)
console.log(` --extensionDevelopmentPath path: A path pointing to an extension to include. [Optional]`);
console.log(` --extensionDevelopmentPath path: A path pointing to an extension under development to include. [Optional]`);
console.log(` --extensionTestsPath path: A path to a test module to run. [Optional]`);
console.log(` --version 'insiders' | 'stable' | 'sources' [Optional, default 'insiders']`);
console.log(` --open-devtools: If set, opens the dev tools [Optional]`);
console.log(` --headless: Whether to hide the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
console.log(` --hideServerLog: Whether to hide the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
console.log(` --permission: Permission granted in the opened browser: e.g. 'clipboard-read', 'clipboard-write': [Optional, Multiple]`);
console.log(` --folder-uri: workspace to open VS Code on. Ignored when folderPath is provided [Optional]`);
console.log(` --extensionPath: A path pointing to a folder containing additional extensions to include [Optional, Multiple]`);
console.log(` folderPath. A local folder to open VS Code on. The folder content will be available as a virtual file system. [Optional]`);
}

async function cliMain(): Promise<void> {
const options: minimist.Opts = { string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'version', 'waitForDebugger', 'folder-uri', 'permission'], boolean: ['open-devtools', 'headless', 'hideServerLog'] };
const options: minimist.Opts = { string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'version', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath'], boolean: ['open-devtools', 'headless', 'hideServerLog'] };
const args = minimist<CommandLineOptions>(process.argv.slice(2), options);

const browserType = valdiateBrowserType(args.browserType);
const extensionTestsPath = await validatePathOrUndefined(args, 'extensionTestsPath', true);
const extensionDevelopmentPath = await validatePathOrUndefined(args, 'extensionDevelopmentPath');
const extensionPaths = await valdiateExtensionPaths(args.extensionPath);
const version = validateVersion(args.version);
const devTools = validateBooleanOrUndefined(args, 'open-devtools');
const headless = validateBooleanOrUndefined(args, 'headless');
Expand Down Expand Up @@ -380,7 +415,8 @@ async function cliMain(): Promise<void> {
folderPath,
headless,
hideServerLog,
permissions
permissions,
extensionPaths
})
} else {
open({
Expand All @@ -393,7 +429,8 @@ async function cliMain(): Promise<void> {
folderPath,
headless,
hideServerLog,
permissions
permissions,
extensionPaths
})
}
}
Expand Down
12 changes: 7 additions & 5 deletions src/server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ export default async function createApp(config: IConfig): Promise<Koa> {

app.use(kmount('/static', kstatic(path.join(__dirname, '../static'))));

if (config.extensionPath) {
console.log('Serving extensions from ' + config.extensionPath);
app.use(kmount('/static/extensions', kstatic(config.extensionPath, { hidden: true })));
}

if (config.extensionDevelopmentPath) {
console.log('Serving dev extensions from ' + config.extensionDevelopmentPath);
app.use(kmount('/static/devextensions', kstatic(config.extensionDevelopmentPath, { hidden: true })));
Expand All @@ -43,6 +38,13 @@ export default async function createApp(config: IConfig): Promise<Koa> {

configureMounts(config, app);

if (config.extensionPaths) {
config.extensionPaths.forEach((extensionPath, index) => {
console.log('Serving additional built-in extensions from ' + extensionPath);
app.use(kmount(`/static/extensions/${index}`, kstatic(extensionPath, { hidden: true })));
});
}

app.use(workbench(config));

return app;
Expand Down
2 changes: 1 addition & 1 deletion src/server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import createApp from './app';

export interface IConfig {
readonly extensionPath?: string;
readonly extensionPaths?: string[];
readonly extensionDevelopmentPath?: string;
readonly extensionTestsPath?: string;
readonly build: Sources | Static | CDN;
Expand Down
2 changes: 1 addition & 1 deletion src/server/mounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Dirent, promises as fs, Stats } from 'fs';
import * as path from 'path';

const mountPrefix = '/static/mount';
export const fsProviderExtensionPrefix = '/static/fsproviderextension';
export const fsProviderExtensionPrefix = '/static/extensions/fs';
export const fsProviderFolderUri = 'vscode-test-web://mount/';

export function configureMounts(config: IConfig, app: Koa): void {
Expand Down
14 changes: 8 additions & 6 deletions src/server/workbench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@ async function getWorkbenchOptions(
config: IConfig
): Promise<IWorkbenchOptions> {
const options: IWorkbenchOptions = {};
if (config.extensionPath) {
options.additionalBuiltinExtensions = await scanForExtensions(config.extensionPath, {
scheme: ctx.protocol,
authority: ctx.host,
path: '/static/extensions',
});
if (config.extensionPaths) {
await Promise.all(config.extensionPaths.map(async (extensionPath, index) => {
options.additionalBuiltinExtensions = await scanForExtensions(extensionPath, {
scheme: ctx.protocol,
authority: ctx.host,
path: `/static/extensions/${index}`,
});
}));
}
if (config.extensionDevelopmentPath) {
const developmentOptions: IDevelopmentOptions = options.developmentOptions = {}
Expand Down

0 comments on commit 8ff1e83

Please sign in to comment.