Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Commit

Permalink
Use component for task configuration instead of container name
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Nikitenko <[email protected]>
  • Loading branch information
RomanNikitenko committed Oct 24, 2019
1 parent 0b5cdb1 commit 9341d4f
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 43 deletions.
2 changes: 1 addition & 1 deletion plugins/task-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The format of a Che task is the following:
"command": "",
"target": {
"workspaceId": "",
"containerName": "",
"component": "",
"workingDir": ""
},
"previewUrl": ""
Expand Down
2 changes: 2 additions & 0 deletions plugins/task-plugin/src/che-task-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ConfigFileTasksExtractor } from './extract/config-file-task-configs-ext
import { VsCodeLaunchConfigsExtractor } from './extract/vscode-launch-configs-extractor';
import { VsCodeTaskConfigsExtractor } from './extract/vscode-task-configs-extractor';
import { PreviewUrlVariableResolver } from './variable/preview-url-variable-resolver';
import { BackwardCompatibilityResolver } from './task/backward-compatibility';

const container = new Container();
container.bind(CheTaskProvider).toSelf().inSingletonScope();
Expand All @@ -54,6 +55,7 @@ container.bind(ConfigFileTasksExtractor).toSelf().inSingletonScope();
container.bind(ConfigFileLaunchConfigsExtractor).toSelf().inSingletonScope();
container.bind(VsCodeLaunchConfigsExtractor).toSelf().inSingletonScope();
container.bind(VsCodeTaskConfigsExtractor).toSelf().inSingletonScope();
container.bind(BackwardCompatibilityResolver).toSelf().inSingletonScope();

