yds-tool 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/app.js +74 -0
- package/bin/cli.js +3 -0
- package/bin/index.js +3 -0
- package/bin/main.js +459 -0
- package/package.json +44 -0
- package/readme.md +24 -0
- package/src/main.ts +479 -0
package/bin/app.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
|
|
2
|
+
// 禁用vweb logo
|
|
3
|
+
global.__vweb_logo = false;
|
|
4
|
+
const {LoggerFactory, startup, defineEnvironment, getApplicationContext } = require('vweb-core');
|
|
5
|
+
const confUtil = require('vweb-core/lib/conf/util')
|
|
6
|
+
const {program} = require('commander');
|
|
7
|
+
confUtil.logger.info = () => {}
|
|
8
|
+
|
|
9
|
+
!(() => {
|
|
10
|
+
const {program} = require('commander');
|
|
11
|
+
let result = program.parseOptions(process.argv);
|
|
12
|
+
for (let i = 0; i < result.unknown?.length; i++) {
|
|
13
|
+
let name = result.unknown[i];
|
|
14
|
+
let value = result.unknown[i + 1] || '';
|
|
15
|
+
if (!value || value.startsWith('-')) continue;
|
|
16
|
+
if (name === '-l' || name === '--level') {
|
|
17
|
+
process.env.level = value;
|
|
18
|
+
}
|
|
19
|
+
}})()
|
|
20
|
+
|
|
21
|
+
process.on('unhandledRejection', (reason, p) => {
|
|
22
|
+
console.error(`${reason}`, p);
|
|
23
|
+
});
|
|
24
|
+
startup({
|
|
25
|
+
conf: defineEnvironment({
|
|
26
|
+
app: {
|
|
27
|
+
name: 'yds'
|
|
28
|
+
},
|
|
29
|
+
config: {
|
|
30
|
+
src: 'lib'
|
|
31
|
+
},
|
|
32
|
+
logger: {
|
|
33
|
+
appenders: {
|
|
34
|
+
console: {
|
|
35
|
+
type: 'console'
|
|
36
|
+
},
|
|
37
|
+
file: {
|
|
38
|
+
type: 'dateFile',
|
|
39
|
+
filename: 'yds',
|
|
40
|
+
pattern: 'yyyy-MM-dd.log',
|
|
41
|
+
alwaysIncludePattern: true,
|
|
42
|
+
compress: true,
|
|
43
|
+
numBackups: 7,
|
|
44
|
+
keepFileExt: true,
|
|
45
|
+
layout: {
|
|
46
|
+
type: 'pattern',
|
|
47
|
+
pattern: '%d{yyyy-MM-dd hh.mm.ss.SSS} [%p] %m'
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
categories: {
|
|
52
|
+
default: {
|
|
53
|
+
appenders: [
|
|
54
|
+
'console', 'file'
|
|
55
|
+
],
|
|
56
|
+
level: '${level:info}'
|
|
57
|
+
},
|
|
58
|
+
VWebApplicationContext: {
|
|
59
|
+
appenders: [
|
|
60
|
+
'file'
|
|
61
|
+
],
|
|
62
|
+
level: '${level:info}'
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
disableClustering: true
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
}).then(() => {
|
|
69
|
+
let Main = require('./index');
|
|
70
|
+
return new Main(getApplicationContext()).startup();
|
|
71
|
+
}).catch(err => {
|
|
72
|
+
console.log(err);
|
|
73
|
+
})
|
|
74
|
+
|
package/bin/cli.js
ADDED
package/bin/index.js
ADDED
package/bin/main.js
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const commander_1 = require("commander");
|
|
46
|
+
const process = __importStar(require("process"));
|
|
47
|
+
const vweb_core_1 = require("vweb-core");
|
|
48
|
+
const path = __importStar(require("node:path"));
|
|
49
|
+
const child_process = __importStar(require("node:child_process"));
|
|
50
|
+
const fs = __importStar(require("node:fs"));
|
|
51
|
+
const os = __importStar(require("node:os"));
|
|
52
|
+
const crypto_1 = require("crypto");
|
|
53
|
+
const domainKey = 'p-hcc-i000-p00a-hrcpe';
|
|
54
|
+
const pkg = require('../package.json');
|
|
55
|
+
const RS_URL = 'https://dfs.zhiper.com/v3r6';
|
|
56
|
+
const logger = vweb_core_1.LoggerFactory.getLogger('YDS');
|
|
57
|
+
const execCmd = (command, cwd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
+
logger.info(`执行命令 ${command} ${cwd ? `,执行目录为${cwd}` : ''}`);
|
|
59
|
+
let start = Date.now();
|
|
60
|
+
child_process.execSync(command, {
|
|
61
|
+
cwd, encoding: 'utf-8',
|
|
62
|
+
timeout: 60000,
|
|
63
|
+
stdio: [0, 1, 2]
|
|
64
|
+
});
|
|
65
|
+
logger.info(`执行命令 ${command} 耗时 \x1B[34m <${Date.now() - start}ms>]`);
|
|
66
|
+
});
|
|
67
|
+
const platform = os.platform();
|
|
68
|
+
if (platform !== 'win32') {
|
|
69
|
+
logger.error('当前工具仅支持windows系统');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const isAdmin = () => {
|
|
73
|
+
try {
|
|
74
|
+
child_process.execSync('net session >nul 2>&1');
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
let wget = path.resolve('wget.exe');
|
|
82
|
+
let zip = path.resolve('zip.exe');
|
|
83
|
+
let unzip = path.resolve('unzip.exe');
|
|
84
|
+
commander_1.program.name("yds")
|
|
85
|
+
.usage("[command] [options]")
|
|
86
|
+
.description("yds 制盘工具 如果命令参数中存在空格 使用双引号\"\"包裹")
|
|
87
|
+
.version(`yds ${pkg.version}`);
|
|
88
|
+
class Main {
|
|
89
|
+
startup() {
|
|
90
|
+
commander_1.program
|
|
91
|
+
.command('init [workdir]')
|
|
92
|
+
.usage('init [workdir]')
|
|
93
|
+
.description('初始化YDS制盘环境, workdir表示制盘工作目录,如果不指定则使用当前目录')
|
|
94
|
+
.action((...args_1) => __awaiter(this, [...args_1], void 0, function* (workdir = path.resolve(process.cwd())) {
|
|
95
|
+
const dir = path.resolve(workdir);
|
|
96
|
+
logger.info(`初始化YDS制盘环境 工作目录:${dir}`);
|
|
97
|
+
const gitExists = yield vweb_core_1.util.cmd.exists('git');
|
|
98
|
+
logger.info(`检查是否安装了git >> ${gitExists ? '已安装' : '未安装'}`);
|
|
99
|
+
if (!gitExists && !fs.existsSync(`${dir}/git-for-windows`)) {
|
|
100
|
+
const gitZipName = 'git-for-windows.zip';
|
|
101
|
+
logger.info(`下载git 安装包 ${gitZipName}`);
|
|
102
|
+
const gitZipFile = `${dir}/${gitZipName}`;
|
|
103
|
+
if (fs.existsSync(gitZipFile)) {
|
|
104
|
+
logger.info(`删除已存在安装包 ${gitZipFile}`);
|
|
105
|
+
fs.rmSync(gitZipFile);
|
|
106
|
+
}
|
|
107
|
+
yield execCmd(`${wget} ${RS_URL}/${gitZipName} -O "${gitZipFile}"`);
|
|
108
|
+
logger.info(`解压安装包 ${gitZipFile}`);
|
|
109
|
+
yield execCmd(`"${unzip}" "${gitZipFile}" -d "${dir}"`);
|
|
110
|
+
fs.rmSync(gitZipFile);
|
|
111
|
+
logger.info(`git 安装完成`);
|
|
112
|
+
}
|
|
113
|
+
const javaExists = yield vweb_core_1.util.cmd.exists('java');
|
|
114
|
+
logger.info(`检查是否安装了java >> ${javaExists ? '已安装' : '未安装'}`);
|
|
115
|
+
if (!javaExists) {
|
|
116
|
+
logger.info('未找到java,准备安装java,开始下载jdk');
|
|
117
|
+
const jdkZipName = 'jdk-11.0.15.1_windows-x64_bin.zip';
|
|
118
|
+
yield execCmd(`${wget} ${RS_URL}/${jdkZipName} -O "${dir}/${jdkZipName}"`);
|
|
119
|
+
logger.info(`解压jdk 安装包 ${dir}/${jdkZipName}`);
|
|
120
|
+
yield execCmd(`"${unzip}" "${dir}/${jdkZipName}"`, dir);
|
|
121
|
+
logger.info(`配置java环境变量`);
|
|
122
|
+
let javaHome = `${dir}/jdk-11.0.15.1`;
|
|
123
|
+
yield execCmd(`setx JAVA_HOME "${javaHome}"`);
|
|
124
|
+
yield execCmd(`setx CLASS_PATH ".;%JAVA_HOME%\lib;"`);
|
|
125
|
+
yield execCmd(`setx PATH "%PATH%;%JAVA_HOME%\bin;"`);
|
|
126
|
+
process.env.JAVA_HOME = javaHome;
|
|
127
|
+
logger.info(`java 安装完成`);
|
|
128
|
+
}
|
|
129
|
+
logger.info(`检查java版本`);
|
|
130
|
+
yield execCmd('java -version');
|
|
131
|
+
const javaHome = process.env.JAVA_HOME;
|
|
132
|
+
if (javaHome) {
|
|
133
|
+
let certsFilename = 'lib/security/cacerts';
|
|
134
|
+
let certsFile = `${javaHome}/${certsFilename}`;
|
|
135
|
+
if (!fs.existsSync(certsFile)) {
|
|
136
|
+
certsFile = `${javaHome}/jre/${certsFilename}`;
|
|
137
|
+
}
|
|
138
|
+
logger.info(`检查java证书目录 ${certsFile}`);
|
|
139
|
+
if (fs.existsSync(certsFile)) {
|
|
140
|
+
try {
|
|
141
|
+
yield execCmd(`keytool -list -v -keystore "${certsFile}" -storepass changeit --alias yyrd`);
|
|
142
|
+
logger.info(`yyrd.crt 证书已存在`);
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
logger.info(`导入 yyrd.crt 证书到java ${certsFile}`);
|
|
146
|
+
yield execCmd(`keytool -importcert -file "${dir}/yyrd.crt" -keystore "${certsFile}" -storepass changeit -noprompt`);
|
|
147
|
+
logger.info(`yyrd.crt 证书导入完成`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const mavenHome = `${dir}/maven-3.8.6`;
|
|
152
|
+
const mavenExists = vweb_core_1.util.cmd.exists('mvn');
|
|
153
|
+
logger.info(`检查是否安装了maven >> ${mavenExists ? '已安装' : '未安装'}`);
|
|
154
|
+
if (!mavenExists) {
|
|
155
|
+
const mavenZipName = 'maven-3.8.6.zip';
|
|
156
|
+
logger.info(`下载maven 安装包 ${mavenZipName}`);
|
|
157
|
+
const mavenZipFile = `${dir}/${mavenZipName}`;
|
|
158
|
+
if (fs.existsSync(mavenZipFile)) {
|
|
159
|
+
logger.info(`删除已存在安装包 ${mavenZipFile}`);
|
|
160
|
+
fs.rmSync(mavenZipFile);
|
|
161
|
+
}
|
|
162
|
+
yield execCmd(`${wget} ${RS_URL}/${mavenZipName} -O "${mavenZipFile}"`);
|
|
163
|
+
logger.info(`解压安装包 ${mavenZipFile}`);
|
|
164
|
+
yield execCmd(`"${unzip}" "${mavenZipFile}" -d "${dir}"`);
|
|
165
|
+
fs.rmSync(mavenZipFile);
|
|
166
|
+
try {
|
|
167
|
+
let mvnPath = path.resolve(`${mavenHome}/bin`);
|
|
168
|
+
yield execCmd(`setx PATH "%PATH%;${mvnPath}"`);
|
|
169
|
+
logger.info(`✅ 成功!Maven路径【${mvnPath}】已添加到系统PATH环境变量`);
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
console.error('❌ 添加失败:', err.message);
|
|
173
|
+
}
|
|
174
|
+
logger.info(`maven 安装完成`);
|
|
175
|
+
}
|
|
176
|
+
logger.info(`初始化node环境`);
|
|
177
|
+
yield execCmd('npm install -g pnpm typescript --registry=https://registry.npmmirror.com');
|
|
178
|
+
logger.info(`初始化node环境完成`);
|
|
179
|
+
logger.info(`检测code是否存在`);
|
|
180
|
+
const codeDir = `${dir}/yds-1.0.3`;
|
|
181
|
+
if (!fs.existsSync(codeDir)) {
|
|
182
|
+
const codeZipName = 'yds-1.0.3-jdk-8-windows-x86_64.zip';
|
|
183
|
+
logger.info(`下载code IDE 安装包 ${codeZipName}`);
|
|
184
|
+
const codeZipFile = `${dir}/${codeZipName}`;
|
|
185
|
+
if (fs.existsSync(codeZipFile)) {
|
|
186
|
+
logger.info(`删除已存在安装包 ${codeZipFile}`);
|
|
187
|
+
fs.rmSync(codeZipFile);
|
|
188
|
+
}
|
|
189
|
+
yield execCmd(`${wget} https://yoncommunity.yonyoucloud.com/YDSDownload/Window/x64/${codeZipName} -O "${codeZipFile}"`);
|
|
190
|
+
logger.info(`解压安装包 ${codeZipFile}`);
|
|
191
|
+
fs.mkdirSync(codeDir, { recursive: true });
|
|
192
|
+
yield execCmd(`"${unzip}" "${codeZipFile}" -d "${codeDir}"`);
|
|
193
|
+
fs.rmSync(codeZipFile);
|
|
194
|
+
yield new Promise((resolve) => setTimeout(resolve, 5000));
|
|
195
|
+
logger.info(`code IDE 安装完成`);
|
|
196
|
+
}
|
|
197
|
+
logger.info(`初始化YDS IDE 全局配置`);
|
|
198
|
+
const settingsJson = `${codeDir}/Code/data/user-data/User/settings.json`;
|
|
199
|
+
let settingsJsonObj = {};
|
|
200
|
+
if (fs.existsSync(settingsJson)) {
|
|
201
|
+
settingsJsonObj = JSON.parse(fs.readFileSync(settingsJson).toString('utf-8'));
|
|
202
|
+
}
|
|
203
|
+
let settingXml = path.resolve(`${mavenHome}/conf/settings.xml`);
|
|
204
|
+
if (!fs.existsSync(settingXml) && !fs.existsSync(`${dir}/settings.xml`)) {
|
|
205
|
+
yield execCmd(`${wget} ${RS_URL}/settings.xml`);
|
|
206
|
+
settingXml = path.resolve(`${dir}/settings.xml`);
|
|
207
|
+
}
|
|
208
|
+
settingsJsonObj["java.configuration.maven.globalSettings"] = settingXml;
|
|
209
|
+
settingsJsonObj["java.configuration.maven.userSettings"] = settingXml;
|
|
210
|
+
settingsJsonObj["maven.settingsFile"] = settingXml;
|
|
211
|
+
fs.writeFileSync(settingsJson, JSON.stringify(settingsJsonObj, null, 4));
|
|
212
|
+
logger.info(`初始化YDS IDE 全局配置完成`);
|
|
213
|
+
const sshDir = path.resolve(process.env.USERPROFILE, '.ssh');
|
|
214
|
+
if (!fs.existsSync(sshDir)) {
|
|
215
|
+
fs.mkdirSync(sshDir);
|
|
216
|
+
}
|
|
217
|
+
if (!fs.existsSync(`${sshDir}/id_ed25519.pub`)) {
|
|
218
|
+
logger.info(`拷贝密钥文件`);
|
|
219
|
+
fs.copyFileSync(`${dir}/id_ed25519.pub`, `${sshDir}/id_ed25519.pub`);
|
|
220
|
+
fs.copyFileSync(`${dir}/id_ed25519`, `${sshDir}/id_ed25519`);
|
|
221
|
+
logger.info(`拷贝密钥文件完成`);
|
|
222
|
+
}
|
|
223
|
+
logger.info(`初始化YDS制盘环境完成`);
|
|
224
|
+
})).hook('postAction', () => process.exit(0));
|
|
225
|
+
commander_1.program
|
|
226
|
+
.command('start <catalog> [workdir]')
|
|
227
|
+
.usage('start <catalog> [workdir]')
|
|
228
|
+
.option('-f, --file <file>', '配置文件')
|
|
229
|
+
.addHelpText('after', `
|
|
230
|
+
配置文件内容示例:
|
|
231
|
+
{
|
|
232
|
+
hosts?: Array<string>;
|
|
233
|
+
git: Record<'hrcpe' | 'fecode', string>;
|
|
234
|
+
catalogs: {
|
|
235
|
+
[catalog: string]: Record<'hrcpe' | 'fecode', string | { url: string, branch: string }>
|
|
236
|
+
}
|
|
237
|
+
}`)
|
|
238
|
+
.description('启动制盘环境,catalog表示需要制盘的模块,对应配置文件中catalogs的key值,用于指定需要出盘的信息,workdir表示制盘工作目录,如果不指定则使用当前目录')
|
|
239
|
+
.action((catalog_1, ...args_1) => __awaiter(this, [catalog_1, ...args_1], void 0, function* (catalog, workdir = path.resolve(process.cwd()), options) {
|
|
240
|
+
const dir = path.resolve(workdir);
|
|
241
|
+
logger.info(`开始检测制盘环境检测`);
|
|
242
|
+
let gitCmd = 'git';
|
|
243
|
+
const gitExists = yield vweb_core_1.util.cmd.exists(gitCmd);
|
|
244
|
+
if (!gitExists) {
|
|
245
|
+
gitCmd = `${dir}/git-for-windows/bin/git.exe`;
|
|
246
|
+
if (!fs.existsSync(gitCmd)) {
|
|
247
|
+
logger.error(`未找到git命令 ${gitCmd}, 请先执行 init 初始化制盘环境`);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
let settingXml = path.resolve(`${dir}/settings.xml`);
|
|
252
|
+
let mvnCmd = 'mvn';
|
|
253
|
+
if (!fs.existsSync(settingXml)) {
|
|
254
|
+
let mavenHome = `${dir}/maven-3.8.6`;
|
|
255
|
+
mvnCmd = `"${mavenHome}/bin/mvn.cmd"`;
|
|
256
|
+
settingXml = `${mavenHome}/conf/settings.xml`;
|
|
257
|
+
if (!fs.existsSync(mvnCmd)) {
|
|
258
|
+
logger.error(`未找到mvn命令 ${mvnCmd}, 请先执行 init 初始化制盘环境`);
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
let idePath = `${dir}/yds-1.0.3`;
|
|
263
|
+
if (!fs.existsSync(idePath)) {
|
|
264
|
+
logger.error(`未找到IDE ${idePath}, 请先执行 init 初始化制盘环境`);
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
logger.info(`制盘环境检测完成`);
|
|
268
|
+
const ydsJson = path.resolve(options.file || `${dir}/yds.json`);
|
|
269
|
+
logger.info(`开始制盘 ${catalog} 工作目录:${dir}`);
|
|
270
|
+
if (!fs.existsSync(ydsJson)) {
|
|
271
|
+
logger.error(`未找到配置文件 ${ydsJson}`);
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
274
|
+
const ydsJsonStr = fs.readFileSync(ydsJson).toString('utf-8');
|
|
275
|
+
let config;
|
|
276
|
+
const checkConfigError = () => {
|
|
277
|
+
logger.error(`配置文件 ${ydsJson} 格式错误 参考示例:
|
|
278
|
+
{
|
|
279
|
+
hosts?: Array<string>;
|
|
280
|
+
git: Record<'hrcpe' | 'fecode', string>;
|
|
281
|
+
catalogs: {
|
|
282
|
+
[catalog: string]: Record<'hrcpe' | 'fecode', string | { url: string, branch: string }>
|
|
283
|
+
}
|
|
284
|
+
}`);
|
|
285
|
+
process.exit(1);
|
|
286
|
+
};
|
|
287
|
+
try {
|
|
288
|
+
config = JSON.parse(ydsJsonStr);
|
|
289
|
+
if (!config.catalogs) {
|
|
290
|
+
checkConfigError();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (e) {
|
|
294
|
+
checkConfigError();
|
|
295
|
+
}
|
|
296
|
+
const git = config.git;
|
|
297
|
+
const catalogConfig = config.catalogs[catalog];
|
|
298
|
+
if (typeof catalogConfig === 'undefined') {
|
|
299
|
+
logger.error(`配置文件 ${ydsJson} 找不到 catalogs.${catalog} 先关配置`);
|
|
300
|
+
process.exit(1);
|
|
301
|
+
}
|
|
302
|
+
if (typeof catalogConfig.hrcpe === 'undefined' || typeof catalogConfig.fecode === 'undefined') {
|
|
303
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog}.hrcpe 或 catalogs.${catalog}.fecode 字段缺失`);
|
|
304
|
+
process.exit(1);
|
|
305
|
+
}
|
|
306
|
+
const namespace = `${dir}/${catalog}`;
|
|
307
|
+
if (!fs.existsSync(namespace)) {
|
|
308
|
+
logger.info(`创建目录 ${namespace}`);
|
|
309
|
+
fs.mkdirSync(namespace);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
logger.info(`目录 ${namespace} 已存在`);
|
|
313
|
+
}
|
|
314
|
+
let hrcpeUrl = typeof catalogConfig.hrcpe === 'string' ? git === null || git === void 0 ? void 0 : git.hrcpe : catalogConfig.hrcpe.url;
|
|
315
|
+
if (!hrcpeUrl) {
|
|
316
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 后端服务 未指定仓库地址,请通过 git.hrcpe 或者 catalogs.${catalog}.hrcpe.url 指定仓库地址`);
|
|
317
|
+
}
|
|
318
|
+
logger.info(`开始拉取后端服务仓库 ${hrcpeUrl}`);
|
|
319
|
+
if (fs.existsSync(`${namespace}/.git`)) {
|
|
320
|
+
logger.info(`目录 ${namespace} 已存在,开始更新仓库`);
|
|
321
|
+
yield execCmd(`"${gitCmd}" pull`, namespace);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
logger.info(`目录 ${namespace} 不存在,开始创建仓库`);
|
|
325
|
+
let branch = typeof catalogConfig.hrcpe === 'string' ? catalogConfig.hrcpe : catalogConfig.hrcpe.branch;
|
|
326
|
+
if (!branch) {
|
|
327
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 后端服务 未指定分支,请通过 git.hrcpe 或者 catalogs.${catalog}.hrcpe.branch 配置分支`);
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
yield execCmd(`"${gitCmd}" clone -b ${branch} ${hrcpeUrl} ${namespace}`, namespace);
|
|
331
|
+
}
|
|
332
|
+
logger.info(`拉取后端服务仓库完成`);
|
|
333
|
+
let boostrapPomXml = `${namespace}/${domainKey}-be/dev-${domainKey}-bootstrap/pom.xml`;
|
|
334
|
+
logger.info(`替换文件 ${boostrapPomXml} 中的ROOT为domainKey,否则会导致制盘失败,无法找到制品`);
|
|
335
|
+
const boostrapPomXmlString = fs.readFileSync(boostrapPomXml).toString('utf-8');
|
|
336
|
+
if (boostrapPomXmlString.includes('ROOT')) {
|
|
337
|
+
fs.writeFileSync(boostrapPomXml, boostrapPomXmlString.replace(/ROOT/g, domainKey));
|
|
338
|
+
}
|
|
339
|
+
if (config.hosts && config.hosts.length) {
|
|
340
|
+
logger.info(`存在hosts配置,检测系统hosts配置文件是否已经配置`);
|
|
341
|
+
let hostsFile = path.resolve(process.env.WINDIR, 'System32', 'drivers', 'etc', 'hosts');
|
|
342
|
+
const hostList = fs.readFileSync(hostsFile).toString('utf-8').split('\n');
|
|
343
|
+
let appendHosts = [...config.hosts];
|
|
344
|
+
for (let hostItem of hostList) {
|
|
345
|
+
if (/#/.test(hostItem)) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
for (let appendHost of config.hosts) {
|
|
349
|
+
const [ip, domain] = appendHost.split(' ').filter(item => item);
|
|
350
|
+
if (hostItem.includes(ip) && hostItem.includes(domain)) {
|
|
351
|
+
logger.info(`系统hosts配置文件已存在 ${appendHost}`);
|
|
352
|
+
appendHosts.remove(appendHost);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (appendHosts.length) {
|
|
357
|
+
if (isAdmin()) {
|
|
358
|
+
fs.appendFileSync(hostsFile, `\n${appendHosts.join('\n')}\n`, {
|
|
359
|
+
encoding: 'utf-8'
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
logger.error(`当前非管理员启动无法更改hosts文件,请使用管理员启动或者手动添加 ${appendHosts.join('\n')} 到文件 ${hostsFile}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
logger.info(`hosts 配置检测完成`);
|
|
367
|
+
}
|
|
368
|
+
logger.info('初始化项目maven环境');
|
|
369
|
+
let mvnConfigDir = `${namespace}/.mvn`;
|
|
370
|
+
if (!fs.existsSync(mvnConfigDir)) {
|
|
371
|
+
yield execCmd(`${mvnCmd} -N io.takari:maven:wrapper -Dmaven=3.8.6`, namespace);
|
|
372
|
+
}
|
|
373
|
+
let configFile = `${mvnConfigDir}/maven.config`;
|
|
374
|
+
if (fs.existsSync(configFile)) {
|
|
375
|
+
fs.rmSync(configFile);
|
|
376
|
+
}
|
|
377
|
+
fs.writeFileSync(`${mvnConfigDir}/maven.config`, `-s\n${settingXml}\n-Dmaven.wagon.http.ssl.insecure=true\n-Dmaven.wagon.http.ssl.allowall=true`);
|
|
378
|
+
logger.info(`当前maven信息`);
|
|
379
|
+
yield execCmd(`${mvnCmd} --version`, namespace);
|
|
380
|
+
logger.info('项目maven清理');
|
|
381
|
+
yield execCmd(`${mvnCmd} clean -DskipTests`, `${namespace}/${domainKey}-be`);
|
|
382
|
+
logger.info('处理前端构建,增加构建文件');
|
|
383
|
+
let feDir = `${namespace}/${domainKey}-fe`;
|
|
384
|
+
let feBuildJs = `${feDir}/build.js`;
|
|
385
|
+
if (!fs.existsSync(feBuildJs)) {
|
|
386
|
+
fs.cpSync(`${dir}/fe-build.js`, feBuildJs);
|
|
387
|
+
}
|
|
388
|
+
let fePackageJson = `${feDir}/package.json`;
|
|
389
|
+
const packageString = fs.readFileSync(fePackageJson).toString('utf-8');
|
|
390
|
+
if (!packageString.includes('build.js')) {
|
|
391
|
+
logger.info(`修改${fePackageJson}`);
|
|
392
|
+
const packageJson = JSON.parse(packageString);
|
|
393
|
+
packageJson.scripts['build:extend'] += ' && node build.js';
|
|
394
|
+
fs.writeFileSync(fePackageJson, JSON.stringify(packageJson, null, 4));
|
|
395
|
+
logger.info(`修改${fePackageJson}完成`);
|
|
396
|
+
}
|
|
397
|
+
let fecodeUrl = typeof catalogConfig.fecode === 'string' ? git === null || git === void 0 ? void 0 : git.fecode : catalogConfig.fecode.url;
|
|
398
|
+
if (!fecodeUrl) {
|
|
399
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 后端服务 未指定仓库地址,请通过 git.fecode 或者 catalogs.${catalog}.fecode.url 指定仓库地址`);
|
|
400
|
+
}
|
|
401
|
+
logger.info(`开始拉取报告服务仓库 ${fecodeUrl}`);
|
|
402
|
+
let reportNamespace = `${namespace}/yonbip-yisv-izp1-dev-fecode`;
|
|
403
|
+
if (fs.existsSync(`${reportNamespace}/.git`)) {
|
|
404
|
+
logger.info(`目录 ${reportNamespace} 已存在,开始更新仓库`);
|
|
405
|
+
yield execCmd(`"${gitCmd}" pull`, reportNamespace);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
logger.info(`目录 ${reportNamespace} 不存在,开始创建仓库`);
|
|
409
|
+
let branch = typeof catalogConfig.fecode === 'string' ? catalogConfig.fecode : catalogConfig.fecode.branch;
|
|
410
|
+
if (!branch) {
|
|
411
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 报告服务未指定分支,请通过 git.fecode 或者 catalogs.${catalog}.fecode.branch 配置分支`);
|
|
412
|
+
process.exit(1);
|
|
413
|
+
}
|
|
414
|
+
yield execCmd(`"${gitCmd}" clone -b ${branch} ${fecodeUrl} ${reportNamespace}`);
|
|
415
|
+
}
|
|
416
|
+
logger.info(`拉取报告服务仓库完成`);
|
|
417
|
+
logger.info('处理报告构建,增加构建文件');
|
|
418
|
+
let fecodeBuildJs = `${reportNamespace}/build.js`;
|
|
419
|
+
if (!fs.existsSync(fecodeBuildJs)) {
|
|
420
|
+
fs.cpSync(`${dir}/fecode-build.js`, fecodeBuildJs);
|
|
421
|
+
}
|
|
422
|
+
let fecodePackageJson = `${reportNamespace}/package.json`;
|
|
423
|
+
const fecodePackageString = fs.readFileSync(fecodePackageJson).toString('utf-8');
|
|
424
|
+
if (!fecodePackageString.includes('build.js')) {
|
|
425
|
+
logger.info(`修改${fecodePackageJson}`);
|
|
426
|
+
const packageJson = JSON.parse(fecodePackageString);
|
|
427
|
+
packageJson.scripts['build'] += ' && node build.js';
|
|
428
|
+
packageJson.domainKey = domainKey;
|
|
429
|
+
delete packageJson.dependencies.zlib;
|
|
430
|
+
fs.writeFileSync(fecodePackageJson, JSON.stringify(packageJson, null, 4));
|
|
431
|
+
logger.info(`修改${fecodePackageJson}完成`);
|
|
432
|
+
}
|
|
433
|
+
logger.info(`安装报告服务依赖`);
|
|
434
|
+
yield execCmd('npm i', reportNamespace);
|
|
435
|
+
logger.info(`生成version.json 文件`);
|
|
436
|
+
const uuid = (0, crypto_1.randomUUID)().toString();
|
|
437
|
+
fs.writeFileSync(`${reportNamespace}/version.json`, `{"version": "${uuid}"}`);
|
|
438
|
+
logger.info('初始化项目环境资源');
|
|
439
|
+
if (fs.existsSync(`${namespace}/disk`) || fs.existsSync(`${namespace}/disks`)) {
|
|
440
|
+
logger.info(`已存在,跳过环境资源文件下载`);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
logger.info(`开始下载项目环境资源文件`);
|
|
444
|
+
let gitZipFile = `${namespace}/env.zip`;
|
|
445
|
+
yield execCmd(`${wget} ${RS_URL}/env.zip -O "${gitZipFile}"`);
|
|
446
|
+
logger.info(`解压资源文件包 ${gitZipFile}`);
|
|
447
|
+
yield execCmd(`"${unzip}" "${gitZipFile}"`, namespace);
|
|
448
|
+
fs.rmSync(gitZipFile);
|
|
449
|
+
}
|
|
450
|
+
logger.info('启动IDE');
|
|
451
|
+
yield execCmd(`"${idePath}/Code/Code.exe" "${namespace}"`);
|
|
452
|
+
yield new Promise(resolve => setTimeout(resolve, 3000));
|
|
453
|
+
logger.info('已启动IDE,请按照文档说明进行制盘操作');
|
|
454
|
+
})).hook('postAction', () => process.exit(0));
|
|
455
|
+
commander_1.program.parse(process.argv);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
exports.default = Main;
|
|
459
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEseUNBQWtDO0FBQ2xDLGlEQUFtQztBQUNuQyx5Q0FBOEM7QUFDOUMsZ0RBQWtDO0FBQ2xDLGtFQUFvRDtBQUNwRCw0Q0FBOEI7QUFDOUIsNENBQThCO0FBQzlCLG1DQUFpQztBQUVqQyxNQUFNLFNBQVMsR0FBRyx1QkFBdUIsQ0FBQztBQUMxQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUN2QyxNQUFNLE1BQU0sR0FBRyw2QkFBNkIsQ0FBQztBQUU3QyxNQUFNLE1BQU0sR0FBVyx5QkFBYSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV0RCxNQUFNLE9BQU8sR0FBRyxDQUFPLE9BQWUsRUFBRSxHQUFZLEVBQUUsRUFBRTtJQUNwRCxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsT0FBTyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUEsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMzRCxJQUFJLEtBQUssR0FBSSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDeEIsYUFBYSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7UUFDNUIsR0FBRyxFQUFFLFFBQVEsRUFBRSxPQUFPO1FBQ3RCLE9BQU8sRUFBRSxLQUFLO1FBQ2QsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7S0FDbkIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLE9BQU8saUJBQWlCLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLE1BQU0sQ0FBQyxDQUFBO0FBQ3pFLENBQUMsQ0FBQSxDQUFBO0FBRUQsTUFBTSxRQUFR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Q0FBQztnQkFDNUUsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7aUJBQU0sQ0FBQztnQkFFSixNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBO2dCQUMzQixJQUFJLFVBQVUsR0FBRyxHQUFHLFNBQVMsVUFBVSxDQUFDO2dCQUN4QyxNQUFNLE9BQU8sQ0FBQyxHQUFHLElBQUksSUFBSSxNQUFNLGdCQUFnQixVQUFVLEdBQUcsQ0FBQyxDQUFDO2dCQUU5RCxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsVUFBVSxFQUFFLENBQUMsQ0FBQTtnQkFDcEMsTUFBTSxPQUFPLENBQUMsSUFBSSxLQUFLLE1BQU0sVUFBVSxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ3ZELEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUE7WUFDekIsQ0FBQztZQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckIsTUFBTSxPQUFPLENBQUMsSUFBSSxPQUFPLG9CQUFvQixTQUFTLEdBQUcsQ0FBQyxDQUFDO1lBRTNELE1BQU0sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7WUFDdkQsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFBO1FBQ3ZDLENBQUMsQ0FBQSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFaEQsbUJBQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQy9CLENBQUM7Q0FDSjtBQTNaRCx1QkEyWkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge3Byb2dyYW19IGZyb20gXCJjb21tYW5kZXJcIjtcclxuaW1wb3J0ICogYXMgcHJvY2VzcyBmcm9tIFwicHJvY2Vzc1wiO1xyXG5pbXBvcnQge0xvZ2dlckZhY3RvcnksIHV0aWx9IGZyb20gXCJ2d2ViLWNvcmVcIjtcclxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XHJcbmltcG9ydCAqIGFzIGNoaWxkX3Byb2Nlc3MgZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xyXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiO1xyXG5pbXBvcnQgKiBhcyBvcyBmcm9tICdub2RlOm9zJztcclxuaW1wb3J0IHtyYW5kb21VVUlEfSBmcm9tICdjcnlwdG8nXHJcblxyXG5jb25zdCBkb21haW5LZXkgPSAncC1oY2MtaTAwMC1wMDBhLWhyY3BlJztcclxuY29uc3QgcGtnID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJyk7XHJcbmNvbnN0IFJTX1VSTCA9ICdodHRwczovL2Rmcy56aGlwZXIuY29tL3YzcjYnO1xyXG5cclxuY29uc3QgbG9nZ2VyOiBMb2dnZXIgPSBMb2dnZXJGYWN0b3J5LmdldExvZ2dlcignWURTJyk7XHJcblxyXG5jb25zdCBleGVjQ21kID0gYXN5bmMgKGNvbW1hbmQ6IHN0cmluZywgY3dkPzogc3RyaW5nKSA9PiB7XHJcbiAgICBsb2dnZXIuaW5mbyhg5omn6KGM5ZG95LukICR7Y29tbWFuZH0gJHtjd2QgPyBg77yM5omn6KGM55uu5b2V5Li6JHtjd2R9YCA6Jyd9YCk7XHJcbiAgICBsZXQgc3RhcnQgID0gRGF0ZS5ub3coKTtcclxuICAgIGNoaWxkX3Byb2Nlc3MuZXhlY1N5bmMoY29tbWFuZCwge1xyXG4gICAgICAgIGN3ZCwgZW5jb2Rpbmc6ICd1dGYtOCcsXHJcbiAgICAgICAgdGltZW91dDogNjAwMDAsXHJcbiAgICAgICAgc3RkaW86IFswLCAxLCAyXVxyXG4gICAgfSk7XHJcbiAgICBsb2dnZXIuaW5mbyhg5omn6KGM5ZG95LukICR7Y29tbWFuZH0g6ICX5pe2IFxceDFCWzM0bSA8JHtEYXRlLm5vdygpIC0gc3RhcnR9bXM+XWApXHJcbn1cclxuXHJcbmNvbnN0IHBsYXRmb3JtID0gb3MucGxhdGZvcm0oKVxyXG5pZiAocGxhdGZvcm0gIT09ICd3aW4zMicpIHtcclxuICAgIGxvZ2dlci5lcnJvcign5b2T5YmN5bel5YW35LuF5pSv5oyBd2luZG93c+ezu+e7nycpO1xyXG4gICAgcHJvY2Vzcy5leGl0KDEpO1xyXG59XHJcblxyXG5jb25zdCBpc0FkbWluID0gKCkgPT4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgICAvLyDlsJ3or5XmiafooYzkuIDkuKrlj6rmnInnrqHnkIblkZjmiY3og73ov5DooYznmoTlkb3ku6RcclxuICAgICAgICAvLyDkvb/nlKggPm51bCAyPiYxIOadpeaKkeWItui+k+WHulxyXG4gICAgICAgIGNoaWxkX3Byb2Nlc3MuZXhlY1N5bmMoJ25ldCBzZXNzaW9uID5udWwgMj4mMScpO1xyXG4gICAgICAgIHJldHVybiB0cnVlOyAvLyDmiJDlip/miafooYxcclxuICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTsgLy8g5omn6KGM5aSx6LSl77yM5p2D6ZmQ5LiN6LazXHJcbiAgICB9XHJcbn1cclxuXHJcbmxldCB3Z2V0ID0gcGF0aC5yZXNvbHZlKCAnd2dldC5leGUnKTtcclxubGV0IHppcCA9IHBhdGgucmVzb2x2ZSgnemlwLmV4ZScpO1xyXG5sZXQgdW56aXAgPSBwYXRoLnJlc29sdmUoJ3VuemlwLmV4ZScpO1xyXG5cclxucHJvZ3JhbS5uYW1lKFwieWRzXCIpXHJcbiAgICAudXNhZ2UoXCJbY29tbWFuZF0gW29wdGlvbnNdXCIpXHJcbiAgICAuZGVzY3JpcHRpb24oXCJ5ZHMg5Yi255uY5bel5YW3IOWmguaenOWRveS7pOWPguaVsOS4reWtmOWcqOepuuagvCDkvb/nlKjlj4zlvJXlj7dcXFwiXFxcIuWMheijuVwiKVxyXG4gICAgLnZlcnNpb24oYHlkcyAke3BrZy52ZXJzaW9ufWApO1xyXG5cclxudHlwZSBNaWNyb1NlcnZpY2UgPSAnaHJjcGUnIHwgJ2ZlY29kZSc7XHJcblxyXG50eXBlIEdpdCA9IHtcclxuICAgIHVybDogc3RyaW5nLFxyXG4gICAgYnJhbmNoOiBzdHJpbmdcclxufVxyXG5cclxudHlwZSBZZHNDb25maWcgPSB7XHJcbiAgICBob3N0czogQXJyYXk8c3RyaW5nPjtcclxuICAgIGdpdDogUmVjb3JkPE1pY3JvU2VydmljZSwgc3RyaW5nPjtcclxuICAgIGNhdGFsb2dzOiB7XHJcbiAgICAgICAgW2NhdGFsb2c6IHN0cmluZ106IFJlY29yZDxNaWNyb1NlcnZpY2UsIHN0cmluZyB8IEdpdD5cclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFpbiB7XHJcblxyXG4gICAgc3RhcnR1cCgpIHtcclxuICAgICAgICBwcm9ncmFtXHJcbiAgICAgICAgICAgIC5jb21tYW5kKCdpbml0IFt3b3JrZGlyXScpXHJcbiAgICAgICAgICAgIC51c2FnZSgnaW5pdCBbd29ya2Rpcl0nKVxyXG4gICAgICAgICAgICAuZGVzY3JpcHRpb24oJ+WIneWni+WMlllEU+WItuebmOeOr+Wigywgd29ya2RpcuihqOekuuWItuebmOW3peS9nOebruW9le+8jOWmguaenOS4jeaMh+WumuWImeS9v+eUqOW9k+WJjeebruW9lScpXHJcbiAgICAgICAgICAgIC5hY3Rpb24oYXN5bmMgKHdvcmtkaXI6IHN0cmluZyA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpKSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGlyID0gcGF0aC5yZXNvbHZlKHdvcmtkaXIpO1xyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOWIneWni+WMlllEU+WItuebmOeOr+WigyDlt6XkvZznm67lvZXvvJoke2Rpcn1gKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGdpdEV4aXN0cyA9IGF3YWl0IHV0aWwuY21kLmV4aXN0cygnZ2l0Jyk7XHJcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5qOA5p+l5piv5ZCm5a6J6KOF5LqGZ2l0ID4+ICR7Z2l0RXhpc3RzID8gJ+W3suWuieijhScgOiAn5pyq5a6J6KOFJ31gKTtcclxuICAgICAgICAgICAgICAgIGlmICghZ2l0RXhpc3RzICYmICFmcy5leGlzdHNTeW5jKGAke2Rpcn0vZ2l0LWZvci13aW5kb3dzYCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBnaXRaaXBOYW1lID0gJ2dpdC1mb3Itd2luZG93cy56aXAnXHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOS4i+i9vWdpdCDlronoo4XljIUgJHtnaXRaaXBOYW1lfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdpdFppcEZpbGUgPSBgJHtkaXJ9LyR7Z2l0WmlwTmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIOajgOafpeaYr+WQpuW3sue7j+WtmOWcqOWuieijheWMhSDlpoLmnpzmnInlhYjliKDpmaRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhnaXRaaXBGaWxlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5Yig6Zmk5bey5a2Y5Zyo5a6J6KOF5YyFICR7Z2l0WmlwRmlsZX1gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnMucm1TeW5jKGdpdFppcEZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyDkuIvovb3lronoo4XljIXlubbovpPlh7rml6Xlv5dcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGAke3dnZXR9ICR7UlNfVVJMfS8ke2dpdFppcE5hbWV9IC1PIFwiJHtnaXRaaXBGaWxlfVwiYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOino+WOi+WuieijheWMhSAke2dpdFppcEZpbGV9YClcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBcIiR7dW56aXB9XCIgXCIke2dpdFppcEZpbGV9XCIgLWQgXCIke2Rpcn1cImApO1xyXG4gICAgICAgICAgICAgICAgICAgIGZzLnJtU3luYyhnaXRaaXBGaWxlKVxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBnaXQg5a6J6KOF5a6M5oiQYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgamF2YUV4aXN0cyA9IGF3YWl0IHV0aWwuY21kLmV4aXN0cygnamF2YScpO1xyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOajgOafpeaYr+WQpuWuieijheS6hmphdmEgPj4gJHtqYXZhRXhpc3RzID8gJ+W3suWuieijhScgOiAn5pyq5a6J6KOFJ31gKTtcclxuICAgICAgICAgICAgICAgIGlmICghamF2YUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCfmnKrmib7liLBqYXZh77yM5YeG5aSH5a6J6KOFamF2Ye+8jOW8gOWni+S4i+i9vWpkaycpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpka1ppcE5hbWUgPSAnamRrLTExLjAuMTUuMV93aW5kb3dzLXg2NF9iaW4uemlwJ1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGV4ZWNDbWQoYCR7d2dldH0gJHtSU19VUkx9LyR7amRrWmlwTmFtZX0gLU8gXCIke2Rpcn0vJHtqZGtaaXBOYW1lfVwiYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOino+WOi2pkayDlronoo4XljIUgJHtkaXJ9LyR7amRrWmlwTmFtZX1gKVxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGV4ZWNDbWQoYFwiJHt1bnppcH1cIiBcIiR7ZGlyfS8ke2pka1ppcE5hbWV9XCJgLCBkaXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDphY3nva5qYXZh546v5aKD5Y+Y6YePYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGphdmFIb21lID0gYCR7ZGlyfS9qZGstMTEuMC4xNS4xYDtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBzZXR4IEpBVkFfSE9NRSBcIiR7amF2YUhvbWV9XCJgKTtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBzZXR4IENMQVNTX1BBVEggXCIuOyVKQVZBX0hPTUUlXFxsaWI7XCJgKTtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKCBgc2V0eCBQQVRIIFwiJVBBVEglOyVKQVZBX0hPTUUlXFxiaW47XCJgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5lbnYuSkFWQV9IT01FID0gamF2YUhvbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYGphdmEg5a6J6KOF5a6M5oiQYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOajgOafpWphdmHniYjmnKxgKTtcclxuICAgICAgICAgICAgICAgIGF3YWl0IGV4ZWNDbWQoJ2phdmEgLXZlcnNpb24nKTtcclxuICAgICAgICAgICAgICAgIC8vIOWvvOWFpeivgeS5puWIsGphdmEg5aaC5p6camF2YeaYrzEuOOeJiOacrCDpnIDopoHlr7zlhaXliLAgSkFWQV9IT01FL2pyZS9saWIvc2VjdXJpdHkvY2FjZXJ0cyDlpoLmnpzmmK8xMeeJiOacrCDpnIDopoHlr7zlhaXliLAgSkFWQV9IT01FL2xpYi9zZWN1cml0eS9jYWNlcnRzXHJcbiAgICAgICAgICAgICAgICBjb25zdCBqYXZhSG9tZSA9IHByb2Nlc3MuZW52LkpBVkFfSE9NRTtcclxuICAgICAgICAgICAgICAgIGlmIChqYXZhSG9tZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjZXJ0c0ZpbGVuYW1lID0gJ2xpYi9zZWN1cml0eS9jYWNlcnRzJztcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY2VydHNGaWxlID0gYCR7amF2YUhvbWV9LyR7Y2VydHNGaWxlbmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhjZXJ0c0ZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlcnRzRmlsZSA9IGAke2phdmFIb21lfS9qcmUvJHtjZXJ0c0ZpbGVuYW1lfWA7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDmo4Dmn6VqYXZh6K+B5Lmm55uu5b2VICR7Y2VydHNGaWxlfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGNlcnRzRmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5Yik5pat6K+B5Lmm5piv5ZCm5bey57uP5a+85YWlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBrZXl0b29sIC1saXN0IC12IC1rZXlzdG9yZSBcIiR7Y2VydHNGaWxlfVwiIC1zdG9yZXBhc3MgY2hhbmdlaXQgLS1hbGlhcyB5eXJkYClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGB5eXJkLmNydCDor4Hkuablt7LlrZjlnKhgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g6K+B5Lmm5LiN5a2Y5ZyoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5a+85YWlIHl5cmQuY3J0IOivgeS5puWIsGphdmEgJHtjZXJ0c0ZpbGV9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBrZXl0b29sIC1pbXBvcnRjZXJ0IC1maWxlIFwiJHtkaXJ9L3l5cmQuY3J0XCIgLWtleXN0b3JlIFwiJHtjZXJ0c0ZpbGV9XCIgLXN0b3JlcGFzcyBjaGFuZ2VpdCAtbm9wcm9tcHRgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGB5eXJkLmNydCDor4Hkuablr7zlhaXlrozmiJBgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBtYXZlbkhvbWUgPSBgJHtkaXJ9L21hdmVuLTMuOC42YDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1hdmVuRXhpc3RzID0gdXRpbC5jbWQuZXhpc3RzKCdtdm4nKTtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDmo4Dmn6XmmK/lkKblronoo4XkuoZtYXZlbiA+PiAke21hdmVuRXhpc3RzID8gJ+W3suWuieijhScgOiAn5pyq5a6J6KOFJ31gKTtcclxuICAgICAgICAgICAgICAgIGlmICghbWF2ZW5FeGlzdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXZlblppcE5hbWUgPSAnbWF2ZW4tMy44LjYuemlwJ1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDkuIvovb1tYXZlbiDlronoo4XljIUgJHttYXZlblppcE5hbWV9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF2ZW5aaXBGaWxlID0gYCR7ZGlyfS8ke21hdmVuWmlwTmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIOajgOafpeaYr+WQpuW3sue7j+WtmOWcqOWuieijheWMhSDlpoLmnpzmnInlhYjliKDpmaRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhtYXZlblppcEZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDliKDpmaTlt7LlrZjlnKjlronoo4XljIUgJHttYXZlblppcEZpbGV9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZzLnJtU3luYyhtYXZlblppcEZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyDkuIvovb3lronoo4XljIXlubbovpPlh7rml6Xlv5dcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGAke3dnZXR9ICR7UlNfVVJMfS8ke21hdmVuWmlwTmFtZX0gLU8gXCIke21hdmVuWmlwRmlsZX1cImApO1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDop6Pljovlronoo4XljIUgJHttYXZlblppcEZpbGV9YClcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBcIiR7dW56aXB9XCIgXCIke21hdmVuWmlwRmlsZX1cIiAtZCBcIiR7ZGlyfVwiYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZnMucm1TeW5jKG1hdmVuWmlwRmlsZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIOa3u+WKoG1hdmVuIOeOr+Wig+WPmOmHj1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpbmRvd3PmoLjlv4Plkb3ku6TvvJrmsLjkuYXov73liqDot6/lvoTliLDjgJDnlKjmiLfnjq/looPlj5jph49QQVRI44CR77yM5rC45LmF55Sf5pWIXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtdm5QYXRoID0gcGF0aC5yZXNvbHZlKGAke21hdmVuSG9tZX0vYmluYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGV4ZWNDbWQoIGBzZXR4IFBBVEggXCIlUEFUSCU7JHttdm5QYXRofVwiYCApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg4pyFIOaIkOWKn++8gU1hdmVu6Lev5b6E44CQJHttdm5QYXRofeOAkeW3sua3u+WKoOWIsOezu+e7n1BBVEjnjq/looPlj5jph49gKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcign4p2MIOa3u+WKoOWksei0pe+8micsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBtYXZlbiDlronoo4XlrozmiJBgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5Yid5aeL5YyWbm9kZeeOr+Wig2ApO1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgZXhlY0NtZCgnbnBtIGluc3RhbGwgLWcgcG5wbSB0eXBlc2NyaXB0IC0tcmVnaXN0cnk9aHR0cHM6Ly9yZWdpc3RyeS5ucG1taXJyb3IuY29tJyk7XHJcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5Yid5aeL5YyWbm9kZeeOr+Wig+WujOaIkGApO1xyXG5cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDmo4DmtYtjb2Rl5piv5ZCm5a2Y5ZyoYClcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvZGVEaXIgPSBgJHtkaXJ9L3lkcy0xLjAuM2A7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoY29kZURpcikpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2RlWmlwTmFtZSA9ICd5ZHMtMS4wLjMtamRrLTgtd2luZG93cy14ODZfNjQuemlwJ1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDkuIvovb1jb2RlIElERSDlronoo4XljIUgJHtjb2RlWmlwTmFtZX1gKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2RlWmlwRmlsZSA9IGAke2Rpcn0vJHtjb2RlWmlwTmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIOajgOafpeaYr+WQpuW3sue7j+WtmOWcqOWuieijheWMhSDlpoLmnpzmnInlhYjliKDpmaRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhjb2RlWmlwRmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOWIoOmZpOW3suWtmOWcqOWuieijheWMhSAke2NvZGVaaXBGaWxlfWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcy5ybVN5bmMoY29kZVppcEZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyDkuIvovb3lronoo4XljIXlubbovpPlh7rml6Xlv5dcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGAke3dnZXR9IGh0dHBzOi8veW9uY29tbXVuaXR5LnlvbnlvdWNsb3VkLmNvbS9ZRFNEb3dubG9hZC9XaW5kb3cveDY0LyR7Y29kZVppcE5hbWV9IC1PIFwiJHtjb2RlWmlwRmlsZX1cImApO1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDop6Pljovlronoo4XljIUgJHtjb2RlWmlwRmlsZX1gKVxyXG4gICAgICAgICAgICAgICAgICAgIGZzLm1rZGlyU3luYyhjb2RlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBcIiR7dW56aXB9XCIgXCIke2NvZGVaaXBGaWxlfVwiIC1kIFwiJHtjb2RlRGlyfVwiYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZnMucm1TeW5jKGNvZGVaaXBGaWxlKVxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDUwMDApKVxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBjb2RlIElERSDlronoo4XlrozmiJBgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDliJ3lp4vljJZZRFMgSURFIOWFqOWxgOmFjee9rmApXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzZXR0aW5nc0pzb24gPSBgJHtjb2RlRGlyfS9Db2RlL2RhdGEvdXNlci1kYXRhL1VzZXIvc2V0dGluZ3MuanNvbmA7XHJcbiAgICAgICAgICAgICAgICBsZXQgc2V0dGluZ3NKc29uT2JqID0ge307XHJcbiAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhzZXR0aW5nc0pzb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3NKc29uT2JqID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoc2V0dGluZ3NKc29uKS50b1N0cmluZygndXRmLTgnKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBsZXQgc2V0dGluZ1htbCA9IHBhdGgucmVzb2x2ZShgJHttYXZlbkhvbWV9L2NvbmYvc2V0dGluZ3MueG1sYCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc2V0dGluZ1htbCkgJiYgIWZzLmV4aXN0c1N5bmMoYCR7ZGlyfS9zZXR0aW5ncy54bWxgKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGV4ZWNDbWQoYCR7d2dldH0gJHtSU19VUkx9L3NldHRpbmdzLnhtbGApO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmdYbWwgPSBwYXRoLnJlc29sdmUoYCR7ZGlyfS9zZXR0aW5ncy54bWxgKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgc2V0dGluZ3NKc29uT2JqW1wiamF2YS5jb25maWd1cmF0aW9uLm1hdmVuLmdsb2JhbFNldHRpbmdzXCJdID0gc2V0dGluZ1htbDtcclxuICAgICAgICAgICAgICAgIHNldHRpbmdzSnNvbk9ialtcImphdmEuY29uZmlndXJhdGlvbi5tYXZlbi51c2VyU2V0dGluZ3NcIl0gPSBzZXR0aW5nWG1sO1xyXG4gICAgICAgICAgICAgICAgc2V0dGluZ3NKc29uT2JqW1wibWF2ZW4uc2V0dGluZ3NGaWxlXCJdID0gc2V0dGluZ1htbDtcclxuICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoc2V0dGluZ3NKc29uLCBKU09OLnN0cmluZ2lmeShzZXR0aW5nc0pzb25PYmosIG51bGwsIDQpKTtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDliJ3lp4vljJZZRFMgSURFIOWFqOWxgOmFjee9ruWujOaIkGApO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIOajgOafpeW9k+WJjeeUqOaIt+ebruW9leS4iy5zc2jmmK/lkKblrZjlnKggaWRfZWQyNTUxOS5wdWIg5a+G6ZKl5paH5Lu277yM5aaC5p6c5rKh5pyJ5YiZ5pS+5YiwLnNzaCDnm67lvZXkuItcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNzaERpciA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmVudi5VU0VSUFJPRklMRSwgJy5zc2gnKTtcclxuICAgICAgICAgICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhzc2hEaXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZnMubWtkaXJTeW5jKHNzaERpcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYCR7c3NoRGlyfS9pZF9lZDI1NTE5LnB1YmApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOaLt+i0neWvhumSpeaWh+S7tmApO1xyXG4gICAgICAgICAgICAgICAgICAgIGZzLmNvcHlGaWxlU3luYyhgJHtkaXJ9L2lkX2VkMjU1MTkucHViYCwgYCR7c3NoRGlyfS9pZF9lZDI1NTE5LnB1YmApO1xyXG4gICAgICAgICAgICAgICAgICAgIGZzLmNvcHlGaWxlU3luYyhgJHtkaXJ9L2lkX2VkMjU1MTlgLCBgJHtzc2hEaXJ9L2lkX2VkMjU1MTlgKTtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5ou36LSd5a+G6ZKl5paH5Lu25a6M5oiQYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOWIneWni+WMlllEU+WItuebmOeOr+Wig+WujOaIkGApXHJcbiAgICAgICAgICAgIH0pLmhvb2soJ3Bvc3RBY3Rpb24nLCAoKSA9PiBwcm9jZXNzLmV4aXQoMCkpO1xyXG5cclxuICAgICAgICBwcm9ncmFtXHJcbiAgICAgICAgICAgIC5jb21tYW5kKCdzdGFydCA8Y2F0YWxvZz4gW3dvcmtkaXJdJylcclxuICAgICAgICAgICAgLnVzYWdlKCdzdGFydCA8Y2F0YWxvZz4gW3dvcmtkaXJdJylcclxuICAgICAgICAgICAgLm9wdGlvbignLWYsIC0tZmlsZSA8ZmlsZT4nLCAn6YWN572u5paH5Lu2JylcclxuICAgICAgICAgICAgLmFkZEhlbHBUZXh0KCdhZnRlcicsIGBcclxu6YWN572u5paH5Lu25YaF5a6556S65L6L77yaXHJcbntcclxuICAgIGhvc3RzPzogQXJyYXk8c3RyaW5nPjtcclxuICAgIGdpdDogUmVjb3JkPCdocmNwZScgfCAnZmVjb2RlJywgc3RyaW5nPjtcclxuICAgIGNhdGFsb2dzOiB7XHJcbiAgICAgICAgW2NhdGFsb2c6IHN0cmluZ106IFJlY29yZDwnaHJjcGUnIHwgJ2ZlY29kZScsIHN0cmluZyB8IHsgdXJsOiBzdHJpbmcsIGJyYW5jaDogc3RyaW5nIH0+XHJcbiAgICB9XHJcbn1gKVxyXG4gICAgICAgICAgICAuZGVzY3JpcHRpb24oJ+WQr+WKqOWItuebmOeOr+Wig++8jGNhdGFsb2fooajnpLrpnIDopoHliLbnm5jnmoTmqKHlnZfvvIzlr7nlupTphY3nva7mlofku7bkuK1jYXRhbG9nc+eahGtleeWAvO+8jOeUqOS6juaMh+WumumcgOimgeWHuuebmOeahOS/oeaBr++8jHdvcmtkaXLooajnpLrliLbnm5jlt6XkvZznm67lvZXvvIzlpoLmnpzkuI3mjIflrprliJnkvb/nlKjlvZPliY3nm67lvZUnKVxyXG4gICAgICAgICAgICAuYWN0aW9uKGFzeW5jIChjYXRhbG9nOiBzdHJpbmcsIHdvcmtkaXI6IHN0cmluZyA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpKSwgb3B0aW9uczogeyBmaWxlOiBzdHJpbmcgfSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGlyID0gcGF0aC5yZXNvbHZlKHdvcmtkaXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDlvIDlp4vmo4DmtYvliLbnm5jnjq/looPmo4DmtYtgKTtcclxuICAgICAgICAgICAgICAgIGxldCBnaXRDbWQgPSAnZ2l0JztcclxuICAgICAgICAgICAgICAgIGNvbnN0IGdpdEV4aXN0cyA9IGF3YWl0IHV0aWwuY21kLmV4aXN0cyhnaXRDbWQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFnaXRFeGlzdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBnaXRDbWQgPSBgJHtkaXJ9L2dpdC1mb3Itd2luZG93cy9iaW4vZ2l0LmV4ZWA7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGdpdENtZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDmnKrmib7liLBnaXTlkb3ku6QgJHtnaXRDbWR9LCDor7flhYjmiafooYwgaW5pdCDliJ3lp4vljJbliLbnm5jnjq/looNgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDEpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGxldCBzZXR0aW5nWG1sID0gcGF0aC5yZXNvbHZlKGAke2Rpcn0vc2V0dGluZ3MueG1sYCk7XHJcbiAgICAgICAgICAgICAgICBsZXQgbXZuQ21kID0gJ212bic7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc2V0dGluZ1htbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgbWF2ZW5Ib21lID0gYCR7ZGlyfS9tYXZlbi0zLjguNmA7XHJcbiAgICAgICAgICAgICAgICAgICAgbXZuQ21kID0gYFwiJHttYXZlbkhvbWV9L2Jpbi9tdm4uY21kXCJgO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmdYbWwgPSBgJHttYXZlbkhvbWV9L2NvbmYvc2V0dGluZ3MueG1sYDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMobXZuQ21kKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYOacquaJvuWIsG12buWRveS7pCAke212bkNtZH0sIOivt+WFiOaJp+ihjCBpbml0IOWIneWni+WMluWItuebmOeOr+Wig2ApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmV4aXQoMSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGlkZVBhdGggPSBgJHtkaXJ9L3lkcy0xLjAuM2BcclxuICAgICAgICAgICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhpZGVQYXRoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihg5pyq5om+5YiwSURFICR7aWRlUGF0aH0sIOivt+WFiOaJp+ihjCBpbml0IOWIneWni+WMluWItuebmOeOr+Wig2ApO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDliLbnm5jnjq/looPmo4DmtYvlrozmiJBgKVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHlkc0pzb24gPSBwYXRoLnJlc29sdmUob3B0aW9ucy5maWxlIHx8IGAke2Rpcn0veWRzLmpzb25gKTtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDlvIDlp4vliLbnm5ggJHtjYXRhbG9nfSDlt6XkvZznm67lvZXvvJoke2Rpcn1gKTtcclxuICAgICAgICAgICAgICAgIC8vIOivu+WPlumFjee9ruaWh+S7tlxyXG4gICAgICAgICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHlkc0pzb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDmnKrmib7liLDphY3nva7mlofku7YgJHt5ZHNKc29ufWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IHlkc0pzb25TdHIgPSBmcy5yZWFkRmlsZVN5bmMoeWRzSnNvbikudG9TdHJpbmcoJ3V0Zi04Jyk7XHJcbiAgICAgICAgICAgICAgICAvLyDmo4DmtYvphY3nva7mlofku7bmmK/lkKblrozmlbRcclxuICAgICAgICAgICAgICAgIGxldCBjb25maWc6IFlkc0NvbmZpZztcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNoZWNrQ29uZmlnRXJyb3IgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDphY3nva7mlofku7YgJHt5ZHNKc29ufSDmoLzlvI/plJnor68g5Y+C6ICD56S65L6L77yaXHJcbntcclxuICAgIGhvc3RzPzogQXJyYXk8c3RyaW5nPjtcclxuICAgIGdpdDogUmVjb3JkPCdocmNwZScgfCAnZmVjb2RlJywgc3RyaW5nPjtcclxuICAgIGNhdGFsb2dzOiB7XHJcbiAgICAgICAgW2NhdGFsb2c6IHN0cmluZ106IFJlY29yZDwnaHJjcGUnIHwgJ2ZlY29kZScsIHN0cmluZyB8IHsgdXJsOiBzdHJpbmcsIGJyYW5jaDogc3RyaW5nIH0+XHJcbiAgICB9XHJcbn1gKTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZyA9IEpTT04ucGFyc2UoeWRzSnNvblN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb25maWcuY2F0YWxvZ3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDb25maWdFcnJvcigpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNoZWNrQ29uZmlnRXJyb3IoKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29uc3QgZ2l0ID0gY29uZmlnLmdpdDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNhdGFsb2dDb25maWcgPSBjb25maWcuY2F0YWxvZ3NbY2F0YWxvZ107XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNhdGFsb2dDb25maWcgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDphY3nva7mlofku7YgJHt5ZHNKc29ufSDmib7kuI3liLAgY2F0YWxvZ3MuJHtjYXRhbG9nfSDlhYjlhbPphY3nva5gKTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNhdGFsb2dDb25maWcuaHJjcGUgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiBjYXRhbG9nQ29uZmlnLmZlY29kZSA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYOmFjee9ruaWh+S7tiAke3lkc0pzb259IGNhdGFsb2dzLiR7Y2F0YWxvZ30uaHJjcGUg5oiWIGNhdGFsb2dzLiR7Y2F0YWxvZ30uZmVjb2RlIOWtl+autee8uuWksWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBuYW1lc3BhY2UgPSBgJHtkaXJ9LyR7Y2F0YWxvZ31gO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKG5hbWVzcGFjZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5Yib5bu655uu5b2VICR7bmFtZXNwYWNlfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIGZzLm1rZGlyU3luYyhuYW1lc3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg55uu5b2VICR7bmFtZXNwYWNlfSDlt7LlrZjlnKhgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCBocmNwZVVybCA9IHR5cGVvZiBjYXRhbG9nQ29uZmlnLmhyY3BlID09PSAnc3RyaW5nJyA/IGdpdD8uaHJjcGUgOiBjYXRhbG9nQ29uZmlnLmhyY3BlLnVybDtcclxuICAgICAgICAgICAgICAgIGlmICghaHJjcGVVcmwpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYOmFjee9ruaWh+S7tiAke3lkc0pzb259IGNhdGFsb2dzLiR7Y2F0YWxvZ30g5ZCO56uv5pyN5YqhIOacquaMh+WumuS7k+W6k+WcsOWdgO+8jOivt+mAmui/hyBnaXQuaHJjcGUg5oiW6ICFIGNhdGFsb2dzLiR7Y2F0YWxvZ30uaHJjcGUudXJsIOaMh+WumuS7k+W6k+WcsOWdgGApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOW8gOWni+aLieWPluWQjuerr+acjeWKoeS7k+W6kyAke2hyY3BlVXJsfWApO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYCR7bmFtZXNwYWNlfS8uZ2l0YCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg55uu5b2VICR7bmFtZXNwYWNlfSDlt7LlrZjlnKjvvIzlvIDlp4vmm7TmlrDku5PlupNgKTtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBcIiR7Z2l0Q21kfVwiIHB1bGxgLCBuYW1lc3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg55uu5b2VICR7bmFtZXNwYWNlfSDkuI3lrZjlnKjvvIzlvIDlp4vliJvlu7rku5PlupNgKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYnJhbmNoID0gdHlwZW9mIGNhdGFsb2dDb25maWcuaHJjcGUgPT09ICdzdHJpbmcnID8gY2F0YWxvZ0NvbmZpZy5ocmNwZSA6IGNhdGFsb2dDb25maWcuaHJjcGUuYnJhbmNoO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghYnJhbmNoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihg6YWN572u5paH5Lu2ICR7eWRzSnNvbn0gY2F0YWxvZ3MuJHtjYXRhbG9nfSDlkI7nq6/mnI3liqEg5pyq5oyH5a6a5YiG5pSv77yM6K+36YCa6L+HIGdpdC5ocmNwZSDmiJbogIUgY2F0YWxvZ3MuJHtjYXRhbG9nfS5ocmNwZS5icmFuY2gg6YWN572u5YiG5pSvYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZXhlY0NtZChgXCIke2dpdENtZH1cIiBjbG9uZSAtYiAke2JyYW5jaH0gJHtocmNwZVVybH0gJHtuYW1lc3BhY2V9YCwgbmFtZXNwYWNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDmi4nlj5blkI7nq6/mnI3liqHku5PlupPlrozmiJBgKTtcclxuICAgICAgICAgICAgICAgIGxldCBib29zdHJhcFBvbVhtbCA9IGAke25hbWVzcGFjZX0vJHtkb21haW5LZXl9LWJlL2Rldi0ke2RvbWFpbktleX0tYm9vdHN0cmFwL3BvbS54bWxgO1xyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOabv+aNouaWh+S7tiAke2Jvb3N0cmFwUG9tWG1sfSDkuK3nmoRST09U5Li6ZG9tYWluS2V577yM5ZCm5YiZ5Lya5a+86Ie05Yi255uY5aSx6LSl77yM5peg5rOV5om+5Yiw5Yi25ZOBYCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBib29zdHJhcFBvbVhtbFN0cmluZyA9IGZzLnJlYWRGaWxlU3luYyhib29zdHJhcFBvbVhtbCkudG9TdHJpbmcoJ3V0Zi04Jyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYm9vc3RyYXBQb21YbWxTdHJpbmcuaW5jbHVkZXMoJ1JPT1QnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoYm9vc3RyYXBQb21YbWwsIGJvb3N0cmFwUG9tWG1sU3RyaW5nLnJlcGxhY2UoL1JPT1QvZywgZG9tYWluS2V5KSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5ob3N0cyAmJiBjb25maWcuaG9zdHMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOWtmOWcqGhvc3Rz6YWN572u77yM5qOA5rWL57O757ufaG9zdHPphY3nva7mlofku7bmmK/lkKblt7Lnu4/phY3nva5gKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgaG9zdHNGaWxlID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuZW52LldJTkRJUiwgJ1N5c3RlbTMyJywgJ2RyaXZlcnMnLCAnZXRjJywgJ2hvc3RzJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaG9zdExpc3QgPSBmcy5yZWFkRmlsZVN5bmMoaG9zdHNGaWxlKS50b1N0cmluZygndXRmLTgnKS5zcGxpdCgnXFxuJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGFwcGVuZEhvc3RzID0gWy4uLmNvbmZpZy5ob3N0c11cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBob3N0SXRlbSBvZiBob3N0TGlzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoLyMvLnRlc3QoaG9zdEl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBhcHBlbmRIb3N0IG9mIGNvbmZpZy5ob3N0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgW2lwLCBkb21haW5dID0gYXBwZW5kSG9zdC5zcGxpdCgnICcpLmZpbHRlcihpdGVtID0+IGl0ZW0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG9zdEl0ZW0uaW5jbHVkZXMoaXApICYmIGhvc3RJdGVtLmluY2x1ZGVzKGRvbWFpbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg57O757ufaG9zdHPphY3nva7mlofku7blt7LlrZjlnKggJHthcHBlbmRIb3N0fWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZEhvc3RzLnJlbW92ZShhcHBlbmRIb3N0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyDor7vlj5bns7vnu59ob3N0c+mFjee9ruaWh+S7tlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHBlbmRIb3N0cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWRtaW4oKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnMuYXBwZW5kRmlsZVN5bmMoaG9zdHNGaWxlLCBgXFxuJHthcHBlbmRIb3N0cy5qb2luKCdcXG4nKX1cXG5gLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICd1dGYtOCdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYOW9k+WJjemdnueuoeeQhuWRmOWQr+WKqOaXoOazleabtOaUuWhvc3Rz5paH5Lu277yM6K+35L2/55So566h55CG5ZGY5ZCv5Yqo5oiW6ICF5omL5Yqo5re75YqgICR7YXBwZW5kSG9zdHMuam9pbignXFxuJyl9IOWIsOaWh+S7tiAke2hvc3RzRmlsZX1gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhgaG9zdHMg6YWN572u5qOA5rWL5a6M5oiQYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ+WIneWni+WMlumhueebrm1hdmVu546v5aKDJyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgbXZuQ29uZmlnRGlyID0gYCR7bmFtZXNwYWNlfS8ubXZuYDtcclxuICAgICAgICAgICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhtdm5Db25maWdEaXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZXhlY0NtZChgJHttdm5DbWR9IC1OIGlvLnRha2FyaTptYXZlbjp3cmFwcGVyIC1EbWF2ZW49My44LjZgLCBuYW1lc3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8g5YaZ5YWlbWF2ZW7phY3nva7liLAgLm12bi9tYXZlbi5jb25maWdcclxuICAgICAgICAgICAgICAgIGxldCBjb25maWdGaWxlID0gYCR7bXZuQ29uZmlnRGlyfS9tYXZlbi5jb25maWdgO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoY29uZmlnRmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBmcy5ybVN5bmMoY29uZmlnRmlsZSlcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoYCR7bXZuQ29uZmlnRGlyfS9tYXZlbi5jb25maWdgLCBgLXNcXG4ke3NldHRpbmdYbWx9XFxuLURtYXZlbi53YWdvbi5odHRwLnNzbC5pbnNlY3VyZT10cnVlXFxuLURtYXZlbi53YWdvbi5odHRwLnNzbC5hbGxvd2FsbD10cnVlYCk7XHJcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg5b2T5YmNbWF2ZW7kv6Hmga9gKVxyXG4gICAgICAgICAgICAgICAgYXdhaXQgZXhlY0NtZChgJHttdm5DbWR9IC0tdmVyc2lvbmAsIG5hbWVzcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ+mhueebrm1hdmVu5riF55CGJylcclxuICAgICAgICAgICAgICAgIGF3YWl0IGV4ZWNDbWQoYCR7bXZuQ21kfSBjbGVhbiAtRHNraXBUZXN0c2AsIGAke25hbWVzcGFjZX0vJHtkb21haW5LZXl9LWJlYCk7XHJcblxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ+WkhOeQhuWJjeerr+aehOW7uu+8jOWinuWKoOaehOW7uuaWh+S7ticpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGZlRGlyID0gYCR7bmFtZXNwYWNlfS8ke2RvbWFpbktleX0tZmVgO1xyXG4gICAgICAgICAgICAgICAgbGV0IGZlQnVpbGRKcyA9IGAke2ZlRGlyfS9idWlsZC5qc2A7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmVCdWlsZEpzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZzLmNwU3luYyhgJHtkaXJ9L2ZlLWJ1aWxkLmpzYCwgZmVCdWlsZEpzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCBmZVBhY2thZ2VKc29uID0gYCR7ZmVEaXJ9L3BhY2thZ2UuanNvbmA7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYWNrYWdlU3RyaW5nID0gZnMucmVhZEZpbGVTeW5jKGZlUGFja2FnZUpzb24pLnRvU3RyaW5nKCd1dGYtOCcpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFwYWNrYWdlU3RyaW5nLmluY2x1ZGVzKCdidWlsZC5qcycpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOS/ruaUuSR7ZmVQYWNrYWdlSnNvbn1gKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZVN0cmluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFja2FnZUpzb24uc2NyaXB0c1snYnVpbGQ6ZXh0ZW5kJ10gKz0gJyAmJiBub2RlIGJ1aWxkLmpzJztcclxuICAgICAgICAgICAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGZlUGFja2FnZUpzb24sIEpTT04uc3RyaW5naWZ5KHBhY2thZ2VKc29uLCBudWxsLCA0KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOS/ruaUuSR7ZmVQYWNrYWdlSnNvbn3lrozmiJBgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGZlY29kZVVybCA9IHR5cGVvZiBjYXRhbG9nQ29uZmlnLmZlY29kZSA9PT0gJ3N0cmluZycgPyBnaXQ/LmZlY29kZSA6IGNhdGFsb2dDb25maWcuZmVjb2RlLnVybDtcclxuICAgICAgICAgICAgICAgIGlmICghZmVjb2RlVXJsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDphY3nva7mlofku7YgJHt5ZHNKc29ufSBjYXRhbG9ncy4ke2NhdGFsb2d9IOWQjuerr+acjeWKoSDmnKrmjIflrprku5PlupPlnLDlnYDvvIzor7fpgJrov4cgZ2l0LmZlY29kZSDmiJbogIUgY2F0YWxvZ3MuJHtjYXRhbG9nfS5mZWNvZGUudXJsIOaMh+WumuS7k+W6k+WcsOWdgGApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOW8gOWni+aLieWPluaKpeWRiuacjeWKoeS7k+W6kyAke2ZlY29kZVVybH1gKTtcclxuICAgICAgICAgICAgICAgIGxldCByZXBvcnROYW1lc3BhY2UgPSBgJHtuYW1lc3BhY2V9L3lvbmJpcC15aXN2LWl6cDEtZGV2LWZlY29kZWA7XHJcbiAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhgJHtyZXBvcnROYW1lc3BhY2V9Ly5naXRgKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDnm67lvZUgJHtyZXBvcnROYW1lc3BhY2V9IOW3suWtmOWcqO+8jOW8gOWni+abtOaWsOS7k+W6k2ApO1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGV4ZWNDbWQoYFwiJHtnaXRDbWR9XCIgcHVsbGAsIHJlcG9ydE5hbWVzcGFjZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDnm67lvZUgJHtyZXBvcnROYW1lc3BhY2V9IOS4jeWtmOWcqO+8jOW8gOWni+WIm+W7uuS7k+W6k2ApO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBicmFuY2ggPSB0eXBlb2YgY2F0YWxvZ0NvbmZpZy5mZWNvZGUgPT09ICdzdHJpbmcnID8gY2F0YWxvZ0NvbmZpZy5mZWNvZGUgOiBjYXRhbG9nQ29uZmlnLmZlY29kZS5icmFuY2g7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFicmFuY2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDphY3nva7mlofku7YgJHt5ZHNKc29ufSBjYXRhbG9ncy4ke2NhdGFsb2d9IOaKpeWRiuacjeWKoeacquaMh+WumuWIhuaUr++8jOivt+mAmui/hyBnaXQuZmVjb2RlIOaIluiAhSBjYXRhbG9ncy4ke2NhdGFsb2d9LmZlY29kZS5icmFuY2gg6YWN572u5YiG5pSvYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZXhlY0NtZChgXCIke2dpdENtZH1cIiBjbG9uZSAtYiAke2JyYW5jaH0gJHtmZWNvZGVVcmx9ICR7cmVwb3J0TmFtZXNwYWNlfWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOaLieWPluaKpeWRiuacjeWKoeS7k+W6k+WujOaIkGApO1xyXG5cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCflpITnkIbmiqXlkYrmnoTlu7rvvIzlop7liqDmnoTlu7rmlofku7YnKTtcclxuICAgICAgICAgICAgICAgIGxldCBmZWNvZGVCdWlsZEpzID0gYCR7cmVwb3J0TmFtZXNwYWNlfS9idWlsZC5qc2A7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmVjb2RlQnVpbGRKcykpIHtcclxuICAgICAgICAgICAgICAgICAgICBmcy5jcFN5bmMoYCR7ZGlyfS9mZWNvZGUtYnVpbGQuanNgLCBmZWNvZGVCdWlsZEpzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCBmZWNvZGVQYWNrYWdlSnNvbiA9IGAke3JlcG9ydE5hbWVzcGFjZX0vcGFja2FnZS5qc29uYDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGZlY29kZVBhY2thZ2VTdHJpbmcgPSBmcy5yZWFkRmlsZVN5bmMoZmVjb2RlUGFja2FnZUpzb24pLnRvU3RyaW5nKCd1dGYtOCcpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFmZWNvZGVQYWNrYWdlU3RyaW5nLmluY2x1ZGVzKCdidWlsZC5qcycpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOS/ruaUuSR7ZmVjb2RlUGFja2FnZUpzb259YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFja2FnZUpzb24gPSBKU09OLnBhcnNlKGZlY29kZVBhY2thZ2VTdHJpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhY2thZ2VKc29uLnNjcmlwdHNbJ2J1aWxkJ10gKz0gJyAmJiBub2RlIGJ1aWxkLmpzJztcclxuICAgICAgICAgICAgICAgICAgICBwYWNrYWdlSnNvbi5kb21haW5LZXkgPSBkb21haW5LZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8g5Yig6Zmk5q2k5L6d6LWWIOS8muWvvOiHtG5wbSBpIOWksei0pVxyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwYWNrYWdlSnNvbi5kZXBlbmRlbmNpZXMuemxpYlxyXG4gICAgICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmVjb2RlUGFja2FnZUpzb24sIEpTT04uc3RyaW5naWZ5KHBhY2thZ2VKc29uLCBudWxsLCA0KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOS/ruaUuSR7ZmVjb2RlUGFja2FnZUpzb2595a6M5oiQYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOWuieijheaKpeWRiuacjeWKoeS+nei1lmApO1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgZXhlY0NtZCgnbnBtIGknLCByZXBvcnROYW1lc3BhY2UpO1xyXG5cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDnlJ/miJB2ZXJzaW9uLmpzb24g5paH5Lu2YClcclxuICAgICAgICAgICAgICAgIGNvbnN0IHV1aWQgPSByYW5kb21VVUlEKCkudG9TdHJpbmcoKVxyXG4gICAgICAgICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhgJHtyZXBvcnROYW1lc3BhY2V9L3ZlcnNpb24uanNvbmAsIGB7XCJ2ZXJzaW9uXCI6IFwiJHt1dWlkfVwifWApO1xyXG5cclxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCfliJ3lp4vljJbpobnnm67njq/looPotYTmupAnKTtcclxuICAgICAgICAgICAgICAgIC8vIOWmguaenCBuYW1lc3BhY2UvKGRpc2t8ZGlza3MpIOWmguaenOWtmOWcqCDot7Pov4dcclxuICAgICAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGAke25hbWVzcGFjZX0vZGlza2ApIHx8IGZzLmV4aXN0c1N5bmMoYCR7bmFtZXNwYWNlfS9kaXNrc2ApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOW3suWtmOWcqO+8jOi3s+i/h+eOr+Wig+i1hOa6kOaWh+S7tuS4i+i9vWApO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBodHRwczovL2Rmcy56aGlwZXIuY29tL3YzcjYvZW52LnppcFxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDlvIDlp4vkuIvovb3pobnnm67njq/looPotYTmupDmlofku7ZgKVxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBnaXRaaXBGaWxlID0gYCR7bmFtZXNwYWNlfS9lbnYuemlwYDtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGAke3dnZXR9ICR7UlNfVVJMfS9lbnYuemlwIC1PIFwiJHtnaXRaaXBGaWxlfVwiYCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDop6PljovotYTmupDmlofku7bljIUgJHtnaXRaaXBGaWxlfWApXHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZXhlY0NtZChgXCIke3VuemlwfVwiIFwiJHtnaXRaaXBGaWxlfVwiYCwgbmFtZXNwYWNlKTtcclxuICAgICAgICAgICAgICAgICAgICBmcy5ybVN5bmMoZ2l0WmlwRmlsZSlcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygn5ZCv5YqoSURFJyk7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCBleGVjQ21kKGBcIiR7aWRlUGF0aH0vQ29kZS9Db2RlLmV4ZVwiIFwiJHtuYW1lc3BhY2V9XCJgKTtcclxuICAgICAgICAgICAgICAgIC8vIOmcgOimgeetieW+hUlEReWQr+WKqOWujOaIkOWQjuWFs+mXrVxyXG4gICAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDMwMDApKVxyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ+W3suWQr+WKqElERe+8jOivt+aMieeFp+aWh+aho+ivtOaYjui/m+ihjOWItuebmOaTjeS9nCcpXHJcbiAgICAgICAgICAgIH0pLmhvb2soJ3Bvc3RBY3Rpb24nLCAoKSA9PiBwcm9jZXNzLmV4aXQoMCkpXHJcblxyXG4gICAgICAgIHByb2dyYW0ucGFyc2UocHJvY2Vzcy5hcmd2KVxyXG4gICAgfVxyXG59XHJcbiJdfQ==
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yds-tool",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "isv本地制盘工具",
|
|
5
|
+
"main": "./bin/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"yds": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"src"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"yds"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"init": "tsc -p tsconfig.json&node bin/app.js init",
|
|
18
|
+
"start": "tsc -p tsconfig.json&node bin/app.js start geer"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git@codeup.aliyun.com:6166f78958608c6ab5d8d66d/isv/create-disk.git"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20.0.0"
|
|
26
|
+
},
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@babel/cli": "^7.16.0",
|
|
31
|
+
"@babel/core": "^7.16.5",
|
|
32
|
+
"@babel/plugin-proposal-decorators": "^7.16.5",
|
|
33
|
+
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
34
|
+
"@babel/plugin-transform-runtime": "^7.16.5",
|
|
35
|
+
"@babel/preset-env": "^7.16.5",
|
|
36
|
+
"@babel/register": "^7.16.5",
|
|
37
|
+
"@babel/runtime": "^7.16.5",
|
|
38
|
+
"@types/node": "^20.1.3",
|
|
39
|
+
"babel-plugin-transform-decorators-legacy": "^1.3.5",
|
|
40
|
+
"commander": "^14.0.2",
|
|
41
|
+
"sqlite3": "^5.1.7",
|
|
42
|
+
"vweb-core": "^3.2.3"
|
|
43
|
+
}
|
|
44
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# YDS制盘工具
|
|
2
|
+
|
|
3
|
+
> 支持ISV V3R6出盘
|
|
4
|
+
|
|
5
|
+
## 本地开发
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
npm run init
|
|
9
|
+
npm run start
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 本地安装调试
|
|
13
|
+
|
|
14
|
+
```shell
|
|
15
|
+
# 查看全局安装的包
|
|
16
|
+
|
|
17
|
+
npm list -g --depth 0
|
|
18
|
+
|
|
19
|
+
# 临时安装 退出时候务必卸载 否则会污染全局环境
|
|
20
|
+
npm link
|
|
21
|
+
|
|
22
|
+
# 卸载
|
|
23
|
+
npm uninstall -g yds-tool
|
|
24
|
+
```
|
package/src/main.ts
ADDED
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import {program} from "commander";
|
|
2
|
+
import * as process from "process";
|
|
3
|
+
import {LoggerFactory, util} from "vweb-core";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import * as child_process from "node:child_process";
|
|
6
|
+
import * as fs from "node:fs";
|
|
7
|
+
import * as os from 'node:os';
|
|
8
|
+
import {randomUUID} from 'crypto'
|
|
9
|
+
|
|
10
|
+
const domainKey = 'p-hcc-i000-p00a-hrcpe';
|
|
11
|
+
const pkg = require('../package.json');
|
|
12
|
+
const RS_URL = 'https://dfs.zhiper.com/v3r6';
|
|
13
|
+
|
|
14
|
+
const logger: Logger = LoggerFactory.getLogger('YDS');
|
|
15
|
+
|
|
16
|
+
const execCmd = async (command: string, cwd?: string) => {
|
|
17
|
+
logger.info(`执行命令 ${command} ${cwd ? `,执行目录为${cwd}` :''}`);
|
|
18
|
+
let start = Date.now();
|
|
19
|
+
child_process.execSync(command, {
|
|
20
|
+
cwd, encoding: 'utf-8',
|
|
21
|
+
timeout: 60000,
|
|
22
|
+
stdio: [0, 1, 2]
|
|
23
|
+
});
|
|
24
|
+
logger.info(`执行命令 ${command} 耗时 \x1B[34m <${Date.now() - start}ms>]`)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const platform = os.platform()
|
|
28
|
+
if (platform !== 'win32') {
|
|
29
|
+
logger.error('当前工具仅支持windows系统');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const isAdmin = () => {
|
|
34
|
+
try {
|
|
35
|
+
// 尝试执行一个只有管理员才能运行的命令
|
|
36
|
+
// 使用 >nul 2>&1 来抑制输出
|
|
37
|
+
child_process.execSync('net session >nul 2>&1');
|
|
38
|
+
return true; // 成功执行
|
|
39
|
+
} catch (err) {
|
|
40
|
+
return false; // 执行失败,权限不足
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let wget = path.resolve( 'wget.exe');
|
|
45
|
+
let zip = path.resolve('zip.exe');
|
|
46
|
+
let unzip = path.resolve('unzip.exe');
|
|
47
|
+
|
|
48
|
+
program.name("yds")
|
|
49
|
+
.usage("[command] [options]")
|
|
50
|
+
.description("yds 制盘工具 如果命令参数中存在空格 使用双引号\"\"包裹")
|
|
51
|
+
.version(`yds ${pkg.version}`);
|
|
52
|
+
|
|
53
|
+
type MicroService = 'hrcpe' | 'fecode';
|
|
54
|
+
|
|
55
|
+
type Git = {
|
|
56
|
+
url: string,
|
|
57
|
+
branch: string
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
type YdsConfig = {
|
|
61
|
+
hosts: Array<string>;
|
|
62
|
+
git: Record<MicroService, string>;
|
|
63
|
+
catalogs: {
|
|
64
|
+
[catalog: string]: Record<MicroService, string | Git>
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export default class Main {
|
|
69
|
+
|
|
70
|
+
startup() {
|
|
71
|
+
program
|
|
72
|
+
.command('init [workdir]')
|
|
73
|
+
.usage('init [workdir]')
|
|
74
|
+
.description('初始化YDS制盘环境, workdir表示制盘工作目录,如果不指定则使用当前目录')
|
|
75
|
+
.action(async (workdir: string = path.resolve(process.cwd())) => {
|
|
76
|
+
const dir = path.resolve(workdir);
|
|
77
|
+
logger.info(`初始化YDS制盘环境 工作目录:${dir}`);
|
|
78
|
+
const gitExists = await util.cmd.exists('git');
|
|
79
|
+
logger.info(`检查是否安装了git >> ${gitExists ? '已安装' : '未安装'}`);
|
|
80
|
+
if (!gitExists && !fs.existsSync(`${dir}/git-for-windows`)) {
|
|
81
|
+
const gitZipName = 'git-for-windows.zip'
|
|
82
|
+
logger.info(`下载git 安装包 ${gitZipName}`);
|
|
83
|
+
const gitZipFile = `${dir}/${gitZipName}`;
|
|
84
|
+
// 检查是否已经存在安装包 如果有先删除
|
|
85
|
+
if (fs.existsSync(gitZipFile)) {
|
|
86
|
+
logger.info(`删除已存在安装包 ${gitZipFile}`);
|
|
87
|
+
fs.rmSync(gitZipFile);
|
|
88
|
+
}
|
|
89
|
+
// 下载安装包并输出日志
|
|
90
|
+
await execCmd(`${wget} ${RS_URL}/${gitZipName} -O "${gitZipFile}"`);
|
|
91
|
+
logger.info(`解压安装包 ${gitZipFile}`)
|
|
92
|
+
await execCmd(`"${unzip}" "${gitZipFile}" -d "${dir}"`);
|
|
93
|
+
fs.rmSync(gitZipFile)
|
|
94
|
+
logger.info(`git 安装完成`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const javaExists = await util.cmd.exists('java');
|
|
98
|
+
logger.info(`检查是否安装了java >> ${javaExists ? '已安装' : '未安装'}`);
|
|
99
|
+
if (!javaExists) {
|
|
100
|
+
logger.info('未找到java,准备安装java,开始下载jdk');
|
|
101
|
+
const jdkZipName = 'jdk-11.0.15.1_windows-x64_bin.zip'
|
|
102
|
+
await execCmd(`${wget} ${RS_URL}/${jdkZipName} -O "${dir}/${jdkZipName}"`);
|
|
103
|
+
logger.info(`解压jdk 安装包 ${dir}/${jdkZipName}`)
|
|
104
|
+
await execCmd(`"${unzip}" "${dir}/${jdkZipName}"`, dir);
|
|
105
|
+
logger.info(`配置java环境变量`);
|
|
106
|
+
let javaHome = `${dir}/jdk-11.0.15.1`;
|
|
107
|
+
await execCmd(`setx JAVA_HOME "${javaHome}"`);
|
|
108
|
+
await execCmd(`setx CLASS_PATH ".;%JAVA_HOME%\lib;"`);
|
|
109
|
+
await execCmd( `setx PATH "%PATH%;%JAVA_HOME%\bin;"` );
|
|
110
|
+
process.env.JAVA_HOME = javaHome;
|
|
111
|
+
logger.info(`java 安装完成`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
logger.info(`检查java版本`);
|
|
115
|
+
await execCmd('java -version');
|
|
116
|
+
// 导入证书到java 如果java是1.8版本 需要导入到 JAVA_HOME/jre/lib/security/cacerts 如果是11版本 需要导入到 JAVA_HOME/lib/security/cacerts
|
|
117
|
+
const javaHome = process.env.JAVA_HOME;
|
|
118
|
+
if (javaHome) {
|
|
119
|
+
let certsFilename = 'lib/security/cacerts';
|
|
120
|
+
let certsFile = `${javaHome}/${certsFilename}`;
|
|
121
|
+
if (!fs.existsSync(certsFile)) {
|
|
122
|
+
certsFile = `${javaHome}/jre/${certsFilename}`;
|
|
123
|
+
}
|
|
124
|
+
logger.info(`检查java证书目录 ${certsFile}`);
|
|
125
|
+
if (fs.existsSync(certsFile)) {
|
|
126
|
+
// 判断证书是否已经导入
|
|
127
|
+
try {
|
|
128
|
+
await execCmd(`keytool -list -v -keystore "${certsFile}" -storepass changeit --alias yyrd`)
|
|
129
|
+
logger.info(`yyrd.crt 证书已存在`);
|
|
130
|
+
} catch (e) {
|
|
131
|
+
// 证书不存在
|
|
132
|
+
logger.info(`导入 yyrd.crt 证书到java ${certsFile}`);
|
|
133
|
+
await execCmd(`keytool -importcert -file "${dir}/yyrd.crt" -keystore "${certsFile}" -storepass changeit -noprompt`);
|
|
134
|
+
logger.info(`yyrd.crt 证书导入完成`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const mavenHome = `${dir}/maven-3.8.6`;
|
|
140
|
+
const mavenExists = util.cmd.exists('mvn');
|
|
141
|
+
logger.info(`检查是否安装了maven >> ${mavenExists ? '已安装' : '未安装'}`);
|
|
142
|
+
if (!mavenExists) {
|
|
143
|
+
const mavenZipName = 'maven-3.8.6.zip'
|
|
144
|
+
logger.info(`下载maven 安装包 ${mavenZipName}`);
|
|
145
|
+
const mavenZipFile = `${dir}/${mavenZipName}`;
|
|
146
|
+
// 检查是否已经存在安装包 如果有先删除
|
|
147
|
+
if (fs.existsSync(mavenZipFile)) {
|
|
148
|
+
logger.info(`删除已存在安装包 ${mavenZipFile}`);
|
|
149
|
+
fs.rmSync(mavenZipFile);
|
|
150
|
+
}
|
|
151
|
+
// 下载安装包并输出日志
|
|
152
|
+
await execCmd(`${wget} ${RS_URL}/${mavenZipName} -O "${mavenZipFile}"`);
|
|
153
|
+
logger.info(`解压安装包 ${mavenZipFile}`)
|
|
154
|
+
await execCmd(`"${unzip}" "${mavenZipFile}" -d "${dir}"`);
|
|
155
|
+
fs.rmSync(mavenZipFile);
|
|
156
|
+
|
|
157
|
+
// 添加maven 环境变量
|
|
158
|
+
try {
|
|
159
|
+
// Windows核心命令:永久追加路径到【用户环境变量PATH】,永久生效
|
|
160
|
+
let mvnPath = path.resolve(`${mavenHome}/bin`);
|
|
161
|
+
await execCmd( `setx PATH "%PATH%;${mvnPath}"` );
|
|
162
|
+
logger.info(`✅ 成功!Maven路径【${mvnPath}】已添加到系统PATH环境变量`);
|
|
163
|
+
} catch (err) {
|
|
164
|
+
console.error('❌ 添加失败:', err.message);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
logger.info(`maven 安装完成`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
logger.info(`初始化node环境`);
|
|
171
|
+
await execCmd('npm install -g pnpm typescript --registry=https://registry.npmmirror.com');
|
|
172
|
+
logger.info(`初始化node环境完成`);
|
|
173
|
+
|
|
174
|
+
logger.info(`检测code是否存在`)
|
|
175
|
+
const codeDir = `${dir}/yds-1.0.3`;
|
|
176
|
+
if (!fs.existsSync(codeDir)) {
|
|
177
|
+
const codeZipName = 'yds-1.0.3-jdk-8-windows-x86_64.zip'
|
|
178
|
+
logger.info(`下载code IDE 安装包 ${codeZipName}`);
|
|
179
|
+
const codeZipFile = `${dir}/${codeZipName}`;
|
|
180
|
+
// 检查是否已经存在安装包 如果有先删除
|
|
181
|
+
if (fs.existsSync(codeZipFile)) {
|
|
182
|
+
logger.info(`删除已存在安装包 ${codeZipFile}`);
|
|
183
|
+
fs.rmSync(codeZipFile);
|
|
184
|
+
}
|
|
185
|
+
// 下载安装包并输出日志
|
|
186
|
+
await execCmd(`${wget} https://yoncommunity.yonyoucloud.com/YDSDownload/Window/x64/${codeZipName} -O "${codeZipFile}"`);
|
|
187
|
+
logger.info(`解压安装包 ${codeZipFile}`)
|
|
188
|
+
fs.mkdirSync(codeDir, { recursive: true });
|
|
189
|
+
await execCmd(`"${unzip}" "${codeZipFile}" -d "${codeDir}"`);
|
|
190
|
+
fs.rmSync(codeZipFile)
|
|
191
|
+
await new Promise((resolve) => setTimeout(resolve, 5000))
|
|
192
|
+
logger.info(`code IDE 安装完成`);
|
|
193
|
+
}
|
|
194
|
+
logger.info(`初始化YDS IDE 全局配置`)
|
|
195
|
+
const settingsJson = `${codeDir}/Code/data/user-data/User/settings.json`;
|
|
196
|
+
let settingsJsonObj = {};
|
|
197
|
+
if (fs.existsSync(settingsJson)) {
|
|
198
|
+
settingsJsonObj = JSON.parse(fs.readFileSync(settingsJson).toString('utf-8'));
|
|
199
|
+
}
|
|
200
|
+
let settingXml = path.resolve(`${mavenHome}/conf/settings.xml`);
|
|
201
|
+
if (!fs.existsSync(settingXml) && !fs.existsSync(`${dir}/settings.xml`)) {
|
|
202
|
+
await execCmd(`${wget} ${RS_URL}/settings.xml`);
|
|
203
|
+
settingXml = path.resolve(`${dir}/settings.xml`)
|
|
204
|
+
}
|
|
205
|
+
settingsJsonObj["java.configuration.maven.globalSettings"] = settingXml;
|
|
206
|
+
settingsJsonObj["java.configuration.maven.userSettings"] = settingXml;
|
|
207
|
+
settingsJsonObj["maven.settingsFile"] = settingXml;
|
|
208
|
+
fs.writeFileSync(settingsJson, JSON.stringify(settingsJsonObj, null, 4));
|
|
209
|
+
logger.info(`初始化YDS IDE 全局配置完成`);
|
|
210
|
+
|
|
211
|
+
// 检查当前用户目录下.ssh是否存在 id_ed25519.pub 密钥文件,如果没有则放到.ssh 目录下
|
|
212
|
+
const sshDir = path.resolve(process.env.USERPROFILE, '.ssh');
|
|
213
|
+
if (!fs.existsSync(sshDir)) {
|
|
214
|
+
fs.mkdirSync(sshDir);
|
|
215
|
+
}
|
|
216
|
+
if (!fs.existsSync(`${sshDir}/id_ed25519.pub`)) {
|
|
217
|
+
logger.info(`拷贝密钥文件`);
|
|
218
|
+
fs.copyFileSync(`${dir}/id_ed25519.pub`, `${sshDir}/id_ed25519.pub`);
|
|
219
|
+
fs.copyFileSync(`${dir}/id_ed25519`, `${sshDir}/id_ed25519`);
|
|
220
|
+
logger.info(`拷贝密钥文件完成`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
logger.info(`初始化YDS制盘环境完成`)
|
|
224
|
+
}).hook('postAction', () => process.exit(0));
|
|
225
|
+
|
|
226
|
+
program
|
|
227
|
+
.command('start <catalog> [workdir]')
|
|
228
|
+
.usage('start <catalog> [workdir]')
|
|
229
|
+
.option('-f, --file <file>', '配置文件')
|
|
230
|
+
.addHelpText('after', `
|
|
231
|
+
配置文件内容示例:
|
|
232
|
+
{
|
|
233
|
+
hosts?: Array<string>;
|
|
234
|
+
git: Record<'hrcpe' | 'fecode', string>;
|
|
235
|
+
catalogs: {
|
|
236
|
+
[catalog: string]: Record<'hrcpe' | 'fecode', string | { url: string, branch: string }>
|
|
237
|
+
}
|
|
238
|
+
}`)
|
|
239
|
+
.description('启动制盘环境,catalog表示需要制盘的模块,对应配置文件中catalogs的key值,用于指定需要出盘的信息,workdir表示制盘工作目录,如果不指定则使用当前目录')
|
|
240
|
+
.action(async (catalog: string, workdir: string = path.resolve(process.cwd()), options: { file: string }) => {
|
|
241
|
+
const dir = path.resolve(workdir);
|
|
242
|
+
|
|
243
|
+
logger.info(`开始检测制盘环境检测`);
|
|
244
|
+
let gitCmd = 'git';
|
|
245
|
+
const gitExists = await util.cmd.exists(gitCmd);
|
|
246
|
+
if (!gitExists) {
|
|
247
|
+
gitCmd = `${dir}/git-for-windows/bin/git.exe`;
|
|
248
|
+
if (!fs.existsSync(gitCmd)) {
|
|
249
|
+
logger.error(`未找到git命令 ${gitCmd}, 请先执行 init 初始化制盘环境`);
|
|
250
|
+
process.exit(1)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
let settingXml = path.resolve(`${dir}/settings.xml`);
|
|
255
|
+
let mvnCmd = 'mvn';
|
|
256
|
+
if (!fs.existsSync(settingXml)) {
|
|
257
|
+
let mavenHome = `${dir}/maven-3.8.6`;
|
|
258
|
+
mvnCmd = `"${mavenHome}/bin/mvn.cmd"`;
|
|
259
|
+
settingXml = `${mavenHome}/conf/settings.xml`;
|
|
260
|
+
if (!fs.existsSync(mvnCmd)) {
|
|
261
|
+
logger.error(`未找到mvn命令 ${mvnCmd}, 请先执行 init 初始化制盘环境`);
|
|
262
|
+
process.exit(1)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
let idePath = `${dir}/yds-1.0.3`
|
|
267
|
+
if (!fs.existsSync(idePath)) {
|
|
268
|
+
logger.error(`未找到IDE ${idePath}, 请先执行 init 初始化制盘环境`);
|
|
269
|
+
process.exit(1)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
logger.info(`制盘环境检测完成`)
|
|
273
|
+
|
|
274
|
+
const ydsJson = path.resolve(options.file || `${dir}/yds.json`);
|
|
275
|
+
logger.info(`开始制盘 ${catalog} 工作目录:${dir}`);
|
|
276
|
+
// 读取配置文件
|
|
277
|
+
if (!fs.existsSync(ydsJson)) {
|
|
278
|
+
logger.error(`未找到配置文件 ${ydsJson}`);
|
|
279
|
+
process.exit(1);
|
|
280
|
+
}
|
|
281
|
+
const ydsJsonStr = fs.readFileSync(ydsJson).toString('utf-8');
|
|
282
|
+
// 检测配置文件是否完整
|
|
283
|
+
let config: YdsConfig;
|
|
284
|
+
const checkConfigError = () => {
|
|
285
|
+
logger.error(`配置文件 ${ydsJson} 格式错误 参考示例:
|
|
286
|
+
{
|
|
287
|
+
hosts?: Array<string>;
|
|
288
|
+
git: Record<'hrcpe' | 'fecode', string>;
|
|
289
|
+
catalogs: {
|
|
290
|
+
[catalog: string]: Record<'hrcpe' | 'fecode', string | { url: string, branch: string }>
|
|
291
|
+
}
|
|
292
|
+
}`);
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
config = JSON.parse(ydsJsonStr);
|
|
297
|
+
if (!config.catalogs) {
|
|
298
|
+
checkConfigError()
|
|
299
|
+
}
|
|
300
|
+
} catch (e) {
|
|
301
|
+
checkConfigError()
|
|
302
|
+
}
|
|
303
|
+
const git = config.git;
|
|
304
|
+
const catalogConfig = config.catalogs[catalog];
|
|
305
|
+
if (typeof catalogConfig === 'undefined') {
|
|
306
|
+
logger.error(`配置文件 ${ydsJson} 找不到 catalogs.${catalog} 先关配置`);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
if (typeof catalogConfig.hrcpe === 'undefined' || typeof catalogConfig.fecode === 'undefined') {
|
|
310
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog}.hrcpe 或 catalogs.${catalog}.fecode 字段缺失`);
|
|
311
|
+
process.exit(1);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const namespace = `${dir}/${catalog}`;
|
|
315
|
+
if (!fs.existsSync(namespace)) {
|
|
316
|
+
logger.info(`创建目录 ${namespace}`);
|
|
317
|
+
fs.mkdirSync(namespace);
|
|
318
|
+
} else {
|
|
319
|
+
logger.info(`目录 ${namespace} 已存在`);
|
|
320
|
+
}
|
|
321
|
+
let hrcpeUrl = typeof catalogConfig.hrcpe === 'string' ? git?.hrcpe : catalogConfig.hrcpe.url;
|
|
322
|
+
if (!hrcpeUrl) {
|
|
323
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 后端服务 未指定仓库地址,请通过 git.hrcpe 或者 catalogs.${catalog}.hrcpe.url 指定仓库地址`);
|
|
324
|
+
}
|
|
325
|
+
logger.info(`开始拉取后端服务仓库 ${hrcpeUrl}`);
|
|
326
|
+
if (fs.existsSync(`${namespace}/.git`)) {
|
|
327
|
+
logger.info(`目录 ${namespace} 已存在,开始更新仓库`);
|
|
328
|
+
await execCmd(`"${gitCmd}" pull`, namespace);
|
|
329
|
+
} else {
|
|
330
|
+
logger.info(`目录 ${namespace} 不存在,开始创建仓库`);
|
|
331
|
+
let branch = typeof catalogConfig.hrcpe === 'string' ? catalogConfig.hrcpe : catalogConfig.hrcpe.branch;
|
|
332
|
+
if (!branch) {
|
|
333
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 后端服务 未指定分支,请通过 git.hrcpe 或者 catalogs.${catalog}.hrcpe.branch 配置分支`);
|
|
334
|
+
process.exit(1);
|
|
335
|
+
}
|
|
336
|
+
await execCmd(`"${gitCmd}" clone -b ${branch} ${hrcpeUrl} ${namespace}`, namespace);
|
|
337
|
+
}
|
|
338
|
+
logger.info(`拉取后端服务仓库完成`);
|
|
339
|
+
let boostrapPomXml = `${namespace}/${domainKey}-be/dev-${domainKey}-bootstrap/pom.xml`;
|
|
340
|
+
logger.info(`替换文件 ${boostrapPomXml} 中的ROOT为domainKey,否则会导致制盘失败,无法找到制品`);
|
|
341
|
+
const boostrapPomXmlString = fs.readFileSync(boostrapPomXml).toString('utf-8');
|
|
342
|
+
if (boostrapPomXmlString.includes('ROOT')) {
|
|
343
|
+
fs.writeFileSync(boostrapPomXml, boostrapPomXmlString.replace(/ROOT/g, domainKey));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (config.hosts && config.hosts.length) {
|
|
347
|
+
logger.info(`存在hosts配置,检测系统hosts配置文件是否已经配置`);
|
|
348
|
+
let hostsFile = path.resolve(process.env.WINDIR, 'System32', 'drivers', 'etc', 'hosts');
|
|
349
|
+
const hostList = fs.readFileSync(hostsFile).toString('utf-8').split('\n');
|
|
350
|
+
let appendHosts = [...config.hosts]
|
|
351
|
+
for (let hostItem of hostList) {
|
|
352
|
+
if (/#/.test(hostItem)) {
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
for (let appendHost of config.hosts) {
|
|
356
|
+
const [ip, domain] = appendHost.split(' ').filter(item => item)
|
|
357
|
+
if (hostItem.includes(ip) && hostItem.includes(domain)) {
|
|
358
|
+
logger.info(`系统hosts配置文件已存在 ${appendHost}`);
|
|
359
|
+
appendHosts.remove(appendHost);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// 读取系统hosts配置文件
|
|
364
|
+
if (appendHosts.length) {
|
|
365
|
+
if (isAdmin()) {
|
|
366
|
+
fs.appendFileSync(hostsFile, `\n${appendHosts.join('\n')}\n`, {
|
|
367
|
+
encoding: 'utf-8'
|
|
368
|
+
})
|
|
369
|
+
} else {
|
|
370
|
+
logger.error(`当前非管理员启动无法更改hosts文件,请使用管理员启动或者手动添加 ${appendHosts.join('\n')} 到文件 ${hostsFile}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
logger.info(`hosts 配置检测完成`);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
logger.info('初始化项目maven环境');
|
|
377
|
+
let mvnConfigDir = `${namespace}/.mvn`;
|
|
378
|
+
if (!fs.existsSync(mvnConfigDir)) {
|
|
379
|
+
await execCmd(`${mvnCmd} -N io.takari:maven:wrapper -Dmaven=3.8.6`, namespace);
|
|
380
|
+
}
|
|
381
|
+
// 写入maven配置到 .mvn/maven.config
|
|
382
|
+
let configFile = `${mvnConfigDir}/maven.config`;
|
|
383
|
+
if (fs.existsSync(configFile)) {
|
|
384
|
+
fs.rmSync(configFile)
|
|
385
|
+
}
|
|
386
|
+
fs.writeFileSync(`${mvnConfigDir}/maven.config`, `-s\n${settingXml}\n-Dmaven.wagon.http.ssl.insecure=true\n-Dmaven.wagon.http.ssl.allowall=true`);
|
|
387
|
+
logger.info(`当前maven信息`)
|
|
388
|
+
await execCmd(`${mvnCmd} --version`, namespace);
|
|
389
|
+
|
|
390
|
+
logger.info('项目maven清理')
|
|
391
|
+
await execCmd(`${mvnCmd} clean -DskipTests`, `${namespace}/${domainKey}-be`);
|
|
392
|
+
|
|
393
|
+
logger.info('处理前端构建,增加构建文件');
|
|
394
|
+
let feDir = `${namespace}/${domainKey}-fe`;
|
|
395
|
+
let feBuildJs = `${feDir}/build.js`;
|
|
396
|
+
if (!fs.existsSync(feBuildJs)) {
|
|
397
|
+
fs.cpSync(`${dir}/fe-build.js`, feBuildJs);
|
|
398
|
+
}
|
|
399
|
+
let fePackageJson = `${feDir}/package.json`;
|
|
400
|
+
const packageString = fs.readFileSync(fePackageJson).toString('utf-8');
|
|
401
|
+
if (!packageString.includes('build.js')) {
|
|
402
|
+
logger.info(`修改${fePackageJson}`);
|
|
403
|
+
const packageJson = JSON.parse(packageString);
|
|
404
|
+
packageJson.scripts['build:extend'] += ' && node build.js';
|
|
405
|
+
fs.writeFileSync(fePackageJson, JSON.stringify(packageJson, null, 4));
|
|
406
|
+
logger.info(`修改${fePackageJson}完成`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
let fecodeUrl = typeof catalogConfig.fecode === 'string' ? git?.fecode : catalogConfig.fecode.url;
|
|
411
|
+
if (!fecodeUrl) {
|
|
412
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 后端服务 未指定仓库地址,请通过 git.fecode 或者 catalogs.${catalog}.fecode.url 指定仓库地址`);
|
|
413
|
+
}
|
|
414
|
+
logger.info(`开始拉取报告服务仓库 ${fecodeUrl}`);
|
|
415
|
+
let reportNamespace = `${namespace}/yonbip-yisv-izp1-dev-fecode`;
|
|
416
|
+
if (fs.existsSync(`${reportNamespace}/.git`)) {
|
|
417
|
+
logger.info(`目录 ${reportNamespace} 已存在,开始更新仓库`);
|
|
418
|
+
await execCmd(`"${gitCmd}" pull`, reportNamespace);
|
|
419
|
+
} else {
|
|
420
|
+
logger.info(`目录 ${reportNamespace} 不存在,开始创建仓库`);
|
|
421
|
+
let branch = typeof catalogConfig.fecode === 'string' ? catalogConfig.fecode : catalogConfig.fecode.branch;
|
|
422
|
+
if (!branch) {
|
|
423
|
+
logger.error(`配置文件 ${ydsJson} catalogs.${catalog} 报告服务未指定分支,请通过 git.fecode 或者 catalogs.${catalog}.fecode.branch 配置分支`);
|
|
424
|
+
process.exit(1);
|
|
425
|
+
}
|
|
426
|
+
await execCmd(`"${gitCmd}" clone -b ${branch} ${fecodeUrl} ${reportNamespace}`);
|
|
427
|
+
}
|
|
428
|
+
logger.info(`拉取报告服务仓库完成`);
|
|
429
|
+
|
|
430
|
+
logger.info('处理报告构建,增加构建文件');
|
|
431
|
+
let fecodeBuildJs = `${reportNamespace}/build.js`;
|
|
432
|
+
if (!fs.existsSync(fecodeBuildJs)) {
|
|
433
|
+
fs.cpSync(`${dir}/fecode-build.js`, fecodeBuildJs);
|
|
434
|
+
}
|
|
435
|
+
let fecodePackageJson = `${reportNamespace}/package.json`;
|
|
436
|
+
const fecodePackageString = fs.readFileSync(fecodePackageJson).toString('utf-8');
|
|
437
|
+
if (!fecodePackageString.includes('build.js')) {
|
|
438
|
+
logger.info(`修改${fecodePackageJson}`);
|
|
439
|
+
const packageJson = JSON.parse(fecodePackageString);
|
|
440
|
+
packageJson.scripts['build'] += ' && node build.js';
|
|
441
|
+
packageJson.domainKey = domainKey;
|
|
442
|
+
// 删除此依赖 会导致npm i 失败
|
|
443
|
+
delete packageJson.dependencies.zlib
|
|
444
|
+
fs.writeFileSync(fecodePackageJson, JSON.stringify(packageJson, null, 4));
|
|
445
|
+
logger.info(`修改${fecodePackageJson}完成`);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
logger.info(`安装报告服务依赖`);
|
|
449
|
+
await execCmd('npm i', reportNamespace);
|
|
450
|
+
|
|
451
|
+
logger.info(`生成version.json 文件`)
|
|
452
|
+
const uuid = randomUUID().toString()
|
|
453
|
+
fs.writeFileSync(`${reportNamespace}/version.json`, `{"version": "${uuid}"}`);
|
|
454
|
+
|
|
455
|
+
logger.info('初始化项目环境资源');
|
|
456
|
+
// 如果 namespace/(disk|disks) 如果存在 跳过
|
|
457
|
+
if (fs.existsSync(`${namespace}/disk`) || fs.existsSync(`${namespace}/disks`)) {
|
|
458
|
+
logger.info(`已存在,跳过环境资源文件下载`);
|
|
459
|
+
} else {
|
|
460
|
+
// https://dfs.zhiper.com/v3r6/env.zip
|
|
461
|
+
logger.info(`开始下载项目环境资源文件`)
|
|
462
|
+
let gitZipFile = `${namespace}/env.zip`;
|
|
463
|
+
await execCmd(`${wget} ${RS_URL}/env.zip -O "${gitZipFile}"`);
|
|
464
|
+
|
|
465
|
+
logger.info(`解压资源文件包 ${gitZipFile}`)
|
|
466
|
+
await execCmd(`"${unzip}" "${gitZipFile}"`, namespace);
|
|
467
|
+
fs.rmSync(gitZipFile)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
logger.info('启动IDE');
|
|
471
|
+
await execCmd(`"${idePath}/Code/Code.exe" "${namespace}"`);
|
|
472
|
+
// 需要等待IDE启动完成后关闭
|
|
473
|
+
await new Promise(resolve => setTimeout(resolve, 3000))
|
|
474
|
+
logger.info('已启动IDE,请按照文档说明进行制盘操作')
|
|
475
|
+
}).hook('postAction', () => process.exit(0))
|
|
476
|
+
|
|
477
|
+
program.parse(process.argv)
|
|
478
|
+
}
|
|
479
|
+
}
|