@git.zone/cli 2.13.13 → 2.14.0
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/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/gitzone.cli.js +46 -35
- package/dist_ts/helpers.climode.d.ts +22 -0
- package/dist_ts/helpers.climode.js +158 -0
- package/dist_ts/helpers.smartconfig.d.ts +11 -0
- package/dist_ts/helpers.smartconfig.js +139 -0
- package/dist_ts/mod_commit/index.d.ts +2 -0
- package/dist_ts/mod_commit/index.js +204 -92
- package/dist_ts/mod_config/index.d.ts +7 -2
- package/dist_ts/mod_config/index.js +390 -176
- package/dist_ts/mod_format/classes.formatcontext.d.ts +11 -2
- package/dist_ts/mod_format/classes.formatcontext.js +14 -4
- package/dist_ts/mod_format/formatters/packagejson.formatter.js +1 -67
- package/dist_ts/mod_format/formatters/smartconfig.formatter.d.ts +2 -7
- package/dist_ts/mod_format/formatters/smartconfig.formatter.js +57 -93
- package/dist_ts/mod_format/index.d.ts +4 -1
- package/dist_ts/mod_format/index.js +235 -67
- package/dist_ts/mod_format/mod.plugins.d.ts +1 -2
- package/dist_ts/mod_format/mod.plugins.js +2 -3
- package/dist_ts/mod_services/index.d.ts +2 -0
- package/dist_ts/mod_services/index.js +366 -168
- package/dist_ts/mod_standard/index.d.ts +3 -1
- package/dist_ts/mod_standard/index.js +159 -59
- package/package.json +1 -1
- package/readme.hints.md +25 -32
- package/readme.md +87 -65
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/gitzone.cli.ts +50 -38
- package/ts/helpers.climode.ts +212 -0
- package/ts/helpers.smartconfig.ts +192 -0
- package/ts/mod_commit/index.ts +325 -98
- package/ts/mod_config/index.ts +490 -182
- package/ts/mod_format/classes.formatcontext.ts +20 -3
- package/ts/mod_format/formatters/packagejson.formatter.ts +0 -91
- package/ts/mod_format/formatters/smartconfig.formatter.ts +67 -94
- package/ts/mod_format/index.ts +294 -81
- package/ts/mod_format/mod.plugins.ts +0 -2
- package/ts/mod_services/index.ts +550 -183
- package/ts/mod_standard/index.ts +191 -58
package/ts/mod_services/index.ts
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
import * as plugins from
|
|
2
|
-
import * as helpers from
|
|
3
|
-
import { ServiceManager } from
|
|
4
|
-
import { GlobalRegistry } from
|
|
5
|
-
import { logger } from
|
|
1
|
+
import * as plugins from "./mod.plugins.js";
|
|
2
|
+
import * as helpers from "./helpers.js";
|
|
3
|
+
import { ServiceManager } from "./classes.servicemanager.js";
|
|
4
|
+
import { GlobalRegistry } from "./classes.globalregistry.js";
|
|
5
|
+
import { logger } from "../gitzone.logging.js";
|
|
6
|
+
import type { ICliMode } from "../helpers.climode.js";
|
|
7
|
+
import { getCliMode, printJson } from "../helpers.climode.js";
|
|
8
|
+
import {
|
|
9
|
+
getCliConfigValueFromData,
|
|
10
|
+
readSmartconfigFile,
|
|
11
|
+
setCliConfigValueInData,
|
|
12
|
+
writeSmartconfigFile,
|
|
13
|
+
} from "../helpers.smartconfig.js";
|
|
6
14
|
|
|
7
15
|
export const run = async (argvArg: any) => {
|
|
16
|
+
const mode = await getCliMode(argvArg);
|
|
8
17
|
const isGlobal = argvArg.g || argvArg.global;
|
|
9
|
-
const command = argvArg._[1] ||
|
|
18
|
+
const command = argvArg._[1] || "help";
|
|
19
|
+
|
|
20
|
+
if (mode.help || command === "help") {
|
|
21
|
+
showHelp(mode);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
10
24
|
|
|
11
25
|
// Handle global commands first
|
|
12
26
|
if (isGlobal) {
|
|
@@ -14,264 +28,597 @@ export const run = async (argvArg: any) => {
|
|
|
14
28
|
return;
|
|
15
29
|
}
|
|
16
30
|
|
|
17
|
-
|
|
18
|
-
const serviceManager = new ServiceManager();
|
|
19
|
-
await serviceManager.init();
|
|
20
|
-
|
|
21
|
-
const service = argvArg._[2] || 'all';
|
|
31
|
+
const service = argvArg._[2] || "all";
|
|
22
32
|
|
|
23
33
|
switch (command) {
|
|
24
|
-
case
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
case 'stop':
|
|
29
|
-
await handleStop(serviceManager, service);
|
|
30
|
-
break;
|
|
31
|
-
|
|
32
|
-
case 'restart':
|
|
33
|
-
await handleRestart(serviceManager, service);
|
|
34
|
-
break;
|
|
35
|
-
|
|
36
|
-
case 'status':
|
|
37
|
-
await serviceManager.showStatus();
|
|
38
|
-
break;
|
|
39
|
-
|
|
40
|
-
case 'config':
|
|
41
|
-
if (service === 'services' || argvArg._[2] === 'services') {
|
|
34
|
+
case "config":
|
|
35
|
+
if (service === "services" || argvArg._[2] === "services") {
|
|
36
|
+
const serviceManager = new ServiceManager();
|
|
37
|
+
await serviceManager.init();
|
|
42
38
|
await handleConfigureServices(serviceManager);
|
|
43
39
|
} else {
|
|
44
|
-
await
|
|
40
|
+
await handleShowConfig(mode);
|
|
45
41
|
}
|
|
46
42
|
break;
|
|
47
43
|
|
|
48
|
-
case
|
|
49
|
-
await
|
|
44
|
+
case "set":
|
|
45
|
+
await handleSetServices(argvArg._[2], mode);
|
|
50
46
|
break;
|
|
51
|
-
|
|
52
|
-
case
|
|
53
|
-
|
|
54
|
-
await serviceManager.showLogs(service, lines);
|
|
55
|
-
break;
|
|
56
|
-
|
|
57
|
-
case 'remove':
|
|
58
|
-
await handleRemove(serviceManager);
|
|
47
|
+
|
|
48
|
+
case "enable":
|
|
49
|
+
await handleEnableServices(argvArg._.slice(2), mode);
|
|
59
50
|
break;
|
|
60
|
-
|
|
61
|
-
case
|
|
62
|
-
await
|
|
51
|
+
|
|
52
|
+
case "disable":
|
|
53
|
+
await handleDisableServices(argvArg._.slice(2), mode);
|
|
63
54
|
break;
|
|
64
|
-
|
|
65
|
-
case
|
|
66
|
-
|
|
55
|
+
|
|
56
|
+
case "start":
|
|
57
|
+
case "stop":
|
|
58
|
+
case "restart":
|
|
59
|
+
case "status":
|
|
60
|
+
case "compass":
|
|
61
|
+
case "logs":
|
|
62
|
+
case "remove":
|
|
63
|
+
case "clean":
|
|
64
|
+
case "reconfigure": {
|
|
65
|
+
const serviceManager = new ServiceManager();
|
|
66
|
+
await serviceManager.init();
|
|
67
|
+
|
|
68
|
+
switch (command) {
|
|
69
|
+
case "start":
|
|
70
|
+
await handleStart(serviceManager, service);
|
|
71
|
+
break;
|
|
72
|
+
|
|
73
|
+
case "stop":
|
|
74
|
+
await handleStop(serviceManager, service);
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case "restart":
|
|
78
|
+
await handleRestart(serviceManager, service);
|
|
79
|
+
break;
|
|
80
|
+
|
|
81
|
+
case "status":
|
|
82
|
+
await serviceManager.showStatus();
|
|
83
|
+
break;
|
|
84
|
+
|
|
85
|
+
case "compass":
|
|
86
|
+
await serviceManager.showCompassConnection();
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
case "logs": {
|
|
90
|
+
const lines = parseInt(argvArg._[3]) || 20;
|
|
91
|
+
await serviceManager.showLogs(service, lines);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
case "remove":
|
|
96
|
+
await handleRemove(serviceManager);
|
|
97
|
+
break;
|
|
98
|
+
|
|
99
|
+
case "clean":
|
|
100
|
+
await handleClean(serviceManager);
|
|
101
|
+
break;
|
|
102
|
+
|
|
103
|
+
case "reconfigure":
|
|
104
|
+
await serviceManager.reconfigure();
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
67
107
|
break;
|
|
68
|
-
|
|
69
|
-
case 'help':
|
|
108
|
+
}
|
|
70
109
|
default:
|
|
71
|
-
showHelp();
|
|
110
|
+
showHelp(mode);
|
|
72
111
|
break;
|
|
73
112
|
}
|
|
74
113
|
};
|
|
75
114
|
|
|
115
|
+
const allowedServices = ["mongodb", "minio", "elasticsearch"];
|
|
116
|
+
|
|
117
|
+
const normalizeServiceName = (service: string): string => {
|
|
118
|
+
switch (service) {
|
|
119
|
+
case "mongo":
|
|
120
|
+
case "mongodb":
|
|
121
|
+
return "mongodb";
|
|
122
|
+
case "minio":
|
|
123
|
+
case "s3":
|
|
124
|
+
return "minio";
|
|
125
|
+
case "elastic":
|
|
126
|
+
case "elasticsearch":
|
|
127
|
+
case "es":
|
|
128
|
+
return "elasticsearch";
|
|
129
|
+
default:
|
|
130
|
+
return service;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
async function readServicesConfig(): Promise<{
|
|
135
|
+
enabledServices: string[];
|
|
136
|
+
environment: Record<string, any> | null;
|
|
137
|
+
}> {
|
|
138
|
+
const smartconfigData = await readSmartconfigFile();
|
|
139
|
+
const enabledServices = getCliConfigValueFromData(
|
|
140
|
+
smartconfigData,
|
|
141
|
+
"services",
|
|
142
|
+
);
|
|
143
|
+
let environment: Record<string, any> | null = null;
|
|
144
|
+
const envPath = plugins.path.join(process.cwd(), ".nogit", "env.json");
|
|
145
|
+
if (await plugins.smartfs.file(envPath).exists()) {
|
|
146
|
+
const envContent = (await plugins.smartfs
|
|
147
|
+
.file(envPath)
|
|
148
|
+
.encoding("utf8")
|
|
149
|
+
.read()) as string;
|
|
150
|
+
environment = JSON.parse(envContent);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
enabledServices: Array.isArray(enabledServices) ? enabledServices : [],
|
|
155
|
+
environment,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function updateEnabledServices(services: string[]): Promise<void> {
|
|
160
|
+
const smartconfigData = await readSmartconfigFile();
|
|
161
|
+
setCliConfigValueInData(smartconfigData, "services", services);
|
|
162
|
+
await writeSmartconfigFile(smartconfigData);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function handleShowConfig(mode: ICliMode) {
|
|
166
|
+
const configData = await readServicesConfig();
|
|
167
|
+
|
|
168
|
+
if (mode.json) {
|
|
169
|
+
printJson(configData);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
helpers.printHeader("Current Services Configuration");
|
|
174
|
+
logger.log(
|
|
175
|
+
"info",
|
|
176
|
+
`Enabled Services: ${configData.enabledServices.length > 0 ? configData.enabledServices.join(", ") : "none configured"}`,
|
|
177
|
+
);
|
|
178
|
+
console.log();
|
|
179
|
+
|
|
180
|
+
if (!configData.environment) {
|
|
181
|
+
logger.log(
|
|
182
|
+
"note",
|
|
183
|
+
"No .nogit/env.json found yet. Start a service once to create runtime defaults.",
|
|
184
|
+
);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const env = configData.environment;
|
|
189
|
+
logger.log("note", "MongoDB:");
|
|
190
|
+
logger.log("info", ` Host: ${env.MONGODB_HOST}:${env.MONGODB_PORT}`);
|
|
191
|
+
logger.log("info", ` Database: ${env.MONGODB_NAME}`);
|
|
192
|
+
logger.log("info", ` User: ${env.MONGODB_USER}`);
|
|
193
|
+
logger.log("info", ` Container: ${env.PROJECT_NAME}-mongodb`);
|
|
194
|
+
logger.log(
|
|
195
|
+
"info",
|
|
196
|
+
` Data: ${plugins.path.join(process.cwd(), ".nogit", "mongodata")}`,
|
|
197
|
+
);
|
|
198
|
+
logger.log("info", ` Connection: ${env.MONGODB_URL}`);
|
|
199
|
+
console.log();
|
|
200
|
+
|
|
201
|
+
logger.log("note", "S3/MinIO:");
|
|
202
|
+
logger.log("info", ` Host: ${env.S3_HOST}`);
|
|
203
|
+
logger.log("info", ` API Port: ${env.S3_PORT}`);
|
|
204
|
+
logger.log("info", ` Console Port: ${env.S3_CONSOLE_PORT}`);
|
|
205
|
+
logger.log("info", ` Bucket: ${env.S3_BUCKET}`);
|
|
206
|
+
logger.log("info", ` Container: ${env.PROJECT_NAME}-minio`);
|
|
207
|
+
logger.log(
|
|
208
|
+
"info",
|
|
209
|
+
` Data: ${plugins.path.join(process.cwd(), ".nogit", "miniodata")}`,
|
|
210
|
+
);
|
|
211
|
+
logger.log("info", ` Endpoint: ${env.S3_ENDPOINT}`);
|
|
212
|
+
console.log();
|
|
213
|
+
|
|
214
|
+
logger.log("note", "Elasticsearch:");
|
|
215
|
+
logger.log(
|
|
216
|
+
"info",
|
|
217
|
+
` Host: ${env.ELASTICSEARCH_HOST}:${env.ELASTICSEARCH_PORT}`,
|
|
218
|
+
);
|
|
219
|
+
logger.log("info", ` User: ${env.ELASTICSEARCH_USER}`);
|
|
220
|
+
logger.log("info", ` Container: ${env.PROJECT_NAME}-elasticsearch`);
|
|
221
|
+
logger.log(
|
|
222
|
+
"info",
|
|
223
|
+
` Data: ${plugins.path.join(process.cwd(), ".nogit", "esdata")}`,
|
|
224
|
+
);
|
|
225
|
+
logger.log("info", ` Connection: ${env.ELASTICSEARCH_URL}`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async function handleSetServices(rawValue: string | undefined, mode: ICliMode) {
|
|
229
|
+
if (!rawValue) {
|
|
230
|
+
throw new Error("Specify a comma-separated list of services");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const requestedServices = rawValue
|
|
234
|
+
.split(",")
|
|
235
|
+
.map((service) => normalizeServiceName(service.trim()))
|
|
236
|
+
.filter(Boolean);
|
|
237
|
+
validateRequestedServices(requestedServices);
|
|
238
|
+
await updateEnabledServices(requestedServices);
|
|
239
|
+
|
|
240
|
+
if (mode.json) {
|
|
241
|
+
printJson({ ok: true, action: "set", enabledServices: requestedServices });
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
logger.log("ok", `Enabled services set to: ${requestedServices.join(", ")}`);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function handleEnableServices(
|
|
249
|
+
requestedServices: string[],
|
|
250
|
+
mode: ICliMode,
|
|
251
|
+
) {
|
|
252
|
+
const normalizedServices = requestedServices.map((service) =>
|
|
253
|
+
normalizeServiceName(service),
|
|
254
|
+
);
|
|
255
|
+
validateRequestedServices(normalizedServices);
|
|
256
|
+
|
|
257
|
+
const configData = await readServicesConfig();
|
|
258
|
+
const nextServices = Array.from(
|
|
259
|
+
new Set([...configData.enabledServices, ...normalizedServices]),
|
|
260
|
+
);
|
|
261
|
+
await updateEnabledServices(nextServices);
|
|
262
|
+
|
|
263
|
+
if (mode.json) {
|
|
264
|
+
printJson({ ok: true, action: "enable", enabledServices: nextServices });
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
logger.log("ok", `Enabled services: ${nextServices.join(", ")}`);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async function handleDisableServices(
|
|
272
|
+
requestedServices: string[],
|
|
273
|
+
mode: ICliMode,
|
|
274
|
+
) {
|
|
275
|
+
const normalizedServices = requestedServices.map((service) =>
|
|
276
|
+
normalizeServiceName(service),
|
|
277
|
+
);
|
|
278
|
+
validateRequestedServices(normalizedServices);
|
|
279
|
+
|
|
280
|
+
const configData = await readServicesConfig();
|
|
281
|
+
const nextServices = configData.enabledServices.filter(
|
|
282
|
+
(service) => !normalizedServices.includes(service),
|
|
283
|
+
);
|
|
284
|
+
await updateEnabledServices(nextServices);
|
|
285
|
+
|
|
286
|
+
if (mode.json) {
|
|
287
|
+
printJson({ ok: true, action: "disable", enabledServices: nextServices });
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
logger.log("ok", `Enabled services: ${nextServices.join(", ")}`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function validateRequestedServices(services: string[]): void {
|
|
295
|
+
if (services.length === 0) {
|
|
296
|
+
throw new Error("Specify at least one service");
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const invalidServices = services.filter(
|
|
300
|
+
(service) => !allowedServices.includes(service),
|
|
301
|
+
);
|
|
302
|
+
if (invalidServices.length > 0) {
|
|
303
|
+
throw new Error(`Unknown service(s): ${invalidServices.join(", ")}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
76
307
|
async function handleStart(serviceManager: ServiceManager, service: string) {
|
|
77
|
-
helpers.printHeader(
|
|
308
|
+
helpers.printHeader("Starting Services");
|
|
78
309
|
|
|
79
310
|
switch (service) {
|
|
80
|
-
case
|
|
81
|
-
case
|
|
311
|
+
case "mongo":
|
|
312
|
+
case "mongodb":
|
|
82
313
|
await serviceManager.startMongoDB();
|
|
83
314
|
break;
|
|
84
315
|
|
|
85
|
-
case
|
|
86
|
-
case
|
|
316
|
+
case "minio":
|
|
317
|
+
case "s3":
|
|
87
318
|
await serviceManager.startMinIO();
|
|
88
319
|
break;
|
|
89
320
|
|
|
90
|
-
case
|
|
91
|
-
case
|
|
321
|
+
case "elasticsearch":
|
|
322
|
+
case "es":
|
|
92
323
|
await serviceManager.startElasticsearch();
|
|
93
324
|
break;
|
|
94
325
|
|
|
95
|
-
case
|
|
96
|
-
case
|
|
326
|
+
case "all":
|
|
327
|
+
case "":
|
|
97
328
|
await serviceManager.startAll();
|
|
98
329
|
break;
|
|
99
330
|
|
|
100
331
|
default:
|
|
101
|
-
logger.log(
|
|
102
|
-
logger.log(
|
|
332
|
+
logger.log("error", `Unknown service: ${service}`);
|
|
333
|
+
logger.log("note", "Use: mongo, s3, elasticsearch, or all");
|
|
103
334
|
break;
|
|
104
335
|
}
|
|
105
336
|
}
|
|
106
337
|
|
|
107
338
|
async function handleStop(serviceManager: ServiceManager, service: string) {
|
|
108
|
-
helpers.printHeader(
|
|
339
|
+
helpers.printHeader("Stopping Services");
|
|
109
340
|
|
|
110
341
|
switch (service) {
|
|
111
|
-
case
|
|
112
|
-
case
|
|
342
|
+
case "mongo":
|
|
343
|
+
case "mongodb":
|
|
113
344
|
await serviceManager.stopMongoDB();
|
|
114
345
|
break;
|
|
115
346
|
|
|
116
|
-
case
|
|
117
|
-
case
|
|
347
|
+
case "minio":
|
|
348
|
+
case "s3":
|
|
118
349
|
await serviceManager.stopMinIO();
|
|
119
350
|
break;
|
|
120
351
|
|
|
121
|
-
case
|
|
122
|
-
case
|
|
352
|
+
case "elasticsearch":
|
|
353
|
+
case "es":
|
|
123
354
|
await serviceManager.stopElasticsearch();
|
|
124
355
|
break;
|
|
125
356
|
|
|
126
|
-
case
|
|
127
|
-
case
|
|
357
|
+
case "all":
|
|
358
|
+
case "":
|
|
128
359
|
await serviceManager.stopAll();
|
|
129
360
|
break;
|
|
130
361
|
|
|
131
362
|
default:
|
|
132
|
-
logger.log(
|
|
133
|
-
logger.log(
|
|
363
|
+
logger.log("error", `Unknown service: ${service}`);
|
|
364
|
+
logger.log("note", "Use: mongo, s3, elasticsearch, or all");
|
|
134
365
|
break;
|
|
135
366
|
}
|
|
136
367
|
}
|
|
137
368
|
|
|
138
369
|
async function handleRestart(serviceManager: ServiceManager, service: string) {
|
|
139
|
-
helpers.printHeader(
|
|
370
|
+
helpers.printHeader("Restarting Services");
|
|
140
371
|
|
|
141
372
|
switch (service) {
|
|
142
|
-
case
|
|
143
|
-
case
|
|
373
|
+
case "mongo":
|
|
374
|
+
case "mongodb":
|
|
144
375
|
await serviceManager.stopMongoDB();
|
|
145
376
|
await plugins.smartdelay.delayFor(2000);
|
|
146
377
|
await serviceManager.startMongoDB();
|
|
147
378
|
break;
|
|
148
379
|
|
|
149
|
-
case
|
|
150
|
-
case
|
|
380
|
+
case "minio":
|
|
381
|
+
case "s3":
|
|
151
382
|
await serviceManager.stopMinIO();
|
|
152
383
|
await plugins.smartdelay.delayFor(2000);
|
|
153
384
|
await serviceManager.startMinIO();
|
|
154
385
|
break;
|
|
155
386
|
|
|
156
|
-
case
|
|
157
|
-
case
|
|
387
|
+
case "elasticsearch":
|
|
388
|
+
case "es":
|
|
158
389
|
await serviceManager.stopElasticsearch();
|
|
159
390
|
await plugins.smartdelay.delayFor(2000);
|
|
160
391
|
await serviceManager.startElasticsearch();
|
|
161
392
|
break;
|
|
162
393
|
|
|
163
|
-
case
|
|
164
|
-
case
|
|
394
|
+
case "all":
|
|
395
|
+
case "":
|
|
165
396
|
await serviceManager.stopAll();
|
|
166
397
|
await plugins.smartdelay.delayFor(2000);
|
|
167
398
|
await serviceManager.startAll();
|
|
168
399
|
break;
|
|
169
400
|
|
|
170
401
|
default:
|
|
171
|
-
logger.log(
|
|
402
|
+
logger.log("error", `Unknown service: ${service}`);
|
|
172
403
|
break;
|
|
173
404
|
}
|
|
174
405
|
}
|
|
175
406
|
|
|
176
407
|
async function handleRemove(serviceManager: ServiceManager) {
|
|
177
|
-
helpers.printHeader(
|
|
178
|
-
logger.log(
|
|
179
|
-
|
|
180
|
-
const shouldContinue =
|
|
181
|
-
|
|
408
|
+
helpers.printHeader("Removing Containers");
|
|
409
|
+
logger.log("note", "⚠️ This will remove containers but preserve data");
|
|
410
|
+
|
|
411
|
+
const shouldContinue =
|
|
412
|
+
await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
413
|
+
"Continue?",
|
|
414
|
+
false,
|
|
415
|
+
);
|
|
416
|
+
|
|
182
417
|
if (shouldContinue) {
|
|
183
418
|
await serviceManager.removeContainers();
|
|
184
419
|
} else {
|
|
185
|
-
logger.log(
|
|
420
|
+
logger.log("note", "Cancelled");
|
|
186
421
|
}
|
|
187
422
|
}
|
|
188
423
|
|
|
189
424
|
async function handleClean(serviceManager: ServiceManager) {
|
|
190
|
-
helpers.printHeader(
|
|
191
|
-
logger.log(
|
|
192
|
-
logger.log(
|
|
425
|
+
helpers.printHeader("Clean All");
|
|
426
|
+
logger.log("error", "⚠️ WARNING: This will remove all containers and data!");
|
|
427
|
+
logger.log("error", "This action cannot be undone!");
|
|
193
428
|
|
|
194
429
|
const smartinteraction = new plugins.smartinteract.SmartInteract();
|
|
195
430
|
const confirmAnswer = await smartinteraction.askQuestion({
|
|
196
|
-
name:
|
|
197
|
-
type:
|
|
431
|
+
name: "confirm",
|
|
432
|
+
type: "input",
|
|
198
433
|
message: 'Type "yes" to confirm:',
|
|
199
|
-
default:
|
|
434
|
+
default: "no",
|
|
200
435
|
});
|
|
201
436
|
|
|
202
|
-
if (confirmAnswer.value ===
|
|
437
|
+
if (confirmAnswer.value === "yes") {
|
|
203
438
|
await serviceManager.removeContainers();
|
|
204
439
|
console.log();
|
|
205
440
|
await serviceManager.cleanData();
|
|
206
|
-
logger.log(
|
|
441
|
+
logger.log("ok", "All cleaned ✓");
|
|
207
442
|
} else {
|
|
208
|
-
logger.log(
|
|
443
|
+
logger.log("note", "Cancelled");
|
|
209
444
|
}
|
|
210
445
|
}
|
|
211
446
|
|
|
212
447
|
async function handleConfigureServices(serviceManager: ServiceManager) {
|
|
213
|
-
helpers.printHeader(
|
|
448
|
+
helpers.printHeader("Configure Services");
|
|
214
449
|
await serviceManager.configureServices();
|
|
215
450
|
}
|
|
216
451
|
|
|
217
|
-
function showHelp() {
|
|
218
|
-
|
|
452
|
+
export function showHelp(mode?: ICliMode) {
|
|
453
|
+
if (mode?.json) {
|
|
454
|
+
printJson({
|
|
455
|
+
command: "services",
|
|
456
|
+
usage: "gitzone services <command> [options]",
|
|
457
|
+
commands: [
|
|
458
|
+
{
|
|
459
|
+
name: "config",
|
|
460
|
+
description:
|
|
461
|
+
"Show configured services and any existing runtime env.json data",
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
name: "set <csv>",
|
|
465
|
+
description: "Set the enabled service list without prompts",
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
name: "enable <service...>",
|
|
469
|
+
description: "Enable one or more services without prompts",
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
name: "disable <service...>",
|
|
473
|
+
description: "Disable one or more services without prompts",
|
|
474
|
+
},
|
|
475
|
+
{ name: "start [service]", description: "Start services" },
|
|
476
|
+
{ name: "stop [service]", description: "Stop services" },
|
|
477
|
+
{ name: "status", description: "Show service status" },
|
|
478
|
+
],
|
|
479
|
+
examples: [
|
|
480
|
+
"gitzone services config --json",
|
|
481
|
+
"gitzone services set mongodb,minio",
|
|
482
|
+
"gitzone services enable elasticsearch",
|
|
483
|
+
],
|
|
484
|
+
});
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
helpers.printHeader("GitZone Services Manager");
|
|
219
489
|
|
|
220
|
-
logger.log(
|
|
490
|
+
logger.log("ok", "Usage: gitzone services [command] [options]");
|
|
221
491
|
console.log();
|
|
222
492
|
|
|
223
|
-
logger.log(
|
|
224
|
-
logger.log(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
logger.log(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
logger.log(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
493
|
+
logger.log("note", "Commands:");
|
|
494
|
+
logger.log(
|
|
495
|
+
"info",
|
|
496
|
+
" start [service] Start services (mongo|s3|elasticsearch|all)",
|
|
497
|
+
);
|
|
498
|
+
logger.log(
|
|
499
|
+
"info",
|
|
500
|
+
" stop [service] Stop services (mongo|s3|elasticsearch|all)",
|
|
501
|
+
);
|
|
502
|
+
logger.log(
|
|
503
|
+
"info",
|
|
504
|
+
" restart [service] Restart services (mongo|s3|elasticsearch|all)",
|
|
505
|
+
);
|
|
506
|
+
logger.log("info", " status Show service status");
|
|
507
|
+
logger.log("info", " config Show current configuration");
|
|
508
|
+
logger.log(
|
|
509
|
+
"info",
|
|
510
|
+
" config services Configure which services are enabled",
|
|
511
|
+
);
|
|
512
|
+
logger.log(
|
|
513
|
+
"info",
|
|
514
|
+
" set <csv> Set enabled services without prompts",
|
|
515
|
+
);
|
|
516
|
+
logger.log("info", " enable <svc...> Enable one or more services");
|
|
517
|
+
logger.log("info", " disable <svc...> Disable one or more services");
|
|
518
|
+
logger.log(
|
|
519
|
+
"info",
|
|
520
|
+
" compass Show MongoDB Compass connection string",
|
|
521
|
+
);
|
|
522
|
+
logger.log(
|
|
523
|
+
"info",
|
|
524
|
+
" logs [service] Show logs (mongo|s3|elasticsearch|all) [lines]",
|
|
525
|
+
);
|
|
526
|
+
logger.log("info", " reconfigure Reassign ports and restart services");
|
|
527
|
+
logger.log("info", " remove Remove all containers");
|
|
528
|
+
logger.log("info", " clean Remove all containers and data ⚠️");
|
|
529
|
+
logger.log("info", " help Show this help message");
|
|
236
530
|
console.log();
|
|
237
531
|
|
|
238
|
-
logger.log(
|
|
239
|
-
logger.log(
|
|
240
|
-
logger.log(
|
|
241
|
-
logger.log(
|
|
532
|
+
logger.log("note", "Available Services:");
|
|
533
|
+
logger.log("info", " • MongoDB (mongo) - Document database");
|
|
534
|
+
logger.log("info", " • MinIO (s3) - S3-compatible object storage");
|
|
535
|
+
logger.log(
|
|
536
|
+
"info",
|
|
537
|
+
" • Elasticsearch (elasticsearch) - Search and analytics engine",
|
|
538
|
+
);
|
|
242
539
|
console.log();
|
|
243
540
|
|
|
244
|
-
logger.log(
|
|
245
|
-
logger.log(
|
|
246
|
-
logger.log(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
logger.log(
|
|
541
|
+
logger.log("note", "Features:");
|
|
542
|
+
logger.log("info", " • Auto-creates .nogit/env.json with smart defaults");
|
|
543
|
+
logger.log(
|
|
544
|
+
"info",
|
|
545
|
+
" • Random ports (20000-30000) for MongoDB/MinIO to avoid conflicts",
|
|
546
|
+
);
|
|
547
|
+
logger.log("info", " • Elasticsearch uses standard port 9200");
|
|
548
|
+
logger.log(
|
|
549
|
+
"info",
|
|
550
|
+
" • Project-specific containers for multi-project support",
|
|
551
|
+
);
|
|
552
|
+
logger.log("info", " • Preserves custom configuration values");
|
|
553
|
+
logger.log("info", " • MongoDB Compass connection support");
|
|
251
554
|
console.log();
|
|
252
555
|
|
|
253
|
-
logger.log(
|
|
254
|
-
logger.log(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
logger.log(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
556
|
+
logger.log("note", "Examples:");
|
|
557
|
+
logger.log(
|
|
558
|
+
"info",
|
|
559
|
+
" gitzone services start # Start all services",
|
|
560
|
+
);
|
|
561
|
+
logger.log(
|
|
562
|
+
"info",
|
|
563
|
+
" gitzone services start mongo # Start only MongoDB",
|
|
564
|
+
);
|
|
565
|
+
logger.log(
|
|
566
|
+
"info",
|
|
567
|
+
" gitzone services start elasticsearch # Start only Elasticsearch",
|
|
568
|
+
);
|
|
569
|
+
logger.log(
|
|
570
|
+
"info",
|
|
571
|
+
" gitzone services stop # Stop all services",
|
|
572
|
+
);
|
|
573
|
+
logger.log(
|
|
574
|
+
"info",
|
|
575
|
+
" gitzone services status # Check service status",
|
|
576
|
+
);
|
|
577
|
+
logger.log(
|
|
578
|
+
"info",
|
|
579
|
+
" gitzone services config # Show configuration",
|
|
580
|
+
);
|
|
581
|
+
logger.log(
|
|
582
|
+
"info",
|
|
583
|
+
" gitzone services config --json # Show configuration as JSON",
|
|
584
|
+
);
|
|
585
|
+
logger.log(
|
|
586
|
+
"info",
|
|
587
|
+
" gitzone services set mongodb,minio # Configure services without prompts",
|
|
588
|
+
);
|
|
589
|
+
logger.log(
|
|
590
|
+
"info",
|
|
591
|
+
" gitzone services compass # Get MongoDB Compass connection",
|
|
592
|
+
);
|
|
593
|
+
logger.log(
|
|
594
|
+
"info",
|
|
595
|
+
" gitzone services logs elasticsearch # Show Elasticsearch logs",
|
|
596
|
+
);
|
|
262
597
|
console.log();
|
|
263
598
|
|
|
264
|
-
logger.log(
|
|
265
|
-
logger.log(
|
|
266
|
-
logger.log(
|
|
267
|
-
logger.log(
|
|
268
|
-
|
|
599
|
+
logger.log("note", "Global Commands (-g/--global):");
|
|
600
|
+
logger.log("info", " list -g List all registered projects");
|
|
601
|
+
logger.log("info", " status -g Show status across all projects");
|
|
602
|
+
logger.log(
|
|
603
|
+
"info",
|
|
604
|
+
" stop -g Stop all containers across all projects",
|
|
605
|
+
);
|
|
606
|
+
logger.log("info", " cleanup -g Remove stale registry entries");
|
|
269
607
|
console.log();
|
|
270
608
|
|
|
271
|
-
logger.log(
|
|
272
|
-
logger.log(
|
|
273
|
-
|
|
274
|
-
|
|
609
|
+
logger.log("note", "Global Examples:");
|
|
610
|
+
logger.log(
|
|
611
|
+
"info",
|
|
612
|
+
" gitzone services list -g # List all registered projects",
|
|
613
|
+
);
|
|
614
|
+
logger.log(
|
|
615
|
+
"info",
|
|
616
|
+
" gitzone services status -g # Show global container status",
|
|
617
|
+
);
|
|
618
|
+
logger.log(
|
|
619
|
+
"info",
|
|
620
|
+
" gitzone services stop -g # Stop all (prompts for confirmation)",
|
|
621
|
+
);
|
|
275
622
|
}
|
|
276
623
|
|
|
277
624
|
// ==================== Global Command Handlers ====================
|
|
@@ -280,23 +627,23 @@ async function handleGlobalCommand(command: string) {
|
|
|
280
627
|
const globalRegistry = GlobalRegistry.getInstance();
|
|
281
628
|
|
|
282
629
|
switch (command) {
|
|
283
|
-
case
|
|
630
|
+
case "list":
|
|
284
631
|
await handleGlobalList(globalRegistry);
|
|
285
632
|
break;
|
|
286
633
|
|
|
287
|
-
case
|
|
634
|
+
case "status":
|
|
288
635
|
await handleGlobalStatus(globalRegistry);
|
|
289
636
|
break;
|
|
290
637
|
|
|
291
|
-
case
|
|
638
|
+
case "stop":
|
|
292
639
|
await handleGlobalStop(globalRegistry);
|
|
293
640
|
break;
|
|
294
641
|
|
|
295
|
-
case
|
|
642
|
+
case "cleanup":
|
|
296
643
|
await handleGlobalCleanup(globalRegistry);
|
|
297
644
|
break;
|
|
298
645
|
|
|
299
|
-
case
|
|
646
|
+
case "help":
|
|
300
647
|
default:
|
|
301
648
|
showHelp();
|
|
302
649
|
break;
|
|
@@ -304,13 +651,13 @@ async function handleGlobalCommand(command: string) {
|
|
|
304
651
|
}
|
|
305
652
|
|
|
306
653
|
async function handleGlobalList(globalRegistry: GlobalRegistry) {
|
|
307
|
-
helpers.printHeader(
|
|
654
|
+
helpers.printHeader("Registered Projects (Global)");
|
|
308
655
|
|
|
309
656
|
const projects = await globalRegistry.getAllProjects();
|
|
310
657
|
const projectPaths = Object.keys(projects);
|
|
311
658
|
|
|
312
659
|
if (projectPaths.length === 0) {
|
|
313
|
-
logger.log(
|
|
660
|
+
logger.log("note", "No projects registered");
|
|
314
661
|
return;
|
|
315
662
|
}
|
|
316
663
|
|
|
@@ -319,20 +666,20 @@ async function handleGlobalList(globalRegistry: GlobalRegistry) {
|
|
|
319
666
|
const lastActive = new Date(project.lastActive).toLocaleString();
|
|
320
667
|
|
|
321
668
|
console.log();
|
|
322
|
-
logger.log(
|
|
323
|
-
logger.log(
|
|
324
|
-
logger.log(
|
|
325
|
-
logger.log(
|
|
669
|
+
logger.log("ok", `📁 ${project.projectName}`);
|
|
670
|
+
logger.log("info", ` Path: ${project.projectPath}`);
|
|
671
|
+
logger.log("info", ` Services: ${project.enabledServices.join(", ")}`);
|
|
672
|
+
logger.log("info", ` Last Active: ${lastActive}`);
|
|
326
673
|
}
|
|
327
674
|
}
|
|
328
675
|
|
|
329
676
|
async function handleGlobalStatus(globalRegistry: GlobalRegistry) {
|
|
330
|
-
helpers.printHeader(
|
|
677
|
+
helpers.printHeader("Global Service Status");
|
|
331
678
|
|
|
332
679
|
const statuses = await globalRegistry.getGlobalStatus();
|
|
333
680
|
|
|
334
681
|
if (statuses.length === 0) {
|
|
335
|
-
logger.log(
|
|
682
|
+
logger.log("note", "No projects registered");
|
|
336
683
|
return;
|
|
337
684
|
}
|
|
338
685
|
|
|
@@ -341,28 +688,39 @@ async function handleGlobalStatus(globalRegistry: GlobalRegistry) {
|
|
|
341
688
|
|
|
342
689
|
for (const project of statuses) {
|
|
343
690
|
console.log();
|
|
344
|
-
logger.log(
|
|
345
|
-
logger.log(
|
|
691
|
+
logger.log("ok", `📁 ${project.projectName}`);
|
|
692
|
+
logger.log("info", ` Path: ${project.projectPath}`);
|
|
346
693
|
|
|
347
694
|
if (project.containers.length === 0) {
|
|
348
|
-
logger.log(
|
|
695
|
+
logger.log("note", " No containers configured");
|
|
349
696
|
continue;
|
|
350
697
|
}
|
|
351
698
|
|
|
352
699
|
for (const container of project.containers) {
|
|
353
700
|
totalContainers++;
|
|
354
|
-
const statusIcon =
|
|
355
|
-
|
|
356
|
-
|
|
701
|
+
const statusIcon =
|
|
702
|
+
container.status === "running"
|
|
703
|
+
? "🟢"
|
|
704
|
+
: container.status === "exited"
|
|
705
|
+
? "🟡"
|
|
706
|
+
: "⚪";
|
|
707
|
+
if (container.status === "running") runningCount++;
|
|
708
|
+
logger.log(
|
|
709
|
+
"info",
|
|
710
|
+
` ${statusIcon} ${container.name}: ${container.status}`,
|
|
711
|
+
);
|
|
357
712
|
}
|
|
358
713
|
}
|
|
359
714
|
|
|
360
715
|
console.log();
|
|
361
|
-
logger.log(
|
|
716
|
+
logger.log(
|
|
717
|
+
"note",
|
|
718
|
+
`Summary: ${runningCount}/${totalContainers} containers running across ${statuses.length} project(s)`,
|
|
719
|
+
);
|
|
362
720
|
}
|
|
363
721
|
|
|
364
722
|
async function handleGlobalStop(globalRegistry: GlobalRegistry) {
|
|
365
|
-
helpers.printHeader(
|
|
723
|
+
helpers.printHeader("Stop All Containers (Global)");
|
|
366
724
|
|
|
367
725
|
const statuses = await globalRegistry.getGlobalStatus();
|
|
368
726
|
|
|
@@ -370,64 +728,73 @@ async function handleGlobalStop(globalRegistry: GlobalRegistry) {
|
|
|
370
728
|
let runningCount = 0;
|
|
371
729
|
for (const project of statuses) {
|
|
372
730
|
for (const container of project.containers) {
|
|
373
|
-
if (container.status ===
|
|
731
|
+
if (container.status === "running") runningCount++;
|
|
374
732
|
}
|
|
375
733
|
}
|
|
376
734
|
|
|
377
735
|
if (runningCount === 0) {
|
|
378
|
-
logger.log(
|
|
736
|
+
logger.log("note", "No running containers found");
|
|
379
737
|
return;
|
|
380
738
|
}
|
|
381
739
|
|
|
382
|
-
logger.log(
|
|
740
|
+
logger.log(
|
|
741
|
+
"note",
|
|
742
|
+
`Found ${runningCount} running container(s) across ${statuses.length} project(s)`,
|
|
743
|
+
);
|
|
383
744
|
console.log();
|
|
384
745
|
|
|
385
746
|
// Show what will be stopped
|
|
386
747
|
for (const project of statuses) {
|
|
387
|
-
const runningContainers = project.containers.filter(
|
|
748
|
+
const runningContainers = project.containers.filter(
|
|
749
|
+
(c) => c.status === "running",
|
|
750
|
+
);
|
|
388
751
|
if (runningContainers.length > 0) {
|
|
389
|
-
logger.log(
|
|
752
|
+
logger.log("info", `${project.projectName}:`);
|
|
390
753
|
for (const container of runningContainers) {
|
|
391
|
-
logger.log(
|
|
754
|
+
logger.log("info", ` • ${container.name}`);
|
|
392
755
|
}
|
|
393
756
|
}
|
|
394
757
|
}
|
|
395
758
|
|
|
396
759
|
console.log();
|
|
397
|
-
const shouldContinue =
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
760
|
+
const shouldContinue =
|
|
761
|
+
await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
762
|
+
"Stop all containers?",
|
|
763
|
+
false,
|
|
764
|
+
);
|
|
401
765
|
|
|
402
766
|
if (!shouldContinue) {
|
|
403
|
-
logger.log(
|
|
767
|
+
logger.log("note", "Cancelled");
|
|
404
768
|
return;
|
|
405
769
|
}
|
|
406
770
|
|
|
407
|
-
logger.log(
|
|
771
|
+
logger.log("note", "Stopping all containers...");
|
|
408
772
|
const result = await globalRegistry.stopAll();
|
|
409
773
|
|
|
410
774
|
if (result.stopped.length > 0) {
|
|
411
|
-
logger.log(
|
|
775
|
+
logger.log("ok", `Stopped: ${result.stopped.join(", ")}`);
|
|
412
776
|
}
|
|
413
777
|
if (result.failed.length > 0) {
|
|
414
|
-
logger.log(
|
|
778
|
+
logger.log("error", `Failed to stop: ${result.failed.join(", ")}`);
|
|
415
779
|
}
|
|
416
780
|
}
|
|
417
781
|
|
|
418
782
|
async function handleGlobalCleanup(globalRegistry: GlobalRegistry) {
|
|
419
|
-
helpers.printHeader(
|
|
783
|
+
helpers.printHeader("Cleanup Registry (Global)");
|
|
420
784
|
|
|
421
|
-
logger.log(
|
|
785
|
+
logger.log("note", "Checking for stale registry entries...");
|
|
422
786
|
const removed = await globalRegistry.cleanup();
|
|
423
787
|
|
|
424
788
|
if (removed.length === 0) {
|
|
425
|
-
logger.log(
|
|
789
|
+
logger.log("ok", "No stale entries found");
|
|
426
790
|
return;
|
|
427
791
|
}
|
|
428
792
|
|
|
429
|
-
logger.log(
|
|
793
|
+
logger.log(
|
|
794
|
+
"ok",
|
|
795
|
+
`Removed ${removed.length} stale entr${removed.length === 1 ? "y" : "ies"}:`,
|
|
796
|
+
);
|
|
430
797
|
for (const path of removed) {
|
|
431
|
-
logger.log(
|
|
798
|
+
logger.log("info", ` • ${path}`);
|
|
432
799
|
}
|
|
433
|
-
}
|
|
800
|
+
}
|