UNPKG

3.29 kBPlain TextView Raw
1import spawn from 'cross-spawn';
2import rp from 'request-promise';
3import { getURL } from './url';
4
5let gitAccount: any;
6let serverUrl: string;
7
8export function setServerUrl(url: string) {
9 serverUrl = url;
10}
11
12function getHostname(url: string): string {
13 if (/https?/.test(url)) {
14 const match: any = url.match(/^http(s)?:\/\/(.*?)\//);
15 return match[2].split('@').pop();
16 } else {
17 const match: any = url.match(/@(.*):/);
18 return match[1];
19 }
20}
21
22async function prepareAccount() {
23 if (gitAccount) {
24 return;
25 }
26 const url = getURL(serverUrl, 'apply/getlist?name=0');
27 if (!url) {
28 return;
29 }
30 const options = {
31 url: url,
32 method: 'GET'
33 };
34 return rp(options)
35 .then((response: any) => {
36 const data = JSON.parse(response);
37 if (data.account) {
38 gitAccount = data.account;
39 }
40 })
41 .catch((err: any) => {});
42}
43
44export async function transformUrl(url: string, account?: any): Promise<any> {
45 if (account) {
46 gitAccount = account;
47 } else {
48 await prepareAccount();
49 }
50 const hostname = getHostname(url);
51 let transformedUrl;
52 if (/https?/.test(url)) {
53 transformedUrl = url;
54 } else {
55 transformedUrl = url.replace(`git@${hostname}:`, `http://${hostname}/`);
56 }
57 if (gitAccount) {
58 const { username, password } = gitAccount;
59 return transformedUrl.replace(
60 /https?:\/\/(.*?(:.*?)?@)?/,
61 `http://${username}:${password}@`
62 );
63 }
64 return transformedUrl;
65}
66
67export async function clearGitCert(url: string) {
68 const { username } = gitAccount;
69 if (!username) {
70 return;
71 }
72 if (!/https?:\/\/(.*?(:.*?)?@)/.test(url)) {
73 url = await transformUrl(url);
74 }
75 return new Promise(resolve => {
76 const child = spawn('git', ['credential', 'reject'], {
77 windowsHide: true,
78 timeout: 60 * 1000 * 1
79 });
80 child.stdin?.write(`url=${url}`);
81 child.stdin?.end();
82 child.on('close', code => {
83 resolve(code);
84 });
85 });
86}
87
88export async function clearGitCertByPath(repoPath: string) {
89 const ret = spawn.sync('git', ['config', '--get', 'remote.origin.url'], {
90 windowsHide: true,
91 cwd: repoPath
92 });
93 const url = ret?.stdout?.toString().trim();
94 return clearGitCert(url);
95}
96
97export async function download(
98 url: string,
99 tag: string,
100 filepath: string
101): Promise<any> {
102 const cloneUrl = await transformUrl(url);
103
104 console.log('clone from', url);
105 return new Promise((resolve, reject) => {
106 const child = spawn(
107 'git',
108 ['clone', '-b', tag, '--progress', '--depth', '1', cloneUrl, filepath],
109 {
110 stdio: 'pipe',
111 windowsHide: true
112 }
113 );
114 let doneFlag = false;
115 child.stderr?.on('data', d => {
116 if (doneFlag) {
117 return;
118 }
119 if (
120 d?.toString()?.startsWith('Note:') ||
121 d?.toString()?.startsWith('注意')
122 ) {
123 doneFlag = true;
124 return;
125 }
126 process.stderr.write(d);
127 });
128 child.stdout?.on('data', d => {
129 if (doneFlag) {
130 return;
131 }
132 process.stdout.write(d);
133 });
134 child.on('close', code => {
135 if (code === 0) {
136 resolve(0);
137 } else {
138 reject(code);
139 }
140 });
141 child.on('error', err => {
142 reject(err);
143 });
144 }).finally(() => clearGitCert(cloneUrl));
145}