Skip to content

Commit ddb5445

Browse files
authored
Add a script to copy language server and debugger binaries to the Extension folder (#14370)
1 parent 2db5c05 commit ddb5445

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/* --------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All Rights Reserved.
3+
* See 'LICENSE' in the project root for license information.
4+
* ------------------------------------------------------------------------------------------ */
5+
6+
import { cp, readdir, rm, stat } from 'node:fs/promises';
7+
import { homedir } from 'node:os';
8+
import { join } from 'node:path';
9+
import { $args, $root, green, heading, note } from './common';
10+
11+
const extensionPrefix = 'ms-vscode.cpptools-';
12+
const foldersToCopy = ['bin', 'debugAdapters', 'LLVM'] as const;
13+
14+
type InstalledExtension = {
15+
path: string;
16+
version: number[];
17+
modified: number;
18+
};
19+
20+
function compareVersions(left: number[], right: number[]): number {
21+
const maxLength: number = Math.max(left.length, right.length);
22+
for (let i = 0; i < maxLength; i++) {
23+
const diff: number = (left[i] ?? 0) - (right[i] ?? 0);
24+
if (diff !== 0) {
25+
return diff;
26+
}
27+
}
28+
return 0;
29+
}
30+
31+
function tryParseVersion(folderName: string): number[] | undefined {
32+
if (!folderName.startsWith(extensionPrefix)) {
33+
return undefined;
34+
}
35+
36+
const versionText: string | undefined = folderName.substring(extensionPrefix.length).match(/^\d+\.\d+\.\d+/)?.[0];
37+
return versionText?.split('.').map(each => Number(each));
38+
}
39+
40+
async function getInstalledExtensions(root: string): Promise<InstalledExtension[]> {
41+
try {
42+
const entries = await readdir(root, { withFileTypes: true });
43+
const candidates: Promise<InstalledExtension | undefined>[] = entries.map(async (entry) => {
44+
if (!entry.isDirectory()) {
45+
return undefined;
46+
}
47+
48+
const version: number[] | undefined = tryParseVersion(entry.name);
49+
if (!version) {
50+
return undefined;
51+
}
52+
53+
const extensionPath: string = join(root, entry.name);
54+
for (const folder of foldersToCopy) {
55+
const info = await stat(join(extensionPath, folder)).catch(() => undefined);
56+
if (!info?.isDirectory()) {
57+
return undefined;
58+
}
59+
}
60+
61+
const info = await stat(extensionPath);
62+
return {
63+
path: extensionPath,
64+
version,
65+
modified: info.mtimeMs
66+
};
67+
});
68+
69+
const found = await Promise.all(candidates);
70+
return found.filter((entry): entry is InstalledExtension => entry !== undefined);
71+
} catch {
72+
return [];
73+
}
74+
}
75+
76+
async function findLatestInstalledExtension(providedPath?: string): Promise<string> {
77+
if (providedPath) {
78+
return providedPath;
79+
}
80+
81+
const searchRoots: string[] = [
82+
join(homedir(), '.vscode', 'extensions'),
83+
join(homedir(), '.vscode-insiders', 'extensions'),
84+
join(homedir(), '.vscode-server', 'extensions'),
85+
join(homedir(), '.vscode-server-insiders', 'extensions')
86+
];
87+
88+
const installed: InstalledExtension[] = (await Promise.all(searchRoots.map(each => getInstalledExtensions(each)))).flat();
89+
if (!installed.length) {
90+
throw new Error(`Unable to find an installed C/C++ extension under ${searchRoots.join(' or ')}.`);
91+
}
92+
93+
installed.sort((left, right) => compareVersions(right.version, left.version) || right.modified - left.modified);
94+
return installed[0].path;
95+
}
96+
97+
export async function main(sourcePath = $args[0]) {
98+
console.log(heading('Copy installed extension binaries'));
99+
100+
const installedExtensionPath: string = await findLatestInstalledExtension(sourcePath);
101+
note(`Using installed extension at ${installedExtensionPath}`);
102+
103+
for (const folder of foldersToCopy) {
104+
const source: string = join(installedExtensionPath, folder);
105+
const destination: string = join($root, folder);
106+
107+
console.log(`Copying ${green(folder)} from ${source}`);
108+
await rm(destination, { recursive: true, force: true });
109+
await cp(source, destination, { recursive: true, force: true });
110+
}
111+
112+
note(`Copied installed binaries into ${$root}`);
113+
}

Extension/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6805,6 +6805,7 @@
68056805
"generate-native-strings": "ts-node -T ./.scripts/generateNativeStrings.ts",
68066806
"generate-options-schema": "ts-node -T ./.scripts/generateOptionsSchema.ts",
68076807
"copy-walkthrough-media": "ts-node -T ./.scripts/copyWalkthruMedia.ts",
6808+
"copy-extension-binaries": "ts-node -T ./.scripts/copyExtensionBinaries.ts",
68086809
"translations-export": "yarn install && yarn prep && yarn generate-native-strings && gulp translations-export",
68096810
"translations-generate": "gulp translations-generate",
68106811
"translations-import": "gulp translations-import",

0 commit comments

Comments
 (0)