diff --git a/build/hygiene.js b/build/hygiene.js index b95b4ee9824..a95c1ca3193 100644 --- a/build/hygiene.js +++ b/build/hygiene.js @@ -119,6 +119,7 @@ const copyrightFilter = [ '!resources/win32/bin/code.js', '!resources/web/code-web.js', '!resources/completions/**', + '!extensions/configuration-editing/build/inline-allOf.ts', '!extensions/markdown-language-features/media/highlight.css', '!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/*/server/bin/*', diff --git a/extensions/configuration-editing/.vscodeignore b/extensions/configuration-editing/.vscodeignore index de8e6dc5913..c5234c346a7 100644 --- a/extensions/configuration-editing/.vscodeignore +++ b/extensions/configuration-editing/.vscodeignore @@ -5,3 +5,5 @@ out/** extension.webpack.config.js extension-browser.webpack.config.js yarn.lock +build/** +schemas/*.schema.src.json diff --git a/extensions/configuration-editing/build/inline-allOf.ts b/extensions/configuration-editing/build/inline-allOf.ts new file mode 100755 index 00000000000..7da64fdddc5 --- /dev/null +++ b/extensions/configuration-editing/build/inline-allOf.ts @@ -0,0 +1,103 @@ +#!/usr/bin/env ts-node + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// Inlines "allOf"s to allow for "additionalProperties": false. (https://github.com/microsoft/vscode-remote-release/issues/2967) +// Run this manually after updating devContainer.schema.src.json. + +import * as fs from 'fs'; + +function transform(schema: any) { + + const definitions = Object.keys(schema.definitions) + .reduce((d, k) => { + d[`#/definitions/${k}`] = (schema.definitions as any)[k]; + return d; + }, {} as any); + + function copy(from: any) { + const type = Array.isArray(from) ? 'array' : typeof from; + switch (type) { + case 'object': { + const to: any = {}; + for (const key in from) { + switch (key) { + case 'definitions': + break; + case 'oneOf': + const list = copy(from[key]) + .reduce((a: any[], o: any) => { + if (o.oneOf) { + a.push(...o.oneOf); + } else { + a.push(o); + } + return a; + }, [] as any[]); + if (list.length === 1) { + Object.assign(to, list[0]); + } else { + to.oneOf = list; + } + break; + case 'allOf': + const all = copy(from[key]); + const leaves = all.map((one: any) => (one.oneOf ? one.oneOf : [one])); + function cross(res: any, leaves: any[][]): any[] { + if (leaves.length) { + const rest = leaves.slice(1); + return ([] as any[]).concat(...leaves[0].map(leaf => { + const intermediate = { ...res, ...leaf }; + if ('properties' in res && 'properties' in leaf) { + intermediate.properties = { + ...res.properties, + ...leaf.properties, + }; + } + return cross(intermediate, rest); + })); + } + return [res]; + } + const list2 = cross({}, leaves); + if (list2.length === 1) { + Object.assign(to, list2[0]); + } else { + to.oneOf = list2; + } + break; + case '$ref': + const ref = from[key]; + const definition = definitions[ref]; + if (definition) { + Object.assign(to, copy(definition)); + } else { + to[key] = ref; + } + break; + default: + to[key] = copy(from[key]); + break; + } + } + if (to.type === 'object' && !('additionalProperties' in to)) { + to.additionalProperties = false; + } + return to; + } + case 'array': { + return from.map(copy); + } + default: + return from; + } + } + + return copy(schema); +} + +const devContainer = JSON.parse(fs.readFileSync('../schemas/devContainer.schema.src.json', 'utf8')); +fs.writeFileSync('../schemas/devContainer.schema.generated.json', JSON.stringify(transform(devContainer), undefined, ' ')); diff --git a/extensions/configuration-editing/build/tsconfig.json b/extensions/configuration-editing/build/tsconfig.json new file mode 100644 index 00000000000..0ac2f0ded80 --- /dev/null +++ b/extensions/configuration-editing/build/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../shared.tsconfig.json", + "compilerOptions": { + "resolveJsonModule": true, + "outDir": "./out" + } +} diff --git a/extensions/configuration-editing/package.json b/extensions/configuration-editing/package.json index 3afe9fa4332..42340041320 100644 --- a/extensions/configuration-editing/package.json +++ b/extensions/configuration-editing/package.json @@ -111,11 +111,11 @@ }, { "fileMatch": "/.devcontainer/devcontainer.json", - "url": "./schemas/devContainer.schema.json" + "url": "./schemas/devContainer.schema.generated.json" }, { "fileMatch": "/.devcontainer.json", - "url": "./schemas/devContainer.schema.json" + "url": "./schemas/devContainer.schema.generated.json" }, { "fileMatch": "%APP_SETTINGS_HOME%/globalStorage/ms-vscode-remote.remote-containers/nameConfigs/*.json", diff --git a/extensions/configuration-editing/schemas/devContainer.schema.generated.json b/extensions/configuration-editing/schemas/devContainer.schema.generated.json new file mode 100644 index 00000000000..8cdf40090d6 --- /dev/null +++ b/extensions/configuration-editing/schemas/devContainer.schema.generated.json @@ -0,0 +1,832 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Defines a dev container", + "allowComments": true, + "allowTrailingCommas": true, + "oneOf": [ + { + "type": "object", + "properties": { + "build": { + "type": "object", + "description": "Docker build-related options.", + "properties": { + "dockerfile": { + "type": "string", + "description": "The location of the Dockerfile that defines the contents of the container. The path is relative to the folder containing the `devcontainer.json` file." + }, + "context": { + "type": "string", + "description": "The location of the context folder for building the Docker image. The path is relative to the folder containing the `devcontainer.json` file." + }, + "target": { + "type": "string", + "description": "Target stage in a multi-stage build." + }, + "args": { + "type": "object", + "additionalProperties": { + "type": [ + "string" + ] + }, + "description": "Build arguments." + } + }, + "required": [ + "dockerfile" + ], + "additionalProperties": false + }, + "appPort": { + "type": [ + "integer", + "string", + "array" + ], + "description": "Application ports that are exposed by the container. This can be a single port or an array of ports. Each port can be a number or a string. A number is mapped to the same port on the host. A string is passed to Docker unchanged and can be used to map ports differently, e.g. \"8000:8010\".", + "items": { + "type": [ + "integer", + "string" + ] + } + }, + "containerEnv": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Container environment variables." + }, + "containerUser": { + "type": "string", + "description": "The user the container will be started with. The default is the user on the Docker image." + }, + "updateRemoteUserUID": { + "type": "boolean", + "description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default." + }, + "mounts": { + "type": "array", + "description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.", + "items": { + "type": "string" + } + }, + "runArgs": { + "type": "array", + "description": "The arguments required when starting in the container.", + "items": { + "type": "string" + } + }, + "shutdownAction": { + "type": "string", + "enum": [ + "none", + "stopContainer" + ], + "description": "Action to take when the VS Code window is closed. The default is to stop the container." + }, + "overrideCommand": { + "type": "boolean", + "description": "Whether to overwrite the command specified in the image. The default is true." + }, + "workspaceFolder": { + "type": "string", + "description": "The path of the workspace folder inside the container." + }, + "workspaceMount": { + "type": "string", + "description": "The --mount parameter for docker run. The default is to mount the project folder at /workspaces/$project." + }, + "name": { + "type": "string", + "description": "A name to show for the workspace folder." + }, + "extensions": { + "type": "array", + "description": "An array of extensions that should be installed into the container.", + "items": { + "type": "string", + "pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$", + "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." + } + }, + "settings": { + "$ref": "vscode://schemas/settings/machine", + "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again." + }, + "forwardPorts": { + "type": "array", + "description": "Ports that are forwarded from the container to the local machine.", + "items": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + } + }, + "remoteEnv": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "description": "Remote environment variables. If these are used in the Integrated Terminal, make sure the 'Terminal > Integrated: Inherit Env' setting is enabled." + }, + "remoteUser": { + "type": "string", + "description": "The user VS Code Server will be started with. The default is the same user as the container." + }, + "initializeCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postCreateCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postStartCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postAttachCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "devPort": { + "type": "integer", + "description": "The port VS Code can use to connect to its backend." + }, + "userEnvProbe": { + "type": "string", + "enum": [ + "none", + "loginShell", + "loginInteractiveShell", + "interactiveShell" + ], + "description": "User environment probe to run. The default is none." + }, + "codespaces": { + "type": "object", + "additionalProperties": true, + "description": "Codespaces-specific configuration." + } + }, + "required": [ + "build" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "dockerFile": { + "type": "string", + "description": "The location of the Dockerfile that defines the contents of the container. The path is relative to the folder containing the `devcontainer.json` file." + }, + "context": { + "type": "string", + "description": "The location of the context folder for building the Docker image. The path is relative to the folder containing the `devcontainer.json` file." + }, + "build": { + "description": "Docker build-related options.", + "type": "object", + "properties": { + "target": { + "type": "string", + "description": "Target stage in a multi-stage build." + }, + "args": { + "type": "object", + "additionalProperties": { + "type": [ + "string" + ] + }, + "description": "Build arguments." + } + }, + "additionalProperties": false + }, + "appPort": { + "type": [ + "integer", + "string", + "array" + ], + "description": "Application ports that are exposed by the container. This can be a single port or an array of ports. Each port can be a number or a string. A number is mapped to the same port on the host. A string is passed to Docker unchanged and can be used to map ports differently, e.g. \"8000:8010\".", + "items": { + "type": [ + "integer", + "string" + ] + } + }, + "containerEnv": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Container environment variables." + }, + "containerUser": { + "type": "string", + "description": "The user the container will be started with. The default is the user on the Docker image." + }, + "updateRemoteUserUID": { + "type": "boolean", + "description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default." + }, + "mounts": { + "type": "array", + "description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.", + "items": { + "type": "string" + } + }, + "runArgs": { + "type": "array", + "description": "The arguments required when starting in the container.", + "items": { + "type": "string" + } + }, + "shutdownAction": { + "type": "string", + "enum": [ + "none", + "stopContainer" + ], + "description": "Action to take when the VS Code window is closed. The default is to stop the container." + }, + "overrideCommand": { + "type": "boolean", + "description": "Whether to overwrite the command specified in the image. The default is true." + }, + "workspaceFolder": { + "type": "string", + "description": "The path of the workspace folder inside the container." + }, + "workspaceMount": { + "type": "string", + "description": "The --mount parameter for docker run. The default is to mount the project folder at /workspaces/$project." + }, + "name": { + "type": "string", + "description": "A name to show for the workspace folder." + }, + "extensions": { + "type": "array", + "description": "An array of extensions that should be installed into the container.", + "items": { + "type": "string", + "pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$", + "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." + } + }, + "settings": { + "$ref": "vscode://schemas/settings/machine", + "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again." + }, + "forwardPorts": { + "type": "array", + "description": "Ports that are forwarded from the container to the local machine.", + "items": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + } + }, + "remoteEnv": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "description": "Remote environment variables. If these are used in the Integrated Terminal, make sure the 'Terminal > Integrated: Inherit Env' setting is enabled." + }, + "remoteUser": { + "type": "string", + "description": "The user VS Code Server will be started with. The default is the same user as the container." + }, + "initializeCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postCreateCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postStartCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postAttachCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "devPort": { + "type": "integer", + "description": "The port VS Code can use to connect to its backend." + }, + "userEnvProbe": { + "type": "string", + "enum": [ + "none", + "loginShell", + "loginInteractiveShell", + "interactiveShell" + ], + "description": "User environment probe to run. The default is none." + }, + "codespaces": { + "type": "object", + "additionalProperties": true, + "description": "Codespaces-specific configuration." + } + }, + "required": [ + "dockerFile" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "image": { + "type": "string", + "description": "The docker image that will be used to create the container." + }, + "appPort": { + "type": [ + "integer", + "string", + "array" + ], + "description": "Application ports that are exposed by the container. This can be a single port or an array of ports. Each port can be a number or a string. A number is mapped to the same port on the host. A string is passed to Docker unchanged and can be used to map ports differently, e.g. \"8000:8010\".", + "items": { + "type": [ + "integer", + "string" + ] + } + }, + "containerEnv": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Container environment variables." + }, + "containerUser": { + "type": "string", + "description": "The user the container will be started with. The default is the user on the Docker image." + }, + "updateRemoteUserUID": { + "type": "boolean", + "description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default." + }, + "mounts": { + "type": "array", + "description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.", + "items": { + "type": "string" + } + }, + "runArgs": { + "type": "array", + "description": "The arguments required when starting in the container.", + "items": { + "type": "string" + } + }, + "shutdownAction": { + "type": "string", + "enum": [ + "none", + "stopContainer" + ], + "description": "Action to take when the VS Code window is closed. The default is to stop the container." + }, + "overrideCommand": { + "type": "boolean", + "description": "Whether to overwrite the command specified in the image. The default is true." + }, + "workspaceFolder": { + "type": "string", + "description": "The path of the workspace folder inside the container." + }, + "workspaceMount": { + "type": "string", + "description": "The --mount parameter for docker run. The default is to mount the project folder at /workspaces/$project." + }, + "name": { + "type": "string", + "description": "A name to show for the workspace folder." + }, + "extensions": { + "type": "array", + "description": "An array of extensions that should be installed into the container.", + "items": { + "type": "string", + "pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$", + "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." + } + }, + "settings": { + "$ref": "vscode://schemas/settings/machine", + "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again." + }, + "forwardPorts": { + "type": "array", + "description": "Ports that are forwarded from the container to the local machine.", + "items": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + } + }, + "remoteEnv": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "description": "Remote environment variables. If these are used in the Integrated Terminal, make sure the 'Terminal > Integrated: Inherit Env' setting is enabled." + }, + "remoteUser": { + "type": "string", + "description": "The user VS Code Server will be started with. The default is the same user as the container." + }, + "initializeCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postCreateCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postStartCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postAttachCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "devPort": { + "type": "integer", + "description": "The port VS Code can use to connect to its backend." + }, + "userEnvProbe": { + "type": "string", + "enum": [ + "none", + "loginShell", + "loginInteractiveShell", + "interactiveShell" + ], + "description": "User environment probe to run. The default is none." + }, + "codespaces": { + "type": "object", + "additionalProperties": true, + "description": "Codespaces-specific configuration." + } + }, + "required": [ + "image" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "dockerComposeFile": { + "type": [ + "string", + "array" + ], + "description": "The name of the docker-compose file(s) used to start the services.", + "items": { + "type": "string" + } + }, + "service": { + "type": "string", + "description": "The service you want to work on." + }, + "runServices": { + "type": "array", + "description": "An array of services that should be started and stopped.", + "items": { + "type": "string" + } + }, + "workspaceFolder": { + "type": "string", + "description": "The path of the workspace folder inside the container. This is typically the target path of a volume mount in the docker-compose.yml." + }, + "shutdownAction": { + "type": "string", + "enum": [ + "none", + "stopCompose" + ], + "description": "Action to take when the VS Code window is closed. The default is to stop the containers." + }, + "name": { + "type": "string", + "description": "A name to show for the workspace folder." + }, + "extensions": { + "type": "array", + "description": "An array of extensions that should be installed into the container.", + "items": { + "type": "string", + "pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$", + "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." + } + }, + "settings": { + "$ref": "vscode://schemas/settings/machine", + "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again." + }, + "forwardPorts": { + "type": "array", + "description": "Ports that are forwarded from the container to the local machine.", + "items": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + } + }, + "remoteEnv": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "description": "Remote environment variables. If these are used in the Integrated Terminal, make sure the 'Terminal > Integrated: Inherit Env' setting is enabled." + }, + "remoteUser": { + "type": "string", + "description": "The user VS Code Server will be started with. The default is the same user as the container." + }, + "initializeCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postCreateCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postStartCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postAttachCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "devPort": { + "type": "integer", + "description": "The port VS Code can use to connect to its backend." + }, + "userEnvProbe": { + "type": "string", + "enum": [ + "none", + "loginShell", + "loginInteractiveShell", + "interactiveShell" + ], + "description": "User environment probe to run. The default is none." + }, + "codespaces": { + "type": "object", + "additionalProperties": true, + "description": "Codespaces-specific configuration." + } + }, + "required": [ + "dockerComposeFile", + "service", + "workspaceFolder" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "A name to show for the workspace folder." + }, + "extensions": { + "type": "array", + "description": "An array of extensions that should be installed into the container.", + "items": { + "type": "string", + "pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$", + "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." + } + }, + "settings": { + "$ref": "vscode://schemas/settings/machine", + "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again." + }, + "forwardPorts": { + "type": "array", + "description": "Ports that are forwarded from the container to the local machine.", + "items": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + } + }, + "remoteEnv": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "description": "Remote environment variables. If these are used in the Integrated Terminal, make sure the 'Terminal > Integrated: Inherit Env' setting is enabled." + }, + "remoteUser": { + "type": "string", + "description": "The user VS Code Server will be started with. The default is the same user as the container." + }, + "initializeCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postCreateCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postStartCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "postAttachCommand": { + "type": [ + "string", + "array" + ], + "description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", + "items": { + "type": "string" + } + }, + "devPort": { + "type": "integer", + "description": "The port VS Code can use to connect to its backend." + }, + "userEnvProbe": { + "type": "string", + "enum": [ + "none", + "loginShell", + "loginInteractiveShell", + "interactiveShell" + ], + "description": "User environment probe to run. The default is none." + }, + "codespaces": { + "type": "object", + "additionalProperties": true, + "description": "Codespaces-specific configuration." + } + }, + "additionalProperties": false + } + ] +} \ No newline at end of file diff --git a/extensions/configuration-editing/schemas/devContainer.schema.json b/extensions/configuration-editing/schemas/devContainer.schema.src.json similarity index 99% rename from extensions/configuration-editing/schemas/devContainer.schema.json rename to extensions/configuration-editing/schemas/devContainer.schema.src.json index 0395a1b3751..ba140ba9431 100644 --- a/extensions/configuration-editing/schemas/devContainer.schema.json +++ b/extensions/configuration-editing/schemas/devContainer.schema.src.json @@ -3,7 +3,6 @@ "description": "Defines a dev container", "allowComments": true, "allowTrailingCommas": true, - "type": "object", "definitions": { "devContainerCommon": { "type": "object", @@ -104,6 +103,7 @@ }, "codespaces": { "type": "object", + "additionalProperties": true, "description": "Codespaces-specific configuration." } }