add workspaceUtils which is used for supporting for multiroot (#73)

* add workspaceUtils which is used for supporting for multiroot

* fix according to comments

* add lodash as a useful utility
This commit is contained in:
Sheng Chen 2018-01-31 13:45:41 +08:00 коммит произвёл GitHub
Родитель 0dcef7e1de
Коммит fee034a685
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 86 добавлений и 31 удалений

6
package-lock.json сгенерированный
Просмотреть файл

@ -27,6 +27,12 @@
"integrity": "sha512-loKBID6UL4QjhD2scuvv6oAPlQ/WAY7aYTDyKlKo7fIgriLS8EZExqT567cHL5CY6si51MRoX1+r3mitD3eYrA==",
"dev": true
},
"@types/lodash": {
"version": "4.14.98",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.98.tgz",
"integrity": "sha512-nVCBlQnsTw+769CM5Xt3jR/UAje48DLqEVQVtPLOILOR2AhCmZJ+LEefmbLVspm9U8YhNnT4afAtDsnIZpLogw==",
"dev": true
},
"@types/mocha": {
"version": "2.2.44",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz",

Просмотреть файл

@ -133,6 +133,7 @@
"devDependencies": {
"@types/fs-extra": "^5.0.0",
"@types/keytar": "^4.0.1",
"@types/lodash": "^4.14.98",
"@types/mocha": "^2.2.42",
"@types/node": "^7.0.43",
"@types/semver": "^5.4.0",
@ -145,6 +146,7 @@
"azure-arm-resource": "^2.0.0-preview",
"azure-storage": "",
"fs-extra": "^4.0.2",
"lodash": "^4.17.4",
"ms-rest": "^2.2.7",
"ms-rest-azure": "^2.2.3",
"opn": "5.1.0",

Просмотреть файл

@ -4,7 +4,7 @@ import * as fse from "fs-extra";
import * as os from "os";
import * as path from "path";
import * as vscode from "vscode";
import { commands, Uri, ViewColumn, workspace } from "vscode";
import { commands, Uri, ViewColumn } from "vscode";
import { BaseShell } from "./baseShell";
import { Constants } from "./constants";
import { TerminalType, TestOption, TFTerminal } from "./shared";
@ -13,27 +13,27 @@ import { isServicePrincipalSetInEnv } from "./utils/azureUtils";
import { executeCommand } from "./utils/cpUtils";
import { isDockerInstalled, runE2EInDocker, runLintInDocker } from "./utils/dockerUtils";
import { drawGraph } from "./utils/dotUtils";
import { selectWorkspaceFolder } from "./utils/workspaceUtils";
export class IntegratedShell extends BaseShell {
private static readonly GRAPH_FILE_NAME = "./graph.png";
private static readonly GRAPH_FILE_NAME = "graph.png";
// terminal wrapper
public term = new TFTerminal(
TerminalType.Integrated,
Constants.TerraformTerminalName);
private graphUri: Uri;
public term = new TFTerminal(TerminalType.Integrated, Constants.TerraformTerminalName);
// Creates a png of terraform resource graph to visualize the resources under management.
public async visualize(): Promise<void> {
await this.deletePng();
const cwd: string = await selectWorkspaceFolder();
if (!cwd) {
return;
}
await this.deletePng(cwd);
await executeCommand(
"terraform",
["init"],
{
shell: true,
cwd: vscode.workspace.workspaceFolders[0].uri.fsPath,
cwd,
},
);
const output: string = await executeCommand(
@ -41,29 +41,24 @@ export class IntegratedShell extends BaseShell {
["graph"],
{
shell: true,
cwd: vscode.workspace.workspaceFolders[0].uri.fsPath,
cwd,
},
);
const tmpFile: string = path.join(os.tmpdir(), "terraformgraph.output");
await fse.writeFile(tmpFile, output);
await drawGraph(vscode.workspace.workspaceFolders[0].uri.fsPath, tmpFile);
await commands.executeCommand("vscode.open", this.graphUri, ViewColumn.Two);
await drawGraph(cwd, tmpFile);
await commands.executeCommand("vscode.open", Uri.file(path.join(cwd, IntegratedShell.GRAPH_FILE_NAME)), ViewColumn.Two);
}
// init shell env and hook up close handler. Close handler ensures if user closes terminal window,
// that extension is notified and can handle appropriately.
protected initShellInternal() {
// set path for
this.graphUri = Uri.file(path.join(workspace.rootPath || "", IntegratedShell.GRAPH_FILE_NAME));
if ("onDidCloseTerminal" in vscode.window as any) {
(vscode.window as any).onDidCloseTerminal((terminal) => {
if (terminal === this.term.terminal) {
this.outputLine("Terraform Terminal closed", terminal.name);
this.term.terminal = null;
}
});
}
vscode.window.onDidCloseTerminal((terminal) => {
if (terminal === this.term.terminal) {
terraformChannel.appendLine("Terraform Terminal closed", terminal.name);
this.term.terminal = null;
}
});
}
protected runTerraformInternal(TFCommand: string, WorkDir: string): void {
@ -155,17 +150,16 @@ export class IntegratedShell extends BaseShell {
return;
}
private async deletePng(): Promise<void> {
if (await fse.pathExists(this.graphUri.path)) {
await fse.remove(this.graphUri.path);
private async deletePng(cwd: string): Promise<void> {
const graphPath: string = path.join(cwd, IntegratedShell.GRAPH_FILE_NAME);
if (await fse.pathExists(graphPath)) {
await fse.remove(graphPath);
}
}
private checkCreateTerminal(): void {
if (this.term.terminal == null) {
this.term.terminal = vscode.window.createTerminal(
Constants.TerraformTerminalName);
if (!this.term.terminal) {
this.term.terminal = vscode.window.createTerminal(Constants.TerraformTerminalName);
}
}
}

Просмотреть файл

@ -10,6 +10,22 @@ export async function openUrlHint(message: string, url: string): Promise<void> {
}
}
export async function showFolderDialog(): Promise<vscode.Uri | undefined> {
const defaultUri: vscode.Uri | undefined = vscode.workspace.rootPath ? vscode.Uri.file(vscode.workspace.rootPath) : undefined;
const options: vscode.OpenDialogOptions = {
canSelectFiles: false,
canSelectFolders: true,
canSelectMany: false,
openLabel: "Select",
defaultUri,
};
const result: vscode.Uri[] | undefined = await vscode.window.showOpenDialog(options);
if (!result || result.length === 0) {
return undefined;
}
return result[0];
}
export namespace DialogOption {
export const OK: vscode.MessageItem = { title: "OK" };
export const CANCEL: vscode.MessageItem = { title: "Cancel", isCloseAffordance: true };

Просмотреть файл

@ -0,0 +1,37 @@
"use strict";
import * as _ from "lodash";
import * as vscode from "vscode";
import { DialogOption, showFolderDialog } from "./uiUtils";
export async function selectWorkspaceFolder(): Promise<string | undefined> {
let folder: vscode.WorkspaceFolder;
if (!_.isEmpty(vscode.workspace.workspaceFolders)) {
if (vscode.workspace.workspaceFolders.length > 1) {
folder = await vscode.window.showWorkspaceFolderPick({
placeHolder: "Select the working directory you wish to use",
ignoreFocusOut: true,
});
} else {
folder = vscode.workspace.workspaceFolders[0];
}
} else {
const response = await vscode.window.showInformationMessage(
"There is no folder opened in current workspace, would you like to open a folder?",
DialogOption.OPEN,
DialogOption.CANCEL,
);
if (response === DialogOption.OPEN) {
const selectedFolder: vscode.Uri = await showFolderDialog();
if (selectedFolder) {
/**
* Open the selected folder in a workspace.
* NOTE: this will restart the extension host.
* See: https://github.com/Microsoft/vscode/issues/58
*/
await vscode.commands.executeCommand("vscode.openFolder", selectedFolder, false /* forceNewWindow */);
}
}
}
return folder ? folder.uri.fsPath : undefined;
}