Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mmorhun committed Jun 6, 2019
1 parent c1291e4 commit d2098c2
Show file tree
Hide file tree
Showing 10 changed files with 1,644 additions and 11 deletions.
17 changes: 16 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
],
"devDependencies": {
"@theia/plugin": "next",
"@eclipse-che/plugin": "latest",
"@theia/plugin-packager": "latest",
"rimraf": "2.6.2",
"typescript-formatter": "7.2.2",
Expand All @@ -31,6 +32,20 @@
"theiaPlugin": "next"
},
"theiaPlugin": {
"backend": "lib/che-theia-git-ui-tools-backend.js"
"backend": "lib/che-theia-git-ui-tools.js"
},
"contributes": {
"viewsContainers": {
"left": [
{
"id": "git-ui-tools",
"title": "Git UI Tools",
"icon": {
"light": "resources/light/Git-Icon-Black.svg",
"dark": "resources/dark/Git-Icon-White.svg"
}
}
]
}
}
}
18 changes: 18 additions & 0 deletions resources/dark/Git-Icon-Black.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions resources/light/Git-Icon-White.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 0 additions & 10 deletions src/che-theia-git-ui-tools-backend.ts

This file was deleted.

51 changes: 51 additions & 0 deletions src/che-theia-git-ui-tools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/********************************************************************************
* Copyright (c) 2019 Mykola Morhun
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
********************************************************************************/

import * as theia from '@theia/plugin';
import { GIT_TOOLS_CONFIGURATION } from './tools-config';
import { createToolsManager } from './tools-manager';
import { GitUiToolsTreeDataProvider, LAUNCH_GIT_UI_TOOL_COMMAND_ID } from './git-ui-tools-tree';
import { getProjectRoot, PROJECTS_ROOT } from './git-utils';

const INITIALIZATION_FAILED_MESSAGE = 'Failed to initialize Git UI Tools plugin';

export async function start(context: theia.PluginContext) {
const toolsManager = await createToolsManager(GIT_TOOLS_CONFIGURATION);
if (!toolsManager) {
theia.window.showErrorMessage(INITIALIZATION_FAILED_MESSAGE);
console.error(INITIALIZATION_FAILED_MESSAGE);
return;
}

// Create git tools list
const gitUiToolsTreeDataProvider = new GitUiToolsTreeDataProvider(GIT_TOOLS_CONFIGURATION);
theia.window.createTreeView('git-ui-tools', { treeDataProvider: gitUiToolsTreeDataProvider });

// Register launch handler
const GitUiToolsTreeLauncherCommand: theia.CommandDescription = {
id: LAUNCH_GIT_UI_TOOL_COMMAND_ID
};
context.subscriptions.push(theia.commands.registerCommand(GitUiToolsTreeLauncherCommand, (...args: any[]) => {
const toolId: string = args[0];
const openedEditor = theia.window.activeTextEditor;
const projectDir: string | undefined = openedEditor ? getProjectRoot(openedEditor.document.uri.fsPath) : undefined;

toolsManager.runTool(toolId, projectDir || PROJECTS_ROOT);
}));

// Clean up desktop on plugin start
toolsManager.closeAllWindows();
toolsManager.setDEWorkspaces(1);
}

export function stop() {

}
45 changes: 45 additions & 0 deletions src/git-ui-tools-tree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/********************************************************************************
* Copyright (c) 2019 Mykola Morhun
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
********************************************************************************/

import * as theia from '@theia/plugin';
import { ToolInformation } from './tools-manager';

export const LAUNCH_GIT_UI_TOOL_COMMAND_ID = 'che-theia-git-ui-tools-launch';

export class GitUiToolsTreeDataProvider implements theia.TreeDataProvider<ToolInformation> {

constructor(
private toolsInfo: ToolInformation[]
) { }

getTreeItem(element: ToolInformation): theia.TreeItem | PromiseLike<theia.TreeItem> {
return {
id: element.id,
label: element.name,
tooltip: 'Launch ' + element.name,
iconPath: 'fa-window-maximize medium-grey',
command: {
command: LAUNCH_GIT_UI_TOOL_COMMAND_ID,
arguments: [element.id]
}
};
}

getChildren(element?: ToolInformation | undefined): theia.ProviderResult<ToolInformation[]> {
if (element) {
// The tree is actually a list, so no child nodes
return undefined;
}
// Return list of tools
return this.toolsInfo;
}

}
34 changes: 34 additions & 0 deletions src/git-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/********************************************************************************
* Copyright (c) 2019 Mykola Morhun
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
********************************************************************************/

