Skip to content

Commit

Permalink
new option --commit
Browse files Browse the repository at this point in the history
  • Loading branch information
aeschli committed Sep 2, 2024
1 parent 0908eea commit a89cbd0
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Changelog
## 0.0.58
* new option `--commit` to specify the build of VS Code to use. By default the latest build is used.

## 0.0.37
* new option `--testRunnerDataDir` to set the temporary folder for storing the VS Code builds used for running the tests


## 0.0.28
* new option `--coi` to enable cross origin isolation.

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ CLI options:
| --extensionDevelopmentPath | A path pointing to an extension under development to include. |
| --extensionTestsPath | A path to a test module to run. |
| --quality | `insiders` (default), or `stable`. Ignored when sourcesPath is provided. |
| --commit | commitHash The servion of the server to use. Defaults to latest build version of the given quality. Ignored when sourcesPath is provided. |
| --sourcesPath | If set, runs the server from VS Code sources located at the given path. Make sure the sources and extensions are compiled (`yarn compile` and `yarn compile-web`). |
| --headless | If set, hides the browser. 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 provided multiple times. |
Expand Down
32 changes: 30 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ export interface Options {
*/
quality?: VSCodeQuality;

/**
* The commit of the VS Code build to use. If not set, the latest build is used.
*
* The setting is ignored when a vsCodeDevPath is provided.
*/
commit?: string;

/**
* @deprecated. Use `quality` or `vsCodeDevPath` instead.
*/
Expand Down Expand Up @@ -230,8 +237,9 @@ async function getBuild(options: Options): Promise<Static | Sources> {
};
}
const quality = options.quality || options.version;
const commit = options.commit;
const testRunnerDataDir = options.testRunnerDataDir ?? path.resolve(process.cwd(), '.vscode-test-web');
return await downloadAndUnzipVSCode(quality === 'stable' ? 'stable' : 'insider', testRunnerDataDir);
return await downloadAndUnzipVSCode(testRunnerDataDir, quality === 'stable' ? 'stable' : 'insider', commit);
}