container.bind(PreviewUrlsWidget).toSelf().inTransientScope();
container.bind(PreviewUrlsWidgetFactory).toDynamicValue(ctx => ({
Expand Down
16 changes: 16 additions & 0 deletions plugins/task-plugin/src/che-workspace-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@ export class CheWorkspaceClient {
return workspace.links;
}

async getContainersNames(): Promise<string[]> {
const containerNames: string[] = [];

try {
const containers = await this.getMachines();
for (const containerName in containers) {
if (containers.hasOwnProperty(containerName)) {
containerNames.push(containerName);
}
}
} catch (error) {
} finally {
return containerNames;
}
}

async getMachines(): Promise<{ [attrName: string]: cheApi.workspace.Machine }> {
const workspace = await this.getCurrentWorkspace();
const runtime = workspace.runtime;
Expand Down
2 changes: 1 addition & 1 deletion plugins/task-plugin/src/export/export-configs-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface ConfigurationsExporter {
* @param workspaceFolder workspace folder for exporting configs in the config file
* @param commands commands with configurations for export
*/
export(workspaceFolder: theia.WorkspaceFolder, commands: cheApi.workspace.Command[]): void;
export(workspaceFolder: theia.WorkspaceFolder, commands: cheApi.workspace.Command[]): Promise<void>;
}
/** Contains configurations as array of object and as raw content and is used at getting configurations from config file for example */
export interface Configurations<T> {
Expand Down
2 changes: 1 addition & 1 deletion plugins/task-plugin/src/export/launch-configs-exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class LaunchConfigurationsExporter implements ConfigurationsExporter {
@inject(VsCodeLaunchConfigsExtractor)
protected readonly vsCodeLaunchConfigsExtractor: VsCodeLaunchConfigsExtractor;

export(workspaceFolder: theia.WorkspaceFolder, commands: cheApi.workspace.Command[]): void {
async export(workspaceFolder: theia.WorkspaceFolder, commands: cheApi.workspace.Command[]): Promise<void> {
const launchConfigFileUri = this.getConfigFileUri(workspaceFolder.uri.path);
const configFileConfigs = this.configFileLaunchConfigsExtractor.extract(launchConfigFileUri);
const vsCodeConfigs = this.vsCodeLaunchConfigsExtractor.extract(commands);
Expand Down
9 changes: 7 additions & 2 deletions plugins/task-plugin/src/export/task-configs-exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { CheTaskConfigsExtractor } from '../extract/che-task-configs-extractor';
import { VsCodeTaskConfigsExtractor } from '../extract/vscode-task-configs-extractor';
import { ConfigurationsExporter } from './export-configs-manager';
import { ConfigFileTasksExtractor } from '../extract/config-file-task-configs-extractor';
import { BackwardCompatibilityResolver } from '../task/backward-compatibility';

const CONFIG_DIR = '.theia';
const TASK_CONFIG_FILE = 'tasks.json';
Expand All @@ -39,17 +40,21 @@ export class TaskConfigurationsExporter implements ConfigurationsExporter {
@inject(VsCodeTaskConfigsExtractor)
protected readonly vsCodeTaskConfigsExtractor: VsCodeTaskConfigsExtractor;

export(workspaceFolder: theia.WorkspaceFolder, commands: cheApi.workspace.Command[]): void {
@inject(BackwardCompatibilityResolver)
protected readonly backwardCompatibilityResolver: BackwardCompatibilityResolver;

async export(workspaceFolder: theia.WorkspaceFolder, commands: cheApi.workspace.Command[]): Promise<void> {
const tasksConfigFileUri = this.getConfigFileUri(workspaceFolder.uri.path);
const configFileTasks = this.configFileTasksExtractor.extract(tasksConfigFileUri);

const cheTasks = this.cheTaskConfigsExtractor.extract(commands);
const vsCodeTasks = this.vsCodeTaskConfigsExtractor.extract(commands);
const devfileConfigs = this.merge(cheTasks, vsCodeTasks.configs, this.getOutputChannelConflictLogger());
const configFileConfigs = await this.backwardCompatibilityResolver.resolveComponent(configFileTasks.configs);

const configFileContent = configFileTasks.content;
if (configFileContent) {
this.saveConfigs(tasksConfigFileUri, configFileContent, this.merge(configFileTasks.configs, devfileConfigs, this.getConsoleConflictLogger()));
this.saveConfigs(tasksConfigFileUri, configFileContent, this.merge(configFileConfigs, devfileConfigs, this.getConsoleConflictLogger()));
return;
}

Expand Down
32 changes: 7 additions & 25 deletions plugins/task-plugin/src/machine/machines-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { injectable, inject } from 'inversify';
import * as theia from '@theia/plugin';
import { CheWorkspaceClient } from '../che-workspace-client';

const MACHINES_PLACE_HOLDER = 'Pick a machine to run the task';
const MACHINES_PLACE_HOLDER = 'Pick a container to run the task';

@injectable()
export class MachinesPicker {
Expand All @@ -24,33 +24,15 @@ export class MachinesPicker {
* Returns a machine name if there's just one machine in the current workspace.
* Shows a quick open widget allows to pick a machine if there are several ones.
*/
async pick(): Promise<string> {
const machines = await this.getMachines();
if (machines.length === 1) {
return Promise.resolve(machines[0]);
async pick(containerNames?: string[]): Promise<string> {
if (!containerNames) {
containerNames = await this.cheWorkspaceClient.getContainersNames();
}

const items: string[] = [];
for (const machineName of machines) {
items.push(machineName);
if (containerNames.length === 1) {
return Promise.resolve(containerNames[0]);
}

return this.showMachineQuickPick(items);
}

protected async getMachines(): Promise<string[]> {
const machineNames: string[] = [];
const machines = await this.cheWorkspaceClient.getMachines();
if (!machines) {
return machineNames;
}

for (const machineName in machines) {
if (machines.hasOwnProperty(machineName)) {
machineNames.push(machineName);
}
}
return machineNames;
return this.showMachineQuickPick(containerNames);
}

private showMachineQuickPick(items: string[]): Promise<string> {
Expand Down
56 changes: 56 additions & 0 deletions plugins/task-plugin/src/task/backward-compatibility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*********************************************************************
* Copyright (c) 2019 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { injectable, inject } from 'inversify';
import * as che from '@eclipse-che/plugin';
import { CHE_TASK_TYPE, COMPONENT_ATTRIBUTE } from './task-protocol';
import { CheWorkspaceClient } from '../che-workspace-client';
import { getAttribute } from '../utils';

/** Contains logic to provide backward compatibility. */
@injectable()
export class BackwardCompatibilityResolver {

@inject(CheWorkspaceClient)
protected readonly cheWorkspaceClient!: CheWorkspaceClient;

async resolveComponent(configs: che.TaskConfiguration[]): Promise<che.TaskConfiguration[]> {
if (configs.length === 0) {
return configs;
}

const containers = await this.cheWorkspaceClient.getMachines();
for (const config of configs) {
if (config.type !== CHE_TASK_TYPE) {
continue;
}

const target = config.target;
if (!target || !target.containerName) {
continue;
}

const containerName = target.containerName;
target.containerName = undefined;
target.component = '';

if (!containers.hasOwnProperty(containerName)) {
continue;
}

const container = containers[containerName];
const component = getAttribute(COMPONENT_ATTRIBUTE, container.attributes);
if (component) {
target.component = component;
}
}
return configs;
}
}
47 changes: 41 additions & 6 deletions plugins/task-plugin/src/task/che-task-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
import { injectable, inject } from 'inversify';
import * as che from '@eclipse-che/plugin';
import { Task, ShellExecution } from '@theia/plugin';
import { CHE_TASK_TYPE, CheTaskDefinition, Target } from './task-protocol';
import { CHE_TASK_TYPE, CheTaskDefinition, Target, COMPONENT_ATTRIBUTE } from './task-protocol';
import { MachinesPicker } from '../machine/machines-picker';
import { CheWorkspaceClient } from '../che-workspace-client';
import { getAttribute } from '../utils';

/** Reads the commands from the current Che workspace and provides it as Task Configurations. */
@injectable()
Expand Down Expand Up @@ -45,11 +46,7 @@ export class CheTaskProvider {
resultTarget.workspaceId = await this.cheWorkspaceClient.getWorkspaceId();
}

if (target && target.containerName) {
resultTarget.containerName = target.containerName;
} else {
resultTarget.containerName = await this.machinePicker.pick();
}
resultTarget.containerName = await this.getContainerName(target);

if (target && target.workingDir) {
resultTarget.workingDir = await che.variables.resolve(target.workingDir);
Expand All @@ -71,4 +68,42 @@ export class CheTaskProvider {
execution: execution
};
}

private async getContainerName(target?: Target): Promise<string> {
if (!target) {
return await this.machinePicker.pick();
}

const containers = await this.cheWorkspaceClient.getMachines();

const targetContainerName = target.containerName;
if (targetContainerName && containers.hasOwnProperty(targetContainerName)) {
return targetContainerName;
}

const targetComponent = target.component;
if (targetComponent) {
const names = [];
for (const containerName in containers) {
if (!containers.hasOwnProperty(containerName)) {
continue;
}

const container = containers[containerName];
const component = getAttribute(COMPONENT_ATTRIBUTE, container.attributes);
if (component && component === targetComponent) {
names.push(containerName);
}
}

if (names.length === 1) {
return names[0];
}

if (names.length > 1) {
return await this.machinePicker.pick(names);
}
}
return await this.machinePicker.pick();
}
}
15 changes: 8 additions & 7 deletions plugins/task-plugin/src/task/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
import { che as cheApi } from '@eclipse-che/api';
import { Task } from '@theia/plugin';
import { TaskConfiguration } from '@eclipse-che/plugin';
import { CHE_TASK_TYPE, MACHINE_NAME_ATTRIBUTE, PREVIEW_URL_ATTRIBUTE, WORKING_DIR_ATTRIBUTE } from './task-protocol';
import { CHE_TASK_TYPE, PREVIEW_URL_ATTRIBUTE, WORKING_DIR_ATTRIBUTE, COMPONENT_ALIAS_ATTRIBUTE } from './task-protocol';
import { getAttribute } from '../utils';

/** Converts the Che command to Theia Task Configuration */
export function toTaskConfiguration(command: cheApi.workspace.Command): TaskConfiguration {
Expand All @@ -21,10 +22,10 @@ export function toTaskConfiguration(command: cheApi.workspace.Command): TaskConf
command: command.commandLine,
_scope: undefined, // not to put into tasks.json
target: {
workingDir: getCommandAttribute(command, WORKING_DIR_ATTRIBUTE),
containerName: getCommandAttribute(command, MACHINE_NAME_ATTRIBUTE)
workingDir: getAttribute(WORKING_DIR_ATTRIBUTE, command.attributes),
component: getAttribute(COMPONENT_ALIAS_ATTRIBUTE, command.attributes)
},
previewUrl: getCommandAttribute(command, PREVIEW_URL_ATTRIBUTE)
previewUrl: getAttribute(PREVIEW_URL_ATTRIBUTE, command.attributes)
};

return taskConfig;
Expand All @@ -37,10 +38,10 @@ export function toTask(command: cheApi.workspace.Command): Task {
type: CHE_TASK_TYPE,
command: command.commandLine,
target: {
workingDir: getCommandAttribute(command, WORKING_DIR_ATTRIBUTE),
containerName: getCommandAttribute(command, MACHINE_NAME_ATTRIBUTE)
workingDir: getAttribute(WORKING_DIR_ATTRIBUTE, command.attributes),
component: getAttribute(COMPONENT_ALIAS_ATTRIBUTE, command.attributes)
},
previewUrl: getCommandAttribute(command, PREVIEW_URL_ATTRIBUTE)
previewUrl: getAttribute(PREVIEW_URL_ATTRIBUTE, command.attributes)
},
name: `${command.name}`,
source: CHE_TASK_TYPE,
Expand Down
3 changes: 3 additions & 0 deletions plugins/task-plugin/src/task/task-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const CHE_TASK_TYPE: string = 'che';
export const MACHINE_NAME_ATTRIBUTE: string = 'machineName';
export const PREVIEW_URL_ATTRIBUTE: string = 'previewUrl';
export const WORKING_DIR_ATTRIBUTE: string = 'workingDir';
export const COMPONENT_ATTRIBUTE: string = 'component';
export const COMPONENT_ALIAS_ATTRIBUTE: string = 'componentAlias';

export interface CheTaskDefinition extends TaskDefinition {
readonly target?: Target,
Expand All @@ -24,4 +26,5 @@ export interface Target {
workspaceId?: string,
containerName?: string,
workingDir?: string
component?: string,
}
14 changes: 14 additions & 0 deletions plugins/task-plugin/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ import { FormattingOptions, ParseError, JSONPath } from 'jsonc-parser';

const fs = require('fs');

/** Allows to get attribute by given name, returns `undefined` if attribute is not found */
export function getAttribute(attributeName: string, attributes?: { [key: string]: string; }): string | undefined {
if (!attributes) {
return undefined;
}

for (const attribute in attributes) {
if (attribute === attributeName) {
return attributes[attribute];
}
}
return undefined;
}

/**
* Apply segments to the url endpoint, where are:
* @param endPointUrl - url endpoint, for example 'http://ws:/some-server/api'
Expand Down

0 comments on commit 9341d4f

Please sign in to comment.