Skip to content
89 changes: 69 additions & 20 deletions src/webview/git-import/gitImportLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,51 @@ import { DetectedServiceData, DetectedStrategy, detectImportStrategies } from '.
import { ComponentTypesView } from '../../registriesView';
import { ComponentTypeDescription } from '../../odo/componentType';
import { Response } from '../../git-import/types';
import { Uri, workspace } from 'vscode';
import { Component } from '../../openshift/component';
import OpenShiftItem from '../../openshift/openshiftItem';
import { selectWorkspaceFolder } from '../../util/workspace';
import jsYaml = require('js-yaml');
import GitUrlParse = require('git-url-parse');
import cp = require('child_process');
import { vsCommand } from '../../vscommand';
import * as odo3 from '../../odo3';
import { ComponentDescription } from '../../odo/componentTypeDescription';
import { ComponentWorkspaceFolder } from '../../odo/workspace';

let panel: vscode.WebviewPanel;

export class Command {
@vsCommand('openshift.component.importFromGit')
static async createComponent(event: any) {
const workspacePath = await selectWorkspaceFolder();
const appendedUri = Uri.joinPath(workspacePath, event.projectName);
//const wsFolderLength = workspace?.workspaceFolders?.length || 0;
let alreadyExist: boolean;
let workspacePath: vscode.Uri, appendedUri: vscode.Uri;
let workspaceFolder: vscode.WorkspaceFolder;
do {
alreadyExist = false;
workspacePath = await selectWorkspaceFolder();
if (!workspacePath) {
return null;
}
appendedUri = vscode.Uri.joinPath(workspacePath, event.projectName);
workspaceFolder = vscode.workspace.getWorkspaceFolder(workspacePath);
const isExistingComponent = await existingComponent(workspacePath);
if (isExistingComponent) {
vscode.window.showErrorMessage(`Unable to create Component inside an existing Component: ${workspacePath}, Please select another folder`);
alreadyExist = true;
} else if (fs.existsSync(appendedUri.fsPath) && fs.readdirSync(appendedUri.fsPath).length > 0) {
vscode.window.showErrorMessage(`Folder ${appendedUri.fsPath.substring(appendedUri.fsPath.lastIndexOf('\\') + 1)} already exist
at the selected location: ${appendedUri.fsPath.substring(0, appendedUri.fsPath.lastIndexOf('\\'))}`);
alreadyExist = true;
}
} while (alreadyExist);
panel.webview.postMessage({
action: 'cloneStarted'
})
//workspace.updateWorkspaceFolders(wsFolderLength, 0, { uri: appendedUri });
workspace.updateWorkspaceFolders(workspace.workspaceFolders? workspace.workspaceFolders.length : 0 , null, { uri: appendedUri });
});
await clone(event, appendedUri.fsPath);
if (!event.isDevFile) {
panel.webview.postMessage({
action: 'start_create_component'
})
});
try {
await Component.createFromRootWorkspaceFolder(appendedUri, undefined,
{
Expand Down Expand Up @@ -69,6 +87,9 @@ export class Command {
});
vscode.window.showInformationMessage('Selected Component added to the workspace.');
}
if (!workspaceFolder) {
vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, null, { uri: appendedUri });
}
}
}

Expand Down Expand Up @@ -195,8 +216,8 @@ function validateGitURL(event: any) {
try {
const parse = GitUrlParse(event.param);
const isGitRepo = isGitURL(parse.host);
if(!isGitRepo) {
throw 'Invalid Git URL';
if (!isGitRepo) {
throw 'Invalid Git URL';
}
if (parse.organization !== '' && parse.name !== '') {
panel.webview.postMessage({
Expand Down Expand Up @@ -242,8 +263,8 @@ function clone(event: any, location: string): Promise<any> {
const gitExtension = vscode.extensions.getExtension('vscode.git').exports;
const git = gitExtension.getAPI(1).git.path;
// run 'git clone url location' as external process and return location
return new Promise((resolve, reject) => cp.exec(`${git} clone ${event.gitURL} ${location}`, (error: cp.ExecException) => error ?
showError(event, location, error.message) : resolve(true)));
return new Promise((resolve, _reject) => cp.exec(`${git} clone ${event.gitURL} ${location}`, (error: cp.ExecException) => error ?
showError(event) : resolve(true)));
}

function validateComponentName(event: any) {
Expand All @@ -263,7 +284,7 @@ function validateDevFilePath(event: any) {
let validationMessage = OpenShiftItem.emptyName(`Required ${event.param}`, event.param.trim());
if (!validationMessage) validationMessage = OpenShiftItem.validateFilePath(`Not matches ^[a-z]:((\/|\\\\)[a-zA-Z0-9_ \\-]+)+\\.yaml$`, event.param);
if (!validationMessage && event.param !== 'devfile.yaml' && event.param !== 'devfile.yml') {
const uri = Uri.parse(event.param);
const uri = vscode.Uri.parse(event.param);
const devFileLocation = path.join(uri.fsPath);
validationMessage = fs.existsSync(devFileLocation) ? null : 'devfile not available on the given path';
}
Expand All @@ -275,19 +296,47 @@ function validateDevFilePath(event: any) {
});
}

function showError(event: any, location: string, message: string): void {
function showError(event: any): void {
panel.webview.postMessage({
action: event.action,
status: false
});
if (message.indexOf('already exists') !== -1) {
vscode.window.showErrorMessage(`Folder already exists on the selected ${location.substring(0, location.lastIndexOf('\\'))}`);
} else {
vscode.window.showErrorMessage('Error occurred while cloning the repository. Please try again.');
}
vscode.window.showErrorMessage('An error occurred while cloning the repository. Please click \'Analyze\' button and try again');
}

function isGitURL(host: string): boolean {
return ['github.com','bitbucket.org','gitlab.com'].includes(host);
return ['github.com', 'bitbucket.org', 'gitlab.com'].includes(host);
}

async function existingComponent(uri: vscode.Uri): Promise<boolean> {
let worksapceFolder = vscode.workspace.getWorkspaceFolder(uri);
if (worksapceFolder?.uri) {
const workspaceSubDirs = fs.readdirSync(worksapceFolder.uri.fsPath, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name).map((subDir) => vscode.Uri.joinPath(worksapceFolder.uri, subDir));
const components = await getComponents(workspaceSubDirs);
if (components?.length > 0) {
const sameFolder = components.filter(component => component.contextPath === uri.fsPath || uri.fsPath.indexOf(component.contextPath) !== -1);
if (sameFolder && sameFolder.length > 0) {
return true;
} else {
return false;
}
}
}
return false;
}

async function getComponents(folders: vscode.Uri[]): Promise<ComponentWorkspaceFolder[]> {
const descriptions = folders.map(
(folder) => odo3.newInstance().describeComponent(folder.fsPath)
.then((component: ComponentDescription) => {
return {
contextPath: folder.fsPath,
component
}
})
);
const results = await Promise.all(descriptions);
return results.filter((compFolder) => !!compFolder.component);
}