export async function open(options: Options): Promise<Disposable> {
Expand Down Expand Up @@ -514,6 +522,21 @@ function validateQuality(quality: unknown, version: unknown, vsCodeDevPath: stri
process.exit(-1);
}

function validateCommit(commit: unknown, vsCodeDevPath: string | undefined): string | undefined {

if (vsCodeDevPath && commit) {
console.log(`Sources folder is provided as input, commit is ignored.`);
return undefined;
}
if (commit === undefined || (typeof commit === 'string' && commit.match(/^[0-9a-f]{40}$/))) {
return commit;
} else {
console.log(`Invalid format for commit. Expected a 40 character long SHA1 hash.`);
}
showHelp();
process.exit(-1);
}

function validatePortNumber(port: unknown): number | undefined {
if (typeof port === 'string') {
const number = Number.parseInt(port);
Expand All @@ -531,6 +554,7 @@ interface CommandLineOptions {
extensionDevelopmentPath?: string;
extensionTestsPath?: string;
quality?: string;
commit?: string;
sourcesPath?: string;
'open-devtools'?: boolean;
headless?: boolean;
Expand All @@ -556,6 +580,7 @@ function showHelp() {
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(` --quality 'insiders' | 'stable' [Optional, default 'insiders', ignored when running from sources]`);
console.log(` --commit commitHash [Optional, defaults to latest build version of the given quality, ignored when running from sources]`);
console.log(` --sourcesPath path: If provided, running from VS Code sources at the given location. [Optional]`);
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]`);
Expand Down Expand Up @@ -588,7 +613,7 @@ async function cliMain(): Promise<void> {
console.log(`${manifest.name}: ${manifest.version}`);

const options: minimist.Opts = {
string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browser', 'browserOption', 'browserType', 'quality', 'version', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath', 'extensionId', 'sourcesPath', 'host', 'port', 'testRunnerDataDir'],
string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browser', 'browserOption', 'browserType', 'quality', 'version', 'commit', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath', 'extensionId', 'sourcesPath', 'host', 'port', 'testRunnerDataDir'],
boolean: ['open-devtools', 'headless', 'hideServerLog', 'printServerLog', 'help', 'verbose', 'coi', 'esm'],
unknown: arg => {
if (arg.startsWith('-')) {
Expand All @@ -613,6 +638,7 @@ async function cliMain(): Promise<void> {
const extensionIds = await validateExtensionIds(args.extensionId);
const vsCodeDevPath = await validatePathOrUndefined(args, 'sourcesPath');
const quality = validateQuality(args.quality, args.version, vsCodeDevPath);
const commit = validateCommit(args.commit, vsCodeDevPath);
const devTools = validateBooleanOrUndefined(args, 'open-devtools');
const headless = validateBooleanOrUndefined(args, 'headless');
const permissions = validatePermissions(args.permission);
Expand Down Expand Up @@ -648,6 +674,7 @@ async function cliMain(): Promise<void> {
browserOptions,
browserType,
quality,
commit,
devTools,
waitForDebugger,
folderUri,
Expand All @@ -674,6 +701,7 @@ async function cliMain(): Promise<void> {
browserOptions,
browserType,
quality,
commit,
devTools,
waitForDebugger,
folderUri,
Expand Down
32 changes: 26 additions & 6 deletions src/server/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ interface DownloadInfo {
version: string;
}

async function getLatestVersion(quality: 'stable' | 'insider'): Promise<DownloadInfo> {
const update: DownloadInfo = await fetchJSON(`https://update.code.visualstudio.com/api/update/web-standalone/${quality}/latest`);
return update;
async function getDownloadInfo(quality: 'stable' | 'insider', commit: string | undefined): Promise<DownloadInfo> {
if (commit) {
const url = await getRedirect(`https://update.code.visualstudio.com/commit:${commit}/web-standalone/${quality}`);
if (!url) {
throw new Error('Failed to download URL for commit ' + commit + '. Is it valid?');
}
return { url, version: commit };
}
return await fetchJSON(`https://update.code.visualstudio.com/api/update/web-standalone/${quality}/latest`);
}

const reset = '\x1b[G\x1b[0K';
Expand Down Expand Up @@ -72,8 +78,9 @@ async function downloadAndUntar(downloadUrl: string, destination: string, messag
});
}

export async function downloadAndUnzipVSCode(quality: 'stable' | 'insider', vscodeTestDir: string): Promise<Static> {
const info = await getLatestVersion(quality);

export async function downloadAndUnzipVSCode(vscodeTestDir: string, quality: 'stable' | 'insider', commit: string | undefined): Promise<Static> {
const info = await getDownloadInfo(quality, commit);

const folderName = `vscode-web-${quality}-${info.version}`;

Expand All @@ -95,7 +102,7 @@ export async function downloadAndUnzipVSCode(quality: 'stable' | 'insider', vsco
await fs.writeFile(path.join(downloadedPath, 'version'), folderName);
} catch (err) {
console.error(err);
throw Error(`Failed to download and unpack ${productName}`);
throw Error(`Failed to download and unpack ${productName}.${commit ? ' Did you specify a valid commit?' : ''}`);
}
return { type: 'static', location: downloadedPath, quality, version: info.version };
}
Expand Down Expand Up @@ -124,6 +131,19 @@ export async function fetch(api: string): Promise<string> {
});
});
}
export async function getRedirect(api: string): Promise<string | undefined> {
return new Promise((resolve, reject) => {
const httpLibrary = api.startsWith('https') ? https : http;
httpLibrary.get(api, { method: 'HEAD', ...getAgent(api) }, res => {
console.log(res.statusCode, res.headers.location);
if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307) {
resolve(res.headers.location);
} else {
resolve(undefined);
}
});
});
}

export async function fetchJSON<T>(api: string): Promise<T> {
const data = await fetch(api);
Expand Down

0 comments on commit a89cbd0

Please sign in to comment.