maolike-cli 1.0.7 → 2.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/README.md +239 -101
- package/dist/src/commands/project/CreateCommand.js +48 -93
- package/dist/src/commands/project/DeleteCommand.js +2 -4
- package/dist/src/commands/project/DeployCommand.js +71 -0
- package/dist/src/commands/project/ListCommand.js +6 -4
- package/dist/src/commands/project/TestCommand.js +13 -22
- package/dist/src/commands/project/UpdateCommand.js +17 -45
- package/dist/src/commands/project/ViewCommand.js +1 -2
- package/dist/src/commands/system/ConnectCommand.js +59 -0
- package/dist/src/commands/system/CursorCommand.js +29 -0
- package/dist/src/commands/system/HelpCommand.js +11 -5
- package/dist/src/commands/system/InitCommand.js +1 -1
- package/dist/src/commands/system/LoadCommand.js +71 -139
- package/dist/src/constants/CommandRegistry.js +19 -1
- package/dist/src/core/pipelines/BaseExecutor.js +135 -0
- package/dist/src/core/pipelines/ProdExecutor.js +119 -0
- package/dist/src/core/pipelines/TestExecutor.js +83 -0
- package/dist/src/index.js +1 -1
- package/dist/src/services/ConfigManager.js +116 -129
- package/dist/src/ui/InitWizard.js +40 -142
- package/dist/src/ui/InteractiveShell.js +27 -6
- package/dist/src/utils/ConfigPrompter.js +157 -224
- package/dist/src/utils/Executor.js +18 -0
- package/dist/src/utils/RemoteServer.js +112 -71
- package/package.json +1 -1
- package/dist/src/commands/system/MenuCommand.js +0 -182
- package/dist/src/core/PipelineExecutor.js +0 -333
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const BaseCommand_1 = tslib_1.__importDefault(require("../../utils/BaseCommand"));
|
|
5
|
+
const ConfigManager_1 = require("../../services/ConfigManager");
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
8
|
+
const ProdExecutor_1 = tslib_1.__importDefault(require("../../core/pipelines/ProdExecutor"));
|
|
9
|
+
/** 部署项目到生产环境。 */
|
|
10
|
+
class DeployCommand extends BaseCommand_1.default {
|
|
11
|
+
init() {
|
|
12
|
+
this.program
|
|
13
|
+
.command("deploy <name>")
|
|
14
|
+
.description("部署项目到生产环境")
|
|
15
|
+
.option("-s, --skip-build", "跳过构建步骤")
|
|
16
|
+
.option("-y, --yes", "跳过确认提示")
|
|
17
|
+
.action(this.action.bind(this));
|
|
18
|
+
}
|
|
19
|
+
action(name, options) {
|
|
20
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
var _a;
|
|
22
|
+
if (!ConfigManager_1.ConfigManager.existsOnDisk()) {
|
|
23
|
+
console.log(chalk_1.default.red("请先运行 `ml init` 初始化配置"));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const task = ConfigManager_1.ConfigManager.findProject(name);
|
|
27
|
+
if (!task) {
|
|
28
|
+
console.log(chalk_1.default.red(`未找到项目: ${name}`));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const production = task.environments.production;
|
|
32
|
+
if (!production) {
|
|
33
|
+
console.log(chalk_1.default.red(`\n❌ 项目 [${task.name}] 未配置生产环境`));
|
|
34
|
+
console.log(chalk_1.default.yellow("提示: 请使用 `ml update <name>` 添加生产环境配置"));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (!options.yes) {
|
|
38
|
+
const effectiveBuildCommand = ((_a = task.build.productionCommand) === null || _a === void 0 ? void 0 : _a.trim()) || task.build.testCommand;
|
|
39
|
+
console.log(chalk_1.default.yellow("\n" + "=".repeat(60)));
|
|
40
|
+
console.log(chalk_1.default.yellow.bold(" ⚠️ 即将执行生产环境部署"));
|
|
41
|
+
console.log(chalk_1.default.cyan(`\n 项目名称: ${chalk_1.default.bold(task.name)}`));
|
|
42
|
+
console.log(chalk_1.default.cyan(` 本地路径: ${chalk_1.default.dim(task.localPath)}`));
|
|
43
|
+
console.log(chalk_1.default.cyan(` 生产工作区: ${chalk_1.default.dim(production.workspacePath)}`));
|
|
44
|
+
console.log(chalk_1.default.cyan(` 上线分支: ${chalk_1.default.green(production.branch)}`));
|
|
45
|
+
console.log(chalk_1.default.cyan(` 上线打包命令: ${chalk_1.default.bold(effectiveBuildCommand)}`));
|
|
46
|
+
if (production.relativePath) {
|
|
47
|
+
console.log(chalk_1.default.cyan(` 产物相对目录: ${chalk_1.default.dim(production.relativePath)}`));
|
|
48
|
+
}
|
|
49
|
+
console.log(chalk_1.default.red("\n 注意: 这是生产环境部署操作,请谨慎确认!\n"));
|
|
50
|
+
console.log(chalk_1.default.yellow("=".repeat(60)));
|
|
51
|
+
const { confirm } = yield inquirer_1.default.prompt([
|
|
52
|
+
{
|
|
53
|
+
type: "confirm",
|
|
54
|
+
name: "confirm",
|
|
55
|
+
message: "确认执行生产环境部署?",
|
|
56
|
+
default: false,
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
if (!confirm) {
|
|
60
|
+
console.log(chalk_1.default.gray("\n已取消部署"));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
console.log(chalk_1.default.magenta(`\n🚀 正在启动 [${task.name}] 生产环境推送流程...`));
|
|
65
|
+
yield new ProdExecutor_1.default(task, ConfigManager_1.ConfigManager.servers, {
|
|
66
|
+
skipBuild: options.skipBuild || false,
|
|
67
|
+
}).run();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.default = DeployCommand;
|
|
@@ -23,14 +23,16 @@ class ListCommand extends BaseCommand_1.default {
|
|
|
23
23
|
console.log(chalk_1.default.yellow("未找到配置,请先运行 `ml init`"));
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
-
const config = ConfigManager_1.ConfigManager.config;
|
|
27
26
|
console.log(chalk_1.default.blue("📋 已配置的项目列表:"));
|
|
28
|
-
if (
|
|
27
|
+
if (ConfigManager_1.ConfigManager.projects.length === 0) {
|
|
29
28
|
console.log(chalk_1.default.dim(" (空)"));
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
[...ConfigManager_1.ConfigManager.projects]
|
|
32
|
+
.sort((a, b) => a.sortOrder - b.sortOrder)
|
|
33
|
+
.forEach((project) => {
|
|
34
|
+
const status = project.enabled ? "" : chalk_1.default.dim(" [已停用]");
|
|
35
|
+
console.log(`- ${chalk_1.default.bold(project.name)}${status} (${project.localPath})`);
|
|
34
36
|
});
|
|
35
37
|
});
|
|
36
38
|
}
|
|
@@ -3,42 +3,33 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const BaseCommand_1 = tslib_1.__importDefault(require("../../utils/BaseCommand"));
|
|
5
5
|
const ConfigManager_1 = require("../../services/ConfigManager");
|
|
6
|
-
const
|
|
6
|
+
const TestExecutor_1 = tslib_1.__importDefault(require("../../core/pipelines/TestExecutor"));
|
|
7
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
|
-
/**
|
|
9
|
-
* 项目测试/同步部署命令
|
|
10
|
-
*/
|
|
8
|
+
/** 构建并同步到测试环境。 */
|
|
11
9
|
class TestCommand extends BaseCommand_1.default {
|
|
12
|
-
/**
|
|
13
|
-
* 初始化命令配置
|
|
14
|
-
*/
|
|
15
10
|
init() {
|
|
16
11
|
this.program.command("test <name>").description("构建并将项目同步到测试环境").action(this.action.bind(this));
|
|
17
12
|
}
|
|
18
|
-
/**
|
|
19
|
-
* 执行核心逻辑
|
|
20
|
-
* @param name 项目名称
|
|
21
|
-
*/
|
|
22
13
|
action(name) {
|
|
23
14
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24
15
|
if (!ConfigManager_1.ConfigManager.existsOnDisk()) {
|
|
25
|
-
console.log(chalk_1.default.red("
|
|
16
|
+
console.log(chalk_1.default.red("请先运行 `ml init` 初始化配置"));
|
|
26
17
|
return;
|
|
27
18
|
}
|
|
28
|
-
const
|
|
29
|
-
const task = config["git-list"].find((item) => item.name === name);
|
|
19
|
+
const task = ConfigManager_1.ConfigManager.findProject(name);
|
|
30
20
|
if (!task) {
|
|
31
21
|
console.log(chalk_1.default.red(`未找到项目: ${name}`));
|
|
32
22
|
return;
|
|
33
23
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
24
|
+
if (!task.environments.test.workspacePath.trim()) {
|
|
25
|
+
console.log(chalk_1.default.red(`\n❌ 项目 [${task.name}] 未配置测试环境`));
|
|
26
|
+
if (task.environments.production) {
|
|
27
|
+
console.log(chalk_1.default.yellow(`提示: 当前项目仅支持生产部署,请使用 \`ml deploy ${task.name}\``));
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console.log(chalk_1.default.magenta(`🚀 正在启动 [${task.name}] 测试环境同步流程...`));
|
|
32
|
+
yield new TestExecutor_1.default(task, ConfigManager_1.ConfigManager.servers).run();
|
|
42
33
|
});
|
|
43
34
|
}
|
|
44
35
|
}
|
|
@@ -6,60 +6,37 @@ const ConfigManager_1 = require("../../services/ConfigManager");
|
|
|
6
6
|
const ConfigPrompter_1 = require("../../utils/ConfigPrompter");
|
|
7
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
8
|
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
9
|
-
/**
|
|
10
|
-
* 项目配置更新命令
|
|
11
|
-
*/
|
|
9
|
+
/** 更新指定项目的新结构配置。 */
|
|
12
10
|
class UpdateCommand extends BaseCommand_1.default {
|
|
13
|
-
/**
|
|
14
|
-
* 初始化命令配置
|
|
15
|
-
*/
|
|
16
11
|
init() {
|
|
17
12
|
this.program.command("update <name>").description("更新指定项目的配置").action(this.action.bind(this));
|
|
18
13
|
}
|
|
19
|
-
/**
|
|
20
|
-
* 执行核心逻辑
|
|
21
|
-
* @param name 要更新的项目名称
|
|
22
|
-
*/
|
|
23
14
|
action(name) {
|
|
24
15
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
25
16
|
if (!ConfigManager_1.ConfigManager.existsOnDisk()) {
|
|
26
17
|
console.log(chalk_1.default.red("配置未初始化"));
|
|
27
18
|
return;
|
|
28
19
|
}
|
|
29
|
-
const
|
|
30
|
-
const taskIndex = config["git-list"].findIndex((item) => item.name === name);
|
|
20
|
+
const taskIndex = ConfigManager_1.ConfigManager.projects.findIndex((project) => project.name === name || project.id === name);
|
|
31
21
|
if (taskIndex === -1) {
|
|
32
22
|
console.log(chalk_1.default.red(`未找到项目: ${name}`));
|
|
33
23
|
return;
|
|
34
24
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
console.log(chalk_1.default.cyan(`\n🔧 正在更新配置: [${name}]`));
|
|
38
|
-
// 逐项弹出更新提示
|
|
25
|
+
const task = ConfigManager_1.ConfigManager.projects[taskIndex];
|
|
26
|
+
console.log(chalk_1.default.cyan(`\n🔧 正在更新配置: [${task.name}]`));
|
|
39
27
|
const newName = yield this.promptNameUpdate(task);
|
|
40
28
|
const localPath = yield this.promptPathUpdate(task);
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
task
|
|
46
|
-
|
|
47
|
-
task.build = buildConfig;
|
|
48
|
-
task.test = testConfig;
|
|
49
|
-
// 目前 server 配置中仅 remotePath
|
|
50
|
-
task.server = Object.assign(Object.assign({}, task.server), serverConfig);
|
|
51
|
-
// 赋值以触发 Proxy 持久化
|
|
52
|
-
config["git-list"][taskIndex] = task;
|
|
29
|
+
const build = yield ConfigPrompter_1.ConfigPrompter.promptBuildConfig(task.build);
|
|
30
|
+
const test = yield ConfigPrompter_1.ConfigPrompter.promptTestEnvironment(task.environments.test);
|
|
31
|
+
const production = yield ConfigPrompter_1.ConfigPrompter.promptProductionConfig(task.environments.production, test, task.build.productionCommand);
|
|
32
|
+
build.productionCommand = production.productionCommand;
|
|
33
|
+
ConfigManager_1.ConfigManager.upsertProject(Object.assign(Object.assign({}, task), { name: newName, localPath,
|
|
34
|
+
build, environments: { test, production: production.environment } }));
|
|
53
35
|
console.log(chalk_1.default.green(`\n✅ 项目 [${newName}] 配置更新成功!`));
|
|
54
36
|
});
|
|
55
37
|
}
|
|
56
|
-
/**
|
|
57
|
-
* 弹出项目名称更新提示
|
|
58
|
-
* @param task 当前项目项
|
|
59
|
-
*/
|
|
60
38
|
promptNameUpdate(task) {
|
|
61
39
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
const config = ConfigManager_1.ConfigManager.config;
|
|
63
40
|
const { newName } = yield inquirer_1.default.prompt([
|
|
64
41
|
{
|
|
65
42
|
type: "input",
|
|
@@ -67,32 +44,27 @@ class UpdateCommand extends BaseCommand_1.default {
|
|
|
67
44
|
message: "项目名称:",
|
|
68
45
|
default: task.name,
|
|
69
46
|
validate: (input) => {
|
|
70
|
-
|
|
47
|
+
const value = input.trim();
|
|
48
|
+
if (!value)
|
|
71
49
|
return "名称不能为空";
|
|
72
|
-
if (
|
|
50
|
+
if (value === task.name)
|
|
73
51
|
return true;
|
|
74
|
-
|
|
75
|
-
return exists ? "该名称已被其他项目占用,请更换" : true;
|
|
52
|
+
return ConfigManager_1.ConfigManager.projects.some((project) => project.name === value) ? "该名称已被其他项目占用" : true;
|
|
76
53
|
},
|
|
77
54
|
},
|
|
78
55
|
]);
|
|
79
|
-
return newName;
|
|
56
|
+
return newName.trim();
|
|
80
57
|
});
|
|
81
58
|
}
|
|
82
|
-
/**
|
|
83
|
-
* 弹出本地路径更新提示
|
|
84
|
-
* @param task 当前项目项
|
|
85
|
-
*/
|
|
86
59
|
promptPathUpdate(task) {
|
|
87
60
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
88
|
-
const pathFilter = (input) => input.trim().replace(/^['"]|['"]$/g, "");
|
|
89
61
|
const { localPath } = yield inquirer_1.default.prompt([
|
|
90
62
|
{
|
|
91
63
|
type: "input",
|
|
92
64
|
name: "localPath",
|
|
93
65
|
message: "项目本地路径:",
|
|
94
|
-
default: task.
|
|
95
|
-
filter:
|
|
66
|
+
default: task.localPath,
|
|
67
|
+
filter: (input) => input.trim().replace(/^['"]|['"]$/g, ""),
|
|
96
68
|
},
|
|
97
69
|
]);
|
|
98
70
|
return localPath;
|
|
@@ -24,8 +24,7 @@ class ViewCommand extends BaseCommand_1.default {
|
|
|
24
24
|
console.log(chalk_1.default.red("配置未初始化"));
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
const
|
|
28
|
-
const task = config["git-list"].find((item) => item.name === name);
|
|
27
|
+
const task = ConfigManager_1.ConfigManager.findProject(name);
|
|
29
28
|
if (!task) {
|
|
30
29
|
console.log(chalk_1.default.red(`未找到项目: ${name}`));
|
|
31
30
|
return;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
|
+
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
6
|
+
const BaseCommand_1 = tslib_1.__importDefault(require("../../utils/BaseCommand"));
|
|
7
|
+
const ConfigManager_1 = require("../../services/ConfigManager");
|
|
8
|
+
const RemoteServer_1 = require("../../utils/RemoteServer");
|
|
9
|
+
/** 选择服务器预设并打开远程交互式 SSH Shell。 */
|
|
10
|
+
class ConnectCommand extends BaseCommand_1.default {
|
|
11
|
+
init() {
|
|
12
|
+
this.program.command("connect").description("选择服务器并打开 SSH 连接").action(this.action.bind(this));
|
|
13
|
+
}
|
|
14
|
+
action() {
|
|
15
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
console.error(chalk_1.default.red("`ml connect` 需要在交互式终端中运行"));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const servers = ConfigManager_1.ConfigManager.servers;
|
|
22
|
+
if (servers.length === 0) {
|
|
23
|
+
console.log(chalk_1.default.yellow("未找到服务器配置,请先运行 `ml init` 或导入 servers.json"));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const { serverId } = yield inquirer_1.default.prompt([
|
|
27
|
+
{
|
|
28
|
+
type: "list",
|
|
29
|
+
name: "serverId",
|
|
30
|
+
message: "请选择要连接的服务器:",
|
|
31
|
+
choices: servers.map((server) => ({
|
|
32
|
+
name: `🖥 ${server.name} (${server.username}@${server.host}:${server.port || 22})`,
|
|
33
|
+
value: server.id,
|
|
34
|
+
})),
|
|
35
|
+
},
|
|
36
|
+
]);
|
|
37
|
+
const profile = servers.find((server) => server.id === serverId);
|
|
38
|
+
if (!profile) {
|
|
39
|
+
throw new Error(`未找到服务器配置: ${serverId}`);
|
|
40
|
+
}
|
|
41
|
+
const server = new RemoteServer_1.RemoteServer(profile);
|
|
42
|
+
console.log(chalk_1.default.blue(`\n正在连接服务器: ${profile.name} (${profile.host})`));
|
|
43
|
+
try {
|
|
44
|
+
yield server.openInteractiveShell();
|
|
45
|
+
console.log(chalk_1.default.gray(`\n已断开服务器: ${profile.name}`));
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
const code = error.code;
|
|
49
|
+
process.exitCode = typeof code === "number" && code > 0 ? code : 1;
|
|
50
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
51
|
+
console.error(chalk_1.default.red(`\n❌ 连接失败: ${message}`));
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
server.disconnect();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.default = ConnectCommand;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const BaseCommand_1 = tslib_1.__importDefault(require("../../utils/BaseCommand"));
|
|
5
|
+
const Executor_1 = require("../../utils/Executor");
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const CURSOR_PACKAGE = "@cometix/ccursor@latest";
|
|
8
|
+
/** 重新安装 Cursor++。 */
|
|
9
|
+
class CursorCommand extends BaseCommand_1.default {
|
|
10
|
+
init() {
|
|
11
|
+
this.program.command("cursor").description("重新安装 Cursor++").action(this.action.bind(this));
|
|
12
|
+
}
|
|
13
|
+
action() {
|
|
14
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
try {
|
|
16
|
+
yield (0, Executor_1.runInteractiveCommand)("npx", [CURSOR_PACKAGE, "uninstall"], process.cwd());
|
|
17
|
+
yield (0, Executor_1.runInteractiveCommand)("npx", [CURSOR_PACKAGE, "install"], process.cwd());
|
|
18
|
+
console.log(chalk_1.default.green("\n✅ Cursor++ 重新安装完成"));
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
const code = error.code;
|
|
22
|
+
process.exitCode = typeof code === "number" && code > 0 ? code : 1;
|
|
23
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
24
|
+
console.error(chalk_1.default.red(`\n❌ Cursor++ 重新安装失败: ${message}`));
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = CursorCommand;
|
|
@@ -20,6 +20,7 @@ class HelpCommand extends BaseCommand_1.default {
|
|
|
20
20
|
*/
|
|
21
21
|
action() {
|
|
22
22
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
var _a;
|
|
23
24
|
console.log(chalk_1.default.bold.magenta("\n🤖 Maolike CLI 帮助手册"));
|
|
24
25
|
console.log(chalk_1.default.dim("-----------------------------------"));
|
|
25
26
|
console.log(chalk_1.default.bold.cyan("\n基础命令:"));
|
|
@@ -29,11 +30,16 @@ class HelpCommand extends BaseCommand_1.default {
|
|
|
29
30
|
});
|
|
30
31
|
console.log(chalk_1.default.bold.cyan("\n部署/测试命令:"));
|
|
31
32
|
if (ConfigManager_1.ConfigManager.existsOnDisk()) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
if (ConfigManager_1.ConfigManager.projects.length > 0) {
|
|
34
|
+
const projects = [...ConfigManager_1.ConfigManager.projects].sort((a, b) => a.sortOrder - b.sortOrder);
|
|
35
|
+
for (const project of projects) {
|
|
36
|
+
if (project.environments.test.workspacePath.trim()) {
|
|
37
|
+
console.log(` ${chalk_1.default.green(`ml test ${project.name}`)}`.padEnd(40) + chalk_1.default.dim(`-> 构建并部署 ${project.name}`));
|
|
38
|
+
}
|
|
39
|
+
if ((_a = project.environments.production) === null || _a === void 0 ? void 0 : _a.workspacePath.trim()) {
|
|
40
|
+
console.log(` ${chalk_1.default.green(`ml deploy ${project.name}`)}`.padEnd(40) + chalk_1.default.dim(`-> 部署 ${project.name} 到生产环境`));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
44
|
else {
|
|
39
45
|
console.log(chalk_1.default.gray(" (暂无配置的项目,请运行 ml init 添加)"));
|
|
@@ -12,7 +12,7 @@ class InitCommand extends BaseCommand_1.default {
|
|
|
12
12
|
* 初始化命令配置
|
|
13
13
|
*/
|
|
14
14
|
init() {
|
|
15
|
-
this.program.command("init").description("
|
|
15
|
+
this.program.command("init").description("初始化分层部署配置").action(this.action.bind(this));
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* 执行核心逻辑
|