• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16const fs = require('fs');
17const path = require('path');
18const { JSDOM } = require('jsdom');
19const os = require('os');
20const unzipper = require('unzipper');
21const {
22    clearDir, deleteDir, existDir, mkdir, moveDir, readDir, renameDir, isExistFile, copyFile
23} = require('../utils/file.js');
24const http = require("http");
25
26module.exports = { prepareHostEnv };
27
28async function getPullsNumberComments(url) {
29    const response = await fetch(url);
30    if (response.ok) {
31        const data = await response.json();
32        for (let i = 0; i < data.length; i++) {
33            if (data[i].body.includes("代码门禁通过")) {
34                const dom = new JSDOM(data[i].body);
35                const document = dom.window.document;
36                const anchors = document.getElementsByTagName('a');
37                for (let j = 0; j < anchors.length; j++) {
38                    const anchor = anchors[j];
39                    const hrefValue = anchor.href;
40                    if (hrefValue.includes("ohos-sdk") && hrefValue.includes(".zip")) {
41                        return { status: response.status, data, hrefValue };
42                    }
43                }
44            }
45        }
46    } else {
47        throw new Error(`HTTP状态码${response.status},请求URL为${url}`);
48    }
49    return null;
50}
51
52async function downloadFile(url, destinationPath) {
53    return new Promise(async (resolve, reject) => {
54        const fileStream = fs.createWriteStream(destinationPath);
55        const request = await http.get(url, (response) => {
56            if (response.statusCode === 404) {
57                console.error("当前PR地址已失效,请更换可用的PR地址后重试");
58                reject(false);
59                return;
60            }
61            if (response.statusCode !== 200) {
62                console.error("下载失败");
63                reject(false);
64                return;
65            }
66            response.pipe(fileStream);
67            fileStream.on('finish', () => {
68                fileStream.close(() => resolve(true));
69            });
70            fileStream.on('error', (error) => {
71                console.error("下载文件错误", error);
72                reject(false);
73            });
74        });
75        request.on('error', (error) => {
76            console.error("请求出错", error);
77            reject(false);
78        });
79    });
80}
81
82async function extractLargeZip(zipFilePath, outputDir) {
83    return new Promise((resolve, reject) => {
84        const readStream = fs.createReadStream(zipFilePath);
85        readStream.pipe(unzipper.Parse())
86            .on('entry', (entry) => {
87                const fileName = entry.path;
88                const type = entry.type;
89
90                if (type === 'File') {
91                    const outputPath = path.join(outputDir, fileName);
92                    entry.pipe(fs.createWriteStream(outputPath));
93                } else if (type === 'Directory') {
94                    fs.mkdirSync(path.join(outputDir, fileName), { recursive: true });
95                    entry.autodrain();
96                }
97            })
98            .on('error', (error) => {
99                throw error;
100            })
101            .on('close', () => {
102                resolve();
103            });
104    });
105}
106
107function judgePlatform() {
108    return os.platform() === 'win32';
109}
110
111async function extractZipFile(zipFilePath, outputDirectory) {
112    try {
113        await new Promise((resolve, reject) => {
114            fs.createReadStream(zipFilePath)
115                .pipe(unzipper.Extract({ path: outputDirectory }))
116                .on('error', reject)
117                .on('finish', () => {
118                    resolve();
119                });
120        });
121    } catch (err) {
122        throw err;
123    }
124    if (!fs.existsSync(outputDirectory)) {
125        fs.mkdirSync(outputDirectory, { recursive: true });
126    }
127}
128
129async function downloadSdk(url, downloadPath) {
130    return new Promise(async (resolve, reject) => {
131        try {
132            const pullsNumberCommentsResponse = await getPullsNumberComments(url);
133            if (pullsNumberCommentsResponse !== null && pullsNumberCommentsResponse.hrefValue !== "") {
134                await downloadFile(pullsNumberCommentsResponse.hrefValue,
135                    path.join(downloadPath, "ohos-sdk.zip")).then((res, rej) => {
136                        if (res) {
137                            resolve(true);
138                        } else {
139                            reject(false);
140                        }
141                    })
142            } else {
143                console.error("暂无可用sdk");
144                reject(false);
145            }
146        } catch (error) {
147            console.error("下载过程中发生错误");
148            reject(false);
149        }
150    });
151}
152
153async function prepareHostEnv(url, downloadPath, sdkPath) {
154    try {
155        let ohosSdkPath;
156        let etsPath = path.join(sdkPath, "ets\\api");
157        const existSdk = await existDir(downloadPath);
158        if (existSdk) {
159            await clearDir(downloadPath);
160        } else {
161            await mkdir(downloadPath);
162        }
163
164        const existSdkPath = await existDir(sdkPath);
165        const existBackUpSdkPath = await existDir(`${sdkPath}-backup`);
166        if (existBackUpSdkPath) {
167            await deleteDir(`${sdkPath}-backup`);
168        }
169        if (existSdkPath) {
170            await renameDir(sdkPath, `${sdkPath}-backup`);
171            await mkdir(sdkPath);
172        } else {
173            await mkdir(sdkPath);
174        }
175        await downloadSdk(url, downloadPath);
176        await extractLargeZip(path.join(downloadPath, "ohos-sdk.zip"), downloadPath);
177
178        if (judgePlatform) {
179            ohosSdkPath = path.join(downloadPath, 'windows');
180        } else {
181            ohosSdkPath = path.join(downloadPath, 'linux');
182        }
183
184        let zipFiles = await readDir(ohosSdkPath);
185        for (let i = 0; i < zipFiles.length; i++) {
186            await extractZipFile(zipFiles[i], ohosSdkPath);
187        }
188
189        let sdks = await readDir(ohosSdkPath);
190        for (let i = 0; i < sdks.length; i++) {
191            if (sdks[i].includes(".zip") !== true) {
192                await moveDir(sdks[i], sdkPath);
193            }
194        }
195        let etsFile = path.join(etsPath, "@ohos.arkui.componentTest.d.ts");
196        if (await isExistFile(etsFile)) {
197            await copyFile("previewer_host\\resource\\componentTest.ts", etsFile)
198        }
199    } catch (error) {
200        console.log("准备环境过程出错,恢复初始状态");
201
202        if (await isExistFile(downloadPath)) {
203            await clearDir(downloadPath);
204        }
205
206        if (await isExistFile(sdkPath)) {
207            await deleteDir(sdkPath);
208        }
209
210        if (await isExistFile(`${sdkPath}-backup`)) {
211            await renameDir(`${sdkPath}-backup`, sdkPath);
212        }
213        console.log("环境清理完成");
214        throw error;
215    }
216}