Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compose grouping as default, add compose down/restart commands to group #2353

Merged
merged 10 commits into from
Sep 30, 2020
1 change: 1 addition & 0 deletions extension.bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ export { DockerImage } from './src/docker/Images';
export { DockerNetwork } from './src/docker/Networks';
export { DockerVolume } from './src/docker/Volumes';
export { CommandTemplate, selectCommandTemplate, defaultCommandTemplates } from './src/commands/selectCommandTemplate';
export { NonComposeGroupName } from './src/tree/containers/ContainersTreeItem';

export * from 'vscode-azureextensionui';
32 changes: 31 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
"onCommand:vscode-docker.containers.start",
"onCommand:vscode-docker.containers.stop",
"onCommand:vscode-docker.containers.viewLogs",
"onCommand:vscode-docker.containers.composeGroup.restart",
"onCommand:vscode-docker.containers.composeGroup.down",
"onCommand:vscode-docker.debugging.initializeForDebugging",
"onCommand:vscode-docker.help.reportIssue",
"onCommand:vscode-docker.images.build",
Expand Down Expand Up @@ -145,6 +147,14 @@
{
"command": "vscode-docker.registries.deployImageToAci",
"when": "vscode-docker:newCliPresent"
},
{
"command": "vscode-docker.containers.composeGroup.restart",
"when": "never"
},
{
"command": "vscode-docker.containers.composeGroup.down",
"when": "never"
}
],
"editor/context": [
Expand Down Expand Up @@ -374,6 +384,16 @@
"when": "view == dockerContainers && viewItem =~ /container$/i",
"group": "containers_2_destructive@1"
},
{
"command": "vscode-docker.containers.composeGroup.restart",
"when": "view == dockerContainers && viewItem =~ /composeGroup$/i && !vscode-docker:aciContext",
bwateratmsft marked this conversation as resolved.
Show resolved Hide resolved
"group": "composeGroup_1_destructive@1"
},
{
"command": "vscode-docker.containers.composeGroup.down",
"when": "view == dockerContainers && viewItem =~ /composeGroup$/i && !vscode-docker:aciContext",
"group": "composeGroup_1_destructive@2"
},
{
"command": "vscode-docker.images.run",
"when": "view == dockerImages && viewItem == image",
Expand Down Expand Up @@ -1741,7 +1761,7 @@
},
"docker.containers.groupBy": {
"type": "string",
"default": "None",
"default": "Compose Project Name",
"description": "%vscode-docker.config.docker.containers.groupBy%",
"enum": [
"Compose Project Name",
Expand Down Expand Up @@ -2286,6 +2306,16 @@
"title": "%vscode-docker.commands.containers.viewLogs%",
"category": "%vscode-docker.commands.category.dockerContainers%"
},
{
"command": "vscode-docker.containers.composeGroup.restart",
"title": "%vscode-docker.commands.containers.composeGroup.restart%",
"category": "%vscode-docker.commands.category.dockerContainers%"
},
{
"command": "vscode-docker.containers.composeGroup.down",
"title": "%vscode-docker.commands.containers.composeGroup.down%",
"category": "%vscode-docker.commands.category.dockerContainers%"
},
{
"command": "vscode-docker.debugging.initializeForDebugging",
"title": "%vscode-docker.commands.debugging.initializeForDebugging%",
Expand Down
2 changes: 2 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@
"vscode-docker.commands.containers.start": "Start",
"vscode-docker.commands.containers.stop": "Stop",
"vscode-docker.commands.containers.viewLogs": "View Logs",
"vscode-docker.commands.containers.composeGroup.restart": "Compose Restart",
bwateratmsft marked this conversation as resolved.
Show resolved Hide resolved
"vscode-docker.commands.containers.composeGroup.down": "Compose Down",
"vscode-docker.commands.debugging.initializeForDebugging": "Initialize for Docker debugging",
"vscode-docker.commands.help.reportIssue": "Report Issue",
"vscode-docker.commands.images.build": "Build Image...",
Expand Down
2 changes: 1 addition & 1 deletion src/commands/compose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export async function composeRestart(context: IActionContext, dockerComposeFileU
return await compose(context, ['down', 'up'], localize('vscode-docker.commands.compose.chooseRestart', 'Choose Docker Compose file to restart'), dockerComposeFileUri, selectedComposeFileUris);
}

async function rewriteCommandForNewCliIfNeeded(command: string): Promise<string> {
export async function rewriteCommandForNewCliIfNeeded(command: string): Promise<string> {
if ((await ext.dockerContextManager.getCurrentContext()).Type === 'aci') {
// Replace 'docker-compose ' at the start of a string with 'docker compose ', and '--build' anywhere with ''
return command.replace(/^docker-compose /, 'docker compose ').replace(/--build/, '');
Expand Down
45 changes: 45 additions & 0 deletions src/commands/containers/composeGroup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { IActionContext } from 'vscode-azureextensionui';
import { localize } from '../../localize';
import { ContainerGroupTreeItem } from '../../tree/containers/ContainerGroupTreeItem';
import { ContainerTreeItem } from '../../tree/containers/ContainerTreeItem';
import { executeAsTask } from '../../utils/executeAsTask';
import { rewriteCommandForNewCliIfNeeded } from '../compose';

export async function composeGroupRestart(context: IActionContext, node: ContainerGroupTreeItem): Promise<void> {
return composeGroup(context, 'restart', node);
}

export async function composeGroupDown(context: IActionContext, node: ContainerGroupTreeItem): Promise<void> {
return composeGroup(context, 'down', node);
}

async function composeGroup(context: IActionContext, composeCommand: 'restart' | 'down', node: ContainerGroupTreeItem): Promise<void> {
const workingDirectory = getComposeWorkingDirectory(node);
const filesArgument = getComposeFiles(node)?.map(f => `-f ${f}`)?.join(' ');
bwateratmsft marked this conversation as resolved.
Show resolved Hide resolved

if (!workingDirectory || !filesArgument) {
context.errorHandling.suppressReportIssue = true;
throw new Error(localize('vscode-docker.commands.containers.composeGroup.noCompose', 'Unable to determine compose project info for container group \'{0}\'.', node.label));
}

const terminalCommand = `docker-compose ${filesArgument} ${composeCommand}`;

await executeAsTask(context, await rewriteCommandForNewCliIfNeeded(terminalCommand), 'Docker Compose', { addDockerEnv: true, cwd: workingDirectory, });
}

function getComposeWorkingDirectory(node: ContainerGroupTreeItem): string | undefined {
// Find a container with the `com.docker.compose.project.working_dir` label, which gives the working directory in which to execute the compose command
const container = (node.ChildTreeItems as ContainerTreeItem[]).find(c => c.labels?.['com.docker.compose.project.working_dir']);
return container?.labels?.['com.docker.compose.project.working_dir'];
}

function getComposeFiles(node: ContainerGroupTreeItem): string[] | undefined {
// Find a container with the `com.docker.compose.project.config_files` label, which gives all the compose files (within the working directory) used to up this container
const container = (node.ChildTreeItems as ContainerTreeItem[]).find(c => c.labels?.['com.docker.compose.project.config_files']);
return container?.labels?.['com.docker.compose.project.config_files']?.split(',');
}
3 changes: 3 additions & 0 deletions src/commands/registerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { viewAzureTaskLogs } from "../utils/lazyLoad";
import { composeDown, composeRestart, composeUp } from "./compose";
import { attachShellContainer } from "./containers/attachShellContainer";
import { browseContainer } from "./containers/browseContainer";
import { composeGroupDown, composeGroupRestart } from "./containers/composeGroup";
import { configureContainersExplorer } from "./containers/configureContainersExplorer";
import { inspectContainer } from "./containers/inspectContainer";
import { pruneContainers } from "./containers/pruneContainers";
Expand Down Expand Up @@ -111,6 +112,8 @@ export function registerCommands(): void {
registerCommand('vscode-docker.containers.start', startContainer);
registerCommand('vscode-docker.containers.stop', stopContainer);
registerWorkspaceCommand('vscode-docker.containers.viewLogs', viewContainerLogs);
registerCommand('vscode-docker.containers.composeGroup.restart', composeGroupRestart);
registerCommand('vscode-docker.containers.composeGroup.down', composeGroupDown);

registerWorkspaceCommand('vscode-docker.images.build', buildImage);
registerCommand('vscode-docker.images.configureExplorer', configureImagesExplorer);
Expand Down
22 changes: 20 additions & 2 deletions src/tree/containers/ContainerGroupTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,36 @@
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { TreeItem, TreeItemCollapsibleState } from "vscode";
import { AzExtTreeItem } from "vscode-azureextensionui";
import { DockerContainer } from "../../docker/Containers";
import { getThemedIconPath, IconPath } from "../IconPath";
import { getImageGroupIcon } from "../images/ImageProperties";
import { LocalGroupTreeItemBase } from "../LocalGroupTreeItemBase";
import { LocalRootTreeItemBase } from "../LocalRootTreeItemBase";
import { ContainerProperty, getContainerStateIcon } from "./ContainerProperties";
import { NonComposeGroupName } from "./ContainersTreeItem";

export class ContainerGroupTreeItem extends LocalGroupTreeItemBase<DockerContainer, ContainerProperty> {
public static readonly contextValue: string = 'containerGroup';
public readonly contextValue: string = ContainerGroupTreeItem.contextValue;
public childTypeLabel: string = 'container';

public constructor(parent: LocalRootTreeItemBase<DockerContainer, ContainerProperty>, group: string, items: DockerContainer[]) {
super(parent, group, items);

if (this.parent.groupBySetting === 'Compose Project Name') {
// Expand compose group nodes by default
(this as TreeItem).collapsibleState = TreeItemCollapsibleState.Expanded;
}
}

public get contextValue(): string {
if (this.parent.groupBySetting === 'Compose Project Name' && this.group !== NonComposeGroupName) {
return 'containerGroup;composeGroup';
}

return 'containerGroup';
}

public get iconPath(): IconPath {
let icon: string;
switch (this.parent.groupBySetting) {
Expand Down
4 changes: 4 additions & 0 deletions src/tree/containers/ContainerTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export class ContainerTreeItem extends AzExtTreeItemIntermediate {
return this._item.Image;
}

public get labels(): { [key: string]: string } {
return this._item.Labels;
}

public get label(): string {
return ext.containersRoot.getTreeItemLabel(this._item);
}
Expand Down
4 changes: 4 additions & 0 deletions src/tree/containers/ContainersTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ export class ContainersTreeItem extends LocalRootTreeItemBase<DockerContainer, C
export const NonComposeGroupName = localize('vscode-docker.tree.containers.otherContainers', 'Other Containers');
bwateratmsft marked this conversation as resolved.
Show resolved Hide resolved

export function getComposeProjectName(container: DockerContainer): string {
if (!container.Labels) {
return NonComposeGroupName;
}

const labels = Object.keys(container.Labels)
.map(label => ({ label: label, value: container.Labels[label] }));

Expand Down
Loading