From 4036edcc9cf2d1a4d0ff896f834efe2d5e3a9fe1 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Tue, 27 Jun 2023 15:32:26 +0530 Subject: [PATCH 1/5] trim the git url till repo name Signed-off-by: msivasubramaniaan --- src/webview/git-import/app/gitImport.tsx | 8 +- src/webview/git-import/git-parse.js | 318 ++++++++++++++++++++++ src/webview/git-import/gitImportLoader.ts | 4 +- 3 files changed, 327 insertions(+), 3 deletions(-) create mode 100644 src/webview/git-import/git-parse.js diff --git a/src/webview/git-import/app/gitImport.tsx b/src/webview/git-import/app/gitImport.tsx index 2440eb61c..8bd675ade 100644 --- a/src/webview/git-import/app/gitImport.tsx +++ b/src/webview/git-import/app/gitImport.tsx @@ -18,6 +18,7 @@ import { ComponentTypeDescription } from '../../../odo/componentType'; import { LoadScreen } from './loading'; import './gitImport.scss'; import { Uri } from 'vscode'; +const gitUrlParse = require('../git-parse'); export interface DefaultProps { analytics?: import('@segment/analytics-next').Analytics; @@ -217,7 +218,7 @@ export class GitImport extends React.Component { + const parsedURL = gitUrlParse(value); + return `${parsedURL.protocol}://${parsedURL.source}/${parsedURL.full_name}`; + } + analyze = (): void => { this.setState({ applicationName: undefined, diff --git a/src/webview/git-import/git-parse.js b/src/webview/git-import/git-parse.js new file mode 100644 index 000000000..dbf303723 --- /dev/null +++ b/src/webview/git-import/git-parse.js @@ -0,0 +1,318 @@ +/*----------------------------------------------------------------------------------------------- + * Copyright (c) Red Hat, Inc. All rights reserved. + * Licensed under the MIT License. See LICENSE file in the project root for license information. + *-----------------------------------------------------------------------------------------------*/ +'use strict'; + +const gitUp = require('git-up'); + +/** + * gitUrlParse + * Parses a Git url. + * + * @name gitUrlParse + * @function + * @param {String} url The Git url to parse. + * @return {GitUrl} The `GitUrl` object containing: + * + * - `protocols` (Array): An array with the url protocols (usually it has one element). + * - `port` (null|Number): The domain port. + * - `resource` (String): The url domain (including subdomains). + * - `user` (String): The authentication user (usually for ssh urls). + * - `pathname` (String): The url pathname. + * - `hash` (String): The url hash. + * - `search` (String): The url querystring value. + * - `href` (String): The input url. + * - `protocol` (String): The git url protocol. + * - `token` (String): The oauth token (could appear in the https urls). + * - `source` (String): The Git provider (e.g. `'github.com'`). + * - `owner` (String): The repository owner. + * - `name` (String): The repository name. + * - `ref` (String): The repository ref (e.g., 'master' or 'dev'). + * - `filepath` (String): A filepath relative to the repository root. + * - `filepathtype` (String): The type of filepath in the url ('blob' or 'tree'). + * - `full_name` (String): The owner and name values in the `owner/name` format. + * - `toString` (Function): A function to stringify the parsed url into another url type. + * - `organization` (String): The organization the owner belongs to. This is CloudForge specific. + * - `git_suffix` (Boolean): Whether to add the `.git` suffix or not. + * + */ +function gitUrlParse(url) { + + if (typeof url !== 'string') { + throw new Error('The url must be a string.'); + } + + const shorthandRe = /^([a-z\d-]{1,39})\/([-\.\w]{1,100})$/i + + if (shorthandRe.test(url)) { + url = `https://github.com/${url}` + } + + let urlInfo = gitUp(url) + , sourceParts = urlInfo.resource.split('.') + , splits = null + ; + + urlInfo.toString = function (type) { + return gitUrlParse.stringify(this, type); + }; + + urlInfo.source = sourceParts.length > 2 + ? sourceParts.slice(1 - sourceParts.length).join('.') + : urlInfo.source = urlInfo.resource + ; + + // Note: Some hosting services (e.g. Visual Studio Team Services) allow whitespace characters + // in the repository and owner names so we decode the URL pieces to get the correct result + urlInfo.git_suffix = /\.git$/.test(urlInfo.pathname); + urlInfo.name = decodeURIComponent((urlInfo.pathname || urlInfo.href).replace(/(^\/)|(\/$)/g, '').replace(/\.git$/, '')); + urlInfo.owner = decodeURIComponent(urlInfo.user); + + switch (urlInfo.source) { + case 'git.cloudforge.com': + urlInfo.owner = urlInfo.user; + urlInfo.organization = sourceParts[0]; + urlInfo.source = 'cloudforge.com'; + break; + case 'visualstudio.com': + // Handle VSTS SSH URLs + if (urlInfo.resource === 'vs-ssh.visualstudio.com') { + splits = urlInfo.name.split('/'); + if (splits.length === 4) { + urlInfo.organization = splits[1]; + urlInfo.owner = splits[2]; + urlInfo.name = splits[3]; + urlInfo.full_name = splits[2] + '/' + splits[3]; + } + break; + } else { + splits = urlInfo.name.split('/'); + if (splits.length === 2) { + urlInfo.owner = splits[1]; + urlInfo.name = splits[1]; + urlInfo.full_name = '_git/' + urlInfo.name; + } else if (splits.length === 3) { + urlInfo.name = splits[2]; + if (splits[0] === 'DefaultCollection') { + urlInfo.owner = splits[2]; + urlInfo.organization = splits[0]; + urlInfo.full_name = urlInfo.organization + '/_git/' + urlInfo.name; + } else { + urlInfo.owner = splits[0]; + urlInfo.full_name = urlInfo.owner + '/_git/' + urlInfo.name; + } + } else if (splits.length === 4) { + urlInfo.organization = splits[0]; + urlInfo.owner = splits[1]; + urlInfo.name = splits[3]; + urlInfo.full_name = urlInfo.organization + '/' + urlInfo.owner + '/_git/' + urlInfo.name; + } + break; + } + + // Azure DevOps (formerly Visual Studio Team Services) + case 'dev.azure.com': + case 'azure.com': + if (urlInfo.resource === 'ssh.dev.azure.com') { + splits = urlInfo.name.split('/'); + if (splits.length === 4) { + urlInfo.organization = splits[1]; + urlInfo.owner = splits[2]; + urlInfo.name = splits[3]; + } + break; + } else { + splits = urlInfo.name.split('/'); + if (splits.length === 5) { + urlInfo.organization = splits[0]; + urlInfo.owner = splits[1]; + urlInfo.name = splits[4]; + urlInfo.full_name = '_git/' + urlInfo.name; + } else if (splits.length === 3) { + urlInfo.name = splits[2]; + if (splits[0] === 'DefaultCollection') { + urlInfo.owner = splits[2]; + urlInfo.organization = splits[0]; + urlInfo.full_name = urlInfo.organization + '/_git/' + urlInfo.name; + } else { + urlInfo.owner = splits[0]; + urlInfo.full_name = urlInfo.owner + '/_git/' + urlInfo.name; + } + } else if (splits.length === 4) { + urlInfo.organization = splits[0]; + urlInfo.owner = splits[1]; + urlInfo.name = splits[3]; + urlInfo.full_name = urlInfo.organization + '/' + urlInfo.owner + '/_git/' + urlInfo.name; + } + if(urlInfo.query && urlInfo.query['path']) { + urlInfo.filepath = urlInfo.query['path'].replace(/^\/+/g, ''); // Strip leading slash (/) + } + if(urlInfo.query && urlInfo.query['version']) { // version=GB + urlInfo.ref = urlInfo.query['version'].replace(/^GB/, ''); // remove GB + } + break; + } + default: + splits = urlInfo.name.split('/'); + let nameIndex = splits.length - 1; + if (splits.length >= 2) { + const dashIndex = splits.indexOf('-', 2) + const blobIndex = splits.indexOf('blob', 2); + const treeIndex = splits.indexOf('tree', 2); + const commitIndex = splits.indexOf('commit', 2); + const issuesIndex = splits.indexOf("issues", 2); + const pullIndex = splits.indexOf("pull", 2); + const srcIndex = splits.indexOf('src', 2); + const rawIndex = splits.indexOf('raw', 2); + const editIndex = splits.indexOf('edit', 2); + nameIndex = dashIndex > 0 ? dashIndex - 1 + : blobIndex > 0 ? blobIndex - 1 + : treeIndex > 0 ? treeIndex - 1 + : commitIndex > 0 ? commitIndex - 1 + : issuesIndex > 0 ? issuesIndex - 1 + : pullIndex > 0 ? pullIndex - 1 + : srcIndex > 0 ? srcIndex - 1 + : rawIndex > 0 ? rawIndex - 1 + : editIndex > 0 ? editIndex - 1 + : nameIndex; + + urlInfo.owner = splits.slice(0, nameIndex).join('/'); + urlInfo.name = splits[nameIndex]; + if (commitIndex !== -1) { + urlInfo.commit = splits[nameIndex + 2] + } + } + + urlInfo.ref = ''; + urlInfo.filepathtype = ''; + urlInfo.filepath = ''; + const offsetNameIndex = splits.length > nameIndex && splits[nameIndex+1] === '-' ? nameIndex + 1 : nameIndex; + + if ((splits.length > offsetNameIndex + 2) && (['raw', 'src', 'blob', 'tree', 'edit'].indexOf(splits[offsetNameIndex + 1]) >= 0)) { + urlInfo.filepathtype = splits[offsetNameIndex + 1]; + urlInfo.ref = splits[offsetNameIndex + 2]; + if (splits.length > offsetNameIndex + 3) { + urlInfo.filepath = splits.slice(offsetNameIndex + 3).join('/'); + } + } + urlInfo.organization = urlInfo.owner; + break; + } + + if (!urlInfo.full_name) { + urlInfo.full_name = urlInfo.owner; + if (urlInfo.name) { + urlInfo.full_name && (urlInfo.full_name += '/'); + urlInfo.full_name += urlInfo.name; + } + } + // Bitbucket Server + if(urlInfo.owner.startsWith('scm/')) { + urlInfo.source = 'bitbucket-server'; + urlInfo.owner = urlInfo.owner.replace('scm/',''); + urlInfo.organization = urlInfo.owner; + urlInfo.full_name = `${urlInfo.owner}/${urlInfo.name}` + } + + const bitbucket = /(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/ + const matches = bitbucket.exec(urlInfo.pathname) + if(matches != null) { + urlInfo.source = 'bitbucket-server'; + if (matches[1] === 'users') { + urlInfo.owner = '~' + matches[2]; + } else { + urlInfo.owner = matches[2]; + } + + urlInfo.organization = urlInfo.owner; + urlInfo.name = matches[3]; + + splits = matches[4].split('/'); + if(splits.length > 1) { + if(['raw','browse'].indexOf(splits[1]) >= 0) { + urlInfo.filepathtype = splits[1]; + if (splits.length > 2) { + urlInfo.filepath = splits.slice(2).join('/'); + } + } else if(splits[1] === 'commits' && splits.length > 2) { + urlInfo.commit = splits[2]; + } + } + urlInfo.full_name = `${urlInfo.owner}/${urlInfo.name}` + + if(urlInfo.query.at) { + urlInfo.ref = urlInfo.query.at; + } else { + urlInfo.ref = ''; + } + } + return urlInfo; +} + +/** + * stringify + * Stringifies a `GitUrl` object. + * + * @name stringify + * @function + * @param {GitUrl} obj The parsed Git url object. + * @param {String} type The type of the stringified url (default `obj.protocol`). + * @return {String} The stringified url. + */ +gitUrlParse.stringify = function (obj, type) { + type = type || ((obj.protocols && obj.protocols.length) ? obj.protocols.join('+') : obj.protocol); + const port = obj.port ? `:${obj.port}` : ''; + const user = obj.user || 'git'; + const maybeGitSuffix = obj.git_suffix ? '.git' : '' + switch (type) { + case 'ssh': + if (port) + return `ssh://${user}@${obj.resource}${port}/${obj.full_name}${maybeGitSuffix}`; + else + return `${user}@${obj.resource}:${obj.full_name}${maybeGitSuffix}`; + case 'git+ssh': + case 'ssh+git': + case 'ftp': + case 'ftps': + return `${type}://${user}@${obj.resource}${port}/${obj.full_name}${maybeGitSuffix}`; + case 'http': + case 'https': + const auth = obj.token + ? buildToken(obj) : obj.user && (obj.protocols.includes('http') || obj.protocols.includes('https')) + ? `${obj.user}@` : ''; + return `${type}://${auth}${obj.resource}${port}/${buildPath(obj)}${maybeGitSuffix}`; + default: + return obj.href; + } +}; + +/*! + * buildToken + * Builds OAuth token prefix (helper function) + * + * @name buildToken + * @function + * @param {GitUrl} obj The parsed Git url object. + * @return {String} token prefix + */ +function buildToken(obj) { + switch (obj.source) { + case 'bitbucket.org': + return `x-token-auth:${obj.token}@`; + default: + return `${obj.token}@` + } +} + +function buildPath(obj) { + switch(obj.source) { + case 'bitbucket-server': + return `scm/${obj.full_name}`; + default: + return `${obj.full_name}`; + + } +} + +module.exports = gitUrlParse; diff --git a/src/webview/git-import/gitImportLoader.ts b/src/webview/git-import/gitImportLoader.ts index 6123fe56d..453b6f995 100644 --- a/src/webview/git-import/gitImportLoader.ts +++ b/src/webview/git-import/gitImportLoader.ts @@ -19,7 +19,7 @@ import { selectWorkspaceFolder } from '../../util/workspace'; import { vsCommand } from '../../vscommand'; import { loadWebviewHtml } from '../common-ext/utils'; import { DevfileConverter } from './devfileConverter'; -import GitUrlParse = require('git-url-parse'); +const gitUrlParse = require('./git-parse'); import treeKill = require('tree-kill') import cp = require('child_process'); let panel: vscode.WebviewPanel; @@ -273,7 +273,7 @@ function validateGitURL(event: any) { }); } else { try { - const parse = GitUrlParse(event.param); + const parse = gitUrlParse(event.param); const isGitRepo = isGitURL(parse.host); if (!isGitRepo) { throw 'Invalid Git URL'; From 4218896a18ab49d200dc114bcd62e595ce03a18f Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Tue, 27 Jun 2023 19:39:11 +0530 Subject: [PATCH 2/5] replaced to js file Signed-off-by: msivasubramaniaan --- src/webview/git-import/app/gitImport.tsx | 2 +- src/webview/git-import/gitImportLoader.ts | 2 +- src/webview/git-import/{git-parse.js => gitParse.ts} | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) rename src/webview/git-import/{git-parse.js => gitParse.ts} (99%) diff --git a/src/webview/git-import/app/gitImport.tsx b/src/webview/git-import/app/gitImport.tsx index 8bd675ade..e2aec1ccf 100644 --- a/src/webview/git-import/app/gitImport.tsx +++ b/src/webview/git-import/app/gitImport.tsx @@ -16,9 +16,9 @@ import { VSCodeMessage } from './vsCodeMessage'; import { CardItem } from './cardItem'; import { ComponentTypeDescription } from '../../../odo/componentType'; import { LoadScreen } from './loading'; +import { gitUrlParse } from '../gitParse'; import './gitImport.scss'; import { Uri } from 'vscode'; -const gitUrlParse = require('../git-parse'); export interface DefaultProps { analytics?: import('@segment/analytics-next').Analytics; diff --git a/src/webview/git-import/gitImportLoader.ts b/src/webview/git-import/gitImportLoader.ts index 453b6f995..8d349bd03 100644 --- a/src/webview/git-import/gitImportLoader.ts +++ b/src/webview/git-import/gitImportLoader.ts @@ -19,7 +19,7 @@ import { selectWorkspaceFolder } from '../../util/workspace'; import { vsCommand } from '../../vscommand'; import { loadWebviewHtml } from '../common-ext/utils'; import { DevfileConverter } from './devfileConverter'; -const gitUrlParse = require('./git-parse'); +import { gitUrlParse } from './gitParse'; import treeKill = require('tree-kill') import cp = require('child_process'); let panel: vscode.WebviewPanel; diff --git a/src/webview/git-import/git-parse.js b/src/webview/git-import/gitParse.ts similarity index 99% rename from src/webview/git-import/git-parse.js rename to src/webview/git-import/gitParse.ts index dbf303723..53457da00 100644 --- a/src/webview/git-import/git-parse.js +++ b/src/webview/git-import/gitParse.ts @@ -37,7 +37,7 @@ const gitUp = require('git-up'); * - `git_suffix` (Boolean): Whether to add the `.git` suffix or not. * */ -function gitUrlParse(url) { +export function gitUrlParse(url) { if (typeof url !== 'string') { throw new Error('The url must be a string.'); @@ -314,5 +314,3 @@ function buildPath(obj) { } } - -module.exports = gitUrlParse; From 9ec59effa39d18c9565ae95c15243ab58cb1049d Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Wed, 28 Jun 2023 00:54:21 +0530 Subject: [PATCH 3/5] trimmed url once user clicked analyze button Signed-off-by: msivasubramaniaan --- package-lock.json | 32 ++++++++++-------------- package.json | 2 +- src/webview/git-import/app/gitImport.tsx | 6 ++--- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30fc93a9b..d82bcf4f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "@redhat-developer/vscode-redhat-telemetry": "^0.5.2", "clsx": "^1.1.1", "fs-extra": "^10.0.0", - "git-url-parse": "^13.1.0", "globby": "^10.0.1", "got": "^11.8.6", "hasha": "^5.2.2", @@ -88,6 +87,7 @@ "eslint-plugin-prettier": "^4.0.0", "express": "^4.17.2", "file-loader": "^6.2.0", + "git-up": "^7.0.0", "glob": "^7.2.0", "istanbul": "^0.4.5", "leasot": "^12.0.0", @@ -11132,19 +11132,12 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", + "dev": true, "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^8.1.0" } }, - "node_modules/git-url-parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", - "dependencies": { - "git-up": "^7.0.0" - } - }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -12360,6 +12353,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", + "dev": true, "dependencies": { "protocols": "^2.0.1" } @@ -16355,6 +16349,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", + "dev": true, "dependencies": { "protocols": "^2.0.0" } @@ -16381,6 +16376,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", + "dev": true, "dependencies": { "parse-path": "^7.0.0" } @@ -16960,7 +16956,8 @@ "node_modules/protocols": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" + "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", + "dev": true }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -28570,19 +28567,12 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", + "dev": true, "requires": { "is-ssh": "^1.4.0", "parse-url": "^8.1.0" } }, - "git-url-parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", - "requires": { - "git-up": "^7.0.0" - } - }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -29455,6 +29445,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", + "dev": true, "requires": { "protocols": "^2.0.1" } @@ -32526,6 +32517,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", + "dev": true, "requires": { "protocols": "^2.0.0" } @@ -32551,6 +32543,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", + "dev": true, "requires": { "parse-path": "^7.0.0" } @@ -32985,7 +32978,8 @@ "protocols": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" + "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", + "dev": true }, "proxy-addr": { "version": "2.0.7", diff --git a/package.json b/package.json index 24b474761..57bcc9f42 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,6 @@ "@redhat-developer/vscode-redhat-telemetry": "^0.5.2", "clsx": "^1.1.1", "fs-extra": "^10.0.0", - "git-url-parse": "^13.1.0", "globby": "^10.0.1", "got": "^11.8.6", "hasha": "^5.2.2", @@ -152,6 +151,7 @@ "eslint-plugin-prettier": "^4.0.0", "express": "^4.17.2", "file-loader": "^6.2.0", + "git-up": "^7.0.0", "glob": "^7.2.0", "istanbul": "^0.4.5", "leasot": "^12.0.0", diff --git a/src/webview/git-import/app/gitImport.tsx b/src/webview/git-import/app/gitImport.tsx index e2aec1ccf..8ee346a3e 100644 --- a/src/webview/git-import/app/gitImport.tsx +++ b/src/webview/git-import/app/gitImport.tsx @@ -136,7 +136,7 @@ export class GitImport extends React.Component Date: Wed, 28 Jun 2023 15:24:53 +0530 Subject: [PATCH 4/5] added git_suffix check on the parser Signed-off-by: msivasubramaniaan --- .editorconfig | 2 +- src/webview/git-import/app/gitImport.tsx | 8 +++-- src/webview/git-import/gitImportLoader.ts | 36 ++++++++++++----------- src/webview/git-import/gitParse.ts | 2 +- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/.editorconfig b/.editorconfig index 24e7dd207..f45bad7fd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ indent_style = space indent_size = 4 # We recommend you to keep these unchanged -end_of_line = lf +end_of_line = crlf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true diff --git a/src/webview/git-import/app/gitImport.tsx b/src/webview/git-import/app/gitImport.tsx index 8ee346a3e..56f2634e2 100644 --- a/src/webview/git-import/app/gitImport.tsx +++ b/src/webview/git-import/app/gitImport.tsx @@ -194,7 +194,9 @@ export class GitImport extends React.Component { const parsedURL = gitUrlParse(value); - return `${parsedURL.protocol}://${parsedURL.source}/${parsedURL.full_name}`; + return gitUrlParse.stringify(parsedURL, ''); } analyze = (): void => { diff --git a/src/webview/git-import/gitImportLoader.ts b/src/webview/git-import/gitImportLoader.ts index 8d349bd03..ed7eba75f 100644 --- a/src/webview/git-import/gitImportLoader.ts +++ b/src/webview/git-import/gitImportLoader.ts @@ -28,7 +28,7 @@ let forceCancel = false; interface CloneProcess { status: boolean, - error: string + error: string | undefined } export class Command { @@ -134,12 +134,13 @@ async function gitImportMessageListener(event: any): Promise { const selctedFolder: vscode.Uri = event.folder; const cloneProcess: CloneProcess = await clone(event.gitURL, selctedFolder.fsPath); if (!cloneProcess.status && cloneProcess.error) { - showError(event, event.folder.fsPath, cloneProcess.error); + showError(event.folder.fsPath, cloneProcess.error); return null; + } else { + panel?.webview.postMessage({ + action: 'cloneCompleted' + }); } - panel?.webview.postMessage({ - action: 'cloneCompleted' - }); } default: break; @@ -249,7 +250,7 @@ async function parseGitURL(event: any) { name: event.projectName + '-comp', error: compDescriptions.length > 0 ? false : true, isDevFile: isDevFile, - helpText: compDescriptions.length > 0 ? 'The git repo is valid.' : 'Issue on Parsing Git URL/devfile', + helpText: compDescriptions.length > 0 ? 'The git repo URL is valid.' : 'Issue on Parsing Git URL/devfile', compDescription: compDescriptions, parser: event.parser }); @@ -282,7 +283,7 @@ function validateGitURL(event: any) { panel?.webview.postMessage({ action: event.action, error: false, - helpText: 'The git repo is valid.', + helpText: 'The git repo URL is valid.', parser: parse, gitURL: event.param }); @@ -319,8 +320,11 @@ function clone(url: string, location: string): Promise { 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) => (childProcess = cp.exec(`${git} clone ${url} ${location}`, (error: cp.ExecException) => error ? - reject({ status: false, error: error.message }) : resolve({ status: true, error: undefined })))); + return new Promise((resolve, reject) => (childProcess = cp.exec(`${git} clone ${url} ${location}`, + (error: cp.ExecException) => { + error ? resolve({ status: false, error: error.message }) : resolve({ status: true, error: undefined }); + } + ))); } function validateComponentName(event: any) { @@ -352,17 +356,15 @@ function validateDevFilePath(event: any) { }); } -function showError(event: any, location: string, message: string): void { +function showError(location: string, message: string): void { + const permissonDeniedIndex = message.toLowerCase().indexOf('permission denied'); + const errorMsg = permissonDeniedIndex !== -1 ? message.substring(permissonDeniedIndex) : 'Error occurred while cloning the repository. Please try again.'; panel?.webview.postMessage({ - action: event.action, - status: false + action: 'cloneError', + error: errorMsg }); if (!forceCancel) { - 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(errorMsg); } } diff --git a/src/webview/git-import/gitParse.ts b/src/webview/git-import/gitParse.ts index 53457da00..b700acc52 100644 --- a/src/webview/git-import/gitParse.ts +++ b/src/webview/git-import/gitParse.ts @@ -283,7 +283,7 @@ gitUrlParse.stringify = function (obj, type) { ? `${obj.user}@` : ''; return `${type}://${auth}${obj.resource}${port}/${buildPath(obj)}${maybeGitSuffix}`; default: - return obj.href; + return obj.git_suffix ? obj.href : `${obj.protocol}://${obj.source}/${obj.full_name}`; } }; From 75dca7f7a6462fe7d92379c3ac60803c8ca3316b Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Wed, 28 Jun 2023 15:25:58 +0530 Subject: [PATCH 5/5] revert Signed-off-by: msivasubramaniaan --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index f45bad7fd..24e7dd207 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ indent_style = space indent_size = 4 # We recommend you to keep these unchanged -end_of_line = crlf +end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true