import * as fs from 'fs';
import * as path from 'path';

export const PROJECTS_ROOT = '/projects';

const fsRoot = path.parse(process.cwd()).root

/**
* Searches for project root by a file which belongs to this project.
*
* @param projectFile path to a file within project
* @returns path to project root (where .git directory is located) or undefined if git repository not found.
*/
export function getProjectRoot(projectFile: string): string | undefined {
let currentDirectory = projectFile;
while (currentDirectory !== fsRoot) {
currentDirectory = path.dirname(currentDirectory);
if (fs.existsSync(currentDirectory + path.sep + '.git')) {
return currentDirectory;
}
}
return undefined;
}
55 changes: 55 additions & 0 deletions src/tools-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/********************************************************************************
* Copyright (c) 2019 Mykola Morhun
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
********************************************************************************/

import { ToolInformation } from "./tools-manager";

export const GIT_TOOLS_CONFIGURATION: ToolInformation[] = [
{
id: 'git-gui',
name: 'Git GUI',
command: 'git-gui'
},
{
id: 'gitk',
name: 'Gitk',
command: 'gitk'
},
{
id: 'gitg',
name: 'Gitg',
command: 'gitg'
},
{
id: 'git-cola',
name: 'Git Cola',
command: 'git-cola'
},
{
id: 'qgit',
name: 'QGit',
command: 'qgit'
},
{
id: 'meld',
name: 'Meld',
command: 'meld'
},
{
id: 'tkcvs',
name: 'TkCVS',
command: 'tkcvs'
},
{
id: 'diffuse',
name: 'Diffuse',
command: 'diffuse'
}
];
99 changes: 99 additions & 0 deletions src/tools-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/********************************************************************************
* Copyright (c) 2019 Mykola Morhun
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
********************************************************************************/

import * as theia from '@theia/plugin';
import * as che from '@eclipse-che/plugin';

export interface ToolInformation {
// Identifier of the program
id: string;
// Human readable name of the program
name: string;
// Command with help of which the program could be run
command: string;
};

const GIT_TOOLS_CONTAINER_NAME = 'git-ui-tools';

export async function createToolsManager(toolsInfo: ToolInformation[], containerName?: string): Promise<ToolsManager | undefined> {
if (!containerName) {
containerName = GIT_TOOLS_CONTAINER_NAME;
}

const workspace = await che.workspace.getCurrentWorkspace();
for (const containerId in workspace.runtime!.machines!) {
if (containerId.startsWith(containerName)) {
return new ToolsManager(toolsInfo, containerId);
}
}
return undefined;
}

export class ToolsManager {

private tools: Map<string, ToolInformation>;
private terminal: TerminalCommandRunner;

constructor(toolsInfo: ToolInformation[], toolsContainerId: string) {
this.tools = new Map<string, ToolInformation>();
for (const tool of toolsInfo) {
this.tools.set(tool.id, tool);
}

this.terminal = new TerminalCommandRunner(toolsContainerId);
}

public runTool(id: string, workDir?: string): void {
const command = this.tools.get(id)!.command;
this.terminal.runCommand(COMMANDS.RUN_TOOL.replace('$1', command));
}

public minimizeAllWindows(): void {
this.terminal.runCommand(COMMANDS.MINIMIZE_ALL_WINDOWS);
}

public closeAllWindows(): void {
this.terminal.runCommand(COMMANDS.CLOSE_ALL_WINDOWS);
}

public setDEWorkspaces(n: number): void {
this.terminal.runCommand(COMMANDS.SET_DE_WORKSPACES_NUMBER.replace('$1', String(n)));
}
}

const COMMANDS = {
RUN_TOOL: '$1 & disown -h $!',
MINIMIZE_ALL_WINDOWS: 'wmctrl -k on',
CLOSE_ALL_WINDOWS: 'for w in $(wmctrl -l | awk "{print $1}"); do wmctrl -ic "$w"; done',
SET_DE_WORKSPACES_NUMBER: 'wmctrl -n $1'
}

class TerminalCommandRunner {

constructor(
private containerId: string
) { }

runCommand(command: string, workDir?: string, timeout?: number): void {
const terminal = theia.window.createTerminal({
shellPath: 'bash',
shellArgs: ['-c', command],
cwd: workDir,
attributes: {
CHE_MACHINE_NAME: this.containerId
}
});
// do not show terminal to not to bother user

// clean up resources
setTimeout(() => terminal.dispose(), timeout ? timeout : 5000);
}
}
Loading

0 comments on commit d2098c2

Please sign in to comment.