Merge remote-tracking branch 'origin/main' into pr/Dylan-86/414

This commit is contained in:
Andrew Pareles 2025-04-29 00:54:55 -07:00
commit c16a45c647
1343 changed files with 104063 additions and 30869 deletions

View file

@ -0,0 +1,46 @@
{
"hydrated": false,
"properties": {
"helpUri": "https://eng.ms/docs/microsoft-security/security/azure-security/cloudai-security-fundamentals-engineering/security-integration/guardian-wiki/microsoft-guardian/general/suppressions"
},
"version": "1.0.0",
"suppressionSets": {
"default": {
"name": "default",
"createdDate": "2025-03-17 11:52:32Z",
"lastUpdatedDate": "2025-03-17 11:52:32Z"
}
},
"results": {
"216e2ac9cb596796224b47799f656570a01fa0d9b5f935608b47d15ab613c8e8": {
"signature": "216e2ac9cb596796224b47799f656570a01fa0d9b5f935608b47d15ab613c8e8",
"alternativeSignatures": [
"07746898f43afab7cc50931b33154c2d9e1a35f82a649dbe8aecf785b3d5a813"
],
"memberOf": [
"default"
],
"createdDate": "2025-03-17 11:52:32Z"
},
"77797a3e44634bb2994bd13ccc95ff4575bba474585dbd2cf3068a1c16bc0624": {
"signature": "77797a3e44634bb2994bd13ccc95ff4575bba474585dbd2cf3068a1c16bc0624",
"alternativeSignatures": [
"4a6cb67bd4b401e9669c13a2162660aaefc0a94a4122e5b50c198414db545672"
],
"memberOf": [
"default"
],
"createdDate": "2025-03-17 11:52:32Z"
},
"30418bcc5269eaeb2832a2404465784431d4e72a2af332320c2b1db4768902ad": {
"signature": "30418bcc5269eaeb2832a2404465784431d4e72a2af332320c2b1db4768902ad",
"alternativeSignatures": [
"b7b9eb974d7d3a4ae14df8695ca5a62592c8c9d20b7eda70a6535d50cbda3e7f"
],
"memberOf": [
"default"
],
"createdDate": "2025-03-17 11:52:32Z"
}
}
}

View file

