UNPKG

esa-cli

Version:

A CLI for operating Alibaba Cloud ESA Functions and Pages.

183 lines (182 loc) 6.81 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { exec } from 'child_process'; import * as fs from 'fs/promises'; import os from 'os'; import * as path from 'path'; import { promisify } from 'util'; import AdmZip from 'adm-zip'; import chalk from 'chalk'; import fetch from 'node-fetch'; import t from '../i18n/index.js'; import logger from '../libs/logger.js'; const execAsync = promisify(exec); function getBinDir() { const home = os.homedir(); return path.join(home || '', '.deno', 'bin'); } /** * 下载文件 * @param url 远程文件URL * @param dest 本地保存路径 */ export function downloadFile(url, dest) { return __awaiter(this, void 0, void 0, function* () { const response = yield fetch(url); if (!response.ok) { throw new Error(`Error downloading file: ${response.status} ${response.statusText}`); } const fileStream = yield fs.open(dest, 'w'); return new Promise((resolve, reject) => { var _a, _b; (_a = response.body) === null || _a === void 0 ? void 0 : _a.pipe(fileStream.createWriteStream()); (_b = response.body) === null || _b === void 0 ? void 0 : _b.on('error', (err) => { fileStream.close(); reject(err); }); fileStream.createWriteStream().on('finish', () => { fileStream.close(); resolve(); }); }); }); } /** * 解压Zip文件 adm 是同步的 * @param zipPath Zip文件路径 * @param extractPath 解压目标目录 */ export function unzipFile(zipPath, extractPath) { const zip = new AdmZip(zipPath); zip.extractAllTo(extractPath, true); logger.info(`UnzipFile success: from ${zipPath} to ${extractPath}`); } /** * 获取用户的 PATH 环境变量(win下专用) * @returns 用户 PATH */ function getUserPath() { return __awaiter(this, void 0, void 0, function* () { const { stdout } = yield execAsync('reg query "HKCU\\Environment" /v Path'); const match = stdout.match(/Path\s+REG_EXPAND_SZ\s+(.*)/i); if (match && match[1]) { return match[1].trim(); } return ''; }); } /** * 检查 BinDir 是否在用户的 PATH 中(win下专用) * @param binDir BinDir 路径 * @returns 是否包含 */ function isBinDirInPath(binDir) { return __awaiter(this, void 0, void 0, function* () { const userPath = yield getUserPath(); return userPath .split(';') .map((p) => p.toLowerCase()) .includes(binDir.toLowerCase()); }); } /** * 将 BinDir 添加到用户的 PATH 环境变量(win下专用) * @param binDir BinDir 路径 */ function addBinDirToPath(binDir) { return __awaiter(this, void 0, void 0, function* () { // Use setx to add to PATH // setx has a 2047 character limit for PATH const command = `setx Path "%Path%;${binDir}"`; try { yield execAsync(command); logger.info(`Path add success: ${binDir}`); } catch (error) { throw new Error(`Add BinDir to Path failed: ${error}`); } }); } export function downloadRuntimeAndUnzipForWindows() { return __awaiter(this, void 0, void 0, function* () { try { const BinDir = getBinDir(); const DenoZip = path.join(BinDir, 'deno.zip'); const Target = 'x86_64-pc-windows-msvc'; const DownloadUrl = `http://esa-runtime.myalicdn.com/runtime/deno-${Target}.zip`; logger.ora.start('Downloading...'); try { yield fs.mkdir(BinDir, { recursive: true }); } catch (error) { const err = error; logger.ora.fail(); logger.error(`mkdir error ${BinDir}: ${err.message}`); process.exit(1); } try { yield downloadFile(DownloadUrl, DenoZip); } catch (error) { const err = error; logger.ora.fail(); logger.error(`${t('deno_download_failed').d('Download failed')}: ${err.message}`); process.exit(1); } logger.info(`Unzip file to: ${BinDir}`); try { logger.ora.text = 'Unzip...'; unzipFile(DenoZip, BinDir); } catch (error) { const err = error; logger.ora.fail(); logger.error(`${t('deno_unzip_failed').d('Unzip failed')}: ${err.message}`); process.exit(1); } try { logger.ora.text = 'Deleting temp file...'; yield fs.unlink(DenoZip); logger.ora.succeed('Download success'); logger.info(`Delete temp file: ${DenoZip}`); } catch (error) { logger.warn(`Delete temp file ${DenoZip} failed: ${error}`); } try { logger.ora.text = 'Adding Bin dir to PATH...'; const inPath = yield isBinDirInPath(BinDir); if (!inPath) { logger.info(`${BinDir} not in PATH`); yield addBinDirToPath(BinDir); } else { logger.info(`${BinDir} in PATH already`); } } catch (error) { const err = error; logger.ora.fail(); logger.error(`${t('deno_add_path_failed').d('Add BinDir to Path failed')}: ${err.message}`); process.exit(1); } logger.success(t('deno_install_success').d('Runtime install success!')); logger.block(); const dev = chalk.green('esa-cli dev'); logger.log(t('deno_install_success_tips', { dev }).d(`Please run ${dev} again`)); } catch (error) { const err = error; logger.ora.fail(); logger.error(`Download Error: ${err.message}`); process.exit(1); } }); }