diff --git a/package.json b/package.json index dc8018c8..29054fab 100644 --- a/package.json +++ b/package.json @@ -1808,6 +1808,46 @@ "advanced" ] }, + "containers.commands.composeLogs": { + "oneOf": [ + { + "type": "array", + "items": { + "properties": { + "template": { + "type": "string", + "description": "%vscode-containers.config.template.composeLogs.template%" + }, + "label": { + "type": "string", + "description": "%vscode-containers.config.template.composeLogs.label%" + }, + "match": { + "type": "string", + "description": "%vscode-containers.config.template.composeLogs.match%" + } + }, + "required": [ + "label", + "template" + ] + } + }, + { + "type": "string" + } + ], + "default": [ + { + "label": "Compose Logs", + "template": "${composeCommand} ${configurationFile} ${projectName} logs --tail 1000 -f" + } + ], + "description": "%vscode-containers.config.template.composeLogs.description%", + "tags": [ + "advanced" + ] + }, "containers.commands.composeUp": { "oneOf": [ { diff --git a/package.nls.json b/package.nls.json index f1d431e0..7a9685bd 100644 --- a/package.nls.json +++ b/package.nls.json @@ -147,6 +147,10 @@ "vscode-containers.config.template.logs.label": "The label displayed to the user.", "vscode-containers.config.template.logs.match": "The regular expression for choosing the right template. Checked against container name, container's image name, etc.", "vscode-containers.config.template.logs.description": "Command templates for container logs commands.", + "vscode-containers.config.template.composeLogs.template": "The command template.", + "vscode-containers.config.template.composeLogs.label": "The label displayed to the user.", + "vscode-containers.config.template.composeLogs.match": "The regular expression for choosing the right template. Checked against compose YAML files, folder name, etc.", + "vscode-containers.config.template.composeLogs.description": "Command templates for compose logs commands.", "vscode-containers.config.template.composeUp.template": "The command template.", "vscode-containers.config.template.composeUp.label": "The label displayed to the user.", "vscode-containers.config.template.composeUp.match": "The regular expression for choosing the right template. Checked against compose YAML files, folder name, etc.", diff --git a/src/commands/containers/composeGroup.ts b/src/commands/containers/composeGroup.ts index 6aa86382..3280de29 100644 --- a/src/commands/containers/composeGroup.ts +++ b/src/commands/containers/composeGroup.ts @@ -6,15 +6,22 @@ import { IActionContext } from '@microsoft/vscode-azext-utils'; import { CommonOrchestratorCommandOptions, IContainerOrchestratorClient, LogsCommandOptions, VoidCommandResponse } from '@microsoft/vscode-container-client'; import * as path from 'path'; -import { l10n } from 'vscode'; +import { l10n, Uri, workspace } from 'vscode'; import { ext } from '../../extensionVariables'; import { TaskCommandRunnerFactory } from '../../runtimes/runners/TaskCommandRunnerFactory'; import { ContainerGroupTreeItem } from '../../tree/containers/ContainerGroupTreeItem'; import { ContainerTreeItem } from '../../tree/containers/ContainerTreeItem'; +import { selectComposeLogsCommand } from '../selectCommandTemplate'; export async function composeGroupLogs(context: IActionContext, node: ContainerGroupTreeItem): Promise { - // Since we're not interested in the output, we can pretend this is a `VoidCommandResponse` - return composeGroup(context, (client, options) => client.logs(options) as Promise, node, { follow: true, tail: 1000 }); + return composeGroup(context, (client, options) => { + const workingDirectory = getComposeWorkingDirectory(node); + let folder; + if (workingDirectory) { + folder = workspace.getWorkspaceFolder(Uri.file(workingDirectory)); + } + return selectComposeLogsCommand(context, folder, options.files?.join('" -f "'), options.projectName, options.environmentFile); + }, node, { follow: true, tail: 1000 }); } export async function composeGroupStart(context: IActionContext, node: ContainerGroupTreeItem): Promise { diff --git a/src/commands/selectCommandTemplate.ts b/src/commands/selectCommandTemplate.ts index df2c308d..9873f43b 100644 --- a/src/commands/selectCommandTemplate.ts +++ b/src/commands/selectCommandTemplate.ts @@ -12,7 +12,7 @@ import { ext } from '../extensionVariables'; import { isComposeV2ableOrchestratorClient } from '../runtimes/clients/AutoConfigurableDockerComposeClient'; import { resolveVariables } from '../utils/resolveVariables'; -type TemplateCommand = 'build' | 'run' | 'runInteractive' | 'attach' | 'logs' | 'composeUp' | 'composeDown' | 'composeUpSubset' | 'composeDownSubset'; +type TemplateCommand = 'build' | 'run' | 'runInteractive' | 'attach' | 'logs' | 'composeUp' | 'composeDown' | 'composeUpSubset' | 'composeDownSubset' | 'composeLogs'; type TemplatePicker = (items: IAzureQuickPickItem[], options: IAzureQuickPickOptions) => Promise>; @@ -78,6 +78,29 @@ export async function selectLogsCommand(context: IActionContext, containerName: ); } +export async function selectComposeLogsCommand(context: IActionContext, folder: vscode.WorkspaceFolder, configurationFile?: string, projectName?: string, envFile?: string): Promise { + const orchestratorClient = await ext.orchestratorManager.getClient(); + let fullComposeCommand: string; + if (isComposeV2ableOrchestratorClient(orchestratorClient) && orchestratorClient.composeV2) { + fullComposeCommand = `${orchestratorClient.commandName} compose`; + } else { + fullComposeCommand = orchestratorClient.commandName; + } + + return await selectCommandTemplate( + context, + 'composeLogs', + [folder.name, configurationFile], + folder, + { + 'configurationFile': configurationFile ? `-f "${configurationFile}"` : '', + 'projectName': projectName ? `-p "${projectName}"` : '', + 'environmentFile': envFile ? `--env-file "${envFile}"` : '', + 'composeCommand': fullComposeCommand + } + ); +} + export async function selectComposeCommand(context: IActionContext, folder: vscode.WorkspaceFolder, composeCommand: 'up' | 'down' | 'upSubset' | 'downSubset', configurationFile?: string, detached?: boolean, build?: boolean): Promise { let template: TemplateCommand;