@ -1,6 +1,6 @@
# Code - OSS Development Container
[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode)
[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode)
This repository includes configuration for a development container for working with Code - OSS in a local container or using [GitHub Codespaces](https://github.com/features/codespaces).

View file

@ -11,10 +11,10 @@
**/extensions/markdown-language-features/notebook-out/**
**/extensions/markdown-math/notebook-out/**
**/extensions/notebook-renderers/renderer-out/index.js
**/extensions/open-remote-ssh/out/extension.js
**/extensions/simple-browser/media/index.js
**/extensions/terminal-suggest/src/completions/upstream/**
**/extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts
**/extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts
**/extensions/terminal-suggest/third_party/**
**/extensions/typescript-language-features/test-workspace/**
**/extensions/typescript-language-features/extension.webpack.config.js
@ -37,4 +37,5 @@
**/test/unit/assert.js
**/test/automation/out/**
**/typings/**
**/.build/**
!.vscode

View file

@ -51,7 +51,7 @@ export = new class ApiProviderNaming implements eslint.Rule.RuleModule {
node,
messageId: 'amdX'
});
}
};
return {
['ImportExpression Literal']: checkImport,

View file

@ -19,7 +19,7 @@ export = new class DeclareServiceBrand implements eslint.Rule.RuleModule {
node,
message: `The '_serviceBrand'-property should not have a value`,
fix: (fixer) => {
return fixer.replaceText(node, 'declare _serviceBrand: undefined;')
return fixer.replaceText(node, 'declare _serviceBrand: undefined;');
}
});
}

View file

@ -27,7 +27,7 @@ export = new class EnsureNoDisposablesAreLeakedInTestSuite implements eslint.Rul
return {
[`Program > ExpressionStatement > CallExpression[callee.name='suite']`]: (node: Node) => {
const src = context.getSourceCode().getText(node)
const src = context.getSourceCode().getText(node);
if (!src.includes('ensureNoDisposablesAreLeakedInTestSuite(')) {
context.report({
node,

View file

@ -44,7 +44,7 @@ export = new class implements eslint.Rule.RuleModule {
readonly meta: eslint.Rule.RuleMetaData = {
messages: {
badImport: 'Imports violates \'{{restrictions}}\' restrictions. See https://github.com/microsoft/vscode/wiki/Source-Code-Organization',
badFilename: 'Missing definition in `code-import-patterns` for this file. Define rules at https://github.com/microsoft/vscode/blob/main/.eslintrc.json',
badFilename: 'Missing definition in `code-import-patterns` for this file. Define rules at https://github.com/microsoft/vscode/blob/main/eslint.config.js',
badAbsolute: 'Imports have to be relative to support ESM',
badExtension: 'Imports have to end with `.js` or `.css` to support ESM',
},

View file

@ -14,13 +14,13 @@ export = new class implements eslint.Rule.RuleModule {
layerbreaker: 'You are only allowed to define limited top level functions.'
},
schema: {
type: "array",
type: 'array',
items: {
type: "object",
type: 'object',
additionalProperties: {
type: "array",
type: 'array',
items: {
type: "string"
type: 'string'
}
}
}
@ -65,6 +65,6 @@ export = new class implements eslint.Rule.RuleModule {
}
}
}
}
};
}
};

View file

@ -14,22 +14,22 @@ const VALID_USES = new Set<TSESTree.AST_NODE_TYPES | undefined>([
export = new class MustUseResults implements eslint.Rule.RuleModule {
readonly meta: eslint.Rule.RuleMetaData = {
schema: false
}
};
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
const config = <{ message: string, functions: string[] }[]>context.options[0];
const config = <{ message: string; functions: string[] }[]>context.options[0];
const listener: eslint.Rule.RuleListener = {};
for (const { message, functions } of config) {
for (const fn of functions) {
const query = `CallExpression[callee.property.name='${fn}'], CallExpression[callee.name='${fn}']`
const query = `CallExpression[callee.property.name='${fn}'], CallExpression[callee.name='${fn}']`;
listener[query] = (node: any) => {
const cast: TSESTree.CallExpression = node;
if (!VALID_USES.has(cast.parent?.type)) {
context.report({ node, message });
}
}
};
}
}

View file

@ -14,7 +14,7 @@ export = new class NoAsyncSuite implements eslint.Rule.RuleModule {
return;
}
const body = context.getSourceCode().getText(node)
const body = context.getSourceCode().getText(node);
if (body.includes('super.dispose')) {
return;

View file

@ -32,7 +32,7 @@ export = new class NoDangerousTypeAssertions implements eslint.Rule.RuleModule {
context.report({
node,
message: "Don't use type assertions for creating objects as this can hide type errors."
message: `Don't use type assertions for creating objects as this can hide type errors.`
});
},
};

View file

@ -25,6 +25,6 @@ export = new class NoGlobalDocumentListener implements eslint.Rule.RuleModule {
});
}
},
}
};
}
};

View file

@ -24,7 +24,7 @@ export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)editor.worker.start/.test(fileName)
) {
return createImportRuleListener((node, path) => {
// resolve relative paths

View file

@ -16,13 +16,13 @@ export = new class implements eslint.Rule.RuleModule {
layerbreaker: 'You are only allowed to import {{import}} from here using `import type ...`.'
},
schema: {
type: "array",
type: 'array',
items: {
type: "object",
type: 'object',
additionalProperties: {
type: "array",
type: 'array',
items: {
type: "string"
type: 'string'
}
}
}

View file

@ -38,7 +38,7 @@ export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.worker.start/.test(path)
) {
context.report({
loc: node.loc,

View file

@ -26,19 +26,19 @@ export = new class implements eslint.Rule.RuleModule {
return;
}
const classCtor = classDeclaration.body.body.find(node => node.type === 'MethodDefinition' && node.kind === 'constructor')
const classCtor = classDeclaration.body.body.find(node => node.type === 'MethodDefinition' && node.kind === 'constructor');
if (!classCtor) {
return;
}
const name = classDeclaration.id.name;
const valueText = context.sourceCode.getText(<any>propertyDefinition.value)
const valueText = context.sourceCode.getText(<any>propertyDefinition.value);
if (valueText.includes(name + '.')) {
if (classCtor.value?.type === 'FunctionExpression' && !classCtor.value.params.find((param: any) => param.type === 'TSParameterProperty' && param.decorators?.length > 0)) {
return
return;
}
context.report({

View file

@ -58,7 +58,7 @@ module.exports = {
allowTernary = config.allowTernary || false,
allowTaggedTemplates = config.allowTaggedTemplates || false;
// eslint-disable-next-line jsdoc/require-description
/**
* @param node any node
* @returns whether the given node structurally represents a directive
@ -68,7 +68,7 @@ module.exports = {
node.expression.type === 'Literal' && typeof node.expression.value === 'string';
}
// eslint-disable-next-line jsdoc/require-description
/**
* @param predicate ([a] -> Boolean) the function used to make the determination
* @param list the input list
@ -83,7 +83,7 @@ module.exports = {
return list.slice();
}
// eslint-disable-next-line jsdoc/require-description
/**
* @param node a Program or BlockStatement node
* @returns the leading sequence of directive nodes in the given node's body
@ -92,7 +92,7 @@ module.exports = {
return takeWhile(looksLikeDirective, node.body);
}
// eslint-disable-next-line jsdoc/require-description
/**
* @param node any node
* @param ancestors the given node's ancestors

View file

@ -1,3 +1,7 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const glob = require('glob');
const path = require('path');

View file

@ -19,7 +19,7 @@ export = new class ApiTypeDiscrimination implements eslint.Rule.RuleModule {
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
return {
['TSPropertySignature[optional=false] TSTypeAnnotation TSLiteralType Literal']: (node: any) => {
const raw = String((<TSESTree.Literal>node).raw)
const raw = String((<TSESTree.Literal>node).raw);
if (/^('|").*\1$/.test(raw)) {
@ -29,6 +29,6 @@ export = new class ApiTypeDiscrimination implements eslint.Rule.RuleModule {
});
}
}
}
};
}
};

View file

@ -0,0 +1,9 @@
---
name: Issue
about: Submit an Issue to Void
title: For VSCode-related issues (eg builds), please start the title with `[App]`. Otherwise, start it with `[Bug]` or `[Feature]`.
---
1. Press `Cmd+Shift+P` in Void, and type `Help: About`. Please paste the information here. Also let us know any other relevant details, like the model and provider you're using if applicable.
2. Describe the issue/feature here.

2
.gitignore vendored
View file

@ -21,6 +21,8 @@ vscode.db
product.overrides.json
*.snap.actual
.vscode-test
# Void added these:
.tmp/
.tmp2/
.tool-versions

2
.npmrc
View file

@ -1,6 +1,6 @@
disturl="https://electronjs.org/headers"
target="34.3.2"
ms_build_id="11044223"
ms_build_id="11161073"
runtime="electron"
build_from_source="true"
legacy-peer-deps="true"

View file

@ -19,7 +19,7 @@ const { defineConfig } = require('@vscode/test-cli');
* A list of extension folders who have opted into tests, or configuration objects.
* Edit me to add more!
*
* @type {Array<string | (Partial<import("@vscode/test-cli").TestConfiguration> & { label: string })>}
* @type {Array<Partial<import("@vscode/test-cli").TestConfiguration> & { label: string }>}
*/
const extensions = [
{
@ -65,6 +65,20 @@ const extensions = [
{
label: 'microsoft-authentication',
mocha: { timeout: 60_000 }
},
{
label: 'vscode-api-tests-folder',
extensionDevelopmentPath: `extensions/vscode-api-tests`,
workspaceFolder: `extensions/vscode-api-tests/testWorkspace`,
mocha: { timeout: 60_000 },
files: 'extensions/vscode-api-tests/out/singlefolder-tests/**/*.test.js',
},
{
label: 'vscode-api-tests-workspace',
extensionDevelopmentPath: `extensions/vscode-api-tests`,
workspaceFolder: `extensions/vscode-api-tests/testworkspace.code-workspace`,
mocha: { timeout: 60_000 },
files: 'extensions/vscode-api-tests/out/workspace-tests/**/*.test.js',
}
];
@ -75,9 +89,12 @@ const defaultLaunchArgs = process.env.API_TESTS_EXTRA_ARGS?.split(' ') || [
const config = defineConfig(extensions.map(extension => {
/** @type {import('@vscode/test-cli').TestConfiguration} */
const config = typeof extension === 'object'
? { files: `extensions/${extension.label}/out/**/*.test.js`, ...extension }
: { files: `extensions/${extension}/out/**/*.test.js`, label: extension };
const config = {
platform: 'desktop',
files: `extensions/${extension.label}/out/**/*.test.js`,
extensionDevelopmentPath: `extensions/${extension.label}`,
...extension,
};
config.mocha ??= {};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {

61
.vscode/launch.json vendored
View file

@ -251,7 +251,51 @@
"timeout": 0,
"env": {
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null,
"VSCODE_SKIP_PRELAUNCH": "1"
"VSCODE_SKIP_PRELAUNCH": "1",
},
"cleanUp": "wholeBrowser",
"runtimeArgs": [
"--inspect-brk=5875",
"--no-cached-data",
"--crash-reporter-directory=${workspaceFolder}/.profile-oss/crashes",
// for general runtime freezes: https://github.com/microsoft/vscode/issues/127861#issuecomment-904144910
"--disable-features=CalculateNativeWinOcclusion",
"--disable-extension=vscode.vscode-api-tests"
],
"userDataDir": "${userHome}/.vscode-oss-dev",
"webRoot": "${workspaceFolder}",
"cascadeTerminateToConfigurations": [
"Attach to Extension Host"
],
"pauseForSourceMap": false,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"browserLaunchLocation": "workspace",
"presentation": {
"hidden": true,
},
},
{
// To debug observables you also need the extension "ms-vscode.debug-value-editor"
"type": "chrome",
"request": "launch",
"name": "Launch VS Code Internal (Dev Debug)",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.bat"
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.sh"
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.sh"
},
"port": 9222,
"timeout": 0,
"env": {
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null,
"VSCODE_SKIP_PRELAUNCH": "1",
"VSCODE_DEV_DEBUG": "1",
},
"cleanUp": "wholeBrowser",
"runtimeArgs": [
@ -568,6 +612,21 @@
"order": 1
}
},
{
"name": "VS Code (Debug Observables)",
"stopAll": true,
"configurations": [
"Launch VS Code Internal (Dev Debug)",
"Attach to Main Process",
"Attach to Extension Host",
"Attach to Shared Process",
],
"preLaunchTask": "Ensure Prelaunch Dependencies",
"presentation": {
"group": "0_vscode",
"order": 1
}
},
{
"name": "Search, Renderer, and Main processes",
"configurations": [

View file

@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPO=repo:microsoft/vscode\n$MILESTONE=milestone:\"February 2025\""
"value": "$REPO=repo:microsoft/vscode\n$MILESTONE=milestone:\"March 2025\""
},
{
"kind": 1,

View file

@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\r\n\r\n$MILESTONE=milestone:\"February 2025\""
"value": "$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\r\n\r\n$MILESTONE=milestone:\"March 2025\""
},
{
"kind": 1,

View file

@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n$MILESTONE=milestone:\"February 2025\"\n\n$MINE=assignee:@me"
"value": "$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n$MILESTONE=milestone:\"March 2025\"\n\n$MINE=assignee:@me"
},
{
"kind": 1,

View file

@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n// current milestone name\n$MILESTONE=milestone:\"February 2025\"\n"
"value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n// current milestone name\n$MILESTONE=milestone:\"March 2025\"\n"
},
{
"kind": 1,

View file

@ -49,6 +49,7 @@
"out-vscode-reh/**": true,
"extensions/**/dist/**": true,
"extensions/**/out/**": true,
"extensions/terminal-suggest/src/completions/upstream/**": true,
"test/smoke/out/**": true,
"test/automation/out/**": true,
"test/integration/browser/out/**": true
@ -156,6 +157,7 @@
"application.experimental.rendererProfiling": true,
"editor.experimental.asyncTokenization": true,
"editor.experimental.asyncTokenizationVerification": true,
"terminal.integrated.suggest.enabled": true,
"typescript.preferences.autoImportFileExcludePatterns": [
"@xterm/xterm",
"@xterm/headless",

6
.vscode/tasks.json vendored
View file

@ -29,7 +29,7 @@
}
}
},
{
{ // Void added this
"type": "npm",
"script": "watchreactd",
"label": "React - Build",
@ -89,8 +89,8 @@
"label": "VS Code - Build",
"dependsOn": [
"Core - Build",
"Ext - Build",
"React - Build"
"React - Build",
"Ext - Build"
],
"group": {
"kind": "build",

View file

@ -23,11 +23,11 @@ Most of Void's code lives in the folder `src/vs/workbench/contrib/void/`.
## Building Void
### a. Build Prerequisites - Mac
### a. Mac - Build Prerequisites
If you're using a Mac, you need Python and XCode. You probably have these by default.
### b. Build Prerequisites - Windows
### b. Windows - Build Prerequisites
If you're using a Windows computer, first get [Visual Studio 2022](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community) (recommended) or [VS Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) (not recommended). If you already have both, you might need to run the next few steps on both of them.
@ -42,7 +42,7 @@ Go to the "Individual Components" tab and select:
Finally, click Install.
### c. Build Prerequisites - Linux
### c. Linux - Build Prerequisites
First, run `npm install -g node-gyp`. Then:
@ -50,27 +50,27 @@ First, run `npm install -g node-gyp`. Then:
- Red Hat (Fedora, etc): `sudo dnf install @development-tools gcc gcc-c++ make libsecret-devel krb5-devel libX11-devel libxkbfile-devel`.
- Others: see [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute).
### d. Building Void
### d. Building Void from inside VSCode
1. `git clone https://github.com/voideditor/void` to clone the repo.
2. `npm install` to install all dependencies.
3. `npm run watchreact` to build Void's browser dependencies like React. (If this doesn't work, try `npm run buildreact`).
4. Build Void.
- Press <kbd>Cmd+Shift+B</kbd> (Mac).
- Press <kbd>Ctrl+Shift+B</kbd> (Windows/Linux).
- This step can take ~5 min. The build is done when you see two check marks (one of the items will continue spinning indefinitely - it compiles our React code).
5. Run Void.
- Run `./scripts/code.sh` (Mac/Linux).
- Run `./scripts/code.bat` (Windows).
6. Nice-to-knows.
- You can always press <kbd>Ctrl+R</kbd> (<kbd>Cmd+R</kbd>) inside the new window to reload and see your new changes. It's faster than <kbd>Ctrl+Shift+P</kbd> and `Reload Window`.
- You might want to add the flags `--user-data-dir ./.tmp/user-data --extensions-dir ./.tmp/extensions` to the above run command, which lets you delete the `.tmp` folder to reset any IDE changes you made when testing.
- You can kill any of the build scripts by pressing `Ctrl+D` in VSCode terminal. If you press `Ctrl+C` the script will close but will keep running in the background (to open all background scripts, just re-build).
3. Build Void.
- Press <kbd>Cmd+Shift+B</kbd> (Mac).
- Press <kbd>Ctrl+Shift+B</kbd> (Windows/Linux).
- This step can take ~5 min. The build is done when you see two check marks (one of the items will continue spinning indefinitely - it compiles our React code).
4. Run Void.
- Run `./scripts/code.sh` (Mac/Linux).
- Run `./scripts/code.bat` (Windows).
5. Nice-to-knows.
- You can always press <kbd>Ctrl+R</kbd> (<kbd>Cmd+R</kbd>) inside the new window to reload and see your new changes. It's faster than <kbd>Ctrl+Shift+P</kbd> and `Reload Window`.
- You might want to add the flags `--user-data-dir ./.tmp/user-data --extensions-dir ./.tmp/extensions` to the above run command, which lets you delete the `.tmp` folder to reset any IDE changes you made when testing.
- You can kill any of the build scripts by pressing `Ctrl+D` in VSCode terminal. If you press `Ctrl+C` the script will close but will keep running in the background (to open all background scripts, just re-build).
If you get any errors, scroll down for common fixes.
#### Building Void from Terminal
Alternatively, if you want to build Void from the terminal, instead of pressing <kbd>Cmd+Shift+B</kbd> you can run `npm run watch`. The build is done when you see something like this:
To build Void from the terminal instead of from inside VSCode, follow the steps above, but instead of pressing <kbd>Cmd+Shift+B</kbd>, run `npm run watch`. The build is done when you see something like this:
```
[watch-extensions] [00:37:39] Finished compilation extensions with 0 errors after 19303 ms
@ -80,15 +80,17 @@ Alternatively, if you want to build Void from the terminal, instead of pressing
```
#### Common Fixes
- Make sure you followed the prerequisite steps.
- Make sure you followed the prerequisite steps above.
- Make sure you have Node version `20.18.2` (the version in `.nvmrc`)!
- If you get `"TypeError: Failed to fetch dynamically imported module"`, make sure all imports end with `.js`.
- If you see missing styles, wait a few seconds and then reload.
- If you get errors like `npm error libtool: error: unrecognised option: '-static'`, make sure you have GNU libtool instead of BSD libtool (BSD is the default in macos).
- Make sure that the path to your Void folder does not have any spaces in it.
- If you get `"TypeError: Failed to fetch dynamically imported module"`, make sure all imports end with `.js`.
- If you get an error with React, try running `NODE_OPTIONS="--max-old-space-size=8192" npm run buildreact`.
- If you see missing styles, wait a few seconds and then reload.
- If you get errors like `npm error libtool: error: unrecognised option: '-static'`, when running ./scripts/code.sh, make sure you have GNU libtool instead of BSD libtool (BSD is the default in macos)
- If you get erorrs like `The SUID sandbox helper binary was found, but is not configured correctly` when running ./scripts/code.sh, run
`sudo chown root:root .build/electron/chrome-sandbox && sudo chmod 4755 .build/electron/chrome-sandbox` and then run `./scripts/code.sh` again.
- If you have any other questions, feel free to [submit an issue](https://github.com/voideditor/void/issues/new). You can also refer to VSCode's complete [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) page.
@ -120,7 +122,7 @@ workspace/
```
### Distributing
Void's maintainers distribute Void on our website and in releases. If you'd like to see the scripts to convert `Mac .app -> .dmg`, `Windows folder -> .exe`, and `Linux folder -> appimage` for distribution, feel free to reach out.
Void's maintainers distribute Void on our website and in releases. Our build pipeline is a fork of VSCodium, and it works by running GitHub Actions which create the downloadables. The build repo with more instructions lives [here](https://github.com/voideditor/void-builder).
## Pull Request Guidelines

View file

@ -27,14 +27,14 @@ This repo contains the full sourcecode for Void. We are currently in [open beta]
1. Feel free to attend a weekly meeting in our Discord channel if you'd like to contribute!
2. To get started working on Void, see [here](https://github.com/voideditor/void/blob/main/HOW_TO_CONTRIBUTE.md).
2. To get started working on Void, see [`HOW_TO_CONTRIBUTE`](https://github.com/voideditor/void/blob/main/HOW_TO_CONTRIBUTE.md).
3. We're open to collaborations and suggestions of all types - just reach out.
## Reference
Void is a fork of the [vscode](https://github.com/microsoft/vscode) repository. For a guide to the VSCode/Void codebase, see [our Codebase Guide](https://github.com/voideditor/void/blob/main/VOID_CODEBASE_GUIDE.md).
Void is a fork of the [vscode](https://github.com/microsoft/vscode) repository. For a guide to the VSCode/Void codebase, see [`VOID_CODEBASE_GUIDE`](https://github.com/voideditor/void/blob/main/VOID_CODEBASE_GUIDE.md).
## Support
Feel free to reach out in our Discord or contact us via email: hello@voideditor.com.

View file

@ -225,7 +225,7 @@ OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
atom/language-sass 0.62.1 - MIT
atom/language-sass 0.61.4 - MIT
https://github.com/atom/language-sass
The MIT License (MIT)
@ -1203,6 +1203,33 @@ to the base-name name of the original file, and an extension of txt, html, or si
---------------------------------------------------------
fish-shell 3.7.1
https://github.com/fish-shell/fish-shell
Fish is a smart and user-friendly command line shell.
Copyright (C) 2005-2009 Axel Liljencrantz
Copyright (C) 2009- fish-shell contributors
fish is free software.
Most of fish is licensed under the GNU General Public License version 2, and
you can redistribute it and/or modify it under the terms of the GNU GPL as
published by the Free Software Foundation.
fish also includes software licensed under the Python Software Foundation License version 2, the MIT
license, and the GNU Library General Public License version 2.
Full licensing information is contained in doc_src/license.rst.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
---------------------------------------------------------
---------------------------------------------------------
go-syntax 0.7.9 - MIT
https://github.com/worlpaker/go-syntax
@ -1519,7 +1546,7 @@ SOFTWARE.
---------------------------------------------------------
jlelong/vscode-latex-basics 1.10.0 - MIT
jlelong/vscode-latex-basics 1.9.0 - MIT
https://github.com/jlelong/vscode-latex-basics
Copyright (c) vscode-latex-basics authors
@ -2101,7 +2128,7 @@ SOFTWARE.
---------------------------------------------------------
microsoft/vscode-mssql 1.23.0 - MIT
microsoft/vscode-mssql 1.29.0 - MIT
https://github.com/microsoft/vscode-mssql
------------------------------------------ START OF LICENSE -----------------------------------------
@ -3485,4 +3512,24 @@ Apache License
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---------------------------------------------------------
---------------------------------------------------------
zsh 5.9
https://github.com/zsh-users/zsh
Unless otherwise noted in the header of specific files, files in this distribution have the licence shown below.
However, note that certain shell functions are licensed under versions of the GNU General Public Licence. Anyone distributing the shell as a binary including those files needs to take account of this. Search shell functions for "Copyright" for specific copyright information. None of the core functions are affected by this, so those files may simply be omitted.
--
The Z Shell is copyright (c) 1992-2017 Paul Falstad, Richard Coleman, Zoltán Hidvégi, Andrew Main, Peter Stephenson, Sven Wischnowsky, and others. All rights reserved. Individual authors, whether or not specifically named, retain copyright in all changes; in what follows, they are referred to as `the Zsh Development Group'. This is for convenience only and this body has no legal status. The Z shell is distributed under the following licence; any provisions made in individual files take precedence.
Permission is hereby granted, without written agreement and without licence or royalty fees, to use, copy, modify, and distribute this software and to distribute modified versions of this software for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software.
In no event shall the Zsh Development Group be liable to any party for direct, indirect, special, incidental, or consequential damages arising out of the use of this software and its documentation, even if the Zsh Development Group have been advised of the possibility of such damage.
The Zsh Development Group specifically disclaim any warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The software provided hereunder is on an "as is" basis, and the Zsh Development Group have no obligation to provide maintenance, support, updates, enhancements, or modifications.
---------------------------------------------------------

View file

@ -4,47 +4,53 @@ The Void codebase is not as intimidating as it seems!
Most of Void's code lives in the folder `src/vs/workbench/contrib/void/`.
The purpose of this document is to explain how Void's codebase works. If you want build instructions, see [Contributing](https://github.com/voideditor/void/blob/main/HOW_TO_CONTRIBUTE.md).
The purpose of this document is to explain how Void's codebase works. If you want build instructions instead, see [Contributing](https://github.com/voideditor/void/blob/main/HOW_TO_CONTRIBUTE.md).
## Void Codebase Guide
### Terminology
### VSCode Rundown
Here's a VSCode rundown if you're just getting started with Void. You can also see Microsoft's [wiki](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) for some pictures. VSCode is an Electron app. Electron runs two processes: a **main** process (for internals) and a **browser** process (browser means HTML in general, not just "web browser").
<p align="center" >
<img src="https://github.com/user-attachments/assets/eef80306-2bfe-4cac-ba15-6156f65ab3bb" alt="Credit - https://github.com/microsoft/vscode/wiki/Source-Code-Organization" width="700px">
</p>
Here is some important terminology you should know if you're working inside VSCode:
- An **Editor** is the thing that you type your code in. If you have 10 tabs open, that's just one editor! Editors contain tabs (or "models").
- A **Model** is an internal representation of a file's contents. It's shared between editors (for example, if you press `Cmd+\` to make a new editor, then the model of a file like `A.ts` is shared between them. Two editors, one model. That's how changes sync.).
- Each model has a **URI** it represents, like `/Users/.../my_file.txt`. (A URI or "resource" is generally just a path).
- The **Workbench** is the wrapper that contains all the editors, the terminal, the file system tree, etc.
- Usually you use the `ITextModel` type for models and the `ICodeEditor` type for editors. There aren't that many other types.
### Minimal VSCode Rundown
Here's a minimal VSCode rundown if you're just getting started with Void:
- VSCode is (and therefore Void is) an Electron app. Electron runs two processes: a **main** process (for internals) and a **browser** process (browser means HTML in general, not just "web browser").
- Code in a `browser/` folder always lives on the browser process, and it can use `window` and other browser items.
- Code in an `electron-main/` folder always lives on the main process, and it can import `node_modules`.
- Code in `common/` can be used by either process, but doesn't get any special imports.
- The browser environment is not allowed to import `node_modules`, but there are two workarounds:
- The browser environment is not allowed to import `node_modules`. We came up with two workarounds:
1. Bundle the raw node_module code to the browser - we're doing this for React.
2. Implement the code on `electron-main/` and set up a channel between main/browser - we're doing this for sendLLMMessage.
VSCode is organized into "Services". A service is just a class that mounts a single time (in computer science theory this is called a "singleton"). You can register services with `registerSingleton` so that you can easily use them in any constructor with `@<Service>`. See _dummyContrib for an example we put together on how to register them. The registration is the same every time.
Services are always lazily created, even if you register them as Eager. If you want something that always runs on Void's mount, you should use a "workbench contribution". See _dummyContrib for this. Very similar to a Service, just registered slightly differently.
### Terminology
Actions or "commands" are functions you register on VSCode so that either you or the user can call them later. You can run actions as a user by pressing Cmd+Shift+P (opens the command pallete), or you can run them internally by using the commandService to call them by ID. We use actions to register keybinding listeners like Cmd+L, Cmd+K, etc. The nice thing about actions is the user can change the keybindings.
Here's some terminology you might want to know about when working inside VSCode:
- An **Editor** is the thing that you type your code in. If you have 10 tabs open, that's just one editor! Editors contain tabs (or "models").
- A **Model** is an internal representation of a file's contents. It's shared between editors (for example, if you press `Cmd+\` to make a new editor, then the model of a file like `A.ts` is shared between them. Two editors, one model. That's how changes sync.).
- Each model has a **URI** it represents, like `/Users/.../my_file.txt`. (A URI or "resource" is generally just a path).
- The **Workbench** is the wrapper that contains all the editors, the terminal, the file system tree, etc.
- Usually you use the `ITextModel` type for models and the `ICodeEditor` type for editors. There aren't that many other types.
<p align="center" >
<img src="https://github.com/user-attachments/assets/6521c228-dc96-4cf5-a673-6b9ca78b9b06" alt="Credit - https://code.visualstudio.com/docs/getstarted/userinterface" width="400px">
</p>
See [here](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) for a decent VSCode guide with even more info.
- VSCode is organized into "**Services**". A service is just a class that mounts a single time (in computer science theory this is called a "singleton"). You can register services with `registerSingleton` so that you can easily use them in any constructor with `@<Service>`. See _dummyContrib for an example we put together on how to register them. The registration is the same every time.
- "**Actions**" are functions you register on VSCode so that either you or the user can call them later. They're also called "**Commands**".
- You can run actions as a user by pressing Cmd+Shift+P (opens the command pallete), or you can run them internally by using the commandService to call them by ID. We use actions to register keybinding listeners like Cmd+L, Cmd+K, etc. The nice thing about actions is the user can change the keybindings.
Each section below contains an overview of a core part of Void's sourcecode. You might want to scroll to find the item that's relevant to you.
### Internal LLM Message Pipeline
@ -58,7 +64,7 @@ Sending LLM messages from the main process avoids CSP issues with local provider
**Notes:** `modelCapabilities` is an important file that must be updated when new models come out!
**Notes:** `modelCapabilities` is an important file that must be updated when new models come out!
### Apply
@ -68,25 +74,28 @@ Void has two types of Apply: **Fast Apply** (uses Search/Replace, see below), an
When you click Apply and Fast Apply is enabled, we prompt the LLM to output Search/Replace block(s) like this:
```
<<<<<<< ORIGINAL
// original code goes here
// original code goes here
=======
// replaced code goes here
>>>>>>> UPDATED
```
This is what allows Void to quickly apply code even on 1000-line files. It's the same as asking the LLM to press Ctrl+F and enter in a search/replace query.
This is what allows Void to quickly apply code even on 1000-line files. It's the same as asking the LLM to press Ctrl+F and enter in a search/replace query.
### Apply Inner Workings
The `editCodeService` file runs Apply. The same exact code is also used when the LLM calls the Edit tool, and when you submit Cmd+K. Just different versions of Fast/Slow Apply mode.
The `editCodeService` file runs Apply. The same exact code is also used when the LLM calls the Edit tool, and when you submit Cmd+K. Just different versions of Fast/Slow Apply mode.
Here is some important terminology:
- A **DiffZone** is a {startLine, endLine} region in which we show Diffs (red/green areas). We update it when the user types, so it's always accurate.
- A **DiffArea** is a generalization that tracks line numbers like a DiffZone.
- The only type of zone that can "stream" is a DiffZone. Each DiffZone has an llmCancelToken if it's streaming.
- A **DiffZone** is a {startLine, endLine} region of text where we compute and show red/green areas, or **Diffs**. When any changes are made to a file, we loop through all the DiffAreas on that file and refresh its Diffs.
- A **DiffArea** is a generalization that just tracks line numbers like a DiffZone.
- The only type of DiffArea that can "stream" is a DiffZone. Each DiffZone has an llmCancelToken if it's streaming.
How Apply works:
- When you click Apply, we create a **DiffZone** over that the full file so that any changes that the LLM makes will show up in red/green. We then stream the change.
- When an LLM calls Edit, it's really calling Apply.
- When you submit Cmd+K, it's the same as Apply except we create a smaller DiffZone (not on the whole file).
### Writing Files Inner Workings
When Void wants to change your code, it just writes to a text model. This means all you need to know to write to a file is its URI - you don't have to load it, save it, etc. There are some annoying background URI/model things to think about to get this to work, but we handled them all in `voidModelService`.
@ -101,7 +110,7 @@ Here's a guide to some of the terminology we're using:
- **FeatureName**: Autocomplete | Chat | CtrlK | Apply
- **ModelSelection**: a {providerName, modelName} pair.
- **ProviderName**: The name of a provider: `'ollama'`, `'openAI'`, etc.
- **ModelName**: The name of a model (string type, eg `'gpt-4o'`).
- **ModelName**: The name of a model (string type, eg `'gpt-4o'`).
- **RefreshProvider**: a provider that we ping repeatedly to update the models list.
- **ChatMode** = normal | gather | agent
@ -121,7 +130,7 @@ If you want to know how our build pipeline works, see our build repo [here](http
## VSCode Codebase Guide (Not Void)
## VSCode Codebase Guide
The Void team put together this list of links to get up and running with VSCode's sourcecode, the foundation of Void. We hope it's helpful!

View file

@ -59,6 +59,7 @@ fsevents/test/**
!@vscode/tree-sitter-wasm/wasm/tree-sitter-typescript.wasm
!@vscode/tree-sitter-wasm/wasm/tree-sitter-regex.wasm
!@vscode/tree-sitter-wasm/wasm/tree-sitter-ini.wasm
!@vscode/tree-sitter-wasm/wasm/tree-sitter-css.wasm
native-keymap/binding.gyp
native-keymap/build/**

View file

@ -2,4 +2,5 @@ disturl="https://nodejs.org/dist"
runtime="node"
build_from_source="true"
legacy-peer-deps="true"
force_process_config="true"
timeout=180000

View file

@ -42,7 +42,6 @@ steps:
- script: |
set -e
if [ -n "$SYSROOT_ARCH" ]; then
export VSCODE_SYSROOT_PREFIX='-glibc-2.17'
export VSCODE_SYSROOT_DIR=$(Build.SourcesDirectory)/.build/sysroots
node -e '(async () => { const { getVSCodeSysroot } = require("../build/linux/debian/install-sysroot.js"); await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()'
if [ "$SYSROOT_ARCH" == "arm64" ]; then
@ -73,7 +72,7 @@ steps:
# verify glibc requirement
if [ -n "$SYSROOT_ARCH" ]; then
glibc_version="2.17"
glibc_version="2.28"
while IFS= read -r line; do
if [[ $line == *"GLIBC_"* ]]; then
version=$(echo "$line" | awk '{print $5}' | tr -d '()')
@ -83,8 +82,8 @@ steps:
fi
fi
done < <("$OBJDUMP" -T "$PWD/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code")
if [[ "$glibc_version" != "2.17" ]]; then
echo "Error: binary has dependency on GLIBC > 2.17, found $glibc_version"
if [[ "$glibc_version" != "2.28" ]]; then
echo "Error: binary has dependency on GLIBC > 2.28, found $glibc_version"
exit 1
fi
fi
@ -120,22 +119,6 @@ steps:
ArtifactServices.Symbol.UseAAD: false
displayName: Publish Symbols
- task: CopyFiles@2
inputs:
SourceFolder: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release
Contents: 'code.*'
TargetFolder: $(Agent.TempDirectory)/binskim-cli
displayName: Copy files for BinSkim
- task: BinSkim@4
inputs:
InputType: Basic
Function: analyze
TargetPattern: guardianGlob
AnalyzeTargetGlob: $(Agent.TempDirectory)/binskim-cli/*.*
AnalyzeSymPath: $(Agent.TempDirectory)/binskim-cli
displayName: Run BinSkim
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"

View file

@ -1,7 +1,7 @@
parameters:
- name: channel
type: string
default: 1.81
default: 1.85
- name: targets
default: []
type: object

View file

@ -1,7 +1,7 @@
parameters:
- name: channel
type: string
default: 1.81
default: 1.85
- name: targets
default: []
type: object

View file

@ -382,7 +382,7 @@ async function unzip(packagePath, outputPath) {
});
}
// Contains all of the logic for mapping details to our actual product names in CosmosDB
function getPlatform(product, os, arch, type, isLegacy) {
function getPlatform(product, os, arch, type) {
switch (os) {
case 'win32':
switch (product) {
@ -427,12 +427,12 @@ function getPlatform(product, os, arch, type, isLegacy) {
case 'client':
return `linux-${arch}`;
case 'server':
return isLegacy ? `server-linux-legacy-${arch}` : `server-linux-${arch}`;
return `server-linux-${arch}`;
case 'web':
if (arch === 'standalone') {
return 'web-standalone';
}
return isLegacy ? `server-linux-legacy-${arch}-web` : `server-linux-${arch}-web`;
return `server-linux-${arch}-web`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
}
@ -556,8 +556,7 @@ async function processArtifact(artifact, filePath) {
await releaseService.createRelease(version, filePath, friendlyFileName);
}
const { product, os, arch, unprocessedType } = match.groups;
const isLegacy = artifact.name.includes('_legacy');
const platform = getPlatform(product, os, arch, unprocessedType, isLegacy);
const platform = getPlatform(product, os, arch, unprocessedType);
const type = getRealType(unprocessedType);
const size = fs_1.default.statSync(filePath).size;
const stream = fs_1.default.createReadStream(filePath);
@ -610,9 +609,6 @@ async function main() {
if (e('VSCODE_BUILD_STAGE_LINUX') === 'True') {
stages.add('Linux');
}
if (e('VSCODE_BUILD_STAGE_LINUX_LEGACY_SERVER') === 'True') {
stages.add('LinuxLegacyServer');
}
if (e('VSCODE_BUILD_STAGE_ALPINE') === 'True') {
stages.add('Alpine');
}

View file

@ -694,7 +694,7 @@ interface Asset {
}
// Contains all of the logic for mapping details to our actual product names in CosmosDB
function getPlatform(product: string, os: string, arch: string, type: string, isLegacy: boolean): string {
function getPlatform(product: string, os: string, arch: string, type: string): string {
switch (os) {
case 'win32':
switch (product) {
@ -739,12 +739,12 @@ function getPlatform(product: string, os: string, arch: string, type: string, is
case 'client':
return `linux-${arch}`;
case 'server':
return isLegacy ? `server-linux-legacy-${arch}` : `server-linux-${arch}`;
return `server-linux-${arch}`;
case 'web':
if (arch === 'standalone') {
return 'web-standalone';
}
return isLegacy ? `server-linux-legacy-${arch}-web` : `server-linux-${arch}-web`;
return `server-linux-${arch}-web`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
}
@ -896,8 +896,7 @@ async function processArtifact(
}
const { product, os, arch, unprocessedType } = match.groups!;
const isLegacy = artifact.name.includes('_legacy');
const platform = getPlatform(product, os, arch, unprocessedType, isLegacy);
const platform = getPlatform(product, os, arch, unprocessedType);
const type = getRealType(unprocessedType);
const size = fs.statSync(filePath).size;
const stream = fs.createReadStream(filePath);
@ -956,7 +955,6 @@ async function main() {
if (e('VSCODE_BUILD_STAGE_WINDOWS') === 'True') { stages.add('Windows'); }
if (e('VSCODE_BUILD_STAGE_LINUX') === 'True') { stages.add('Linux'); }
if (e('VSCODE_BUILD_STAGE_LINUX_LEGACY_SERVER') === 'True') { stages.add('LinuxLegacyServer'); }
if (e('VSCODE_BUILD_STAGE_ALPINE') === 'True') { stages.add('Alpine'); }
if (e('VSCODE_BUILD_STAGE_MACOS') === 'True') { stages.add('macOS'); }
if (e('VSCODE_BUILD_STAGE_WEB') === 'True') { stages.add('Web'); }

View file

@ -23,10 +23,10 @@ steps:
- script: npm run test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: npm run test-browser-no-install -- --sequential --browser chromium --browser webkit --tfs "Browser Unit Tests"
- script: npm run test-browser-no-install -- --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & Webkit)
displayName: Run unit tests (Browser, Webkit)
timeoutInMinutes: 30
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
@ -36,10 +36,10 @@ steps:
- script: npm run test-node -- --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: npm run test-browser-no-install -- --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests"
- script: npm run test-browser-no-install -- --build --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & Webkit)
displayName: Run unit tests (Browser, Webkit)
timeoutInMinutes: 30
- ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}:

View file

@ -121,6 +121,11 @@ steps:
- template: ../common/install-builtin-extensions.yml@self
- ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}:
- script: node build/lib/policies darwin
displayName: Generate policy definitions
retryCountOnTaskFailure: 3
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e

View file

@ -1,233 +0,0 @@
parameters:
- name: VSCODE_QUALITY
type: string
- name: VSCODE_RUN_INTEGRATION_TESTS
type: boolean
- name: VSCODE_ARCH
type: string
steps:
- task: NodeTool@0
inputs:
versionSource: fromFile
versionFilePath: .nvmrc
nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download
- template: ../distro/download-distro.yml
- task: AzureKeyVault@2
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: vscode
KeyVaultName: vscode-build-secrets
SecretsFilter: "github-distro-mixin-password"
- task: DownloadPipelineArtifact@2
inputs:
artifact: Compilation
path: $(Build.ArtifactStagingDirectory)
displayName: Download compilation output
- script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz
displayName: Extract compilation output
- script: |
set -e
# Start X server
./build/azure-pipelines/linux/apt-retry.sh sudo apt-get update
./build/azure-pipelines/linux/apt-retry.sh sudo apt-get install -y pkg-config \
dbus \
xvfb \
libgtk-3-0 \
libxkbfile-dev \
libkrb5-dev \
libgbm1 \
rpm \
gcc-10 \
g++-10
sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb
sudo chmod +x /etc/init.d/xvfb
sudo update-rc.d xvfb defaults
sudo service xvfb start
# Start dbus session
sudo mkdir -p /var/run/dbus
DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address)
echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT"
displayName: Setup system services
- script: node build/setup-npm-registry.js $NPM_REGISTRY
condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM Registry
- script: |
set -e
# Set the private NPM registry to the global npmrc file
# so that authentication works for subfolders like build/, remote/, extensions/ etc
# which does not have their own .npmrc file
npm config set registry "$NPM_REGISTRY"
echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)"
condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM
- task: npmAuthenticate@0
inputs:
workingFile: $(NPMRC_PATH)
condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM Authentication
- ${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}:
- task: Docker@1
displayName: "Pull Docker image"
inputs:
azureSubscriptionEndpoint: vscode
azureContainerRegistry: vscodehub.azurecr.io
command: "Run an image"
imageName: vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH)
containerCommand: uname
- script: |
set -e
for i in {1..5}; do # try 5 times
npm ci && break
if [ $i -eq 5 ]; then
echo "Npm install failed too many times" >&2
exit 1
fi
echo "Npm install failed $i, trying again..."
done
workingDirectory: build
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Install build dependencies
- script: |
set -e
export VSCODE_SYSROOT_PREFIX='-glibc-2.17'
export CC=$(which gcc-10)
export CXX=$(which g++-10)
source ./build/azure-pipelines/linux/setup-env.sh --skip-sysroot
for i in {1..5}; do # try 5 times
npm ci && break
if [ $i -eq 5 ]; then
echo "Npm install failed too many times" >&2
exit 1
fi
echo "Npm install failed $i, trying again..."
done
env:
npm_config_arch: $(NPM_ARCH)
VSCODE_ARCH: $(VSCODE_ARCH)
NPM_REGISTRY: "$(NPM_REGISTRY)"
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
VSCODE_HOST_MOUNT: "/mnt/vss/_work/1/s"
${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}:
VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH)
displayName: Install dependencies
- script: node build/azure-pipelines/distro/mixin-npm
displayName: Mixin distro node modules
- script: node build/azure-pipelines/distro/mixin-quality
displayName: Mixin distro quality
- template: ../common/install-builtin-extensions.yml
- script: |
set -e
npm run gulp vscode-linux-$(VSCODE_ARCH)-min-ci
ARCHIVE_PATH=".build/linux/client/code-${{ parameters.VSCODE_QUALITY }}-$(VSCODE_ARCH)-$(date +%s).tar.gz"
mkdir -p $(dirname $ARCHIVE_PATH)
echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH"
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Build client
- script: |
set -e
tar -czf $CLIENT_PATH -C .. VSCode-linux-$(VSCODE_ARCH)
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Archive client
- script: |
set -e
export VSCODE_NODE_GLIBC="-glibc-2.17"
npm run gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci
mv ../vscode-reh-linux-$(VSCODE_ARCH) ../vscode-server-linux-$(VSCODE_ARCH) # TODO@joaomoreno
ARCHIVE_PATH=".build/linux/server/vscode-server-linux-legacy-$(VSCODE_ARCH).tar.gz"
UNARCHIVE_PATH="`pwd`/../vscode-server-linux-$(VSCODE_ARCH)"
mkdir -p $(dirname $ARCHIVE_PATH)
tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-linux-$(VSCODE_ARCH)
echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH"
echo "##vso[task.setvariable variable=SERVER_UNARCHIVE_PATH]$UNARCHIVE_PATH"
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Build server
- script: |
set -e
export VSCODE_NODE_GLIBC="-glibc-2.17"
npm run gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci
mv ../vscode-reh-web-linux-$(VSCODE_ARCH) ../vscode-server-linux-$(VSCODE_ARCH)-web # TODO@joaomoreno
ARCHIVE_PATH=".build/linux/web/vscode-server-linux-legacy-$(VSCODE_ARCH)-web.tar.gz"
mkdir -p $(dirname $ARCHIVE_PATH)
tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-linux-$(VSCODE_ARCH)-web
echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH"
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Build server (web)
- ${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}:
- script: |
set -e
EXPECTED_GLIBC_VERSION="2.17" \
EXPECTED_GLIBCXX_VERSION="3.4.19" \
./build/azure-pipelines/linux/verify-glibc-requirements.sh
env:
SEARCH_PATH: $(SERVER_UNARCHIVE_PATH)
displayName: Check GLIBC and GLIBCXX dependencies in server archive
- ${{ else }}:
- script: |
set -e
EXPECTED_GLIBC_VERSION="2.17" \
EXPECTED_GLIBCXX_VERSION="3.4.22" \
./build/azure-pipelines/linux/verify-glibc-requirements.sh
env:
SEARCH_PATH: $(SERVER_UNARCHIVE_PATH)
displayName: Check GLIBC and GLIBCXX dependencies in server archive
- ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}:
- template: product-build-linux-test.yml
parameters:
VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }}
VSCODE_RUN_SMOKE_TESTS: false
${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1
- task: 1ES.PublishPipelineArtifact@1
inputs:
targetPath: $(SERVER_PATH)
artifactName: $(ARTIFACT_PREFIX)vscode_server_linux_legacy_$(VSCODE_ARCH)_archive-unsigned
sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)
sbomPackageName: "VS Code Linux $(VSCODE_ARCH) Legacy Server"
sbomPackageVersion: $(Build.SourceVersion)
condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''))
displayName: Publish server archive
- task: 1ES.PublishPipelineArtifact@1
inputs:
targetPath: $(WEB_PATH)
artifactName: $(ARTIFACT_PREFIX)vscode_web_linux_legacy_$(VSCODE_ARCH)_archive-unsigned
sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)-web
sbomPackageName: "VS Code Linux $(VSCODE_ARCH) Legacy Web"
sbomPackageVersion: $(Build.SourceVersion)
condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''))
displayName: Publish web server archive

View file

@ -16,56 +16,50 @@ else
fi
if [ "$npm_config_arch" == "x64" ]; then
# Download clang based on chromium revision used by vscode
curl -s https://raw.githubusercontent.com/chromium/chromium/132.0.6834.196/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux
# Download clang based on chromium revision used by vscode
curl -s https://raw.githubusercontent.com/chromium/chromium/132.0.6834.210/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux
# Download libcxx headers and objects from upstream electron releases
DEBUG=libcxx-fetcher \
VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \
VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \
VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \
VSCODE_ARCH="$npm_config_arch" \
node build/linux/libcxx-fetcher.js
# Download libcxx headers and objects from upstream electron releases
DEBUG=libcxx-fetcher \
VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \
VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \
VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \
VSCODE_ARCH="$npm_config_arch" \
node build/linux/libcxx-fetcher.js
# Set compiler toolchain
# Flags for the client build are based on
# https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.196:build/config/arm.gni
# https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.196:build/config/compiler/BUILD.gn
# https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.196:build/config/c++/BUILD.gn
export CC="$PWD/.build/CR_Clang/bin/clang --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu"
export CXX="$PWD/.build/CR_Clang/bin/clang++ --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu"
export CXXFLAGS="-nostdinc++ -D__NO_INLINE__ -DSPDLOG_USE_STD_FORMAT -I$PWD/.build/libcxx_headers -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit -D_LIBCPP_ABI_NAMESPACE=Cr -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot"
export LDFLAGS="-stdlib=libc++ --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -fuse-ld=lld -flto=thin -L$PWD/.build/libcxx-objects -lc++abi -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu -Wl,--lto-O0"
# Set compiler toolchain
# Flags for the client build are based on
# https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:build/config/arm.gni
# https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:build/config/compiler/BUILD.gn
# https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:build/config/c++/BUILD.gn
export CC="$PWD/.build/CR_Clang/bin/clang --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu"
export CXX="$PWD/.build/CR_Clang/bin/clang++ --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu"
export CXXFLAGS="-nostdinc++ -D__NO_INLINE__ -DSPDLOG_USE_STD_FORMAT -I$PWD/.build/libcxx_headers -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit -D_LIBCPP_ABI_NAMESPACE=Cr -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot"
export LDFLAGS="-stdlib=libc++ --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -fuse-ld=lld -flto=thin -L$PWD/.build/libcxx-objects -lc++abi -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu -Wl,--lto-O0"
if [ "$(echo "$@" | grep -c -- "--skip-sysroot")" -eq 0 ]; then
# Set compiler toolchain for remote server
export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc
export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-g++
export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot"
export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu"
fi
# Set compiler toolchain for remote server
export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc
export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-g++
export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot"
export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu"
elif [ "$npm_config_arch" == "arm64" ]; then
if [ "$(echo "$@" | grep -c -- "--skip-sysroot")" -eq 0 ]; then
# Set compiler toolchain for client native modules
export CC=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
export CXX=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot"
export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/lib/aarch64-linux-gnu"
# Set compiler toolchain for client native modules
export CC=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
export CXX=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot"
export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/lib/aarch64-linux-gnu"
# Set compiler toolchain for remote server
export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot"
export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/lib/aarch64-linux-gnu"
fi
# Set compiler toolchain for remote server
export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot"
export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/lib/aarch64-linux-gnu"
elif [ "$npm_config_arch" == "arm" ]; then
if [ "$(echo "$@" | grep -c -- "--skip-sysroot")" -eq 0 ]; then
# Set compiler toolchain for client native modules
export CC=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc
export CXX=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-g++
export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot"
export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/arm-linux-gnueabihf -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/lib/arm-linux-gnueabihf"
fi
# Set compiler toolchain for client native modules
export CC=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc
export CXX=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-g++
export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot"
export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/arm-linux-gnueabihf -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/lib/arm-linux-gnueabihf"
# Set compiler toolchain for remote server
export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc

View file

@ -41,26 +41,14 @@ parameters:
displayName: "🎯 Linux x64"
type: boolean
default: true
- name: VSCODE_BUILD_LINUX_X64_LEGACY_SERVER
displayName: "🎯 Linux x64 Legacy Server"
type: boolean
default: true
- name: VSCODE_BUILD_LINUX_ARM64
displayName: "🎯 Linux arm64"
type: boolean
default: true
- name: VSCODE_BUILD_LINUX_ARM64_LEGACY_SERVER
displayName: "🎯 Linux arm64 Legacy Server"
type: boolean
default: true
- name: VSCODE_BUILD_LINUX_ARMHF
displayName: "🎯 Linux armhf"
type: boolean
default: true
- name: VSCODE_BUILD_LINUX_ARMHF_LEGACY_SERVER
displayName: "🎯 Linux armhf Legacy Server"
type: boolean
default: true
- name: VSCODE_BUILD_ALPINE
displayName: "🎯 Alpine x64"
type: boolean
@ -118,8 +106,6 @@ variables:
value: ${{ or(eq(parameters.VSCODE_BUILD_WIN32, true), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}
- name: VSCODE_BUILD_STAGE_LINUX
value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX, true), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}
- name: VSCODE_BUILD_STAGE_LINUX_LEGACY_SERVER
value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX_X64_LEGACY_SERVER, true), eq(parameters.VSCODE_BUILD_LINUX_ARMHF_LEGACY_SERVER, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64_LEGACY_SERVER, true)) }}
- name: VSCODE_BUILD_STAGE_ALPINE
value: ${{ or(eq(parameters.VSCODE_BUILD_ALPINE, true), eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true)) }}
- name: VSCODE_BUILD_STAGE_MACOS
@ -183,6 +169,8 @@ extends:
tsa:
enabled: true
configFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/tsaoptions.json
binskim:
analyzeTargetGlob: '+:file|$(Agent.BuildDirectory)/VSCode-*/**/*.exe;+:file|$(Agent.BuildDirectory)/VSCode-*/**/*.node;+:file|$(Agent.BuildDirectory)/VSCode-*/**/*.dll;-:file|$(Build.SourcesDirectory)/.build/**/system-setup/VSCodeSetup*.exe;-:file|$(Build.SourcesDirectory)/.build/**/user-setup/VSCodeUserSetup*.exe'
codeql:
runSourceLanguagesInSourceAnalysis: true
compiled:
@ -279,6 +267,10 @@ extends:
name: Azure Pipelines
image: macOS-13
os: macOS
variables:
# todo@connor4312 to diagnose build flakes
- name: MSRUSTUP_LOG
value: debug
steps:
- template: build/azure-pipelines/darwin/cli-build-darwin.yml@self
parameters:
@ -292,6 +284,10 @@ extends:
name: Azure Pipelines
image: macOS-13
os: macOS
variables:
# todo@connor4312 to diagnose build flakes
- name: MSRUSTUP_LOG
value: debug
steps:
- template: build/azure-pipelines/darwin/cli-build-darwin.yml@self
parameters:
@ -322,13 +318,13 @@ extends:
VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }}
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false)) }}:
- stage: CustomSDL
- stage: APIScan
dependsOn: []
pool:
name: 1es-windows-2019-x64
os: windows
jobs:
- job: WindowsSDL
- job: WindowsAPIScan
steps:
- template: build/azure-pipelines/win32/sdl-scan-win32.yml@self
parameters:
@ -394,6 +390,10 @@ extends:
timeoutInMinutes: 120
variables:
VSCODE_ARCH: x64
templateContext:
sdl:
suppression:
suppressionFile: $(Build.SourcesDirectory)\.config\guardian\.gdnsuppress
steps:
- template: build/azure-pipelines/win32/product-build-win32.yml@self
parameters:
@ -418,6 +418,10 @@ extends:
timeoutInMinutes: 90
variables:
VSCODE_ARCH: arm64
templateContext:
sdl:
suppression:
suppressionFile: $(Build.SourcesDirectory)\.config\guardian\.gdnsuppress
steps:
- template: build/azure-pipelines/win32/product-build-win32.yml@self
parameters:
@ -547,51 +551,6 @@ extends:
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_LINUX_LEGACY_SERVER'], true)) }}:
- stage: LinuxLegacyServer
dependsOn:
- Compile
pool:
name: 1es-ubuntu-20.04-x64
os: linux
jobs:
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_X64_LEGACY_SERVER, true) }}:
- job: Linuxx64LegacyServer
variables:
VSCODE_ARCH: x64
NPM_ARCH: x64
DISPLAY: ":10"
steps:
- template: build/azure-pipelines/linux/product-build-linux-legacy-server.yml@self
parameters:
VSCODE_ARCH: x64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF_LEGACY_SERVER, true) }}:
- job: LinuxArmhfLegacyServer
variables:
VSCODE_ARCH: armhf
NPM_ARCH: arm
steps:
- template: build/azure-pipelines/linux/product-build-linux-legacy-server.yml@self
parameters:
VSCODE_ARCH: armhf
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_RUN_INTEGRATION_TESTS: false
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64_LEGACY_SERVER, true) }}:
- job: LinuxArm64LegacyServer
variables:
VSCODE_ARCH: arm64
NPM_ARCH: arm64
steps:
- template: build/azure-pipelines/linux/product-build-linux-legacy-server.yml@self
parameters:
VSCODE_ARCH: arm64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_RUN_INTEGRATION_TESTS: false
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_ALPINE'], true)) }}:
- stage: Alpine
dependsOn:

View file

@ -104,12 +104,12 @@ steps:
- template: common/install-builtin-extensions.yml@self
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- script: npm exec -- npm-run-all -lp core-ci-pr extensions-ci-pr hygiene eslint valid-layers-check vscode-dts-compile-check tsec-compile-check
- script: npm exec -- npm-run-all -lp core-ci-pr extensions-ci-pr hygiene eslint valid-layers-check property-init-order-check vscode-dts-compile-check tsec-compile-check
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Compile & Hygiene (OSS)
- ${{ else }}:
- script: npm exec -- npm-run-all -lp core-ci extensions-ci hygiene eslint valid-layers-check vscode-dts-compile-check tsec-compile-check
- script: npm exec -- npm-run-all -lp core-ci extensions-ci hygiene eslint valid-layers-check property-init-order-check vscode-dts-compile-check tsec-compile-check
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Compile & Hygiene (non-OSS)

View file

@ -102,7 +102,6 @@ steps:
$stages = @(
if ($env:VSCODE_BUILD_STAGE_WINDOWS -eq 'True') { 'Windows' }
if ($env:VSCODE_BUILD_STAGE_LINUX -eq 'True') { 'Linux' }
if ($env:VSCODE_BUILD_STAGE_LINUX_LEGACY_SERVER -eq 'True') { 'LinuxLegacyServer' }
if ($env:VSCODE_BUILD_STAGE_ALPINE -eq 'True') { 'Alpine' }
if ($env:VSCODE_BUILD_STAGE_MACOS -eq 'True') { 'macOS' }
if ($env:VSCODE_BUILD_STAGE_WEB -eq 'True') { 'Web' }

View file

@ -28,7 +28,7 @@ steps:
- powershell: npm run test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- powershell: node test/unit/browser/index.js --sequential --browser chromium --tfs "Browser Unit Tests"
- powershell: node test/unit/browser/index.js --browser chromium --tfs "Browser Unit Tests"
displayName: Run unit tests (Browser, Chromium)
timeoutInMinutes: 20
@ -39,7 +39,7 @@ steps:
- powershell: npm run test-node -- --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- powershell: npm run test-browser-no-install -- --sequential --build --browser chromium --tfs "Browser Unit Tests"
- powershell: npm run test-browser-no-install -- --build --browser chromium --tfs "Browser Unit Tests"
displayName: Run unit tests (Browser, Chromium)
timeoutInMinutes: 20

View file

@ -124,7 +124,7 @@ steps:
- template: ../common/install-builtin-extensions.yml@self
- ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}:
- powershell: node build\lib\policies
- powershell: node build\lib\policies win32
displayName: Generate Group Policy definitions
retryCountOnTaskFailure: 3
@ -145,7 +145,7 @@ steps:
exec { npm run gulp "vscode-win32-$(VSCODE_ARCH)-min-ci" }
exec { npm run gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" }
echo "##vso[task.setvariable variable=BUILT_CLIENT]true"
echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)"
echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH)"
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Build client
@ -156,7 +156,7 @@ steps:
exec { npm run gulp "vscode-reh-win32-$(VSCODE_ARCH)-min-ci" }
mv ..\vscode-reh-win32-$(VSCODE_ARCH) ..\vscode-server-win32-$(VSCODE_ARCH) # TODO@joaomoreno
echo "##vso[task.setvariable variable=BUILT_SERVER]true"
echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(agent.builddirectory)/vscode-server-win32-$(VSCODE_ARCH)"
echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)"
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Build server
@ -196,10 +196,10 @@ steps:
$ErrorActionPreference = "Stop"
$ArtifactName = (gci -Path "$(Build.ArtifactStagingDirectory)/cli" | Select-Object -last 1).FullName
Expand-Archive -Path $ArtifactName -DestinationPath "$(Build.ArtifactStagingDirectory)/cli"
$AppProductJson = Get-Content -Raw -Path "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)\resources\app\product.json" | ConvertFrom-Json
$AppProductJson = Get-Content -Raw -Path "$(Agent.BuildDirectory)\VSCode-win32-$(VSCODE_ARCH)\resources\app\product.json" | ConvertFrom-Json
$CliAppName = $AppProductJson.tunnelApplicationName
$AppName = $AppProductJson.applicationName
Move-Item -Path "$(Build.ArtifactStagingDirectory)/cli/$AppName.exe" -Destination "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/$CliAppName.exe"
Move-Item -Path "$(Build.ArtifactStagingDirectory)/cli/$AppName.exe" -Destination "$(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/$CliAppName.exe"
displayName: Move VS Code CLI
- task: UseDotNet@2
@ -231,6 +231,11 @@ steps:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Codesign executables and shared libraries
- powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows-appx $(CodeSigningFolderPath) '*.ps1'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Codesign Powershell scripts
- ${{ if eq(parameters.VSCODE_QUALITY, 'insider') }}:
- powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows-appx $(CodeSigningFolderPath) '*.appx'
env:
@ -247,13 +252,16 @@ steps:
condition: succeededOrFailed()
displayName: Get product version
- powershell: |
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$ArchivePath = ".build\win32-$(VSCODE_ARCH)\VSCode-win32-$(VSCODE_ARCH)-$(VSCODE_VERSION).zip"
New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force
exec { 7z.exe a -tzip $ArchivePath -x!CodeSignSummary*.md ..\VSCode-win32-$(VSCODE_ARCH)\* -r }
exec { 7z.exe a -tzip $ArchivePath ..\VSCode-win32-$(VSCODE_ARCH)\* "-xr!CodeSignSummary*.md" }
echo "##vso[task.setvariable variable=CLIENT_PATH]$ArchivePath"
echo "Listing archive contents"
7z.exe l $ArchivePath
condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true'))
displayName: Package client
@ -262,8 +270,11 @@ steps:
$ErrorActionPreference = "Stop"
$ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH).zip"
New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force
exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH) -r }
exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH) }
echo "##vso[task.setvariable variable=SERVER_PATH]$ArchivePath"
echo "Listing archive contents"
7z.exe l $ArchivePath
condition: and(succeededOrFailed(), eq(variables['BUILT_SERVER'], 'true'))
displayName: Package server
@ -272,32 +283,30 @@ steps:
$ErrorActionPreference = "Stop"
$ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH)-web.zip"
New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force
exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web -r }
exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web }
echo "##vso[task.setvariable variable=WEB_PATH]$ArchivePath"
echo "Listing archive contents"
7z.exe l $ArchivePath
condition: and(succeededOrFailed(), eq(variables['BUILT_WEB'], 'true'))
displayName: Package server (web)
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npm run -- gulp "vscode-win32-$(VSCODE_ARCH)-system-setup" --sign }
$SetupPath = ".build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe"
mv .build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe $SetupPath
echo "##vso[task.setvariable variable=SYSTEM_SETUP_PATH]$SetupPath"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Build system setup
exec { npm exec -- npm-run-all -lp "gulp vscode-win32-$(VSCODE_ARCH)-system-setup -- --sign" "gulp vscode-win32-$(VSCODE_ARCH)-user-setup -- --sign" }
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npm run -- gulp "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign }
$SetupPath = ".build\win32-$(VSCODE_ARCH)\user-setup\VSCodeUserSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe"
mv .build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe $SetupPath
echo "##vso[task.setvariable variable=USER_SETUP_PATH]$SetupPath"
$SystemSetupPath = ".build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe"
$UserSetupPath = ".build\win32-$(VSCODE_ARCH)\user-setup\VSCodeUserSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe"
mv .build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe $SystemSetupPath
mv .build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe $UserSetupPath
echo "##vso[task.setvariable variable=SYSTEM_SETUP_PATH]$SystemSetupPath"
echo "##vso[task.setvariable variable=USER_SETUP_PATH]$UserSetupPath"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Build user setup
displayName: Build setup packages (system, user)
- powershell: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_"
condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues'))

View file

@ -102,13 +102,6 @@ steps:
- powershell: npm run compile
displayName: Compile
- powershell: |
Get-ChildItem '$(Build.SourcesDirectory)' -Recurse -Filter "*.exe"
Get-ChildItem '$(Build.SourcesDirectory)' -Recurse -Filter "*.dll"
Get-ChildItem '$(Build.SourcesDirectory)' -Recurse -Filter "*.node"
Get-ChildItem '$(Build.SourcesDirectory)' -Recurse -Filter "*.pdb"
displayName: List files
- powershell: npm run gulp "vscode-symbols-win32-${{ parameters.VSCODE_ARCH }}"
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
@ -119,16 +112,7 @@ steps:
Get-ChildItem '$(Agent.BuildDirectory)\scanbin' -Recurse -Filter "*.dll"
Get-ChildItem '$(Agent.BuildDirectory)\scanbin' -Recurse -Filter "*.node"
Get-ChildItem '$(Agent.BuildDirectory)\scanbin' -Recurse -Filter "*.pdb"
displayName: List files again
- task: BinSkim@4
inputs:
InputType: "Basic"
Function: "analyze"
TargetPattern: "guardianGlob"
AnalyzeIgnorePdbLoadError: true
AnalyzeTargetGlob: '$(Agent.BuildDirectory)\scanbin\**.dll;$(Agent.BuildDirectory)\scanbin\**.exe;$(Agent.BuildDirectory)\scanbin\**.node'
AnalyzeLocalSymbolDirectories: '$(Agent.BuildDirectory)\scanbin\VSCode-win32-${{ parameters.VSCODE_ARCH }}\pdb'
displayName: List files
- task: CopyFiles@2
displayName: 'Collect Symbols for API Scan'
@ -139,19 +123,6 @@ steps:
flattenFolders: true
condition: succeeded()
- task: PublishSymbols@2
inputs:
IndexSources: false
SymbolsFolder: '$(Agent.BuildDirectory)\symbols'
SearchPattern: '**\*.pdb'
SymbolServerType: TeamServices
SymbolsProduct: 'code'
ArtifactServices.Symbol.AccountName: microsoft
ArtifactServices.Symbol.PAT: $(System.AccessToken)
ArtifactServices.Symbol.UseAAD: false
displayName: Publish Symbols
condition: succeeded()
- task: APIScan@2
inputs:
softwareFolder: $(Agent.BuildDirectory)\scanbin

View file

@ -5,31 +5,22 @@
/**
* @param {string} name
* @param {string[]=} exclude
* @returns {import('./lib/bundle').IEntryPoint}
*/
function createModuleDescription(name, exclude) {
function createModuleDescription(name) {
return {
name,
exclude
name
};
}
/**
* @param {string} name
*/
function createEditorWorkerModuleDescription(name) {
return createModuleDescription(name, ['vs/base/common/worker/simpleWorker', 'vs/editor/common/services/editorSimpleWorker']);
}
exports.workerEditor = createEditorWorkerModuleDescription('vs/editor/common/services/editorSimpleWorkerMain');
exports.workerExtensionHost = createEditorWorkerModuleDescription('vs/workbench/api/worker/extensionHostWorkerMain');
exports.workerNotebook = createEditorWorkerModuleDescription('vs/workbench/contrib/notebook/common/services/notebookSimpleWorkerMain');
exports.workerLanguageDetection = createEditorWorkerModuleDescription('vs/workbench/services/languageDetection/browser/languageDetectionSimpleWorkerMain');
exports.workerLocalFileSearch = createEditorWorkerModuleDescription('vs/workbench/services/search/worker/localFileSearchMain');
exports.workerProfileAnalysis = createEditorWorkerModuleDescription('vs/platform/profiling/electron-sandbox/profileAnalysisWorkerMain');
exports.workerOutputLinks = createEditorWorkerModuleDescription('vs/workbench/contrib/output/common/outputLinkComputerMain');
exports.workerBackgroundTokenization = createEditorWorkerModuleDescription('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain');
exports.workerEditor = createModuleDescription('vs/editor/common/services/editorWebWorkerMain');
exports.workerExtensionHost = createModuleDescription('vs/workbench/api/worker/extensionHostWorkerMain');
exports.workerNotebook = createModuleDescription('vs/workbench/contrib/notebook/common/services/notebookWebWorkerMain');
exports.workerLanguageDetection = createModuleDescription('vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain');
exports.workerLocalFileSearch = createModuleDescription('vs/workbench/services/search/worker/localFileSearchMain');
exports.workerProfileAnalysis = createModuleDescription('vs/platform/profiling/electron-sandbox/profileAnalysisWorkerMain');
exports.workerOutputLinks = createModuleDescription('vs/workbench/contrib/output/common/outputLinkComputerMain');
exports.workerBackgroundTokenization = createModuleDescription('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain');
exports.workbenchDesktop = [
createModuleDescription('vs/workbench/contrib/debug/node/telemetryApp'),

View file

@ -72,4 +72,4 @@ f7db8ebe91a1cc8d24ef6aad12949a18d8e4975ac296e3e5e9ecd88c9bccb143 *mksnapshot-v34
4da23a950bfcc377ef21c37d496017ab4c36da03f3b41049ac114042c42608ce *mksnapshot-v34.3.2-mas-x64.zip
fab59573d3c2f9bdf31146a1896d24ac0c51f736aad86d2f3c7ecef13c05a7fd *mksnapshot-v34.3.2-win32-arm64-x64.zip
66f25e07c6f8d5d2009577a129440255a3baf63c929a5b60b2e77cd52e46105b *mksnapshot-v34.3.2-win32-ia32.zip
8168bfbf61882cfac80aed1e71e364e1c7f2fccd11eac298e6abade8b46894ea *mksnapshot-v34.3.2-win32-x64.zip
8168bfbf61882cfac80aed1e71e364e1c7f2fccd11eac298e6abade8b46894ea *mksnapshot-v34.3.2-win32-x64.zip

View file

@ -1,7 +1,7 @@
fa76d5b5340f14070ebaa88ef8faa28c1e9271502725e830cb52f0cf5b6493de node-v20.18.2-darwin-arm64.tar.gz
00a16bb0a82a2ad5d00d66b466ae1afa678482283747c27e9bce96668f334744 node-v20.18.2-darwin-x64.tar.gz
319789e8a055ff80793a05e633c8c5c9226050144a09da3747225b4ec56a2a99 node-v20.18.2-linux-arm64.tar.gz
65397a4a63960bda94718099698d2961623e9ef400f60f4c3a71add2268bccfb node-v20.18.2-linux-armv7l.tar.gz
eb5b031bdd728871c3b9a82655dbfa533bc262c0b6da1d09a86842430cef07d4 node-v20.18.2-linux-x64.tar.gz
83e7ad1b8c4d4d9c5e06849c3e8f3a5948a5eb6aa34c5bd973ba700e0386f42c win-arm64/node.exe
8487a277e92282904dfe0f860dbd5d229543e97a858a223fbe9c9b8670bbe170 win-x64/node.exe
1f15b7ed18a580af31cf32bc126572292d820f547bf55bf9cdce08041a24e1d9 node-v20.18.3-darwin-arm64.tar.gz
ba668f64df9239843fefcef095ee539f5ac5aa1b0fc15a71f1ecca16abedec7a node-v20.18.3-darwin-x64.tar.gz
93a9df19238adfaa289f4784041d03edaf2fdd89fbb247faffca2fe4a1000703 node-v20.18.3-linux-arm64.tar.gz
8a84eb34287db6a273066934d7195e429f57b91686b62fc19497210204a2b3de node-v20.18.3-linux-armv7l.tar.gz
9fc3952da39b20d1fcfdb777b198cc035485afbbb1004b4df93f35245d61151e node-v20.18.3-linux-x64.tar.gz
4258e333f4b95060681d61bffa762542a8068547d3dffebe57c575b38d380dda win-arm64/node.exe
528a9aa64888a2a3ba71c6aea89434dd5ab5cb3caa9f0f31345cf5facf685ab0 win-x64/node.exe

View file

@ -1,6 +1,3 @@
68a17006021975ff271a1dd615f9db9eda7c25f2cc65e750c87980dc57a06c94 aarch64-linux-gnu-glibc-2.17.tar.gz
0de422a81683cf9e8cf875dbd1e0c27545ac3c775b2d53015daf3ca2b31d3f15 aarch64-linux-gnu-glibc-2.28.tar.gz
3ced48cb479f2cdba95aa649710fcb7778685551c745bbd76ac706c3c0ead9fb arm-rpi-linux-gnueabihf-glibc-2.17.tar.gz
7aea163f7fad8cc50000c86b5108be880121d35e2f55d016ef8c96bbe54129eb arm-rpi-linux-gnueabihf-glibc-2.28.tar.gz
5aae21115f1d284c3cdf32c83db15771b59bc80793f1423032abf5a823c0d658 x86_64-linux-gnu-glibc-2.17.tar.gz
dbb927408393041664a020661f2641c9785741be3d29b050b9dac58980967784 x86_64-linux-gnu-glibc-2.28.tar.gz

View file

@ -27,6 +27,7 @@ async function main(buildDir) {
const filesToSkip = [
'**/CodeResources',
'**/Credits.rtf',
'**/policies/{*.mobileconfig,**/*.plist}',
// TODO: Should we consider expanding this to other files in this area?
'**/node_modules/@parcel/node-addon-api/nothing.target.mk'
];

View file

@ -28,6 +28,7 @@ async function main(buildDir?: string) {
const filesToSkip = [
'**/CodeResources',
'**/Credits.rtf',
'**/policies/{*.mobileconfig,**/*.plist}',
// TODO: Should we consider expanding this to other files in this area?
'**/node_modules/@parcel/node-addon-api/nothing.target.mk'
];

View file

@ -54,11 +54,9 @@ async function main(buildDir) {
...defaultOpts,
// TODO(deepak1556): Incorrectly declared type in electron-osx-sign
ignore: (filePath) => {
const ext = path_1.default.extname(filePath);
return filePath.includes(gpuHelperAppName) ||
filePath.includes(rendererHelperAppName) ||
filePath.includes(pluginHelperAppName) ||
ext === '.asar' || ext === '.dat' || ext === '.gif' || ext === '.icns' || ext === '.ico' || ext === '.json' || ext === '.mp3' || ext === '.nib' || ext === '.pak' || ext === '.png' || ext === '.scpt' || ext === '.ttf' || ext === '.wasm' || ext === '.woff' || ext === '.woff2';
filePath.includes(pluginHelperAppName);
}
};
const gpuHelperOpts = {
@ -83,7 +81,7 @@ async function main(buildDir) {
// universal will get its copy from the x64 build.
if (arch !== 'universal') {
await (0, cross_spawn_promise_1.spawn)('plutil', [
'-replace', // Void changed this to replace
'-insert',
'NSAppleEventsUsageDescription',
'-string',
'An application in Visual Studio Code wants to use AppleScript.',

View file

@ -58,11 +58,9 @@ async function main(buildDir?: string): Promise<void> {
...defaultOpts,
// TODO(deepak1556): Incorrectly declared type in electron-osx-sign
ignore: (filePath: string) => {
const ext = path.extname(filePath);
return filePath.includes(gpuHelperAppName) ||
filePath.includes(rendererHelperAppName) ||
filePath.includes(pluginHelperAppName) ||
ext === '.asar' || ext === '.dat' || ext === '.gif' || ext === '.icns' || ext === '.ico' || ext === '.json' || ext === '.mp3' || ext === '.nib' || ext === '.pak' || ext === '.png' || ext === '.scpt' || ext === '.ttf' || ext === '.wasm' || ext === '.woff' || ext === '.woff2';
filePath.includes(pluginHelperAppName);
}
};
@ -91,7 +89,7 @@ async function main(buildDir?: string): Promise<void> {
// universal will get its copy from the x64 build.
if (arch !== 'universal') {
await spawn('plutil', [
'-replace', // Void changed this to replace
'-insert',
'NSAppleEventsUsageDescription',
'-string',
'An application in Visual Studio Code wants to use AppleScript.',

View file

@ -57,6 +57,7 @@ module.exports.unicodeFilter = [
'!extensions/**/out/**',
'!extensions/**/snippets/**',
'!extensions/**/colorize-fixtures/**',
'!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts',
'!src/vs/base/browser/dompurify/**',
'!src/vs/workbench/services/keybinding/browser/keyboardLayouts/**',
@ -79,6 +80,7 @@ module.exports.indentationFilter = [
'!src/vs/base/node/terminateProcess.sh',
'!src/vs/base/node/cpuUsage.sh',
'!src/vs/editor/common/languages/highlights/*.scm',
'!src/vs/editor/common/languages/injections/*.scm',
'!test/unit/assert.js',
'!resources/linux/snap/electron-launch',
'!build/ext.js',
@ -90,6 +92,7 @@ module.exports.indentationFilter = [
'!test/monaco/out/**',
'!test/smoke/out/**',
'!extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts',
'!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts',
'!extensions/terminal-suggest/src/completions/upstream/**',
'!extensions/typescript-language-features/test-workspace/**',
'!extensions/typescript-language-features/resources/walkthroughs/**',
@ -137,9 +140,6 @@ module.exports.indentationFilter = [
'!extensions/ipynb/notebook-out/**',
'!extensions/notebook-renderers/renderer-out/*.js',
'!extensions/simple-browser/media/*.js',
'!extensions/open-remote-ssh/out/*.js', // Void added this
'!extensions/open-remote-wsl/out/*.js', // Void added this
];
module.exports.copyrightFilter = [
@ -198,6 +198,7 @@ module.exports.tsFormattingFilter = [
'!extensions/**/*.test.ts',
'!extensions/html-language-features/server/lib/jquery.d.ts',
'!extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts',
'!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts',
];
module.exports.eslintFilter = [
@ -205,6 +206,7 @@ module.exports.eslintFilter = [
'**/*.cjs',
'**/*.mjs',
'**/*.ts',
'.eslint-plugin-local/**/*.ts',
...readFileSync(join(__dirname, '..', '.eslint-ignore'))
.toString()
.split(/\r\n|\n/)

View file

@ -24,12 +24,12 @@ function makeCompileBuildTask(disableMangle) {
);
}
// Full compile, including nls and inline sources in sourcemaps, mangling, minification, for build
const compileBuildTask = task.define('compile-build', makeCompileBuildTask(false));
gulp.task(compileBuildTask);
exports.compileBuildTask = compileBuildTask;
// Local/PR compile, including nls and inline sources in sourcemaps, minification, no mangling
const compileBuildWithoutManglingTask = task.define('compile-build-without-mangling', makeCompileBuildTask(true));
gulp.task(compileBuildWithoutManglingTask);
exports.compileBuildWithoutManglingTask = compileBuildWithoutManglingTask;
// Full compile for PR ci, e.g no mangling
const compileBuildTaskPullRequest = task.define('compile-build-pr', makeCompileBuildTask(true));
gulp.task(compileBuildTaskPullRequest);
exports.compileBuildTaskPullRequest = compileBuildTaskPullRequest;
// CI compile, including nls and inline sources in sourcemaps, mangling, minification, for build
const compileBuildWithManglingTask = task.define('compile-build-with-mangling', makeCompileBuildTask(false));
gulp.task(compileBuildWithManglingTask);
exports.compileBuildWithManglingTask = compileBuildWithManglingTask;

View file

@ -3,12 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
const gulp = require('gulp');
const path = require('path');
const util = require('./lib/util');
const { getVersion } = require('./lib/getVersion');
const task = require('./lib/task');
const optimize = require('./lib/optimize');
const es = require('event-stream');
const File = require('vinyl');
const i18n = require('./lib/i18n');
@ -17,39 +18,13 @@ const cp = require('child_process');
const compilation = require('./lib/compilation');
const monacoapi = require('./lib/monaco-api');
const fs = require('fs');
const filter = require('gulp-filter');
const root = path.dirname(__dirname);
const sha1 = getVersion(root);
const semver = require('./monaco/package.json').version;
const headerVersion = semver + '(' + sha1 + ')';
// Build
const editorEntryPoints = [
{
name: 'vs/editor/editor.main',
include: [],
exclude: ['vs/css'],
prepend: [
{ path: 'out-editor-build/vs/css.js', amdModuleId: 'vs/css' }
],
},
{
name: 'vs/base/common/worker/simpleWorker',
include: ['vs/editor/common/services/editorSimpleWorker'],
exclude: [],
prepend: [
{ path: 'vs/loader.js' },
{ path: 'vs/base/worker/workerMain.js' }
],
dest: 'vs/base/worker/workerMain.js'
}
];
const editorResources = [
'out-editor-build/vs/base/browser/ui/codicons/**/*.ttf'
];
const BUNDLED_FILE_HEADER = [
'/*!-----------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
@ -60,8 +35,6 @@ const BUNDLED_FILE_HEADER = [
''
].join('\n');
const languages = i18n.defaultLanguages.concat([]); // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);
const extractEditorSrcTask = task.define('extract-editor-src', () => {
const apiusages = monacoapi.execute().usageContent;
const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString();
@ -69,128 +42,43 @@ const extractEditorSrcTask = task.define('extract-editor-src', () => {
sourcesRoot: path.join(root, 'src'),
entryPoints: [
'vs/editor/editor.main',
'vs/editor/editor.worker',
'vs/base/worker/workerMain',
'vs/editor/editor.worker.start',
'vs/editor/common/services/editorWebWorkerMain',
],
inlineEntryPoints: [
apiusages,
extrausages
],
typings: [],
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
importIgnorePattern: /\.css$/,
destRoot: path.join(root, 'out-editor-src'),
tsOutDir: '../out-monaco-editor-core/esm/vs',
redirects: {
'@vscode/tree-sitter-wasm': '../node_modules/@vscode/tree-sitter-wasm/wasm/web-tree-sitter',
}
});
});
// Disable mangling for the editor, as it complicates debugging & quite a few users rely on private/protected fields.
// Disable NLS task to remove english strings to preserve backwards compatibility when we removed the `vs/nls!` AMD plugin.
const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true, { disableMangle: true, preserveEnglish: true }));
const bundleEditorAMDTask = task.define('bundle-editor-amd', optimize.bundleTask(
{
out: 'out-editor',
esm: {
src: 'out-editor-build',
entryPoints: editorEntryPoints,
resources: editorResources
}
}
));
const minifyEditorAMDTask = task.define('minify-editor-amd', optimize.minifyTask('out-editor'));
const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => {
standalone.createESMSourcesAndResources2({
srcFolder: './out-editor-src',
outFolder: './out-editor-esm',
outResourcesFolder: './out-monaco-editor-core/esm',
ignores: [
'inlineEntryPoint:0.ts',
'inlineEntryPoint:1.ts',
'vs/loader.js',
'vs/base/worker/workerMain.ts',
],
renames: {
}
});
});
const compileEditorESMTask = task.define('compile-editor-esm', () => {
const KEEP_PREV_ANALYSIS = false;
const FAIL_ON_PURPOSE = false;
console.log(`Launching the TS compiler at ${path.join(__dirname, '../out-editor-esm')}...`);
let result;
if (process.platform === 'win32') {
result = cp.spawnSync(`..\\node_modules\\.bin\\tsc.cmd`, {
cwd: path.join(__dirname, '../out-editor-esm'),
shell: true
});
} else {
result = cp.spawnSync(`node`, [`../node_modules/.bin/tsc`], {
cwd: path.join(__dirname, '../out-editor-esm')
});
}
console.log(result.stdout.toString());
console.log(result.stderr.toString());
const src = 'out-editor-src';
const out = 'out-monaco-editor-core/esm';
if (FAIL_ON_PURPOSE || result.status !== 0) {
console.log(`The TS Compilation failed, preparing analysis folder...`);
const destPath = path.join(__dirname, '../../vscode-monaco-editor-esm-analysis');
const keepPrevAnalysis = (KEEP_PREV_ANALYSIS && fs.existsSync(destPath));
const cleanDestPath = (keepPrevAnalysis ? Promise.resolve() : util.rimraf(destPath)());
return cleanDestPath.then(() => {
// build a list of files to copy
const files = util.rreddir(path.join(__dirname, '../out-editor-esm'));
const compile = compilation.createCompile(src, { build: true, emitError: true, transpileOnly: false, preserveEnglish: true });
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
if (!keepPrevAnalysis) {
fs.mkdirSync(destPath);
// initialize a new repository
cp.spawnSync(`git`, [`init`], {
cwd: destPath
});
// copy files from src
for (const file of files) {
const srcFilePath = path.join(__dirname, '../src', file);
const dstFilePath = path.join(destPath, file);
if (fs.existsSync(srcFilePath)) {
util.ensureDir(path.dirname(dstFilePath));
const contents = fs.readFileSync(srcFilePath).toString().replace(/\r\n|\r|\n/g, '\n');
fs.writeFileSync(dstFilePath, contents);
}
}
// create an initial commit to diff against
cp.spawnSync(`git`, [`add`, `.`], {
cwd: destPath
});
// create the commit
cp.spawnSync(`git`, [`commit`, `-m`, `"original sources"`, `--no-gpg-sign`], {
cwd: destPath
});
}
// copy files from tree shaken src
for (const file of files) {
const srcFilePath = path.join(__dirname, '../out-editor-src', file);
const dstFilePath = path.join(destPath, file);
if (fs.existsSync(srcFilePath)) {
util.ensureDir(path.dirname(dstFilePath));
const contents = fs.readFileSync(srcFilePath).toString().replace(/\r\n|\r|\n/g, '\n');
fs.writeFileSync(dstFilePath, contents);
}
}
console.log(`Open in VS Code the folder at '${destPath}' and you can analyze the compilation error`);
throw new Error('Standalone Editor compilation failed. If this is the build machine, simply launch `npm run gulp editor-distro` on your machine to further analyze the compilation problem.');
});
}
return (
srcPipe
.pipe(compile())
.pipe(i18n.processNlsFiles({
out,
fileHeader: BUNDLED_FILE_HEADER,
languages: i18n.defaultLanguages,
}))
.pipe(filter(['**', '!**/inlineEntryPoint*', '!**/tsconfig.json', '!**/loader.js']))
.pipe(gulp.dest(out))
);
});
/**
@ -239,18 +127,6 @@ function toExternalDTS(contents) {
return lines.join('\n').replace(/\n\n\n+/g, '\n\n');
}
/**
* @param {{ (path: string): boolean }} testFunc
*/
function filterStream(testFunc) {
return es.through(function (data) {
if (!testFunc(data.relative)) {
return;
}
this.emit('data', data);
});
}
const finalEditorResourcesTask = task.define('final-editor-resources', () => {
return es.merge(
// other assets
@ -299,42 +175,6 @@ const finalEditorResourcesTask = task.define('final-editor-resources', () => {
}));
}))
.pipe(gulp.dest('out-monaco-editor-core')),
// dev folder
es.merge(
gulp.src('out-editor/**/*')
).pipe(gulp.dest('out-monaco-editor-core/dev')),
// min folder
es.merge(
gulp.src('out-editor-min/**/*')
).pipe(filterStream(function (path) {
// no map files
return !/(\.js\.map$)|(nls\.metadata\.json$)|(bundleInfo\.json$)/.test(path);
})).pipe(es.through(function (data) {
// tweak the sourceMappingURL
if (!/\.js$/.test(data.path)) {
this.emit('data', data);
return;
}
const relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map'));
let strContents = data.contents.toString();
const newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/');
strContents = strContents.replace(/\/\/# sourceMappingURL=[^ ]+$/, newStr);
data.contents = Buffer.from(strContents);
this.emit('data', data);
})).pipe(gulp.dest('out-monaco-editor-core/min')),
// min-maps folder
es.merge(
gulp.src('out-editor-min/**/*')
).pipe(filterStream(function (path) {
// no map files
return /\.js\.map$/.test(path);
})).pipe(gulp.dest('out-monaco-editor-core/min-maps'))
);
});
@ -349,38 +189,11 @@ gulp.task('editor-distro',
task.series(
task.parallel(
util.rimraf('out-editor-src'),
util.rimraf('out-editor-build'),
util.rimraf('out-editor-esm'),
util.rimraf('out-monaco-editor-core'),
util.rimraf('out-editor'),
util.rimraf('out-editor-min')
),
extractEditorSrcTask,
task.parallel(
task.series(
compileEditorAMDTask,
bundleEditorAMDTask,
minifyEditorAMDTask
),
task.series(
createESMSourcesAndResourcesTask,
compileEditorESMTask,
)
),
finalEditorResourcesTask
)
);
gulp.task('editor-esm',
task.series(
task.parallel(
util.rimraf('out-editor-src'),
util.rimraf('out-editor-esm'),
util.rimraf('out-monaco-editor-core'),
),
extractEditorSrcTask,
createESMSourcesAndResourcesTask,
compileEditorESMTask,
finalEditorResourcesTask
)
);
@ -393,6 +206,9 @@ gulp.task('monacodts', task.define('monacodts', () => {
//#region monaco type checking
/**
* @param {boolean} watch
*/
function createTscCompileTask(watch) {
return () => {
const createReporter = require('./lib/reporter').createReporter;
@ -421,6 +237,7 @@ function createTscCompileTask(watch) {
report = reporter.end(false);
} else if (str.indexOf('Compilation complete') >= 0) {
// @ts-ignore
report.end();
} else if (str) {

View file

@ -71,10 +71,6 @@ const compilations = [
'.vscode/extensions/vscode-selfhost-test-provider/tsconfig.json',
'.vscode/extensions/vscode-selfhost-import-aid/tsconfig.json',
'extensions/open-remote-ssh/tsconfig.json', // Void added this
'extensions/open-remote-wsl/tsconfig.json', // Void added this
];
const getBaseUrl = out => `https://main.vscode-cdn.net/sourcemaps/${commit}/${out}`;

View file

@ -26,7 +26,7 @@ const gunzip = require('gulp-gunzip');
const File = require('vinyl');
const fs = require('fs');
const glob = require('glob');
const { compileBuildTask } = require('./gulpfile.compile');
const { compileBuildWithManglingTask } = require('./gulpfile.compile');
const { cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileExtensionMediaBuildTask } = require('./gulpfile.extensions');
const { vscodeWebResourceIncludes, createVSCodeWebFileContentMapper } = require('./gulpfile.vscode.web');
const cp = require('child_process');
@ -154,20 +154,9 @@ function getNodeChecksum(expectedName) {
}
function extractAlpinefromDocker(nodeVersion, platform, arch) {
let imageName = 'node';
let dockerPlatform = '';
if (arch === 'arm64') {
imageName = 'arm64v8/node';
const architecture = cp.execSync(`docker info --format '{{json .Architecture}}'`, { encoding: 'utf8' }).trim();
if (architecture !== '"aarch64"') {
dockerPlatform = '--platform=linux/arm64';
}
}
const imageName = arch === 'arm64' ? 'arm64v8/node' : 'node';
log(`Downloading node.js ${nodeVersion} ${platform} ${arch} from docker image ${imageName}`);
const contents = cp.execSync(`docker run --rm ${dockerPlatform} ${imageName}:${nodeVersion}-alpine /bin/sh -c 'cat \`which node\`'`, { maxBuffer: 100 * 1024 * 1024, encoding: 'buffer' });
const contents = cp.execSync(`docker run --rm ${imageName}:${nodeVersion}-alpine /bin/sh -c 'cat \`which node\`'`, { maxBuffer: 100 * 1024 * 1024, encoding: 'buffer' });
return es.readArray([new File({ path: 'node', contents, stat: { mode: parseInt('755', 8) } })]);
}
@ -319,11 +308,10 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
}
const name = product.nameShort;
const release = packageJson.release;
let packageJsonContents;
const packageJsonStream = gulp.src(['remote/package.json'], { base: 'remote' })
.pipe(json({ name, version, release, dependencies: undefined, optionalDependencies: undefined, type: 'module' }))
.pipe(json({ name, version, dependencies: undefined, optionalDependencies: undefined, type: 'module' }))
.pipe(es.through(function (file) {
packageJsonContents = file.contents.toString();
this.emit('data', file);
@ -331,7 +319,7 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
let productJsonContents;
const productJsonStream = gulp.src(['product.json'], { base: '.' })
.pipe(json({ commit, date: readISODate('out-build'), version, release }))
.pipe(json({ commit, date: readISODate('out-build'), version }))
.pipe(es.through(function (file) {
productJsonContents = file.contents.toString();
this.emit('data', file);
@ -414,13 +402,7 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
);
}
if (platform === 'linux' && process.env['VSCODE_NODE_GLIBC'] === '-glibc-2.17') {
result = es.merge(result,
gulp.src(`resources/server/bin/helpers/check-requirements-linux-legacy.sh`, { base: '.' })
.pipe(rename(`bin/helpers/check-requirements.sh`))
.pipe(util.setExecutableBit())
);
} else if (platform === 'linux' || platform === 'alpine') {
if (platform === 'linux' || platform === 'alpine') {
result = es.merge(result,
gulp.src(`resources/server/bin/helpers/check-requirements-linux.sh`, { base: '.' })
.pipe(rename(`bin/helpers/check-requirements.sh`))
@ -491,7 +473,7 @@ function tweakProductForServerWeb(product) {
gulp.task(serverTaskCI);
const serverTask = task.define(`vscode-${type}${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series(
compileBuildTask,
compileBuildWithManglingTask,
cleanExtensionsBuildTask,
compileNonNativeExtensionsBuildTask,
compileExtensionMediaBuildTask,

View file

@ -30,7 +30,7 @@ const { getProductionDependencies } = require('./lib/dependencies');
const { config } = require('./lib/electron');
const createAsar = require('./lib/asar').createAsar;
const minimist = require('minimist');
const { compileBuildTask } = require('./gulpfile.compile');
const { compileBuildWithoutManglingTask, compileBuildWithManglingTask } = require('./gulpfile.compile');
const { compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileAllExtensionsBuildTask, compileExtensionMediaBuildTask, cleanExtensionsBuildTask } = require('./gulpfile.extensions');
const { promisify } = require('util');
const glob = promisify(require('glob'));
@ -101,6 +101,9 @@ const vscodeResourceIncludes = [
// Tree Sitter highlights
'out-build/vs/editor/common/languages/highlights/*.scm',
// Tree Sitter injection queries
'out-build/vs/editor/common/languages/injections/*.scm',
];
const vscodeResources = [
@ -166,25 +169,25 @@ const minifyVSCodeTask = task.define('minify-vscode', task.series(
));
gulp.task(minifyVSCodeTask);
const core = task.define('core-ci', task.series(
gulp.task('compile-build'),
const coreCI = task.define('core-ci', task.series(
gulp.task('compile-build-with-mangling'),
task.parallel(
gulp.task('minify-vscode'),
gulp.task('minify-vscode-reh'),
gulp.task('minify-vscode-reh-web'),
)
));
gulp.task(core);
gulp.task(coreCI);
const corePr = task.define('core-ci-pr', task.series(
gulp.task('compile-build-pr'),
const coreCIPR = task.define('core-ci-pr', task.series(
gulp.task('compile-build-without-mangling'),
task.parallel(
gulp.task('minify-vscode'),
gulp.task('minify-vscode-reh'),
gulp.task('minify-vscode-reh-web'),
)
));
gulp.task(corePr);
gulp.task(coreCIPR);
/**
* Compute checksums for some files.
@ -267,8 +270,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
}
const name = product.nameShort;
const release = packageJson.release;
const packageJsonUpdates = { name, version, release };
const packageJsonUpdates = { name, version };
if (platform === 'linux') {
packageJsonUpdates.desktopName = `${product.applicationName}.desktop`;
@ -282,10 +284,9 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
this.emit('data', file);
}));
// Void - this is important, creates the product.json in .app
let productJsonContents;
const productJsonStream = gulp.src(['product.json'], { base: '.' })
.pipe(json({ commit, date: readISODate('out-build'), checksums, version, release }))
.pipe(json({ commit, date: readISODate('out-build'), checksums, version }))
.pipe(es.through(function (file) {
productJsonContents = file.contents.toString();
this.emit('data', file);
@ -373,9 +374,10 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
} else if (platform === 'darwin') {
const shortcut = gulp.src('resources/darwin/bin/code.sh')
.pipe(replace('@@APPNAME@@', product.applicationName))
.pipe(rename('bin/' + product.applicationName));
all = es.merge(all, shortcut);
.pipe(rename('bin/code'));
const policyDest = gulp.src('.build/policies/darwin/**', { base: '.build/policies/darwin' })
.pipe(rename(f => f.dirname = `policies/${f.dirname}`));
all = es.merge(all, shortcut, policyDest);
}
let result = all
@ -502,7 +504,7 @@ BUILD_TARGETS.forEach(buildTarget => {
gulp.task(vscodeTaskCI);
const vscodeTask = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series(
compileBuildTask,
minified ? compileBuildWithManglingTask : compileBuildWithoutManglingTask,
cleanExtensionsBuildTask,
compileNonNativeExtensionsBuildTask,
compileExtensionMediaBuildTask,
@ -540,7 +542,7 @@ const innoSetupConfig = {
gulp.task(task.define(
'vscode-translations-export',
task.series(
core,
coreCI,
compileAllExtensionsBuildTask,
function () {
const pathToMetadata = './out-build/nls.metadata.json';

View file

@ -25,6 +25,7 @@ const exec = util.promisify(cp.exec);
const root = path.dirname(__dirname);
const commit = getVersion(root);
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
/**
* @param {string} arch
@ -38,7 +39,9 @@ function prepareDebPackage(arch) {
const debArch = getDebPackageArch(arch);
const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch;
return function () {
return async function () {
const dependencies = await dependenciesGenerator.getDependencies('deb', binaryDir, product.applicationName, debArch);
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(rename('usr/share/applications/' + product.applicationName + '.desktop'));
@ -81,12 +84,11 @@ function prepareDebPackage(arch) {
let size = 0;
const control = code.pipe(es.through(
function (f) { size += f.isDirectory() ? 4096 : f.contents.length; },
async function () {
function () {
const that = this;
const dependencies = await dependenciesGenerator.getDependencies('deb', binaryDir, product.applicationName, debArch);
gulp.src('resources/linux/debian/control.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@VERSION@@', `${packageJson.version}.${packageJson.release}`))
.pipe(replace('@@VERSION@@', packageJson.version + '-' + linuxPackageRevision))
.pipe(replace('@@ARCHITECTURE@@', debArch))
.pipe(replace('@@DEPENDS@@', dependencies.join(', ')))
.pipe(replace('@@RECOMMENDS@@', debianRecommendedDependencies.join(', ')))
@ -153,7 +155,9 @@ function prepareRpmPackage(arch) {
const rpmArch = getRpmPackageArch(arch);
const stripBinary = process.env['STRIP'] ?? '/usr/bin/strip';
return function () {
return async function () {
const dependencies = await dependenciesGenerator.getDependencies('rpm', binaryDir, product.applicationName, rpmArch);
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '.desktop'));
@ -193,24 +197,19 @@ function prepareRpmPackage(arch) {
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) { p.dirname = 'BUILD/usr/share/' + product.applicationName + '/' + p.dirname; }));
const spec = code.pipe(es.through(
async function () {
const that = this;
const dependencies = await dependenciesGenerator.getDependencies('rpm', binaryDir, product.applicationName, rpmArch);
gulp.src('resources/linux/rpm/code.spec.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@ICON@@', product.linuxIconName))
.pipe(replace('@@VERSION@@', `${packageJson.version}.${packageJson.release}`))
.pipe(replace('@@ARCHITECTURE@@', rpmArch))
.pipe(replace('@@LICENSE@@', product.licenseName))
.pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@'))
.pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@'))
.pipe(replace('@@DEPENDENCIES@@', dependencies.join(', ')))
.pipe(replace('@@STRIP@@', stripBinary))
.pipe(rename('SPECS/' + product.applicationName + '.spec'))
.pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); }));
}));
const spec = gulp.src('resources/linux/rpm/code.spec.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@ICON@@', product.linuxIconName))
.pipe(replace('@@VERSION@@', packageJson.version))
.pipe(replace('@@RELEASE@@', linuxPackageRevision))
.pipe(replace('@@ARCHITECTURE@@', rpmArch))
.pipe(replace('@@LICENSE@@', product.licenseName))
.pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@'))
.pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@'))
.pipe(replace('@@DEPENDENCIES@@', dependencies.join(', ')))
.pipe(replace('@@STRIP@@', stripBinary))
.pipe(rename('SPECS/' + product.applicationName + '.spec'));
const specIcon = gulp.src('resources/linux/rpm/code.xpm', { base: '.' })
.pipe(rename('SOURCES/' + product.applicationName + '.xpm'));
@ -277,7 +276,7 @@ function prepareSnapPackage(arch) {
const snapcraft = gulp.src('resources/linux/snap/snapcraft.yaml', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@VERSION@@', `${packageJson.version}.${packageJson.release}`))
.pipe(replace('@@VERSION@@', commit.substr(0, 8)))
// Possible run-on values https://snapcraft.io/docs/architectures
.pipe(replace('@@ARCHITECTURE@@', arch === 'x64' ? 'amd64' : arch))
.pipe(rename('snap/snapcraft.yaml'));

View file

@ -19,7 +19,7 @@ const filter = require('gulp-filter');
const { getProductionDependencies } = require('./lib/dependencies');
const vfs = require('vinyl-fs');
const packageJson = require('../package.json');
const { compileBuildTask } = require('./gulpfile.compile');
const { compileBuildWithManglingTask } = require('./gulpfile.compile');
const extensions = require('./lib/extensions');
const VinylFile = require('vinyl');
@ -52,6 +52,9 @@ const vscodeWebResourceIncludes = [
// Tree Sitter highlights
'out-build/vs/editor/common/languages/highlights/*.scm',
// Tree Sitter injections
'out-build/vs/editor/common/languages/injections/*.scm',
// Extension Host Worker
'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html',
];
@ -223,7 +226,7 @@ const dashed = (/** @type {string} */ str) => (str ? `-${str}` : ``);
gulp.task(vscodeWebTaskCI);
const vscodeWebTask = task.define(`vscode-web${dashed(minified)}`, task.series(
compileBuildTask,
compileBuildWithManglingTask,
vscodeWebTaskCI
));
gulp.task(vscodeWebTask);

View file

@ -82,13 +82,14 @@ function buildWin32Setup(arch, target) {
productJson['target'] = target;
fs.writeFileSync(productJsonPath, JSON.stringify(productJson, undefined, '\t'));
console.log('RawVersion!!!!!!!!!!!!!!', pkg.version.replace(/-\w+$/, '')) // Void
const quality = product.quality || 'dev';
const definitions = {
NameLong: product.nameLong,
NameShort: product.nameShort,
DirName: product.win32DirName,
Version: `${pkg.version}.${pkg.release}`,
RawVersion: `${pkg.version.replace(/-\w+$/, '')}.${pkg.release}`,
Version: pkg.version,
RawVersion: pkg.version.replace(/-\w+$/, ''),
NameVersion: product.win32NameVersion + (target === 'user' ? ' (User)' : ''),
ExeBasename: product.nameShort,
RegValueName: product.win32RegValueName,

View file

@ -85,7 +85,10 @@ function getExtensionDownloadStream(extension) {
if (extension.vsix) {
input = ext.fromVsix(path_1.default.join(root, extension.vsix), extension);
}
else { // Void - ext-from-gh.patch
else if (productjson.extensionsGallery?.serviceUrl) {
input = ext.fromMarketplace(productjson.extensionsGallery.serviceUrl, extension);
}
else {
input = ext.fromGithub(extension);
}
return input.pipe((0, gulp_rename_1.default)(p => p.dirname = `${extension.name}/${p.dirname}`));

View file

@ -73,7 +73,9 @@ function getExtensionDownloadStream(extension: IExtensionDefinition) {
if (extension.vsix) {
input = ext.fromVsix(path.join(root, extension.vsix), extension);
} else { // Void - ext-from-gh.patch
} else if (productjson.extensionsGallery?.serviceUrl) {
input = ext.fromMarketplace(productjson.extensionsGallery.serviceUrl, extension);
} else {
input = ext.fromGithub(extension);
}

View file

@ -3,229 +3,8 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.bundle = bundle;
exports.removeAllTSBoilerplate = removeAllTSBoilerplate;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const vm_1 = __importDefault(require("vm"));
/**
* Bundle `entryPoints` given config `config`.
*/
function bundle(entryPoints, config, callback) {
const entryPointsMap = {};
entryPoints.forEach((module) => {
if (entryPointsMap[module.name]) {
throw new Error(`Cannot have two entry points with the same name '${module.name}'`);
}
entryPointsMap[module.name] = module;
});
const allMentionedModulesMap = {};
entryPoints.forEach((module) => {
allMentionedModulesMap[module.name] = true;
module.include?.forEach(function (includedModule) {
allMentionedModulesMap[includedModule] = true;
});
module.exclude?.forEach(function (excludedModule) {
allMentionedModulesMap[excludedModule] = true;
});
});
const code = require('fs').readFileSync(path_1.default.join(__dirname, '../../src/vs/loader.js'));
const r = vm_1.default.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
const loaderModule = { exports: {} };
r.call({}, require, loaderModule, loaderModule.exports);
const loader = loaderModule.exports;
config.isBuild = true;
config.paths = config.paths || {};
if (!config.paths['vs/css']) {
config.paths['vs/css'] = 'out-build/vs/css.build';
}
config.buildForceInvokeFactory = config.buildForceInvokeFactory || {};
config.buildForceInvokeFactory['vs/css'] = true;
loader.config(config);
loader(['require'], (localRequire) => {
const resolvePath = (entry) => {
let r = localRequire.toUrl(entry.path);
if (!r.endsWith('.js')) {
r += '.js';
}
// avoid packaging the build version of plugins:
r = r.replace('vs/css.build.js', 'vs/css.js');
return { path: r, amdModuleId: entry.amdModuleId };
};
for (const moduleId in entryPointsMap) {
const entryPoint = entryPointsMap[moduleId];
if (entryPoint.prepend) {
entryPoint.prepend = entryPoint.prepend.map(resolvePath);
}
}
});
loader(Object.keys(allMentionedModulesMap), () => {
const modules = loader.getBuildInfo();
const partialResult = emitEntryPoints(modules, entryPointsMap);
const cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, (err) => callback(err, null));
}
function emitEntryPoints(modules, entryPoints) {
const modulesMap = {};
modules.forEach((m) => {
modulesMap[m.id] = m;
});
const modulesGraph = {};
modules.forEach((m) => {
modulesGraph[m.id] = m.dependencies;
});
const sortedModules = topologicalSort(modulesGraph);
let result = [];
const usedPlugins = {};
const bundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach((moduleToBundle) => {
const info = entryPoints[moduleToBundle];
const rootNodes = [moduleToBundle].concat(info.include || []);
const allDependencies = visit(rootNodes, modulesGraph);
const excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach((excludeRoot) => {
const allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach((exclude) => {
delete allDependencies[exclude];
});
});
const includedModules = sortedModules.filter((module) => {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
const res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend || [], info.dest);
result = result.concat(res.files);
for (const pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach((pluginName) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
const write = (filename, contents) => {
result.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.finishBuild(write);
}
});
return {
// TODO@TS 2.1.2
files: extractStrings(removeAllDuplicateTSBoilerplate(result)),
bundleData: bundleData
};
}
function extractStrings(destFiles) {
const parseDefineCall = (moduleMatch, depsMatch) => {
const module = moduleMatch.replace(/^"|"$/g, '');
let deps = depsMatch.split(',');
deps = deps.map((dep) => {
dep = dep.trim();
dep = dep.replace(/^"|"$/g, '');
dep = dep.replace(/^'|'$/g, '');
let prefix = null;
let _path = null;
const pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
_path = pieces[1];
}
else {
prefix = '';
_path = pieces[0];
}
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
const res = path_1.default.join(path_1.default.dirname(module), _path).replace(/\\/g, '/');
return prefix + res;
}
return prefix + _path;
});
return {
module: module,
deps: deps
};
};
destFiles.forEach((destFile) => {
if (!/\.js$/.test(destFile.dest)) {
return;
}
if (/\.nls\.js$/.test(destFile.dest)) {
return;
}
// Do one pass to record the usage counts for each module id
const useCounts = {};
destFile.sources.forEach((source) => {
const matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
return;
}
const defineCall = parseDefineCall(matches[1], matches[2]);
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
defineCall.deps.forEach((dep) => {
useCounts[dep] = (useCounts[dep] || 0) + 1;
});
});
const sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort((a, b) => {
return useCounts[b] - useCounts[a];
});
const replacementMap = {};
sortedByUseModules.forEach((module, index) => {
replacementMap[module] = index;
});
destFile.sources.forEach((source) => {
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, (_, moduleMatch, depsMatch) => {
const defineCall = parseDefineCall(moduleMatch, depsMatch);
return `define(__m[${replacementMap[defineCall.module]}/*${defineCall.module}*/], __M([${defineCall.deps.map(dep => replacementMap[dep] + '/*' + dep + '*/').join(',')}])`;
});
});
destFile.sources.unshift({
path: null,
contents: [
'(function() {',
`var __m = ${JSON.stringify(sortedByUseModules)};`,
`var __M = function(deps) {`,
` var result = [];`,
` for (var i = 0, len = deps.length; i < len; i++) {`,
` result[i] = __m[deps[i]];`,
` }`,
` return result;`,
`};`
].join('\n')
});
destFile.sources.push({
path: null,
contents: '}).call(this);'
});
});
return destFiles;
}
function removeAllDuplicateTSBoilerplate(destFiles) {
destFiles.forEach((destFile) => {
const SEEN_BOILERPLATE = [];
destFile.sources.forEach((source) => {
source.contents = removeDuplicateTSBoilerplate(source.contents, SEEN_BOILERPLATE);
});
});
return destFiles;
}
function removeAllTSBoilerplate(source) {
const seen = new Array(BOILERPLATE.length).fill(true, 0, BOILERPLATE.length);
return removeDuplicateTSBoilerplate(source, seen);
@ -280,213 +59,4 @@ function removeDuplicateTSBoilerplate(source, SEEN_BOILERPLATE = []) {
}
return newLines.join('\n');
}
function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend, dest) {
if (!dest) {
dest = entryPoint + '.js';
}
const mainResult = {
sources: [],
dest: dest
}, results = [mainResult];
const usedPlugins = {};
const getLoaderPlugin = (pluginName) => {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach((c) => {
const bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
const pluginName = c.substr(0, bangIndex);
const plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
const module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
const contents = readFileAndRemoveBOM(module.path);
if (module.shim) {
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
}
else if (module.defineLocation) {
mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents));
}
else {
const moduleCopy = {
id: module.id,
path: module.path,
defineLocation: module.defineLocation,
dependencies: module.dependencies
};
throw new Error(`Cannot bundle module '${module.id}' for entry point '${entryPoint}' because it has no shim and it lacks a defineLocation: ${JSON.stringify(moduleCopy)}`);
}
});
Object.keys(usedPlugins).forEach((pluginName) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
const req = (() => {
throw new Error('no-no!');
});
req.toUrl = something => something;
const write = (filename, contents) => {
results.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
const toIFile = (entry) => {
let contents = readFileAndRemoveBOM(entry.path);
if (entry.amdModuleId) {
contents = contents.replace(/^define\(/m, `define("${entry.amdModuleId}",`);
}
return {
path: entry.path,
contents: contents
};
};
const toPrepend = (prepend || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources);
return {
files: results,
usedPlugins: usedPlugins
};
}
function readFileAndRemoveBOM(path) {
const BOM_CHAR_CODE = 65279;
let contents = fs_1.default.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
}
return contents;
}
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
let result = '';
if (typeof plugin.write === 'function') {
const write = ((what) => {
result += what;
});
write.getEntryPoint = () => {
return entryPoint;
};
write.asModule = (moduleId, code) => {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
plugin.write(pluginName, moduleName, write);
}
return {
path: null,
contents: result
};
}
function emitNamedModule(moduleId, defineCallPosition, path, contents) {
// `defineCallPosition` is the position in code: |define()
const defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
const parensOffset = contents.indexOf('(', defineCallOffset);
const insertStr = '"' + moduleId + '", ';
return {
path: path,
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
};
}
function emitShimmedModule(moduleId, myDeps, factory, path, contents) {
const strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
const strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
};
}
/**
* Convert a position (line:col) to (offset) in string `str`
*/
function positionToOffset(str, desiredLine, desiredCol) {
if (desiredLine === 1) {
return desiredCol - 1;
}
let line = 1;
let lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
}
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
line++;
} while (lastNewLineOffset >= 0);
return -1;
}
/**
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes, graph) {
const result = {};
const queue = rootNodes;
rootNodes.forEach((node) => {
result[node] = true;
});
while (queue.length > 0) {
const el = queue.shift();
const myEdges = graph[el] || [];
myEdges.forEach((toNode) => {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
}
});
}
return result;
}
/**
* Perform a topological sort on `graph`
*/
function topologicalSort(graph) {
const allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach((fromNode) => {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach((toNode) => {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
inverseEdges[toNode].push(fromNode);
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
const S = [], L = [];
Object.keys(allNodes).forEach((node) => {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
}
});
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
const n = S.shift();
L.push(n);
const myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach((m) => {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];
S.push(m);
}
});
}
if (Object.keys(outgoingEdgeCount).length > 0) {
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
}
return L;
}
//# sourceMappingURL=bundle.js.map

View file

@ -3,360 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import fs from 'fs';
import path from 'path';
import vm from 'vm';
interface IPosition {
line: number;
col: number;
}
interface IBuildModuleInfo {
id: string;
path: string;
defineLocation: IPosition | null;
dependencies: string[];
shim: string;
exports: any;
}
interface IBuildModuleInfoMap {
[moduleId: string]: IBuildModuleInfo;
}
interface ILoaderPlugin {
write(pluginName: string, moduleName: string, write: ILoaderPluginWriteFunc): void;
writeFile(pluginName: string, entryPoint: string, req: ILoaderPluginReqFunc, write: (filename: string, contents: string) => void, config: any): void;
finishBuild(write: (filename: string, contents: string) => void): void;
}
interface ILoaderPluginWriteFunc {
(something: string): void;
getEntryPoint(): string;
asModule(moduleId: string, code: string): void;
}
interface ILoaderPluginReqFunc {
(something: string): void;
toUrl(something: string): string;
}
export interface IExtraFile {
path: string;
amdModuleId?: string;
}
export interface IEntryPoint {
name: string;
include?: string[];
exclude?: string[];
/** @deprecated unsupported by ESM */
prepend?: IExtraFile[];
dest?: string;
}
interface IEntryPointMap {
[moduleId: string]: IEntryPoint;
}
export interface IGraph {
[node: string]: string[];
}
interface INodeSet {
[node: string]: boolean;
}
export interface IFile {
path: string | null;
contents: string;
}
export interface IConcatFile {
dest: string;
sources: IFile[];
}
export interface IBundleData {
graph: IGraph;
bundles: { [moduleId: string]: string[] };
}
export interface IBundleResult {
files: IConcatFile[];
cssInlinedResources: string[];
bundleData: IBundleData;
}
interface IPartialBundleResult {
files: IConcatFile[];
bundleData: IBundleData;
}
export interface ILoaderConfig {
isBuild?: boolean;
paths?: { [path: string]: any };
/*
* Normally, during a build, no module factories are invoked. This can be used
* to forcefully execute a module's factory.
*/
buildForceInvokeFactory: {
[moduleId: string]: boolean;
};
}
/**
* Bundle `entryPoints` given config `config`.
*/
export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callback: (err: any, result: IBundleResult | null) => void): void {
const entryPointsMap: IEntryPointMap = {};
entryPoints.forEach((module: IEntryPoint) => {
if (entryPointsMap[module.name]) {
throw new Error(`Cannot have two entry points with the same name '${module.name}'`);
}
entryPointsMap[module.name] = module;
});
const allMentionedModulesMap: { [modules: string]: boolean } = {};
entryPoints.forEach((module: IEntryPoint) => {
allMentionedModulesMap[module.name] = true;
module.include?.forEach(function (includedModule) {
allMentionedModulesMap[includedModule] = true;
});
module.exclude?.forEach(function (excludedModule) {
allMentionedModulesMap[excludedModule] = true;
});
});
const code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
const r: Function = <any>vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
const loaderModule = { exports: {} };
r.call({}, require, loaderModule, loaderModule.exports);
const loader: any = loaderModule.exports;
config.isBuild = true;
config.paths = config.paths || {};
if (!config.paths['vs/css']) {
config.paths['vs/css'] = 'out-build/vs/css.build';
}
config.buildForceInvokeFactory = config.buildForceInvokeFactory || {};
config.buildForceInvokeFactory['vs/css'] = true;
loader.config(config);
loader(['require'], (localRequire: any) => {
const resolvePath = (entry: IExtraFile) => {
let r = localRequire.toUrl(entry.path);
if (!r.endsWith('.js')) {
r += '.js';
}
// avoid packaging the build version of plugins:
r = r.replace('vs/css.build.js', 'vs/css.js');
return { path: r, amdModuleId: entry.amdModuleId };
};
for (const moduleId in entryPointsMap) {
const entryPoint = entryPointsMap[moduleId];
if (entryPoint.prepend) {
entryPoint.prepend = entryPoint.prepend.map(resolvePath);
}
}
});
loader(Object.keys(allMentionedModulesMap), () => {
const modules = <IBuildModuleInfo[]>loader.getBuildInfo();
const partialResult = emitEntryPoints(modules, entryPointsMap);
const cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, (err: any) => callback(err, null));
}
function emitEntryPoints(modules: IBuildModuleInfo[], entryPoints: IEntryPointMap): IPartialBundleResult {
const modulesMap: IBuildModuleInfoMap = {};
modules.forEach((m: IBuildModuleInfo) => {
modulesMap[m.id] = m;
});
const modulesGraph: IGraph = {};
modules.forEach((m: IBuildModuleInfo) => {
modulesGraph[m.id] = m.dependencies;
});
const sortedModules = topologicalSort(modulesGraph);
let result: IConcatFile[] = [];
const usedPlugins: IPluginMap = {};
const bundleData: IBundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach((moduleToBundle: string) => {
const info = entryPoints[moduleToBundle];
const rootNodes = [moduleToBundle].concat(info.include || []);
const allDependencies = visit(rootNodes, modulesGraph);
const excludes: string[] = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach((excludeRoot: string) => {
const allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach((exclude: string) => {
delete allDependencies[exclude];
});
});
const includedModules = sortedModules.filter((module: string) => {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
const res = emitEntryPoint(
modulesMap,
modulesGraph,
moduleToBundle,
includedModules,
info.prepend || [],
info.dest
);
result = result.concat(res.files);
for (const pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach((pluginName: string) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
const write = (filename: string, contents: string) => {
result.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.finishBuild(write);
}
});
return {
// TODO@TS 2.1.2
files: extractStrings(removeAllDuplicateTSBoilerplate(result)),
bundleData: bundleData
};
}
function extractStrings(destFiles: IConcatFile[]): IConcatFile[] {
const parseDefineCall = (moduleMatch: string, depsMatch: string) => {
const module = moduleMatch.replace(/^"|"$/g, '');
let deps = depsMatch.split(',');
deps = deps.map((dep) => {
dep = dep.trim();
dep = dep.replace(/^"|"$/g, '');
dep = dep.replace(/^'|'$/g, '');
let prefix: string | null = null;
let _path: string | null = null;
const pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
_path = pieces[1];
} else {
prefix = '';
_path = pieces[0];
}
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
const res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
return prefix + res;
}
return prefix + _path;
});
return {
module: module,
deps: deps
};
};
destFiles.forEach((destFile) => {
if (!/\.js$/.test(destFile.dest)) {
return;
}
if (/\.nls\.js$/.test(destFile.dest)) {
return;
}
// Do one pass to record the usage counts for each module id
const useCounts: { [moduleId: string]: number } = {};
destFile.sources.forEach((source) => {
const matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
return;
}
const defineCall = parseDefineCall(matches[1], matches[2]);
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
defineCall.deps.forEach((dep) => {
useCounts[dep] = (useCounts[dep] || 0) + 1;
});
});
const sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort((a, b) => {
return useCounts[b] - useCounts[a];
});
const replacementMap: { [moduleId: string]: number } = {};
sortedByUseModules.forEach((module, index) => {
replacementMap[module] = index;
});
destFile.sources.forEach((source) => {
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, (_, moduleMatch, depsMatch) => {
const defineCall = parseDefineCall(moduleMatch, depsMatch);
return `define(__m[${replacementMap[defineCall.module]}/*${defineCall.module}*/], __M([${defineCall.deps.map(dep => replacementMap[dep] + '/*' + dep + '*/').join(',')}])`;
});
});
destFile.sources.unshift({
path: null,
contents: [
'(function() {',
`var __m = ${JSON.stringify(sortedByUseModules)};`,
`var __M = function(deps) {`,
` var result = [];`,
` for (var i = 0, len = deps.length; i < len; i++) {`,
` result[i] = __m[deps[i]];`,
` }`,
` return result;`,
`};`
].join('\n')
});
destFile.sources.push({
path: null,
contents: '}).call(this);'
});
});
return destFiles;
}
function removeAllDuplicateTSBoilerplate(destFiles: IConcatFile[]): IConcatFile[] {
destFiles.forEach((destFile) => {
const SEEN_BOILERPLATE: boolean[] = [];
destFile.sources.forEach((source) => {
source.contents = removeDuplicateTSBoilerplate(source.contents, SEEN_BOILERPLATE);
});
});
return destFiles;
}
export function removeAllTSBoilerplate(source: string) {
const seen = new Array<boolean>(BOILERPLATE.length).fill(true, 0, BOILERPLATE.length);
return removeDuplicateTSBoilerplate(source, seen);
@ -411,273 +63,3 @@ function removeDuplicateTSBoilerplate(source: string, SEEN_BOILERPLATE: boolean[
}
return newLines.join('\n');
}
interface IPluginMap {
[moduleId: string]: ILoaderPlugin;
}
interface IEmitEntryPointResult {
files: IConcatFile[];
usedPlugins: IPluginMap;
}
function emitEntryPoint(
modulesMap: IBuildModuleInfoMap,
deps: IGraph,
entryPoint: string,
includedModules: string[],
prepend: IExtraFile[],
dest: string | undefined
): IEmitEntryPointResult {
if (!dest) {
dest = entryPoint + '.js';
}
const mainResult: IConcatFile = {
sources: [],
dest: dest
},
results: IConcatFile[] = [mainResult];
const usedPlugins: IPluginMap = {};
const getLoaderPlugin = (pluginName: string): ILoaderPlugin => {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach((c: string) => {
const bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
const pluginName = c.substr(0, bangIndex);
const plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
const module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
const contents = readFileAndRemoveBOM(module.path);
if (module.shim) {
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
} else if (module.defineLocation) {
mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents));
} else {
const moduleCopy = {
id: module.id,
path: module.path,
defineLocation: module.defineLocation,
dependencies: module.dependencies
};
throw new Error(`Cannot bundle module '${module.id}' for entry point '${entryPoint}' because it has no shim and it lacks a defineLocation: ${JSON.stringify(moduleCopy)}`);
}
});
Object.keys(usedPlugins).forEach((pluginName: string) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
const req: ILoaderPluginReqFunc = <any>(() => {
throw new Error('no-no!');
});
req.toUrl = something => something;
const write = (filename: string, contents: string) => {
results.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
const toIFile = (entry: IExtraFile): IFile => {
let contents = readFileAndRemoveBOM(entry.path);
if (entry.amdModuleId) {
contents = contents.replace(/^define\(/m, `define("${entry.amdModuleId}",`);
}
return {
path: entry.path,
contents: contents
};
};
const toPrepend = (prepend || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources);
return {
files: results,
usedPlugins: usedPlugins
};
}
function readFileAndRemoveBOM(path: string): string {
const BOM_CHAR_CODE = 65279;
let contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
}
return contents;
}
function emitPlugin(entryPoint: string, plugin: ILoaderPlugin, pluginName: string, moduleName: string): IFile {
let result = '';
if (typeof plugin.write === 'function') {
const write: ILoaderPluginWriteFunc = <any>((what: string) => {
result += what;
});
write.getEntryPoint = () => {
return entryPoint;
};
write.asModule = (moduleId: string, code: string) => {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
plugin.write(pluginName, moduleName, write);
}
return {
path: null,
contents: result
};
}
function emitNamedModule(moduleId: string, defineCallPosition: IPosition, path: string, contents: string): IFile {
// `defineCallPosition` is the position in code: |define()
const defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
const parensOffset = contents.indexOf('(', defineCallOffset);
const insertStr = '"' + moduleId + '", ';
return {
path: path,
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
};
}
function emitShimmedModule(moduleId: string, myDeps: string[], factory: string, path: string, contents: string): IFile {
const strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
const strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
};
}
/**
* Convert a position (line:col) to (offset) in string `str`
*/
function positionToOffset(str: string, desiredLine: number, desiredCol: number): number {
if (desiredLine === 1) {
return desiredCol - 1;
}
let line = 1;
let lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
}
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
line++;
} while (lastNewLineOffset >= 0);
return -1;
}
/**
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes: string[], graph: IGraph): INodeSet {
const result: INodeSet = {};
const queue = rootNodes;
rootNodes.forEach((node) => {
result[node] = true;
});
while (queue.length > 0) {
const el = queue.shift();
const myEdges = graph[el!] || [];
myEdges.forEach((toNode) => {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
}
});
}
return result;
}
/**
* Perform a topological sort on `graph`
*/
function topologicalSort(graph: IGraph): string[] {
const allNodes: INodeSet = {},
outgoingEdgeCount: { [node: string]: number } = {},
inverseEdges: IGraph = {};
Object.keys(graph).forEach((fromNode: string) => {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach((toNode) => {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
inverseEdges[toNode].push(fromNode);
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
const S: string[] = [],
L: string[] = [];
Object.keys(allNodes).forEach((node: string) => {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
}
});
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
const n: string = S.shift()!;
L.push(n);
const myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach((m: string) => {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];
S.push(m);
}
});
}
if (Object.keys(outgoingEdgeCount).length > 0) {
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
}
return L;
}

View file

@ -41,6 +41,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.watchApiProposalNamesTask = exports.compileApiProposalNamesTask = void 0;
exports.createCompile = createCompile;
exports.transpileTask = transpileTask;
exports.compileTask = compileTask;
exports.watchTask = watchTask;

View file

@ -49,7 +49,7 @@ interface ICompileTaskOptions {
readonly preserveEnglish: boolean;
}
function createCompile(src: string, { build, emitError, transpileOnly, preserveEnglish }: ICompileTaskOptions) {
export function createCompile(src: string, { build, emitError, transpileOnly, preserveEnglish }: ICompileTaskOptions) {
const tsb = require('./tsb') as typeof import('./tsb');
const sourcemaps = require('gulp-sourcemaps') as typeof import('gulp-sourcemaps');

View file

@ -90,7 +90,7 @@ function darwinBundleDocumentType(extensions, icon, nameOrSuffix, utis) {
role: 'Editor',
ostypes: ['TEXT', 'utxt', 'TUTX', '****'],
extensions,
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns', // <-- Void icon code.icns
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns',
utis
};
}
@ -215,7 +215,7 @@ exports.config = {
darwinForceDarkModeSupport: true,
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined,
linuxExecutableName: product.applicationName,
winIcon: 'resources/win32/code.ico', // <-- Void icon
winIcon: 'resources/win32/code.ico',
token: process.env['GITHUB_TOKEN'],
repo: product.electronRepository || undefined,
validateChecksum: true,

View file

@ -68,7 +68,7 @@ function darwinBundleDocumentType(extensions: string[], icon: string, nameOrSuff
role: 'Editor',
ostypes: ['TEXT', 'utxt', 'TUTX', '****'],
extensions,
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns', // <-- Void icon code.icns
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns',
utis
};
}
@ -196,7 +196,7 @@ export const config = {
darwinForceDarkModeSupport: true,
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined,
linuxExecutableName: product.applicationName,
winIcon: 'resources/win32/code.ico', // <-- Void icon
winIcon: 'resources/win32/code.ico',
token: process.env['GITHUB_TOKEN'],
repo: product.electronRepository || undefined,
validateChecksum: true,

View file

@ -319,9 +319,10 @@ globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`),
function processNlsFiles(opts) {
return (0, event_stream_1.through)(function (file) {
const fileName = path_1.default.basename(file.path);
if (fileName === 'bundleInfo.json') { // pick a root level file to put the core bundles (TODO@esm this file is not created anymore, pick another)
if (fileName === 'nls.keys.json') {
try {
const json = JSON.parse(fs_1.default.readFileSync(path_1.default.join(REPO_ROOT_PATH, opts.out, 'nls.keys.json')).toString());
const contents = file.contents.toString('utf8');
const json = JSON.parse(contents);
if (NLSKeysFormat.is(json)) {
processCoreBundleFormat(file.base, opts.fileHeader, opts.languages, json, this);
}

View file

@ -387,9 +387,10 @@ globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`),
export function processNlsFiles(opts: { out: string; fileHeader: string; languages: Language[] }): ThroughStream {
return through(function (this: ThroughStream, file: File) {
const fileName = path.basename(file.path);
if (fileName === 'bundleInfo.json') { // pick a root level file to put the core bundles (TODO@esm this file is not created anymore, pick another)
if (fileName === 'nls.keys.json') {
try {
const json = JSON.parse(fs.readFileSync(path.join(REPO_ROOT_PATH, opts.out, 'nls.keys.json')).toString());
const contents = file.contents.toString('utf8');
const json = JSON.parse(contents);
if (NLSKeysFormat.is(json)) {
processCoreBundleFormat(file.base, opts.fileHeader, opts.languages, json, this);
}

View file

@ -79,9 +79,12 @@ const CORE_TYPES = [
'PerformanceMark',
'PerformanceObserver',
'ImportMeta',
'structuredClone',
// webcrypto has been available since Node.js 19, but still live in dom.d.ts
'Crypto',
'SubtleCrypto'
'SubtleCrypto',
'JsonWebKey',
'MessageEvent',
];
// Types that are defined in a common layer but are known to be only
// available in native environments should not be allowed in browser

View file

@ -77,10 +77,13 @@ const CORE_TYPES = [
'PerformanceMark',
'PerformanceObserver',
'ImportMeta',
'structuredClone',
// webcrypto has been available since Node.js 19, but still live in dom.d.ts
'Crypto',
'SubtleCrypto'
'SubtleCrypto',
'JsonWebKey',
'MessageEvent',
];
// Types that are defined in a common layer but are known to be only

View file

@ -70,12 +70,6 @@ function bundleESMTask(opts) {
}
return entryPoint;
});
const allMentionedModules = new Set();
for (const entryPoint of entryPoints) {
allMentionedModules.add(entryPoint.name);
entryPoint.include?.forEach(allMentionedModules.add, allMentionedModules);
entryPoint.exclude?.forEach(allMentionedModules.add, allMentionedModules);
}
const bundleAsync = async () => {
const files = [];
const tasks = [];
@ -127,7 +121,6 @@ function bundleESMTask(opts) {
};
const task = esbuild_1.default.build({
bundle: true,
external: entryPoint.exclude,
packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages
platform: 'neutral', // makes esm
format: 'esm',

View file

@ -62,13 +62,6 @@ function bundleESMTask(opts: IBundleESMTaskOpts): NodeJS.ReadWriteStream {
return entryPoint;
});
const allMentionedModules = new Set<string>();
for (const entryPoint of entryPoints) {
allMentionedModules.add(entryPoint.name);
entryPoint.include?.forEach(allMentionedModules.add, allMentionedModules);
entryPoint.exclude?.forEach(allMentionedModules.add, allMentionedModules);
}
const bundleAsync = async () => {
const files: VinylFile[] = [];
const tasks: Promise<any>[] = [];
@ -129,7 +122,6 @@ function bundleESMTask(opts: IBundleESMTaskOpts): NodeJS.ReadWriteStream {
const task = esbuild.build({
bundle: true,
external: entryPoint.exclude,
packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages
platform: 'neutral', // makes esm
format: 'esm',

View file

@ -27,7 +27,11 @@ function isNlsStringArray(value) {
}
var PolicyType;
(function (PolicyType) {
PolicyType[PolicyType["StringEnum"] = 0] = "StringEnum";
PolicyType["Boolean"] = "boolean";
PolicyType["Number"] = "number";
PolicyType["Object"] = "object";
PolicyType["String"] = "string";
PolicyType["StringEnum"] = "stringEnum";
})(PolicyType || (PolicyType = {}));
function renderADMLString(prefix, moduleName, nlsString, translations) {
let value;
@ -42,15 +46,28 @@ function renderADMLString(prefix, moduleName, nlsString, translations) {
}
return `<string id="${prefix}_${nlsString.nlsKey.replace(/\./g, '_')}">${value}</string>`;
}
function renderProfileString(_prefix, moduleName, nlsString, translations) {
let value;
if (translations) {
const moduleTranslations = translations[moduleName];
if (moduleTranslations) {
value = moduleTranslations[nlsString.nlsKey];
}
}
if (!value) {
value = nlsString.value;
}
return value;
}
class BasePolicy {
policyType;
type;
name;
category;
minimumVersion;
description;
moduleName;
constructor(policyType, name, category, minimumVersion, description, moduleName) {
this.policyType = policyType;
constructor(type, name, category, minimumVersion, description, moduleName) {
this.type = type;
this.name = name;
this.category = category;
this.minimumVersion = minimumVersion;
@ -80,17 +97,25 @@ class BasePolicy {
renderADMLPresentation() {
return `<presentation id="${this.name}">${this.renderADMLPresentationContents()}</presentation>`;
}
renderProfile() {
return [`<key>${this.name}</key>`, this.renderProfileValue()];
}
renderProfileManifest(translations) {
return `<dict>
${this.renderProfileManifestValue(translations)}
</dict>`;
}
}
class BooleanPolicy extends BasePolicy {
static from(name, category, minimumVersion, description, moduleName, settingNode) {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'boolean') {
return undefined;
}
return new BooleanPolicy(name, category, minimumVersion, description, moduleName);
}
constructor(name, category, minimumVersion, description, moduleName) {
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
super(PolicyType.Boolean, name, category, minimumVersion, description, moduleName);
}
renderADMXElements() {
return [
@ -102,19 +127,39 @@ class BooleanPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
}
renderProfileValue() {
return `<false/>`;
}
renderProfileManifestValue(translations) {
return `<key>pfm_default</key>
<false/>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>boolean</string>`;
}
}
class IntPolicy extends BasePolicy {
class ParseError extends Error {
constructor(message, moduleName, node) {
super(`${message}. ${moduleName}.ts:${node.startPosition.row + 1}`);
}
}
class NumberPolicy extends BasePolicy {
defaultValue;
static from(name, category, minimumVersion, description, moduleName, settingNode) {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'number') {
return undefined;
}
const defaultValue = getIntProperty(settingNode, 'default');
const defaultValue = getNumberProperty(moduleName, settingNode, 'default');
if (typeof defaultValue === 'undefined') {
throw new Error(`Missing required 'default' property.`);
throw new ParseError(`Missing required 'default' property.`, moduleName, settingNode);
}
return new IntPolicy(name, category, minimumVersion, description, moduleName, defaultValue);
return new NumberPolicy(name, category, minimumVersion, description, moduleName, defaultValue);
}
constructor(name, category, minimumVersion, description, moduleName, defaultValue) {
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
@ -129,17 +174,32 @@ class IntPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
}
renderProfileValue() {
return `<integer>${this.defaultValue}</integer>`;
}
renderProfileManifestValue(translations) {
return `<key>pfm_default</key>
<integer>${this.defaultValue}</integer>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>integer</string>`;
}
}
class StringPolicy extends BasePolicy {
static from(name, category, minimumVersion, description, moduleName, settingNode) {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'string') {
return undefined;
}
return new StringPolicy(name, category, minimumVersion, description, moduleName);
}
constructor(name, category, minimumVersion, description, moduleName) {
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
super(PolicyType.String, name, category, minimumVersion, description, moduleName);
}
renderADMXElements() {
return [`<text id="${this.name}" valueName="${this.name}" required="true" />`];
@ -147,17 +207,32 @@ class StringPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
}
renderProfileValue() {
return `<string></string>`;
}
renderProfileManifestValue(translations) {
return `<key>pfm_default</key>
<string></string>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>string</string>`;
}
}
class ObjectPolicy extends BasePolicy {
static from(name, category, minimumVersion, description, moduleName, settingNode) {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'object' && type !== 'array') {
return undefined;
}
return new ObjectPolicy(name, category, minimumVersion, description, moduleName);
}
constructor(name, category, minimumVersion, description, moduleName) {
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
super(PolicyType.Object, name, category, minimumVersion, description, moduleName);
}
renderADMXElements() {
return [`<multiText id="${this.name}" valueName="${this.name}" required="true" />`];
@ -165,28 +240,44 @@ class ObjectPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<multiTextBox refId="${this.name}" />`;
}
renderProfileValue() {
return `<string></string>`;
}
renderProfileManifestValue(translations) {
return `<key>pfm_default</key>
<string></string>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>string</string>
`;
}
}
class StringEnumPolicy extends BasePolicy {
enum_;
enumDescriptions;
static from(name, category, minimumVersion, description, moduleName, settingNode) {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'string') {
return undefined;
}
const enum_ = getStringArrayProperty(settingNode, 'enum');
const enum_ = getStringArrayProperty(moduleName, settingNode, 'enum');
if (!enum_) {
return undefined;
}
if (!isStringArray(enum_)) {
throw new Error(`Property 'enum' should not be localized.`);
throw new ParseError(`Property 'enum' should not be localized.`, moduleName, settingNode);
}
const enumDescriptions = getStringArrayProperty(settingNode, 'enumDescriptions');
const enumDescriptions = getStringArrayProperty(moduleName, settingNode, 'enumDescriptions');
if (!enumDescriptions) {
throw new Error(`Missing required 'enumDescriptions' property.`);
throw new ParseError(`Missing required 'enumDescriptions' property.`, moduleName, settingNode);
}
else if (!isNlsStringArray(enumDescriptions)) {
throw new Error(`Property 'enumDescriptions' should be localized.`);
throw new ParseError(`Property 'enumDescriptions' should be localized.`, moduleName, settingNode);
}
return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions);
}
@ -211,8 +302,27 @@ class StringEnumPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<dropdownList refId="${this.name}" />`;
}
renderProfileValue() {
return `<string>${this.enum_[0]}</string>`;
}
renderProfileManifestValue(translations) {
return `<key>pfm_default</key>
<string>${this.enum_[0]}</string>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>string</string>
<key>pfm_range_list</key>
<array>
${this.enum_.map(e => `<string>${e}</string>`).join('\n ')}
</array>`;
}
}
const IntQ = {
const NumberQ = {
Q: `(number) @value`,
value(matches) {
const match = matches[0];
@ -229,7 +339,16 @@ const IntQ = {
const StringQ = {
Q: `[
(string (string_fragment) @value)
(call_expression function: (identifier) @localizeFn arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) (#eq? @localizeFn localize))
(call_expression
function: [
(identifier) @localizeFn (#eq? @localizeFn localize)
(member_expression
object: (identifier) @nlsObj (#eq? @nlsObj nls)
property: (property_identifier) @localizeFn (#eq? @localizeFn localize)
)
]
arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value))
)
]`,
value(matches) {
const match = matches[0];
@ -260,47 +379,53 @@ const StringArrayQ = {
});
}
};
function getProperty(qtype, node, key) {
function getProperty(qtype, moduleName, node, key) {
const query = new tree_sitter_1.default.Query(typescript, `(
(pair
key: [(property_identifier)(string)] @key
value: ${qtype.Q}
)
(#eq? @key ${key})
(#any-of? @key "${key}" "'${key}'")
)`);
return qtype.value(query.matches(node));
try {
const matches = query.matches(node).filter(m => m.captures[0].node.parent?.parent === node);
return qtype.value(matches);
}
catch (e) {
throw new ParseError(e.message, moduleName, node);
}
}
function getIntProperty(node, key) {
return getProperty(IntQ, node, key);
function getNumberProperty(moduleName, node, key) {
return getProperty(NumberQ, moduleName, node, key);
}
function getStringProperty(node, key) {
return getProperty(StringQ, node, key);
function getStringProperty(moduleName, node, key) {
return getProperty(StringQ, moduleName, node, key);
}
function getStringArrayProperty(node, key) {
return getProperty(StringArrayQ, node, key);
function getStringArrayProperty(moduleName, node, key) {
return getProperty(StringArrayQ, moduleName, node, key);
}
// TODO: add more policy types
const PolicyTypes = [
BooleanPolicy,
IntPolicy,
NumberPolicy,
StringEnumPolicy,
StringPolicy,
ObjectPolicy
];
function getPolicy(moduleName, configurationNode, settingNode, policyNode, categories) {
const name = getStringProperty(policyNode, 'name');
const name = getStringProperty(moduleName, policyNode, 'name');
if (!name) {
throw new Error(`Missing required 'name' property.`);
throw new ParseError(`Missing required 'name' property`, moduleName, policyNode);
}
else if (isNlsString(name)) {
throw new Error(`Property 'name' should be a literal string.`);
throw new ParseError(`Property 'name' should be a literal string`, moduleName, policyNode);
}
const categoryName = getStringProperty(configurationNode, 'title');
const categoryName = getStringProperty(moduleName, configurationNode, 'title');
if (!categoryName) {
throw new Error(`Missing required 'title' property.`);
throw new ParseError(`Missing required 'title' property`, moduleName, configurationNode);
}
else if (!isNlsString(categoryName)) {
throw new Error(`Property 'title' should be localized.`);
throw new ParseError(`Property 'title' should be localized`, moduleName, configurationNode);
}
const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`;
let category = categories.get(categoryKey);
@ -308,19 +433,19 @@ function getPolicy(moduleName, configurationNode, settingNode, policyNode, categ
category = { moduleName, name: categoryName };
categories.set(categoryKey, category);
}
const minimumVersion = getStringProperty(policyNode, 'minimumVersion');
const minimumVersion = getStringProperty(moduleName, policyNode, 'minimumVersion');
if (!minimumVersion) {
throw new Error(`Missing required 'minimumVersion' property.`);
throw new ParseError(`Missing required 'minimumVersion' property.`, moduleName, policyNode);
}
else if (isNlsString(minimumVersion)) {
throw new Error(`Property 'minimumVersion' should be a literal string.`);
throw new ParseError(`Property 'minimumVersion' should be a literal string.`, moduleName, policyNode);
}
const description = getStringProperty(settingNode, 'description');
const description = getStringProperty(moduleName, policyNode, 'description') ?? getStringProperty(moduleName, settingNode, 'description');
if (!description) {
throw new Error(`Missing required 'description' property.`);
throw new ParseError(`Missing required 'description' property.`, moduleName, settingNode);
}
if (!isNlsString(description)) {
throw new Error(`Property 'description' should be localized.`);
throw new ParseError(`Property 'description' should be localized.`, moduleName, settingNode);
}
let result;
for (const policyType of PolicyTypes) {
@ -329,7 +454,7 @@ function getPolicy(moduleName, configurationNode, settingNode, policyNode, categ
}
}
if (!result) {
throw new Error(`Failed to parse policy '${name}'.`);
throw new ParseError(`Failed to parse policy '${name}'.`, moduleName, settingNode);
}
return result;
}
@ -339,11 +464,11 @@ function getPolicies(moduleName, node) {
(call_expression
function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration)
arguments: (arguments (object (pair
key: [(property_identifier)(string)] @propertiesKey (#eq? @propertiesKey properties)
key: [(property_identifier)(string)] @propertiesKey (#any-of? @propertiesKey "properties" "'properties'")
value: (object (pair
key: [(property_identifier)(string)(computed_property_name)]
value: (object (pair
key: [(property_identifier)(string)] @policyKey (#eq? @policyKey policy)
key: [(property_identifier)(string)] @policyKey (#any-of? @policyKey "policy" "'policy'")
value: (object) @policy
)) @setting
))
@ -400,8 +525,8 @@ function renderADML(appName, versions, categories, policies, translations) {
<resources>
<stringTable>
<string id="Application">${appName}</string>
${versions.map(v => `<string id="Supported_${v.replace(/\./g, '_')}">${appName} &gt;= ${v}</string>`)}
${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations))}
${versions.map(v => `<string id="Supported_${v.replace(/\./g, '_')}">${appName} &gt;= ${v}</string>`).join(`\n `)}
${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations)).join(`\n `)}
${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)}
</stringTable>
<presentationTable>
@ -411,6 +536,186 @@ function renderADML(appName, versions, categories, policies, translations) {
</policyDefinitionResources>
`;
}
function renderProfileManifest(appName, bundleIdentifier, _versions, _categories, policies, translations) {
const requiredPayloadFields = `
<dict>
<key>pfm_default</key>
<string>Configure ${appName}</string>
<key>pfm_name</key>
<string>PayloadDescription</string>
<key>pfm_title</key>
<string>Payload Description</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string>${appName}</string>
<key>pfm_name</key>
<string>PayloadDisplayName</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Display Name</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string>${bundleIdentifier}</string>
<key>pfm_name</key>
<string>PayloadIdentifier</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Identifier</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string>${bundleIdentifier}</string>
<key>pfm_name</key>
<string>PayloadType</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Type</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string></string>
<key>pfm_name</key>
<string>PayloadUUID</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload UUID</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<integer>1</integer>
<key>pfm_name</key>
<string>PayloadVersion</string>
<key>pfm_range_list</key>
<array>
<integer>1</integer>
</array>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Version</string>
<key>pfm_type</key>
<string>integer</string>
</dict>
<dict>
<key>pfm_default</key>
<string>Microsoft</string>
<key>pfm_name</key>
<string>PayloadOrganization</string>
<key>pfm_title</key>
<string>Payload Organization</string>
<key>pfm_type</key>
<string>string</string>
</dict>`;
const profileManifestSubkeys = policies.map(policy => {
return policy.renderProfileManifest(translations);
}).join('');
return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>pfm_app_url</key>
<string>https://code.visualstudio.com/</string>
<key>pfm_description</key>
<string>${appName} Managed Settings</string>
<key>pfm_documentation_url</key>
<string>https://code.visualstudio.com/docs/setup/enterprise</string>
<key>pfm_domain</key>
<string>${bundleIdentifier}</string>
<key>pfm_format_version</key>
<integer>1</integer>
<key>pfm_interaction</key>
<string>combined</string>
<key>pfm_last_modified</key>
<date>${new Date().toISOString().replace(/\.\d+Z$/, 'Z')}</date>
<key>pfm_platforms</key>
<array>
<string>macOS</string>
</array>
<key>pfm_subkeys</key>
<array>
${requiredPayloadFields}
${profileManifestSubkeys}
</array>
<key>pfm_title</key>
<string>${appName}</string>
<key>pfm_unique</key>
<true/>
<key>pfm_version</key>
<integer>1</integer>
</dict>
</plist>`;
}
function renderMacOSPolicy(policies, translations) {
const appName = product.nameLong;
const bundleIdentifier = product.darwinBundleIdentifier;
const payloadUUID = product.darwinProfilePayloadUUID;
const UUID = product.darwinProfileUUID;
const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort();
const categories = [...new Set(policies.map(p => p.category))];
const policyEntries = policies.map(policy => policy.renderProfile())
.flat()
.map(entry => `\t\t\t\t${entry}`)
.join('\n');
return {
profile: `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>${appName}</string>
<key>PayloadIdentifier</key>
<string>${bundleIdentifier}.${UUID}</string>
<key>PayloadType</key>
<string>${bundleIdentifier}</string>
<key>PayloadUUID</key>
<string>${UUID}</string>
<key>PayloadVersion</key>
<integer>1</integer>
${policyEntries}
</dict>
</array>
<key>PayloadDescription</key>
<string>This profile manages ${appName}. For more information see https://code.visualstudio.com/docs/setup/enterprise</string>
<key>PayloadDisplayName</key>
<string>${appName}</string>
<key>PayloadIdentifier</key>
<string>${bundleIdentifier}</string>
<key>PayloadOrganization</key>
<string>Microsoft</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>${payloadUUID}</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>TargetDeviceType</key>
<integer>5</integer>
</dict>
</plist>`,
manifests: [{ languageId: 'en-us', contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies) },
...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies, languageTranslations) }))
]
};
}
function renderGP(policies, translations) {
const appName = product.nameLong;
const regKey = product.win32RegValueName;
@ -526,10 +831,9 @@ async function getTranslations() {
return await Promise.all(languageIds.map(languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version)
.then(languageTranslations => ({ languageId, languageTranslations }))));
}
async function main() {
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
const { admx, adml } = await renderGP(policies, translations);
async function windowsMain(policies, translations) {
const root = '.build/policies/win32';
const { admx, adml } = await renderGP(policies, translations);
await fs_1.promises.rm(root, { recursive: true, force: true });
await fs_1.promises.mkdir(root, { recursive: true });
await fs_1.promises.writeFile(path_1.default.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n'));
@ -539,9 +843,44 @@ async function main() {
await fs_1.promises.writeFile(path_1.default.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n'));
}
}
async function darwinMain(policies, translations) {
const bundleIdentifier = product.darwinBundleIdentifier;
if (!bundleIdentifier || !product.darwinProfilePayloadUUID || !product.darwinProfileUUID) {
throw new Error(`Missing required product information.`);
}
const root = '.build/policies/darwin';
const { profile, manifests } = await renderMacOSPolicy(policies, translations);
await fs_1.promises.rm(root, { recursive: true, force: true });
await fs_1.promises.mkdir(root, { recursive: true });
await fs_1.promises.writeFile(path_1.default.join(root, `${bundleIdentifier}.mobileconfig`), profile.replace(/\r?\n/g, '\n'));
for (const { languageId, contents } of manifests) {
const languagePath = path_1.default.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId]);
await fs_1.promises.mkdir(languagePath, { recursive: true });
await fs_1.promises.writeFile(path_1.default.join(languagePath, `${bundleIdentifier}.plist`), contents.replace(/\r?\n/g, '\n'));
}
}
async function main() {
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
const platform = process.argv[2];
if (platform === 'darwin') {
await darwinMain(policies, translations);
}
else if (platform === 'win32') {
await windowsMain(policies, translations);
}
else {
console.error(`Usage: node build/lib/policies <darwin|win32>`);
process.exit(1);
}
}
if (require.main === module) {
main().catch(err => {
console.error(err);
if (err instanceof ParseError) {
console.error(`Parse Error:`, err.message);
}
else {
console.error(err);
}
process.exit(1);
});
}

View file

@ -33,15 +33,24 @@ interface Category {
}
enum PolicyType {
StringEnum
Boolean = 'boolean',
Number = 'number',
Object = 'object',
String = 'string',
StringEnum = 'stringEnum',
}
interface Policy {
readonly name: string;
readonly type: PolicyType;
readonly category: Category;
readonly minimumVersion: string;
renderADMX(regKey: string): string[];
renderADMLStrings(translations?: LanguageTranslations): string[];
renderADMLPresentation(): string;
renderProfile(): string[];
// https://github.com/ProfileManifests/ProfileManifests/wiki/Manifest-Format
renderProfileManifest(translations?: LanguageTranslations): string;
}
function renderADMLString(prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string {
@ -62,10 +71,28 @@ function renderADMLString(prefix: string, moduleName: string, nlsString: NlsStri
return `<string id="${prefix}_${nlsString.nlsKey.replace(/\./g, '_')}">${value}</string>`;
}
function renderProfileString(_prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string {
let value: string | undefined;
if (translations) {
const moduleTranslations = translations[moduleName];
if (moduleTranslations) {
value = moduleTranslations[nlsString.nlsKey];
}
}
if (!value) {
value = nlsString.value;
}
return value;
}
abstract class BasePolicy implements Policy {
constructor(
protected policyType: PolicyType,
protected name: string,
readonly type: PolicyType,
readonly name: string,
readonly category: Category,
readonly minimumVersion: string,
protected description: NlsString,
@ -102,6 +129,19 @@ abstract class BasePolicy implements Policy {
}
protected abstract renderADMLPresentationContents(): string;
renderProfile() {
return [`<key>${this.name}</key>`, this.renderProfileValue()];
}
renderProfileManifest(translations?: LanguageTranslations): string {
return `<dict>
${this.renderProfileManifestValue(translations)}
</dict>`;
}
abstract renderProfileValue(): string;
abstract renderProfileManifestValue(translations?: LanguageTranslations): string;
}
class BooleanPolicy extends BasePolicy {
@ -114,7 +154,7 @@ class BooleanPolicy extends BasePolicy {
moduleName: string,
settingNode: Parser.SyntaxNode
): BooleanPolicy | undefined {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'boolean') {
return undefined;
@ -130,7 +170,7 @@ class BooleanPolicy extends BasePolicy {
description: NlsString,
moduleName: string,
) {
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
super(PolicyType.Boolean, name, category, minimumVersion, description, moduleName);
}
protected renderADMXElements(): string[] {
@ -144,9 +184,32 @@ class BooleanPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
}
renderProfileValue(): string {
return `<false/>`;
}
renderProfileManifestValue(translations?: LanguageTranslations): string {
return `<key>pfm_default</key>
<false/>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>boolean</string>`;
}
}
class IntPolicy extends BasePolicy {
class ParseError extends Error {
constructor(message: string, moduleName: string, node: Parser.SyntaxNode) {
super(`${message}. ${moduleName}.ts:${node.startPosition.row + 1}`);
}
}
class NumberPolicy extends BasePolicy {
static from(
name: string,
@ -155,20 +218,20 @@ class IntPolicy extends BasePolicy {
description: NlsString,
moduleName: string,
settingNode: Parser.SyntaxNode
): IntPolicy | undefined {
const type = getStringProperty(settingNode, 'type');
): NumberPolicy | undefined {
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'number') {
return undefined;
}
const defaultValue = getIntProperty(settingNode, 'default');
const defaultValue = getNumberProperty(moduleName, settingNode, 'default');
if (typeof defaultValue === 'undefined') {
throw new Error(`Missing required 'default' property.`);
throw new ParseError(`Missing required 'default' property.`, moduleName, settingNode);
}
return new IntPolicy(name, category, minimumVersion, description, moduleName, defaultValue);
return new NumberPolicy(name, category, minimumVersion, description, moduleName, defaultValue);
}
private constructor(
@ -192,6 +255,23 @@ class IntPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
}
renderProfileValue() {
return `<integer>${this.defaultValue}</integer>`;
}
renderProfileManifestValue(translations?: LanguageTranslations) {
return `<key>pfm_default</key>
<integer>${this.defaultValue}</integer>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>integer</string>`;
}
}
class StringPolicy extends BasePolicy {
@ -204,7 +284,7 @@ class StringPolicy extends BasePolicy {
moduleName: string,
settingNode: Parser.SyntaxNode
): StringPolicy | undefined {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'string') {
return undefined;
@ -220,7 +300,7 @@ class StringPolicy extends BasePolicy {
description: NlsString,
moduleName: string,
) {
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
super(PolicyType.String, name, category, minimumVersion, description, moduleName);
}
protected renderADMXElements(): string[] {
@ -230,6 +310,23 @@ class StringPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
}
renderProfileValue(): string {
return `<string></string>`;
}
renderProfileManifestValue(translations?: LanguageTranslations): string {
return `<key>pfm_default</key>
<string></string>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>string</string>`;
}
}
class ObjectPolicy extends BasePolicy {
@ -242,7 +339,7 @@ class ObjectPolicy extends BasePolicy {
moduleName: string,
settingNode: Parser.SyntaxNode
): ObjectPolicy | undefined {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'object' && type !== 'array') {
return undefined;
@ -258,7 +355,7 @@ class ObjectPolicy extends BasePolicy {
description: NlsString,
moduleName: string,
) {
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
super(PolicyType.Object, name, category, minimumVersion, description, moduleName);
}
protected renderADMXElements(): string[] {
@ -268,6 +365,24 @@ class ObjectPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<multiTextBox refId="${this.name}" />`;
}
renderProfileValue(): string {
return `<string></string>`;
}
renderProfileManifestValue(translations?: LanguageTranslations): string {
return `<key>pfm_default</key>
<string></string>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>string</string>
`;
}
}
class StringEnumPolicy extends BasePolicy {
@ -280,28 +395,28 @@ class StringEnumPolicy extends BasePolicy {
moduleName: string,
settingNode: Parser.SyntaxNode
): StringEnumPolicy | undefined {
const type = getStringProperty(settingNode, 'type');
const type = getStringProperty(moduleName, settingNode, 'type');
if (type !== 'string') {
return undefined;
}
const enum_ = getStringArrayProperty(settingNode, 'enum');
const enum_ = getStringArrayProperty(moduleName, settingNode, 'enum');
if (!enum_) {
return undefined;
}
if (!isStringArray(enum_)) {
throw new Error(`Property 'enum' should not be localized.`);
throw new ParseError(`Property 'enum' should not be localized.`, moduleName, settingNode);
}
const enumDescriptions = getStringArrayProperty(settingNode, 'enumDescriptions');
const enumDescriptions = getStringArrayProperty(moduleName, settingNode, 'enumDescriptions');
if (!enumDescriptions) {
throw new Error(`Missing required 'enumDescriptions' property.`);
throw new ParseError(`Missing required 'enumDescriptions' property.`, moduleName, settingNode);
} else if (!isNlsStringArray(enumDescriptions)) {
throw new Error(`Property 'enumDescriptions' should be localized.`);
throw new ParseError(`Property 'enumDescriptions' should be localized.`, moduleName, settingNode);
}
return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions);
@ -337,6 +452,27 @@ class StringEnumPolicy extends BasePolicy {
renderADMLPresentationContents() {
return `<dropdownList refId="${this.name}" />`;
}
renderProfileValue() {
return `<string>${this.enum_[0]}</string>`;
}
renderProfileManifestValue(translations?: LanguageTranslations): string {
return `<key>pfm_default</key>
<string>${this.enum_[0]}</string>
<key>pfm_description</key>
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
<key>pfm_name</key>
<string>${this.name}</string>
<key>pfm_title</key>
<string>${this.name}</string>
<key>pfm_type</key>
<string>string</string>
<key>pfm_range_list</key>
<array>
${this.enum_.map(e => `<string>${e}</string>`).join('\n ')}
</array>`;
}
}
interface QType<T> {
@ -344,7 +480,7 @@ interface QType<T> {
value(matches: Parser.QueryMatch[]): T | undefined;
}
const IntQ: QType<number> = {
const NumberQ: QType<number> = {
Q: `(number) @value`,
value(matches: Parser.QueryMatch[]): number | undefined {
@ -367,7 +503,16 @@ const IntQ: QType<number> = {
const StringQ: QType<string | NlsString> = {
Q: `[
(string (string_fragment) @value)
(call_expression function: (identifier) @localizeFn arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) (#eq? @localizeFn localize))
(call_expression
function: [
(identifier) @localizeFn (#eq? @localizeFn localize)
(member_expression
object: (identifier) @nlsObj (#eq? @nlsObj nls)
property: (property_identifier) @localizeFn (#eq? @localizeFn localize)
)
]
arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value))
)
]`,
value(matches: Parser.QueryMatch[]): string | NlsString | undefined {
@ -407,7 +552,7 @@ const StringArrayQ: QType<(string | NlsString)[]> = {
}
};
function getProperty<T>(qtype: QType<T>, node: Parser.SyntaxNode, key: string): T | undefined {
function getProperty<T>(qtype: QType<T>, moduleName: string, node: Parser.SyntaxNode, key: string): T | undefined {
const query = new Parser.Query(
typescript,
`(
@ -415,29 +560,34 @@ function getProperty<T>(qtype: QType<T>, node: Parser.SyntaxNode, key: string):
key: [(property_identifier)(string)] @key
value: ${qtype.Q}
)
(#eq? @key ${key})
(#any-of? @key "${key}" "'${key}'")
)`
);
return qtype.value(query.matches(node));
try {
const matches = query.matches(node).filter(m => m.captures[0].node.parent?.parent === node);
return qtype.value(matches);
} catch (e) {
throw new ParseError(e.message, moduleName, node);
}
}
function getIntProperty(node: Parser.SyntaxNode, key: string): number | undefined {
return getProperty(IntQ, node, key);
function getNumberProperty(moduleName: string, node: Parser.SyntaxNode, key: string): number | undefined {
return getProperty(NumberQ, moduleName, node, key);
}
function getStringProperty(node: Parser.SyntaxNode, key: string): string | NlsString | undefined {
return getProperty(StringQ, node, key);
function getStringProperty(moduleName: string, node: Parser.SyntaxNode, key: string): string | NlsString | undefined {
return getProperty(StringQ, moduleName, node, key);
}
function getStringArrayProperty(node: Parser.SyntaxNode, key: string): (string | NlsString)[] | undefined {
return getProperty(StringArrayQ, node, key);
function getStringArrayProperty(moduleName: string, node: Parser.SyntaxNode, key: string): (string | NlsString)[] | undefined {
return getProperty(StringArrayQ, moduleName, node, key);
}
// TODO: add more policy types
const PolicyTypes = [
BooleanPolicy,
IntPolicy,
NumberPolicy,
StringEnumPolicy,
StringPolicy,
ObjectPolicy
@ -450,20 +600,20 @@ function getPolicy(
policyNode: Parser.SyntaxNode,
categories: Map<string, Category>
): Policy {
const name = getStringProperty(policyNode, 'name');
const name = getStringProperty(moduleName, policyNode, 'name');
if (!name) {
throw new Error(`Missing required 'name' property.`);
throw new ParseError(`Missing required 'name' property`, moduleName, policyNode);
} else if (isNlsString(name)) {
throw new Error(`Property 'name' should be a literal string.`);
throw new ParseError(`Property 'name' should be a literal string`, moduleName, policyNode);
}
const categoryName = getStringProperty(configurationNode, 'title');
const categoryName = getStringProperty(moduleName, configurationNode, 'title');
if (!categoryName) {
throw new Error(`Missing required 'title' property.`);
throw new ParseError(`Missing required 'title' property`, moduleName, configurationNode);
} else if (!isNlsString(categoryName)) {
throw new Error(`Property 'title' should be localized.`);
throw new ParseError(`Property 'title' should be localized`, moduleName, configurationNode);
}
const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`;
@ -474,20 +624,20 @@ function getPolicy(
categories.set(categoryKey, category);
}
const minimumVersion = getStringProperty(policyNode, 'minimumVersion');
const minimumVersion = getStringProperty(moduleName, policyNode, 'minimumVersion');
if (!minimumVersion) {
throw new Error(`Missing required 'minimumVersion' property.`);
throw new ParseError(`Missing required 'minimumVersion' property.`, moduleName, policyNode);
} else if (isNlsString(minimumVersion)) {
throw new Error(`Property 'minimumVersion' should be a literal string.`);
throw new ParseError(`Property 'minimumVersion' should be a literal string.`, moduleName, policyNode);
}
const description = getStringProperty(settingNode, 'description');
const description = getStringProperty(moduleName, policyNode, 'description') ?? getStringProperty(moduleName, settingNode, 'description');
if (!description) {
throw new Error(`Missing required 'description' property.`);
throw new ParseError(`Missing required 'description' property.`, moduleName, settingNode);
} if (!isNlsString(description)) {
throw new Error(`Property 'description' should be localized.`);
throw new ParseError(`Property 'description' should be localized.`, moduleName, settingNode);
}
let result: Policy | undefined;
@ -499,7 +649,7 @@ function getPolicy(
}
if (!result) {
throw new Error(`Failed to parse policy '${name}'.`);
throw new ParseError(`Failed to parse policy '${name}'.`, moduleName, settingNode);
}
return result;
@ -511,11 +661,11 @@ function getPolicies(moduleName: string, node: Parser.SyntaxNode): Policy[] {
(call_expression
function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration)
arguments: (arguments (object (pair
key: [(property_identifier)(string)] @propertiesKey (#eq? @propertiesKey properties)
key: [(property_identifier)(string)] @propertiesKey (#any-of? @propertiesKey "properties" "'properties'")
value: (object (pair
key: [(property_identifier)(string)(computed_property_name)]
value: (object (pair
key: [(property_identifier)(string)] @policyKey (#eq? @policyKey policy)
key: [(property_identifier)(string)] @policyKey (#any-of? @policyKey "policy" "'policy'")
value: (object) @policy
)) @setting
))
@ -578,8 +728,8 @@ function renderADML(appName: string, versions: string[], categories: Category[],
<resources>
<stringTable>
<string id="Application">${appName}</string>
${versions.map(v => `<string id="Supported_${v.replace(/\./g, '_')}">${appName} &gt;= ${v}</string>`)}
${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations))}
${versions.map(v => `<string id="Supported_${v.replace(/\./g, '_')}">${appName} &gt;= ${v}</string>`).join(`\n `)}
${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations)).join(`\n `)}
${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)}
</stringTable>
<presentationTable>
@ -590,6 +740,197 @@ function renderADML(appName: string, versions: string[], categories: Category[],
`;
}
function renderProfileManifest(appName: string, bundleIdentifier: string, _versions: string[], _categories: Category[], policies: Policy[], translations?: LanguageTranslations) {
const requiredPayloadFields = `
<dict>
<key>pfm_default</key>
<string>Configure ${appName}</string>
<key>pfm_name</key>
<string>PayloadDescription</string>
<key>pfm_title</key>
<string>Payload Description</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string>${appName}</string>
<key>pfm_name</key>
<string>PayloadDisplayName</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Display Name</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string>${bundleIdentifier}</string>
<key>pfm_name</key>
<string>PayloadIdentifier</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Identifier</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string>${bundleIdentifier}</string>
<key>pfm_name</key>
<string>PayloadType</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Type</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<string></string>
<key>pfm_name</key>
<string>PayloadUUID</string>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload UUID</string>
<key>pfm_type</key>
<string>string</string>
</dict>
<dict>
<key>pfm_default</key>
<integer>1</integer>
<key>pfm_name</key>
<string>PayloadVersion</string>
<key>pfm_range_list</key>
<array>
<integer>1</integer>
</array>
<key>pfm_require</key>
<string>always</string>
<key>pfm_title</key>
<string>Payload Version</string>
<key>pfm_type</key>
<string>integer</string>
</dict>
<dict>
<key>pfm_default</key>
<string>Microsoft</string>
<key>pfm_name</key>
<string>PayloadOrganization</string>
<key>pfm_title</key>
<string>Payload Organization</string>
<key>pfm_type</key>
<string>string</string>
</dict>`;
const profileManifestSubkeys = policies.map(policy => {
return policy.renderProfileManifest(translations);
}).join('');
return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>pfm_app_url</key>
<string>https://code.visualstudio.com/</string>
<key>pfm_description</key>
<string>${appName} Managed Settings</string>
<key>pfm_documentation_url</key>
<string>https://code.visualstudio.com/docs/setup/enterprise</string>
<key>pfm_domain</key>
<string>${bundleIdentifier}</string>
<key>pfm_format_version</key>
<integer>1</integer>
<key>pfm_interaction</key>
<string>combined</string>
<key>pfm_last_modified</key>
<date>${new Date().toISOString().replace(/\.\d+Z$/, 'Z')}</date>
<key>pfm_platforms</key>
<array>
<string>macOS</string>
</array>
<key>pfm_subkeys</key>
<array>
${requiredPayloadFields}
${profileManifestSubkeys}
</array>
<key>pfm_title</key>
<string>${appName}</string>
<key>pfm_unique</key>
<true/>
<key>pfm_version</key>
<integer>1</integer>
</dict>
</plist>`;
}
function renderMacOSPolicy(policies: Policy[], translations: Translations) {
const appName = product.nameLong;
const bundleIdentifier = product.darwinBundleIdentifier;
const payloadUUID = product.darwinProfilePayloadUUID;
const UUID = product.darwinProfileUUID;
const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort();
const categories = [...new Set(policies.map(p => p.category))];
const policyEntries =
policies.map(policy => policy.renderProfile())
.flat()
.map(entry => `\t\t\t\t${entry}`)
.join('\n');
return {
profile: `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>${appName}</string>
<key>PayloadIdentifier</key>
<string>${bundleIdentifier}.${UUID}</string>
<key>PayloadType</key>
<string>${bundleIdentifier}</string>
<key>PayloadUUID</key>
<string>${UUID}</string>
<key>PayloadVersion</key>
<integer>1</integer>
${policyEntries}
</dict>
</array>
<key>PayloadDescription</key>
<string>This profile manages ${appName}. For more information see https://code.visualstudio.com/docs/setup/enterprise</string>
<key>PayloadDisplayName</key>
<string>${appName}</string>
<key>PayloadIdentifier</key>
<string>${bundleIdentifier}</string>
<key>PayloadOrganization</key>
<string>Microsoft</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>${payloadUUID}</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>TargetDeviceType</key>
<integer>5</integer>
</dict>
</plist>`,
manifests: [{ languageId: 'en-us', contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies) },
...translations.map(({ languageId, languageTranslations }) =>
({ languageId, contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies, languageTranslations) }))
]
};
}
function renderGP(policies: Policy[], translations: Translations) {
const appName = product.nameLong;
const regKey = product.win32RegValueName;
@ -735,11 +1076,10 @@ async function getTranslations(): Promise<Translations> {
));
}
async function main() {
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
async function windowsMain(policies: Policy[], translations: Translations) {
const root = '.build/policies/win32';
const { admx, adml } = await renderGP(policies, translations);
const root = '.build/policies/win32';
await fs.rm(root, { recursive: true, force: true });
await fs.mkdir(root, { recursive: true });
@ -752,9 +1092,46 @@ async function main() {
}
}
async function darwinMain(policies: Policy[], translations: Translations) {
const bundleIdentifier = product.darwinBundleIdentifier;
if (!bundleIdentifier || !product.darwinProfilePayloadUUID || !product.darwinProfileUUID) {
throw new Error(`Missing required product information.`);
}
const root = '.build/policies/darwin';
const { profile, manifests } = await renderMacOSPolicy(policies, translations);
await fs.rm(root, { recursive: true, force: true });
await fs.mkdir(root, { recursive: true });
await fs.writeFile(path.join(root, `${bundleIdentifier}.mobileconfig`), profile.replace(/\r?\n/g, '\n'));
for (const { languageId, contents } of manifests) {
const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId as keyof typeof Languages]);
await fs.mkdir(languagePath, { recursive: true });
await fs.writeFile(path.join(languagePath, `${bundleIdentifier}.plist`), contents.replace(/\r?\n/g, '\n'));
}
}
async function main() {
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
const platform = process.argv[2];
if (platform === 'darwin') {
await darwinMain(policies, translations);
} else if (platform === 'win32') {
await windowsMain(policies, translations);
} else {
console.error(`Usage: node build/lib/policies <darwin|win32>`);
process.exit(1);
}
}
if (require.main === module) {
main().catch(err => {
console.error(err);
if (err instanceof ParseError) {
console.error(`Parse Error:`, err.message);
} else {
console.error(err);
}
process.exit(1);
});
}

View file

@ -0,0 +1,367 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.EntryKind = void 0;
const ts = __importStar(require("typescript"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const TS_CONFIG_PATH = path.join(__dirname, '../../', 'src', 'tsconfig.json');
//
// #############################################################################################
//
// A custom typescript checker that ensure constructor properties are NOT used to initialize
// defined properties. This is needed for the times when `useDefineForClassFields` is gone.
//
// see https://github.com/microsoft/vscode/issues/243049, https://github.com/microsoft/vscode/issues/186726,
// https://github.com/microsoft/vscode/pull/241544
//
// #############################################################################################
//
const ignored = new Set([
'vs/base/common/arrays.ts',
'vs/platform/extensionManagement/common/extensionsScannerService.ts',
'vs/platform/configuration/common/configurations.ts',
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts',
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts',
'vs/editor/common/model/textModelTokens.ts',
'vs/editor/common/model/tokenizationTextModelPart.ts',
'vs/editor/common/core/textEdit.ts',
'vs/workbench/contrib/debug/common/debugStorage.ts',
'vs/workbench/contrib/debug/common/debugModel.ts',
'vs/workbench/api/common/extHostCommands.ts',
'vs/editor/browser/view/viewLayer.ts',
'vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts',
'vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts',
'vs/editor/browser/widget/diffEditor/utils.ts',
'vs/editor/browser/observableCodeEditor.ts',
'vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts',
'vs/editor/browser/widget/diffEditor/diffEditorOptions.ts',
'vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts',
'vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts',
'vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts',
'vs/editor/browser/widget/diffEditor/utils/editorGutter.ts',
'vs/editor/browser/widget/diffEditor/features/gutterFeature.ts',
'vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts',
'vs/editor/browser/widget/diffEditor/diffEditorWidget.ts',
'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts',
'vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts',
'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts',
'vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts',
'vs/editor/contrib/inlayHints/browser/inlayHintsController.ts',
'vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts',
'vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineCompletionsView.ts',
'vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts',
'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts',
'vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts',
'vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts',
'vs/workbench/contrib/chat/common/promptSyntax/parsers/basePromptParser.ts',
'vs/workbench/contrib/files/browser/views/openEditorsView.ts',
'vs/workbench/contrib/chat/browser/chatContentParts/chatAttachmentsContentPart.ts',
'vs/workbench/contrib/chat/browser/contrib/chatImplicitContext.ts',
'vs/workbench/contrib/chat/browser/chatInputPart.ts',
'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts',
'vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts',
'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts',
'vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts',
'vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts',
'vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts',
'vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts',
'vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts',
'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts',
'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts',
'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts',
'vs/platform/terminal/common/capabilities/commandDetectionCapability.ts',
'vs/workbench/contrib/testing/common/testExclusions.ts',
'vs/workbench/contrib/testing/common/testResultStorage.ts',
'vs/workbench/services/userDataProfile/browser/snippetsResource.ts',
'vs/platform/quickinput/browser/quickInputController.ts',
'vs/platform/userDataSync/common/abstractSynchronizer.ts',
'vs/workbench/services/authentication/browser/authenticationExtensionsService.ts',
'vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts',
'vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts',
'vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts',
'vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts',
'vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts',
'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts',
'vs/workbench/contrib/notebook/browser/diff/notebookMultiDiffEditor.ts',
'vs/workbench/contrib/chat/common/promptSyntax/contentProviders/textModelContentsProvider.ts',
'vs/workbench/contrib/chat/common/promptSyntax/service/promptsService.ts',
'vs/workbench/contrib/search/common/cacheState.ts',
'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts',
'vs/workbench/contrib/search/browser/anythingQuickAccess.ts',
'vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts',
'vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts',
'vs/workbench/contrib/testing/common/testExplorerFilterState.ts',
'vs/workbench/contrib/testing/browser/testResultsView/testResultsTree.ts',
'vs/workbench/contrib/testing/browser/testingOutputPeek.ts',
'vs/workbench/contrib/testing/browser/explorerProjections/index.ts',
'vs/workbench/contrib/testing/browser/testingExplorerFilter.ts',
'vs/workbench/contrib/testing/browser/testingExplorerView.ts',
'vs/workbench/contrib/testing/common/testServiceImpl.ts',
'vs/platform/quickinput/browser/commandsQuickAccess.ts',
'vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts',
'vs/workbench/contrib/multiDiffEditor/browser/scmMultiDiffSourceResolver.ts',
'vs/workbench/contrib/debug/browser/debugMemory.ts',
'vs/workbench/contrib/markers/browser/markersViewActions.ts',
'vs/workbench/contrib/mergeEditor/browser/view/viewZones.ts',
'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts',
'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts',
'vs/workbench/contrib/output/browser/outputServices.ts',
'vs/workbench/contrib/terminalContrib/typeAhead/browser/terminalTypeAheadAddon.ts',
'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts',
'vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts',
'vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts',
'vs/workbench/contrib/inlineCompletions/browser/inlineCompletionLanguageStatusBarContribution.ts',
'vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts',
'vs/workbench/contrib/welcomeDialog/browser/welcomeWidget.ts',
'vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordInsertView.ts',
'vs/platform/terminal/node/ptyService.ts',
'vs/workbench/api/common/extHostLanguageFeatures.ts',
'vs/workbench/api/common/extHostSearch.ts',
'vs/workbench/contrib/testing/test/common/testStubs.ts'
]);
const cancellationToken = {
isCancellationRequested: () => false,
throwIfCancellationRequested: () => { },
};
const seenFiles = new Set();
let errorCount = 0;
function createProgram(tsconfigPath) {
const tsConfig = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
const configHostParser = { fileExists: fs.existsSync, readDirectory: ts.sys.readDirectory, readFile: file => fs.readFileSync(file, 'utf8'), useCaseSensitiveFileNames: process.platform === 'linux' };
const tsConfigParsed = ts.parseJsonConfigFileContent(tsConfig.config, configHostParser, path.resolve(path.dirname(tsconfigPath)), { noEmit: true });
const compilerHost = ts.createCompilerHost(tsConfigParsed.options, true);
return ts.createProgram(tsConfigParsed.fileNames, tsConfigParsed.options, compilerHost);
}
const program = createProgram(TS_CONFIG_PATH);
program.getTypeChecker();
for (const file of program.getSourceFiles()) {
if (!file || file.isDeclarationFile) {
continue;
}
const relativePath = path.relative(path.dirname(TS_CONFIG_PATH), file.fileName).replace(/\\/g, '/');
if (ignored.has(relativePath)) {
continue;
}
visit(file);
}
if (seenFiles.size) {
console.log();
console.log(`Found ${errorCount} error${errorCount === 1 ? '' : 's'} in ${seenFiles.size} file${seenFiles.size === 1 ? '' : 's'}.`);
process.exit(errorCount);
}
function visit(node) {
if (ts.isParameter(node) && ts.isParameterPropertyDeclaration(node, node.parent)) {
checkParameterPropertyDeclaration(node);
}
ts.forEachChild(node, visit);
}
function checkParameterPropertyDeclaration(param) {
const uses = [...collectReferences(param.name, [])];
if (!uses.length) {
return;
}
const sourceFile = param.getSourceFile();
if (!seenFiles.has(sourceFile)) {
if (seenFiles.size) {
console.log(``);
}
console.log(`${formatFileName(param)}:`);
seenFiles.add(sourceFile);
}
else {
console.log(``);
}
console.log(` Parameter property '${param.name.getText()}' is used before its declaration.`);
for (const { stack, container } of uses) {
const use = stack[stack.length - 1];
console.log(` at ${formatLocation(use)}: ${formatMember(container)} -> ${formatStack(stack)}`);
errorCount++;
}
}
function* collectReferences(node, stack, requiresInvocationDepth = 0, seen = new Set()) {
for (const use of findAllReferencesInClass(node)) {
const container = findContainer(use);
if (!container || seen.has(container) || ts.isConstructorDeclaration(container)) {
continue;
}
seen.add(container);
const nextStack = [...stack, use];
let nextRequiresInvocationDepth = requiresInvocationDepth;
if (isInvocation(use) && nextRequiresInvocationDepth > 0) {
nextRequiresInvocationDepth--;
}
if (ts.isPropertyDeclaration(container) && nextRequiresInvocationDepth === 0) {
yield { stack: nextStack, container };
}
else if (requiresInvocation(container)) {
nextRequiresInvocationDepth++;
}
yield* collectReferences(container.name ?? container, nextStack, nextRequiresInvocationDepth, seen);
}
}
function requiresInvocation(definition) {
return ts.isMethodDeclaration(definition) || ts.isFunctionDeclaration(definition) || ts.isFunctionExpression(definition) || ts.isArrowFunction(definition);
}
function isInvocation(use) {
let location = use;
if (ts.isPropertyAccessExpression(location.parent) && location.parent.name === location) {
location = location.parent;
}
else if (ts.isElementAccessExpression(location.parent) && location.parent.argumentExpression === location) {
location = location.parent;
}
return ts.isCallExpression(location.parent) && location.parent.expression === location
|| ts.isTaggedTemplateExpression(location.parent) && location.parent.tag === location;
}
function formatFileName(node) {
const sourceFile = node.getSourceFile();
return path.resolve(sourceFile.fileName);
}
function formatLocation(node) {
const sourceFile = node.getSourceFile();
const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos);
return `${formatFileName(sourceFile)}(${line + 1},${character + 1})`;
}
function formatStack(stack) {
return stack.slice().reverse().map((use) => formatUse(use)).join(' -> ');
}
function formatMember(container) {
const name = container.name?.getText();
if (name) {
const className = findClass(container)?.name?.getText();
if (className) {
return `${className}.${name}`;
}
return name;
}
return '<unknown>';
}
function formatUse(use) {
let text = use.getText();
if (use.parent && ts.isPropertyAccessExpression(use.parent) && use.parent.name === use) {
if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) {
text = `this.${text}`;
}
use = use.parent;
}
else if (use.parent && ts.isElementAccessExpression(use.parent) && use.parent.argumentExpression === use) {
if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) {
text = `this['${text}']`;
}
use = use.parent;
}
if (ts.isCallExpression(use.parent)) {
text = `${text}(...)`;
}
return text;
}
function findContainer(node) {
return ts.findAncestor(node, ancestor => {
switch (ancestor.kind) {
case ts.SyntaxKind.PropertyDeclaration:
case ts.SyntaxKind.MethodDeclaration:
case ts.SyntaxKind.GetAccessor:
case ts.SyntaxKind.SetAccessor:
case ts.SyntaxKind.Constructor:
case ts.SyntaxKind.ClassStaticBlockDeclaration:
case ts.SyntaxKind.ArrowFunction:
case ts.SyntaxKind.FunctionExpression:
case ts.SyntaxKind.FunctionDeclaration:
case ts.SyntaxKind.Parameter:
return true;
}
return false;
});
}
function findClass(node) {
return ts.findAncestor(node, ts.isClassLike);
}
function* findAllReferencesInClass(node) {
const classDecl = findClass(node);
if (!classDecl) {
return [];
}
for (const ref of findAllReferences(node)) {
for (const entry of ref.references) {
if (entry.kind !== 1 /* EntryKind.Node */ || entry.node === node) {
continue;
}
if (findClass(entry.node) === classDecl) {
yield entry.node;
}
}
}
}
// NOTE: The following uses TypeScript internals and are subject to change from version to version.
function findAllReferences(node) {
const sourceFile = node.getSourceFile();
const position = node.getStart();
const name = ts.getTouchingPropertyName(sourceFile, position);
const options = { use: ts.FindAllReferences.FindReferencesUse.References };
return ts.FindAllReferences.Core.getReferencedSymbolsForNode(position, name, program, [sourceFile], cancellationToken, options) ?? [];
}
var DefinitionKind;
(function (DefinitionKind) {
DefinitionKind[DefinitionKind["Symbol"] = 0] = "Symbol";
DefinitionKind[DefinitionKind["Label"] = 1] = "Label";
DefinitionKind[DefinitionKind["Keyword"] = 2] = "Keyword";
DefinitionKind[DefinitionKind["This"] = 3] = "This";
DefinitionKind[DefinitionKind["String"] = 4] = "String";
DefinitionKind[DefinitionKind["TripleSlashReference"] = 5] = "TripleSlashReference";
})(DefinitionKind || (DefinitionKind = {}));
/** @internal */
var EntryKind;
(function (EntryKind) {
EntryKind[EntryKind["Span"] = 0] = "Span";
EntryKind[EntryKind["Node"] = 1] = "Node";
EntryKind[EntryKind["StringLiteral"] = 2] = "StringLiteral";
EntryKind[EntryKind["SearchedLocalFoundProperty"] = 3] = "SearchedLocalFoundProperty";
EntryKind[EntryKind["SearchedPropertyFoundLocal"] = 4] = "SearchedPropertyFoundLocal";
})(EntryKind || (exports.EntryKind = EntryKind = {}));
//# sourceMappingURL=propertyInitOrderChecker.js.map

View file

@ -0,0 +1,417 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as ts from 'typescript';
import * as path from 'path';
import * as fs from 'fs';
const TS_CONFIG_PATH = path.join(__dirname, '../../', 'src', 'tsconfig.json');
//
// #############################################################################################
//
// A custom typescript checker that ensure constructor properties are NOT used to initialize
// defined properties. This is needed for the times when `useDefineForClassFields` is gone.
//
// see https://github.com/microsoft/vscode/issues/243049, https://github.com/microsoft/vscode/issues/186726,
// https://github.com/microsoft/vscode/pull/241544
//
// #############################################################################################
//
const ignored = new Set([
'vs/base/common/arrays.ts',
'vs/platform/extensionManagement/common/extensionsScannerService.ts',
'vs/platform/configuration/common/configurations.ts',
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts',
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts',
'vs/editor/common/model/textModelTokens.ts',
'vs/editor/common/model/tokenizationTextModelPart.ts',
'vs/editor/common/core/textEdit.ts',
'vs/workbench/contrib/debug/common/debugStorage.ts',
'vs/workbench/contrib/debug/common/debugModel.ts',
'vs/workbench/api/common/extHostCommands.ts',
'vs/editor/browser/view/viewLayer.ts',
'vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts',
'vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts',
'vs/editor/browser/widget/diffEditor/utils.ts',
'vs/editor/browser/observableCodeEditor.ts',
'vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts',
'vs/editor/browser/widget/diffEditor/diffEditorOptions.ts',
'vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts',
'vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts',
'vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts',
'vs/editor/browser/widget/diffEditor/utils/editorGutter.ts',
'vs/editor/browser/widget/diffEditor/features/gutterFeature.ts',
'vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts',
'vs/editor/browser/widget/diffEditor/diffEditorWidget.ts',
'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts',
'vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts',
'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts',
'vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts',
'vs/editor/contrib/inlayHints/browser/inlayHintsController.ts',
'vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts',
'vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineCompletionsView.ts',
'vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts',
'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts',
'vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts',
'vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts',
'vs/workbench/contrib/chat/common/promptSyntax/parsers/basePromptParser.ts',
'vs/workbench/contrib/files/browser/views/openEditorsView.ts',
'vs/workbench/contrib/chat/browser/chatContentParts/chatAttachmentsContentPart.ts',
'vs/workbench/contrib/chat/browser/contrib/chatImplicitContext.ts',
'vs/workbench/contrib/chat/browser/chatInputPart.ts',
'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts',
'vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts',
'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts',
'vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts',
'vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts',
'vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts',
'vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts',
'vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts',
'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts',
'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts',
'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts',
'vs/platform/terminal/common/capabilities/commandDetectionCapability.ts',
'vs/workbench/contrib/testing/common/testExclusions.ts',
'vs/workbench/contrib/testing/common/testResultStorage.ts',
'vs/workbench/services/userDataProfile/browser/snippetsResource.ts',
'vs/platform/quickinput/browser/quickInputController.ts',
'vs/platform/userDataSync/common/abstractSynchronizer.ts',
'vs/workbench/services/authentication/browser/authenticationExtensionsService.ts',
'vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts',
'vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts',
'vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts',
'vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts',
'vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts',
'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts',
'vs/workbench/contrib/notebook/browser/diff/notebookMultiDiffEditor.ts',
'vs/workbench/contrib/chat/common/promptSyntax/contentProviders/textModelContentsProvider.ts',
'vs/workbench/contrib/chat/common/promptSyntax/service/promptsService.ts',
'vs/workbench/contrib/search/common/cacheState.ts',
'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts',
'vs/workbench/contrib/search/browser/anythingQuickAccess.ts',
'vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts',
'vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts',
'vs/workbench/contrib/testing/common/testExplorerFilterState.ts',
'vs/workbench/contrib/testing/browser/testResultsView/testResultsTree.ts',
'vs/workbench/contrib/testing/browser/testingOutputPeek.ts',
'vs/workbench/contrib/testing/browser/explorerProjections/index.ts',
'vs/workbench/contrib/testing/browser/testingExplorerFilter.ts',
'vs/workbench/contrib/testing/browser/testingExplorerView.ts',
'vs/workbench/contrib/testing/common/testServiceImpl.ts',
'vs/platform/quickinput/browser/commandsQuickAccess.ts',
'vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts',
'vs/workbench/contrib/multiDiffEditor/browser/scmMultiDiffSourceResolver.ts',
'vs/workbench/contrib/debug/browser/debugMemory.ts',
'vs/workbench/contrib/markers/browser/markersViewActions.ts',
'vs/workbench/contrib/mergeEditor/browser/view/viewZones.ts',
'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts',
'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts',
'vs/workbench/contrib/output/browser/outputServices.ts',
'vs/workbench/contrib/terminalContrib/typeAhead/browser/terminalTypeAheadAddon.ts',
'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts',
'vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts',
'vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts',
'vs/workbench/contrib/inlineCompletions/browser/inlineCompletionLanguageStatusBarContribution.ts',
'vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts',
'vs/workbench/contrib/welcomeDialog/browser/welcomeWidget.ts',
'vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts',
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordInsertView.ts',
'vs/platform/terminal/node/ptyService.ts',
'vs/workbench/api/common/extHostLanguageFeatures.ts',
'vs/workbench/api/common/extHostSearch.ts',
'vs/workbench/contrib/testing/test/common/testStubs.ts'
]);
const cancellationToken: ts.CancellationToken = {
isCancellationRequested: () => false,
throwIfCancellationRequested: () => { },
};
const seenFiles = new Set<ts.SourceFile>();
let errorCount = 0;
function createProgram(tsconfigPath: string): ts.Program {
const tsConfig = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
const configHostParser: ts.ParseConfigHost = { fileExists: fs.existsSync, readDirectory: ts.sys.readDirectory, readFile: file => fs.readFileSync(file, 'utf8'), useCaseSensitiveFileNames: process.platform === 'linux' };
const tsConfigParsed = ts.parseJsonConfigFileContent(tsConfig.config, configHostParser, path.resolve(path.dirname(tsconfigPath)), { noEmit: true });
const compilerHost = ts.createCompilerHost(tsConfigParsed.options, true);
return ts.createProgram(tsConfigParsed.fileNames, tsConfigParsed.options, compilerHost);
}
const program = createProgram(TS_CONFIG_PATH);
program.getTypeChecker();
for (const file of program.getSourceFiles()) {
if (!file || file.isDeclarationFile) {
continue;
}
const relativePath = path.relative(path.dirname(TS_CONFIG_PATH), file.fileName).replace(/\\/g, '/');
if (ignored.has(relativePath)) {
continue;
}
visit(file);
}
if (seenFiles.size) {
console.log();
console.log(`Found ${errorCount} error${errorCount === 1 ? '' : 's'} in ${seenFiles.size} file${seenFiles.size === 1 ? '' : 's'}.`);
process.exit(errorCount);
}
function visit(node: ts.Node) {
if (ts.isParameter(node) && ts.isParameterPropertyDeclaration(node, node.parent)) {
checkParameterPropertyDeclaration(node);
}
ts.forEachChild(node, visit);
}
function checkParameterPropertyDeclaration(param: ts.ParameterPropertyDeclaration) {
const uses = [...collectReferences(param.name, [])];
if (!uses.length) {
return;
}
const sourceFile = param.getSourceFile();
if (!seenFiles.has(sourceFile)) {
if (seenFiles.size) {
console.log(``);
}
console.log(`${formatFileName(param)}:`);
seenFiles.add(sourceFile);
} else {
console.log(``);
}
console.log(` Parameter property '${param.name.getText()}' is used before its declaration.`);
for (const { stack, container } of uses) {
const use = stack[stack.length - 1];
console.log(` at ${formatLocation(use)}: ${formatMember(container)} -> ${formatStack(stack)}`);
errorCount++;
}
}
interface InvalidUse {
stack: ts.Node[];
container: ReferenceContainer;
}
function* collectReferences(node: ts.Node, stack: ts.Node[], requiresInvocationDepth: number = 0, seen = new Set<ReferenceContainer>()): Generator<InvalidUse> {
for (const use of findAllReferencesInClass(node)) {
const container = findContainer(use);
if (!container || seen.has(container) || ts.isConstructorDeclaration(container)) {
continue;
}
seen.add(container);
const nextStack = [...stack, use];
let nextRequiresInvocationDepth = requiresInvocationDepth;
if (isInvocation(use) && nextRequiresInvocationDepth > 0) {
nextRequiresInvocationDepth--;
}
if (ts.isPropertyDeclaration(container) && nextRequiresInvocationDepth === 0) {
yield { stack: nextStack, container };
}
else if (requiresInvocation(container)) {
nextRequiresInvocationDepth++;
}
yield* collectReferences(container.name ?? container, nextStack, nextRequiresInvocationDepth, seen);
}
}
function requiresInvocation(definition: ReferenceContainer): boolean {
return ts.isMethodDeclaration(definition) || ts.isFunctionDeclaration(definition) || ts.isFunctionExpression(definition) || ts.isArrowFunction(definition);
}
function isInvocation(use: ts.Node): boolean {
let location = use;
if (ts.isPropertyAccessExpression(location.parent) && location.parent.name === location) {
location = location.parent;
}
else if (ts.isElementAccessExpression(location.parent) && location.parent.argumentExpression === location) {
location = location.parent;
}
return ts.isCallExpression(location.parent) && location.parent.expression === location
|| ts.isTaggedTemplateExpression(location.parent) && location.parent.tag === location;
}
function formatFileName(node: ts.Node): string {
const sourceFile = node.getSourceFile();
return path.resolve(sourceFile.fileName);
}
function formatLocation(node: ts.Node): string {
const sourceFile = node.getSourceFile();
const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos);
return `${formatFileName(sourceFile)}(${line + 1},${character + 1})`;
}
function formatStack(stack: ts.Node[]): string {
return stack.slice().reverse().map((use) => formatUse(use)).join(' -> ');
}
function formatMember(container: ReferenceContainer): string {
const name = container.name?.getText();
if (name) {
const className = findClass(container)?.name?.getText();
if (className) {
return `${className}.${name}`;
}
return name;
}
return '<unknown>';
}
function formatUse(use: ts.Node): string {
let text = use.getText();
if (use.parent && ts.isPropertyAccessExpression(use.parent) && use.parent.name === use) {
if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) {
text = `this.${text}`;
}
use = use.parent;
}
else if (use.parent && ts.isElementAccessExpression(use.parent) && use.parent.argumentExpression === use) {
if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) {
text = `this['${text}']`;
}
use = use.parent;
}
if (ts.isCallExpression(use.parent)) {
text = `${text}(...)`;
}
return text;
}
type ReferenceContainer =
| ts.PropertyDeclaration
| ts.MethodDeclaration
| ts.GetAccessorDeclaration
| ts.SetAccessorDeclaration
| ts.ConstructorDeclaration
| ts.ClassStaticBlockDeclaration
| ts.ArrowFunction
| ts.FunctionExpression
| ts.FunctionDeclaration
| ts.ParameterDeclaration;
function findContainer(node: ts.Node): ReferenceContainer | undefined {
return ts.findAncestor(node, ancestor => {
switch (ancestor.kind) {
case ts.SyntaxKind.PropertyDeclaration:
case ts.SyntaxKind.MethodDeclaration:
case ts.SyntaxKind.GetAccessor:
case ts.SyntaxKind.SetAccessor:
case ts.SyntaxKind.Constructor:
case ts.SyntaxKind.ClassStaticBlockDeclaration:
case ts.SyntaxKind.ArrowFunction:
case ts.SyntaxKind.FunctionExpression:
case ts.SyntaxKind.FunctionDeclaration:
case ts.SyntaxKind.Parameter:
return true;
}
return false;
}) as ReferenceContainer | undefined;
}
function findClass(node: ts.Node): ts.ClassLikeDeclaration | undefined {
return ts.findAncestor(node, ts.isClassLike);
}
function* findAllReferencesInClass(node: ts.Node): Generator<ts.Node> {
const classDecl = findClass(node);
if (!classDecl) {
return [];
}
for (const ref of findAllReferences(node)) {
for (const entry of ref.references) {
if (entry.kind !== EntryKind.Node || entry.node === node) {
continue;
}
if (findClass(entry.node) === classDecl) {
yield entry.node;
}
}
}
}
// NOTE: The following uses TypeScript internals and are subject to change from version to version.
function findAllReferences(node: ts.Node): readonly SymbolAndEntries[] {
const sourceFile = node.getSourceFile();
const position = node.getStart();
const name: ts.Node = (ts as any).getTouchingPropertyName(sourceFile, position);
const options = { use: (ts as any).FindAllReferences.FindReferencesUse.References };
return (ts as any).FindAllReferences.Core.getReferencedSymbolsForNode(position, name, program, [sourceFile], cancellationToken, options) ?? [];
}
interface SymbolAndEntries {
readonly definition: Definition | undefined;
readonly references: readonly Entry[];
}
const enum DefinitionKind {
Symbol,
Label,
Keyword,
This,
String,
TripleSlashReference,
}
type Definition =
| { readonly type: DefinitionKind.Symbol; readonly symbol: ts.Symbol }
| { readonly type: DefinitionKind.Label; readonly node: ts.Identifier }
| { readonly type: DefinitionKind.Keyword; readonly node: ts.Node }
| { readonly type: DefinitionKind.This; readonly node: ts.Node }
| { readonly type: DefinitionKind.String; readonly node: ts.StringLiteralLike }
| { readonly type: DefinitionKind.TripleSlashReference; readonly reference: ts.FileReference; readonly file: ts.SourceFile };
/** @internal */
export const enum EntryKind {
Span,
Node,
StringLiteral,
SearchedLocalFoundProperty,
SearchedPropertyFoundLocal,
}
type NodeEntryKind = EntryKind.Node | EntryKind.StringLiteral | EntryKind.SearchedLocalFoundProperty | EntryKind.SearchedPropertyFoundLocal;
type Entry = NodeEntry | SpanEntry;
interface ContextWithStartAndEndNode {
start: ts.Node;
end: ts.Node;
}
type ContextNode = ts.Node | ContextWithStartAndEndNode;
interface NodeEntry {
readonly kind: NodeEntryKind;
readonly node: ts.Node;
readonly context?: ContextNode;
}
interface SpanEntry {
readonly kind: EntryKind.Span;
readonly fileName: string;
readonly textSpan: ts.TextSpan;
}

View file

@ -41,7 +41,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractEditor = extractEditor;
exports.createESMSourcesAndResources2 = createESMSourcesAndResources2;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const tss = __importStar(require("./treeshaking"));
@ -75,6 +74,9 @@ function extractEditor(options) {
compilerOptions = tsConfig.compilerOptions;
}
tsConfig.compilerOptions = compilerOptions;
tsConfig.compilerOptions.sourceMap = true;
tsConfig.compilerOptions.module = 'es2022';
tsConfig.compilerOptions.outDir = options.tsOutDir;
compilerOptions.noEmit = false;
compilerOptions.noUnusedLocals = false;
compilerOptions.preserveConstEnums = false;
@ -142,102 +144,6 @@ function extractEditor(options) {
'vs/loader.js'
].forEach(copyFile);
}
function createESMSourcesAndResources2(options) {
const SRC_FOLDER = path_1.default.join(REPO_ROOT, options.srcFolder);
const OUT_FOLDER = path_1.default.join(REPO_ROOT, options.outFolder);
const OUT_RESOURCES_FOLDER = path_1.default.join(REPO_ROOT, options.outResourcesFolder);
const getDestAbsoluteFilePath = (file) => {
const dest = options.renames[file.replace(/\\/g, '/')] || file;
if (dest === 'tsconfig.json') {
return path_1.default.join(OUT_FOLDER, `tsconfig.json`);
}
if (/\.ts$/.test(dest)) {
return path_1.default.join(OUT_FOLDER, dest);
}
return path_1.default.join(OUT_RESOURCES_FOLDER, dest);
};
const allFiles = walkDirRecursive(SRC_FOLDER);
for (const file of allFiles) {
if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
continue;
}
if (file === 'tsconfig.json') {
const tsConfig = JSON.parse(fs_1.default.readFileSync(path_1.default.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.module = 'es2022';
tsConfig.compilerOptions.outDir = path_1.default.join(path_1.default.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs').replace(/\\/g, '/');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
}
if (/\.ts$/.test(file) || /\.d\.ts$/.test(file) || /\.css$/.test(file) || /\.js$/.test(file) || /\.ttf$/.test(file)) {
// Transport the files directly
write(getDestAbsoluteFilePath(file), fs_1.default.readFileSync(path_1.default.join(SRC_FOLDER, file)));
continue;
}
console.log(`UNKNOWN FILE: ${file}`);
}
function walkDirRecursive(dir) {
if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') {
dir += '/';
}
const result = [];
_walkDirRecursive(dir, result, dir.length);
return result;
}
function _walkDirRecursive(dir, result, trimPos) {
const files = fs_1.default.readdirSync(dir);
for (let i = 0; i < files.length; i++) {
const file = path_1.default.join(dir, files[i]);
if (fs_1.default.statSync(file).isDirectory()) {
_walkDirRecursive(file, result, trimPos);
}
else {
result.push(file.substr(trimPos));
}
}
}
function write(absoluteFilePath, contents) {
if (/(\.ts$)|(\.js$)/.test(absoluteFilePath)) {
contents = toggleComments(contents.toString());
}
writeFile(absoluteFilePath, contents);
function toggleComments(fileContents) {
const lines = fileContents.split(/\r\n|\r|\n/);
let mode = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (mode === 0) {
if (/\/\/ ESM-comment-begin/.test(line)) {
mode = 1;
continue;
}
if (/\/\/ ESM-uncomment-begin/.test(line)) {
mode = 2;
continue;
}
continue;
}
if (mode === 1) {
if (/\/\/ ESM-comment-end/.test(line)) {
mode = 0;
continue;
}
lines[i] = '// ' + line;
continue;
}
if (mode === 2) {
if (/\/\/ ESM-uncomment-end/.test(line)) {
mode = 0;
continue;
}
lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) {
return indent;
});
}
}
return lines.join('\n');
}
}
}
function transportCSS(module, enqueue, write) {
if (!/\.css/.test(module)) {
return false;

View file

@ -29,7 +29,7 @@ function writeFile(filePath: string, contents: Buffer | string): void {
fs.writeFileSync(filePath, contents);
}
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string; tsOutDir: string }): void {
const ts = require('typescript') as typeof import('typescript');
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString());
@ -41,6 +41,9 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
compilerOptions = tsConfig.compilerOptions;
}
tsConfig.compilerOptions = compilerOptions;
tsConfig.compilerOptions.sourceMap = true;
tsConfig.compilerOptions.module = 'es2022';
tsConfig.compilerOptions.outDir = options.tsOutDir;
compilerOptions.noEmit = false;
compilerOptions.noUnusedLocals = false;
@ -119,125 +122,6 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
].forEach(copyFile);
}
export interface IOptions2 {
srcFolder: string;
outFolder: string;
outResourcesFolder: string;
ignores: string[];
renames: { [filename: string]: string };
}
export function createESMSourcesAndResources2(options: IOptions2): void {
const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
const getDestAbsoluteFilePath = (file: string): string => {
const dest = options.renames[file.replace(/\\/g, '/')] || file;
if (dest === 'tsconfig.json') {
return path.join(OUT_FOLDER, `tsconfig.json`);
}
if (/\.ts$/.test(dest)) {
return path.join(OUT_FOLDER, dest);
}
return path.join(OUT_RESOURCES_FOLDER, dest);
};
const allFiles = walkDirRecursive(SRC_FOLDER);
for (const file of allFiles) {
if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
continue;
}
if (file === 'tsconfig.json') {
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.module = 'es2022';
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs').replace(/\\/g, '/');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
}
if (/\.ts$/.test(file) || /\.d\.ts$/.test(file) || /\.css$/.test(file) || /\.js$/.test(file) || /\.ttf$/.test(file)) {
// Transport the files directly
write(getDestAbsoluteFilePath(file), fs.readFileSync(path.join(SRC_FOLDER, file)));
continue;
}
console.log(`UNKNOWN FILE: ${file}`);
}
function walkDirRecursive(dir: string): string[] {
if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') {
dir += '/';
}
const result: string[] = [];
_walkDirRecursive(dir, result, dir.length);
return result;
}
function _walkDirRecursive(dir: string, result: string[], trimPos: number): void {
const files = fs.readdirSync(dir);
for (let i = 0; i < files.length; i++) {
const file = path.join(dir, files[i]);
if (fs.statSync(file).isDirectory()) {
_walkDirRecursive(file, result, trimPos);
} else {
result.push(file.substr(trimPos));
}
}
}
function write(absoluteFilePath: string, contents: string | Buffer): void {
if (/(\.ts$)|(\.js$)/.test(absoluteFilePath)) {
contents = toggleComments(contents.toString());
}
writeFile(absoluteFilePath, contents);
function toggleComments(fileContents: string): string {
const lines = fileContents.split(/\r\n|\r|\n/);
let mode = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (mode === 0) {
if (/\/\/ ESM-comment-begin/.test(line)) {
mode = 1;
continue;
}
if (/\/\/ ESM-uncomment-begin/.test(line)) {
mode = 2;
continue;
}
continue;
}
if (mode === 1) {
if (/\/\/ ESM-comment-end/.test(line)) {
mode = 0;
continue;
}
lines[i] = '// ' + line;
continue;
}
if (mode === 2) {
if (/\/\/ ESM-uncomment-end/.test(line)) {
mode = 0;
continue;
}
lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) {
return indent;
});
}
}
return lines.join('\n');
}
}
}
function transportCSS(module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean {
if (!/\.css/.test(module)) {

View file

@ -234,6 +234,8 @@
"--vscode-editorGutter-commentUnresolvedGlyphForeground",
"--vscode-editorGutter-deletedBackground",
"--vscode-editorGutter-foldingControlForeground",
"--vscode-editorGutter-itemBackground",
"--vscode-editorGutter-itemGlyphForeground",
"--vscode-editorGutter-modifiedBackground",
"--vscode-editorHint-border",
"--vscode-editorHint-foreground",
@ -345,6 +347,7 @@
"--vscode-extensionButton-prominentHoverBackground",
"--vscode-extensionButton-separator",
"--vscode-extensionIcon-preReleaseForeground",
"--vscode-extensionIcon-privateForeground",
"--vscode-extensionIcon-sponsorForeground",
"--vscode-extensionIcon-starForeground",
"--vscode-extensionIcon-verifiedForeground",
@ -370,14 +373,14 @@
"--vscode-inlineChatInput-placeholderForeground",
"--vscode-inlineEdit-gutterIndicator-background",
"--vscode-inlineEdit-gutterIndicator-primaryBackground",
"--vscode-inlineEdit-gutterIndicator-primaryBorder",
"--vscode-inlineEdit-gutterIndicator-primaryForeground",
"--vscode-inlineEdit-gutterIndicator-secondaryBackground",
"--vscode-inlineEdit-gutterIndicator-secondaryBorder",
"--vscode-inlineEdit-gutterIndicator-secondaryForeground",
"--vscode-inlineEdit-gutterIndicator-successfulBackground",
"--vscode-inlineEdit-gutterIndicator-successfulBorder",
"--vscode-inlineEdit-gutterIndicator-successfulForeground",
"--vscode-inlineEdit-indicator-background",
"--vscode-inlineEdit-indicator-border",
"--vscode-inlineEdit-indicator-foreground",
"--vscode-inlineEdit-modifiedBackground",
"--vscode-inlineEdit-modifiedBorder",
"--vscode-inlineEdit-modifiedChangedLineBackground",
@ -386,8 +389,8 @@
"--vscode-inlineEdit-originalBorder",
"--vscode-inlineEdit-originalChangedLineBackground",
"--vscode-inlineEdit-originalChangedTextBackground",
"--vscode-inlineEdit-tabWillAcceptBorder",
"--vscode-inlineEdit-wordReplacementView-background",
"--vscode-inlineEdit-tabWillAcceptModifiedBorder",
"--vscode-inlineEdit-tabWillAcceptOriginalBorder",
"--vscode-input-background",
"--vscode-input-border",
"--vscode-input-foreground",
@ -783,7 +786,14 @@
"--vscode-terminalStickyScroll-border",
"--vscode-terminalStickyScrollHover-background",
"--vscode-terminalSymbolIcon-aliasForeground",
"--vscode-terminalSymbolIcon-argumentForeground",
"--vscode-terminalSymbolIcon-fileForeground",
"--vscode-terminalSymbolIcon-flagForeground",
"--vscode-terminalSymbolIcon-folderForeground",
"--vscode-terminalSymbolIcon-inlineSuggestionForeground",
"--vscode-terminalSymbolIcon-methodForeground",
"--vscode-terminalSymbolIcon-optionForeground",
"--vscode-terminalSymbolIcon-optionValueForeground",
"--vscode-testing-coverCountBadgeBackground",
"--vscode-testing-coverCountBadgeForeground",
"--vscode-testing-coveredBackground",

View file

@ -26,7 +26,7 @@ const product = require("../../product.json");
// The reference dependencies, which one has to update when the new dependencies
// are valid, are in dep-lists.ts
const FAIL_BUILD_FOR_NEW_DEPENDENCIES = true;
// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.196:chrome/installer/linux/BUILD.gn;l=64-80
// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:chrome/installer/linux/BUILD.gn;l=64-80
// and the Linux Archive build
// Shared library dependencies that we already bundle.
const bundledDeps = [

View file

@ -25,7 +25,7 @@ import product = require('../../product.json');
// are valid, are in dep-lists.ts
const FAIL_BUILD_FOR_NEW_DEPENDENCIES: boolean = true;
// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.196:chrome/installer/linux/BUILD.gn;l=64-80
// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:chrome/installer/linux/BUILD.gn;l=64-80
// and the Linux Archive build
// Shared library dependencies that we already bundle.
const bundledDeps = [

View file

@ -46,6 +46,7 @@ exports.referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.18)(64bit)',
'libc.so.6(GLIBC_2.2.5)(64bit)',
'libc.so.6(GLIBC_2.25)(64bit)',
'libc.so.6(GLIBC_2.27)(64bit)',
'libc.so.6(GLIBC_2.28)(64bit)',
'libc.so.6(GLIBC_2.3)(64bit)',
'libc.so.6(GLIBC_2.3.2)(64bit)',
@ -140,6 +141,7 @@ exports.referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.17)',
'libc.so.6(GLIBC_2.18)',
'libc.so.6(GLIBC_2.25)',
'libc.so.6(GLIBC_2.27)',
'libc.so.6(GLIBC_2.28)',
'libc.so.6(GLIBC_2.4)',
'libc.so.6(GLIBC_2.6)',
@ -240,6 +242,7 @@ exports.referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.17)(64bit)',
'libc.so.6(GLIBC_2.18)(64bit)',
'libc.so.6(GLIBC_2.25)(64bit)',
'libc.so.6(GLIBC_2.27)(64bit)',
'libc.so.6(GLIBC_2.28)(64bit)',
'libcairo.so.2()(64bit)',
'libcurl.so.4()(64bit)',

View file

@ -45,6 +45,7 @@ export const referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.18)(64bit)',
'libc.so.6(GLIBC_2.2.5)(64bit)',
'libc.so.6(GLIBC_2.25)(64bit)',
'libc.so.6(GLIBC_2.27)(64bit)',
'libc.so.6(GLIBC_2.28)(64bit)',
'libc.so.6(GLIBC_2.3)(64bit)',
'libc.so.6(GLIBC_2.3.2)(64bit)',
@ -139,6 +140,7 @@ export const referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.17)',
'libc.so.6(GLIBC_2.18)',
'libc.so.6(GLIBC_2.25)',
'libc.so.6(GLIBC_2.27)',
'libc.so.6(GLIBC_2.28)',
'libc.so.6(GLIBC_2.4)',
'libc.so.6(GLIBC_2.6)',
@ -239,6 +241,7 @@ export const referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.17)(64bit)',
'libc.so.6(GLIBC_2.18)(64bit)',
'libc.so.6(GLIBC_2.25)(64bit)',
'libc.so.6(GLIBC_2.27)(64bit)',
'libc.so.6(GLIBC_2.28)(64bit)',
'libcairo.so.2()(64bit)',
'libcurl.so.4()(64bit)',

View file

@ -92,7 +92,7 @@ declare namespace monaco.editor {
#includeAll(vs/editor/standalone/browser/standaloneEditor;languages.Token=>Token):
#include(vs/editor/standalone/common/standaloneTheme): BuiltinTheme, IStandaloneThemeData, IColors
#include(vs/editor/common/languages/supports/tokenization): ITokenThemeRule
#include(vs/editor/standalone/browser/standaloneWebWorker): MonacoWebWorker, IWebWorkerOptions
#include(vs/editor/standalone/browser/standaloneWebWorker): MonacoWebWorker, IInternalWebWorkerOptions
#include(vs/editor/standalone/browser/standaloneCodeEditor): IActionDescriptor, IGlobalEditorOptions, IStandaloneEditorConstructionOptions, IStandaloneDiffEditorConstructionOptions, IStandaloneCodeEditor, IStandaloneDiffEditor
export interface ICommandHandler {
(...args: any[]): void;
@ -145,7 +145,7 @@ declare namespace monaco.languages {
declare namespace monaco.worker {
#include(vs/editor/common/model/mirrorTextModel): IMirrorTextModel
#includeAll(vs/editor/common/services/editorSimpleWorker;):
#includeAll(vs/editor/common/services/editorWebWorker;):
}

View file

@ -4,8 +4,7 @@
import { IObservable } from './vs/base/common/observable';
import { ServiceIdentifier } from './vs/platform/instantiation/common/instantiation';
import { create as create1 } from './vs/base/common/worker/simpleWorker';
import { create as create2 } from './vs/editor/common/services/editorSimpleWorker';
import { start } from './vs/editor/editor.worker.start';
import { SyncDescriptor0 } from './vs/platform/instantiation/common/descriptors';
import * as editorAPI from './vs/editor/editor.api';
@ -13,8 +12,7 @@ import * as editorAPI from './vs/editor/editor.api';
var a: any;
var b: any;
a = (<ServiceIdentifier<any>>b).type;
a = create1;
a = create2;
a = start;
// injection madness
a = (<SyncDescriptor0<any>>b).ctor;

View file

@ -85,7 +85,7 @@ function setNpmrcConfig(dir, env) {
// the correct clang variable. So keep the version check
// in preinstall sync with this logic.
// Change was first introduced in https://github.com/nodejs/node/commit/6e0a2bb54c5bbeff0e9e33e1a0c683ed980a8a0f
if (dir === 'remote' && process.platform === 'darwin') {
if ((dir === 'remote' || dir === 'build') && process.platform === 'darwin') {
env['npm_config_force_process_config'] = 'true';
} else {
delete env['npm_config_force_process_config'];

231
build/package-lock.json generated
View file

@ -57,13 +57,13 @@
"source-map": "0.6.1",
"ternary-stream": "^3.0.0",
"through2": "^4.0.2",
"tree-sitter": "^0.20.5",
"tree-sitter": "^0.22.4",
"vscode-universal-bundler": "^0.1.3",
"workerpool": "^6.4.0",
"yauzl": "^2.10.0"
},
"optionalDependencies": {
"tree-sitter-typescript": "^0.20.5",
"tree-sitter-typescript": "^0.23.2",
"vscode-gulp-watch": "^5.0.3"
}
},
@ -1551,7 +1551,7 @@
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "github",
@ -1580,7 +1580,8 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@ -1632,7 +1633,7 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "github",
@ -1647,6 +1648,7 @@
"url": "https://feross.org/support"
}
],
"optional": true,
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
@ -1821,7 +1823,8 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"devOptional": true
"dev": true,
"optional": true
},
"node_modules/clone": {
"version": "2.1.2",
@ -1991,7 +1994,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"devOptional": true,
"dev": true,
"dependencies": {
"mimic-response": "^3.1.0"
},
@ -2006,7 +2009,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=10"
},
@ -2018,7 +2021,8 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"devOptional": true,
"dev": true,
"optional": true,
"engines": {
"node": ">=4.0.0"
}
@ -2075,7 +2079,8 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
"integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
"devOptional": true,
"dev": true,
"optional": true,
"engines": {
"node": ">=8"
}
@ -2214,7 +2219,7 @@
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"devOptional": true,
"dev": true,
"dependencies": {
"once": "^1.4.0"
}
@ -2331,7 +2336,8 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"devOptional": true,
"dev": true,
"optional": true,
"engines": {
"node": ">=6"
}
@ -2471,7 +2477,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"devOptional": true
"dev": true,
"optional": true
},
"node_modules/fs-extra": {
"version": "8.1.0",
@ -2553,7 +2560,8 @@
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"devOptional": true
"dev": true,
"optional": true
},
"node_modules/glob": {
"version": "7.2.3",
@ -2867,7 +2875,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "github",
@ -2881,7 +2889,8 @@
"type": "consulting",
"url": "https://feross.org/support"
}
]
],
"optional": true
},
"node_modules/inflight": {
"version": "1.0.6",
@ -2904,7 +2913,8 @@
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"devOptional": true
"dev": true,
"optional": true
},
"node_modules/is-binary-path": {
"version": "2.1.0",
@ -3222,7 +3232,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"devOptional": true,
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
@ -3330,13 +3340,14 @@
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"devOptional": true
"dev": true
},
"node_modules/mkdirp-classic": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"devOptional": true
"dev": true,
"optional": true
},
"node_modules/ms": {
"version": "2.1.2",
@ -3350,23 +3361,19 @@
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
"dev": true
},
"node_modules/nan": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz",
"integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==",
"devOptional": true
},
"node_modules/napi-build-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
"devOptional": true
"dev": true,
"optional": true
},
"node_modules/node-abi": {
"version": "3.30.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz",
"integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"semver": "^7.3.5"
},
@ -3378,7 +3385,8 @@
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
@ -3402,6 +3410,18 @@
"dev": true,
"optional": true
},
"node_modules/node-gyp-build": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
"devOptional": true,
"license": "MIT",
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -3470,7 +3490,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"devOptional": true,
"dev": true,
"dependencies": {
"wrappy": "1"
}
@ -3646,7 +3666,8 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
"integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
@ -3700,7 +3721,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"devOptional": true,
"dev": true,
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@ -3737,7 +3758,8 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
@ -3950,27 +3972,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"devOptional": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/simple-get": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "github",
@ -3985,6 +3987,28 @@
"url": "https://feross.org/support"
}
],
"optional": true
},
"node_modules/simple-get": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"optional": true,
"dependencies": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
@ -4079,7 +4103,8 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo= sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"devOptional": true,
"dev": true,
"optional": true,
"engines": {
"node": ">=0.10.0"
}
@ -4119,7 +4144,8 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
@ -4131,7 +4157,8 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
@ -4211,25 +4238,86 @@
}
},
"node_modules/tree-sitter": {
"version": "0.20.6",
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.6.tgz",
"integrity": "sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg==",
"devOptional": true,
"version": "0.22.4",
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.4.tgz",
"integrity": "sha512-usbHZP9/oxNsUY65MQUsduGRqDHQOou1cagUSwjhoSYAmSahjQDAVsh9s+SlZkn8X8+O1FULRGwHu7AFP3kjzg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"nan": "^2.18.0",
"prebuild-install": "^7.1.1"
"node-addon-api": "^8.3.0",
"node-gyp-build": "^4.8.4"
}
},
"node_modules/tree-sitter-javascript": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/tree-sitter-javascript/-/tree-sitter-javascript-0.23.1.tgz",
"integrity": "sha512-/bnhbrTD9frUYHQTiYnPcxyHORIw157ERBa6dqzaKxvR/x3PC4Yzd+D1pZIMS6zNg2v3a8BZ0oK7jHqsQo9fWA==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"node-addon-api": "^8.2.2",
"node-gyp-build": "^4.8.2"
},
"peerDependencies": {
"tree-sitter": "^0.21.1"
},
"peerDependenciesMeta": {
"tree-sitter": {
"optional": true
}
}
},
"node_modules/tree-sitter-javascript/node_modules/node-addon-api": {
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz",
"integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==",
"license": "MIT",
"optional": true,
"engines": {
"node": "^18 || ^20 || >= 21"
}
},
"node_modules/tree-sitter-typescript": {
"version": "0.20.5",
"resolved": "https://registry.npmjs.org/tree-sitter-typescript/-/tree-sitter-typescript-0.20.5.tgz",
"integrity": "sha512-RzK/Pc6k4GiXvInIBlo8ZggekP6rODfW2P6KHFCTSUHENsw6ynh+iacFhfkJRa4MT8EIN2WHygFJ7076/+eHKg==",
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/tree-sitter-typescript/-/tree-sitter-typescript-0.23.2.tgz",
"integrity": "sha512-e04JUUKxTT53/x3Uq1zIL45DoYKVfHH4CZqwgZhPg5qYROl5nQjV+85ruFzFGZxu+QeFVbRTPDRnqL9UbU4VeA==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"nan": "^2.18.0",
"tree-sitter": "^0.20.6"
"node-addon-api": "^8.2.2",
"node-gyp-build": "^4.8.2",
"tree-sitter-javascript": "^0.23.1"
},
"peerDependencies": {
"tree-sitter": "^0.21.0"
},
"peerDependenciesMeta": {
"tree-sitter": {
"optional": true
}
}
},
"node_modules/tree-sitter-typescript/node_modules/node-addon-api": {
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz",
"integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==",
"license": "MIT",
"optional": true,
"engines": {
"node": "^18 || ^20 || >= 21"
}
},
"node_modules/tree-sitter/node_modules/node-addon-api": {
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz",
"integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18 || ^20 || >= 21"
}
},
"node_modules/tslib": {
@ -4251,7 +4339,8 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"devOptional": true,
"dev": true,
"optional": true,
"dependencies": {
"safe-buffer": "^5.0.1"
},
@ -4500,7 +4589,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"devOptional": true
"dev": true
},
"node_modules/xml2js": {
"version": "0.5.0",
@ -4546,7 +4635,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
"dev": true
},
"node_modules/yauzl": {
"version": "2.10.0",

View file

@ -51,7 +51,7 @@
"source-map": "0.6.1",
"ternary-stream": "^3.0.0",
"through2": "^4.0.2",
"tree-sitter": "^0.20.5",
"tree-sitter": "^0.22.4",
"vscode-universal-bundler": "^0.1.3",
"workerpool": "^6.4.0",
"yauzl": "^2.10.0"
@ -63,7 +63,7 @@
"npmCheckJs": "../node_modules/.bin/tsc --noEmit"
},
"optionalDependencies": {
"tree-sitter-typescript": "^0.20.5",
"tree-sitter-typescript": "^0.23.2",
"vscode-gulp-watch": "^5.0.3"
}
}

View file

@ -95,7 +95,7 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "inno_updater"
version = "0.12.1"
version = "0.14.2"
dependencies = [
"byteorder",
"crc",

View file

@ -1,6 +1,6 @@
[package]
name = "inno_updater"
version = "0.12.1"
version = "0.14.2"
authors = ["Microsoft <monacotools@microsoft.com>"]
build = "build.rs"

Some files were not shown because too many files have changed in this diff Show more