1 | import spawn from 'cross-spawn';
|
2 |
|
3 | let isSSH: any;
|
4 | async function isSupportSSH(url: string): Promise<any> {
|
5 | if (isSSH) {
|
6 | return isSSH;
|
7 | }
|
8 | try {
|
9 | const res: any = await Promise.race([
|
10 | spawn.sync('ssh', ['-vT', url]),
|
11 | new Promise((resolve: any, reject: any) => {
|
12 | setTimeout(() => {
|
13 | reject(new Error('SSH check timeout'));
|
14 | }, 1000);
|
15 | })
|
16 | ]);
|
17 |
|
18 | const stderr = res?.stderr?.toString();
|
19 | if (/Authentication succeeded/.test(stderr)) {
|
20 | isSSH = true;
|
21 | } else {
|
22 | isSSH = false;
|
23 | }
|
24 | return isSSH;
|
25 | } catch (err) {
|
26 | console.log('Git ssh check timeout, use https');
|
27 | isSSH = false;
|
28 | return isSSH;
|
29 | }
|
30 | }
|
31 |
|
32 | function getHostname(url: string): string {
|
33 | if (/https?/.test(url)) {
|
34 | const match: any = url.match(/^http(s)?:\/\/(.*?)\//);
|
35 | return match[2];
|
36 | } else {
|
37 | const match: any = url.match(/@(.*):/);
|
38 | return match[1];
|
39 | }
|
40 | }
|
41 |
|
42 | let gitAccount: any;
|
43 | export async function transformUrl(url: string, account?: any): Promise<any> {
|
44 | const hostname = getHostname(url);
|
45 | const isSSH = await isSupportSSH(`git@${hostname}`);
|
46 | if (isSSH) {
|
47 | if (/https?/.test(url)) {
|
48 | return url.replace(/https?:\/\//, 'git@').replace(/\//, ':');
|
49 | } else {
|
50 | return url;
|
51 | }
|
52 | } else {
|
53 | let transformedUrl;
|
54 | if (/https?/.test(url)) {
|
55 | transformedUrl = url;
|
56 | } else {
|
57 | transformedUrl = url.replace(`git@${ hostname }:`, `http://${ hostname }/`);
|
58 | }
|
59 | if (account) {
|
60 | gitAccount = account;
|
61 | }
|
62 | if (gitAccount) {
|
63 | const { username, password } = gitAccount;
|
64 | return transformedUrl.replace(/http:\/\//, `http://${username}:${password}@`);
|
65 | }
|
66 | return transformedUrl;
|
67 | }
|
68 | } |
\ | No newline at end of file |