@microsoft/compose-language-service
Version:
Language service for Docker Compose documents
171 lines • 8.3 kB
JavaScript
;
/*!--------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.KeyHoverProvider = void 0;
const vscode_languageserver_1 = require("vscode-languageserver");
const ComposeDocument_1 = require("../ComposeDocument");
const ActionContext_1 = require("../utils/ActionContext");
const ProviderBase_1 = require("./ProviderBase");
class KeyHoverProvider extends ProviderBase_1.ProviderBase {
async on(params, token) {
var _a, _b, _c;
const ctx = (0, ActionContext_1.getCurrentContext)();
ctx.telemetry.groupingStrategy = 'eventName'; // The below `hoverMatch` property that is attached will be lossy, but that's not serious; at global scales it will still be representative of usage
const contentFormat = (_b = (_a = ctx.clientCapabilities.textDocument) === null || _a === void 0 ? void 0 : _a.hover) === null || _b === void 0 ? void 0 : _b.contentFormat;
const preferMarkdown = (contentFormat === null || contentFormat === void 0 ? void 0 : contentFormat.length) ? (contentFormat === null || contentFormat === void 0 ? void 0 : contentFormat[0]) === vscode_languageserver_1.MarkupKind.Markdown : false;
const positionInfo = await params.document.getPositionInfo(params);
for (const keyInfo of ComposeKeyInfo) {
const pathMatch = keyInfo.pathRegex.exec(positionInfo.path);
if (!pathMatch) {
continue;
}
const line = params.document.lineAt(params.position);
const lineMatch = ComposeDocument_1.KeyValueRegex.exec(line);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const pathKeyName = pathMatch.groups['keyName']; // Can't be undefined if it matched
const lineKeyName = (_c = lineMatch === null || lineMatch === void 0 ? void 0 : lineMatch.groups) === null || _c === void 0 ? void 0 : _c['keyName'];
// Need to ensure the key on the line is the same as the key in the path
// They can be different is because if you are in the whitespace before a key--the path will be in the parent key, but no hover should be provided here
if (lineKeyName === pathKeyName) {
const keyIndex = line.indexOf(lineKeyName);
// Attach the key name to telemetry
ctx.telemetry.properties.keyName = lineKeyName;
return {
contents: {
kind: preferMarkdown ? vscode_languageserver_1.MarkupKind.Markdown : vscode_languageserver_1.MarkupKind.PlainText,
value: (preferMarkdown && keyInfo.markdownContents) || keyInfo.plaintextContents,
},
range: vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(params.position.line, keyIndex), vscode_languageserver_1.Position.create(params.position.line, keyIndex + lineKeyName.length)),
};
}
}
return undefined;
}
}
exports.KeyHoverProvider = KeyHoverProvider;
const ComposeKeyInfo = [
{
pathRegex: /^\/(?<keyName>configs)$/i,
plaintextContents: 'Configurations for services in the project',
},
{
pathRegex: /^\/(?<keyName>networks)$/i,
plaintextContents: 'Networks that are shared among multiple services',
},
{
pathRegex: /^\/networks\/[.\w-]+\/(?<keyName>driver)$/i,
plaintextContents: 'The driver used for this network',
},
{
pathRegex: /^\/(?<keyName>secrets)$/i,
plaintextContents: 'Secrets that are shared among multiple services',
},
{
pathRegex: /^\/(?<keyName>services)$/i,
plaintextContents: 'The services in your project',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>build)$/i,
plaintextContents: 'The context used for building the image',
},
{
pathRegex: /^\/services\/[.\w-]+\/build\/(?<keyName>args)$/i,
plaintextContents: 'Arguments used during the image build process',
},
{
pathRegex: /^\/services\/[.\w-]+\/build\/(?<keyName>context)$/i,
plaintextContents: 'The context used for building the image',
},
{
pathRegex: /^\/services\/[.\w-]+\/build\/(?<keyName>dockerfile)$/i,
plaintextContents: 'The Dockerfile used for building the image',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>command)$/i,
plaintextContents: 'The command that will be run in the container',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>container_name)$/i,
plaintextContents: 'The name that will be given to the container',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>depends_on)$/i,
plaintextContents: 'Other services that this service depends on, which will be started before this one',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>entrypoint)$/i,
plaintextContents: 'The entrypoint to the application in the container',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>env_file)$/i,
plaintextContents: 'Files containing environment variables that will be included',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>environment)$/i,
plaintextContents: 'Environment variables that will be included',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>expose)$/i,
plaintextContents: 'Ports exposed to the other services but not to the host machine',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>healthcheck)$/i,
plaintextContents: 'A command for checking if the container is healthy',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>image)$/i,
plaintextContents: 'The image that will be pulled for the service. If `build` is specified, the built image will be given this tag.',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>labels)$/i,
plaintextContents: 'Labels that will be given to the container',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>logging)$/i,
plaintextContents: 'Settings for logging for this service',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>networks)$/i,
plaintextContents: 'The service will be included in these networks, allowing it to reach other containers on the same network',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>ports)$/i,
plaintextContents: 'Ports that will be exposed to the host',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>profiles)$/i,
plaintextContents: 'Profiles that this service is a part of. When the profile is started, this service will be started.',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>secrets)$/i,
plaintextContents: 'Secrets the service will have access to',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>user)$/i,
plaintextContents: 'The username under which the app in the container will be started',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>volumes)$/i,
plaintextContents: 'Named volumes and paths on the host mapped to paths in the container',
},
{
pathRegex: /^\/services\/[.\w-]+\/(?<keyName>working_dir)$/i,
plaintextContents: 'The working directory in which the entrypoint or command will be run',
},
{
pathRegex: /^\/(?<keyName>version)$/i,
plaintextContents: 'The version of the Docker Compose document',
},
{
pathRegex: /^\/(?<keyName>volumes)$/i,
plaintextContents: 'Named volumes that are shared among multiple services',
},
{
pathRegex: /^\/volumes\/[.\w-]+\/(?<keyName>driver)$/i,
plaintextContents: 'The driver used for this volume',
},
];
//# sourceMappingURL=KeyHoverProvider.js.map