@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_config/index.ts
CHANGED
|
@@ -1,73 +1,116 @@
|
|
|
1
1
|
// gitzone config - manage release registry configuration
|
|
2
2
|
|
|
3
|
-
import * as plugins from
|
|
4
|
-
import { ReleaseConfig } from
|
|
5
|
-
import { CommitConfig } from
|
|
6
|
-
import { runFormatter, type ICheckResult } from
|
|
3
|
+
import * as plugins from "./mod.plugins.js";
|
|
4
|
+
import { ReleaseConfig } from "./classes.releaseconfig.js";
|
|
5
|
+
import { CommitConfig } from "./classes.commitconfig.js";
|
|
6
|
+
import { runFormatter, type ICheckResult } from "../mod_format/index.js";
|
|
7
|
+
import type { ICliMode } from "../helpers.climode.js";
|
|
8
|
+
import { getCliMode, printJson } from "../helpers.climode.js";
|
|
9
|
+
import {
|
|
10
|
+
getCliConfigValueFromData,
|
|
11
|
+
readSmartconfigFile,
|
|
12
|
+
setCliConfigValueInData,
|
|
13
|
+
unsetCliConfigValueInData,
|
|
14
|
+
writeSmartconfigFile,
|
|
15
|
+
} from "../helpers.smartconfig.js";
|
|
7
16
|
|
|
8
17
|
export { ReleaseConfig, CommitConfig };
|
|
9
18
|
|
|
19
|
+
const defaultCliMode: ICliMode = {
|
|
20
|
+
output: "human",
|
|
21
|
+
interactive: true,
|
|
22
|
+
json: false,
|
|
23
|
+
plain: false,
|
|
24
|
+
quiet: false,
|
|
25
|
+
yes: false,
|
|
26
|
+
help: false,
|
|
27
|
+
agent: false,
|
|
28
|
+
checkUpdates: true,
|
|
29
|
+
isTty: true,
|
|
30
|
+
};
|
|
31
|
+
|
|
10
32
|
/**
|
|
11
33
|
* Format .smartconfig.json with diff preview
|
|
12
34
|
* Shows diff first, asks for confirmation, then applies
|
|
13
35
|
*/
|
|
14
|
-
async function formatSmartconfigWithDiff(): Promise<void> {
|
|
36
|
+
async function formatSmartconfigWithDiff(mode: ICliMode): Promise<void> {
|
|
37
|
+
if (!mode.interactive) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
15
41
|
// Check for diffs first
|
|
16
|
-
const checkResult = await runFormatter(
|
|
42
|
+
const checkResult = (await runFormatter("smartconfig", {
|
|
17
43
|
checkOnly: true,
|
|
18
44
|
showDiff: true,
|
|
19
|
-
}) as ICheckResult | void;
|
|
45
|
+
})) as ICheckResult | void;
|
|
20
46
|
|
|
21
47
|
if (checkResult && checkResult.hasDiff) {
|
|
22
|
-
const shouldApply =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
48
|
+
const shouldApply =
|
|
49
|
+
await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
50
|
+
"Apply formatting changes to .smartconfig.json?",
|
|
51
|
+
true,
|
|
52
|
+
);
|
|
26
53
|
if (shouldApply) {
|
|
27
|
-
await runFormatter(
|
|
54
|
+
await runFormatter("smartconfig", { silent: true });
|
|
28
55
|
}
|
|
29
56
|
}
|
|
30
57
|
}
|
|
31
58
|
|
|
32
59
|
export const run = async (argvArg: any) => {
|
|
60
|
+
const mode = await getCliMode(argvArg);
|
|
33
61
|
const command = argvArg._?.[1];
|
|
34
62
|
const value = argvArg._?.[2];
|
|
35
63
|
|
|
64
|
+
if (mode.help || command === "help") {
|
|
65
|
+
showHelp(mode);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
36
69
|
// If no command provided, show interactive menu
|
|
37
70
|
if (!command) {
|
|
71
|
+
if (!mode.interactive) {
|
|
72
|
+
showHelp(mode);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
38
75
|
await handleInteractiveMenu();
|
|
39
76
|
return;
|
|
40
77
|
}
|
|
41
78
|
|
|
42
79
|
switch (command) {
|
|
43
|
-
case
|
|
44
|
-
await handleShow();
|
|
80
|
+
case "show":
|
|
81
|
+
await handleShow(mode);
|
|
45
82
|
break;
|
|
46
|
-
case
|
|
47
|
-
await handleAdd(value);
|
|
83
|
+
case "add":
|
|
84
|
+
await handleAdd(value, mode);
|
|
48
85
|
break;
|
|
49
|
-
case
|
|
50
|
-
await handleRemove(value);
|
|
86
|
+
case "remove":
|
|
87
|
+
await handleRemove(value, mode);
|
|
51
88
|
break;
|
|
52
|
-
case
|
|
53
|
-
await handleClear();
|
|
89
|
+
case "clear":
|
|
90
|
+
await handleClear(mode);
|
|
54
91
|
break;
|
|
55
|
-
case
|
|
56
|
-
case
|
|
57
|
-
await handleAccessLevel(value);
|
|
92
|
+
case "access":
|
|
93
|
+
case "accessLevel":
|
|
94
|
+
await handleAccessLevel(value, mode);
|
|
58
95
|
break;
|
|
59
|
-
case
|
|
60
|
-
await handleCommit(argvArg._?.[2], argvArg._?.[3]);
|
|
96
|
+
case "commit":
|
|
97
|
+
await handleCommit(argvArg._?.[2], argvArg._?.[3], mode);
|
|
61
98
|
break;
|
|
62
|
-
case
|
|
63
|
-
await handleServices();
|
|
99
|
+
case "services":
|
|
100
|
+
await handleServices(mode);
|
|
64
101
|
break;
|
|
65
|
-
case
|
|
66
|
-
|
|
102
|
+
case "get":
|
|
103
|
+
await handleGet(value, mode);
|
|
104
|
+
break;
|
|
105
|
+
case "set":
|
|
106
|
+
await handleSet(value, argvArg._?.[3], mode);
|
|
107
|
+
break;
|
|
108
|
+
case "unset":
|
|
109
|
+
await handleUnset(value, mode);
|
|
67
110
|
break;
|
|
68
111
|
default:
|
|
69
|
-
plugins.logger.log(
|
|
70
|
-
showHelp();
|
|
112
|
+
plugins.logger.log("error", `Unknown command: ${command}`);
|
|
113
|
+
showHelp(mode);
|
|
71
114
|
}
|
|
72
115
|
};
|
|
73
116
|
|
|
@@ -75,55 +118,61 @@ export const run = async (argvArg: any) => {
|
|
|
75
118
|
* Interactive menu for config command
|
|
76
119
|
*/
|
|
77
120
|
async function handleInteractiveMenu(): Promise<void> {
|
|
78
|
-
console.log(
|
|
79
|
-
console.log(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
console.log(
|
|
121
|
+
console.log("");
|
|
122
|
+
console.log(
|
|
123
|
+
"╭─────────────────────────────────────────────────────────────╮",
|
|
124
|
+
);
|
|
125
|
+
console.log(
|
|
126
|
+
"│ gitzone config - Project Configuration │",
|
|
127
|
+
);
|
|
128
|
+
console.log(
|
|
129
|
+
"╰─────────────────────────────────────────────────────────────╯",
|
|
130
|
+
);
|
|
131
|
+
console.log("");
|
|
83
132
|
|
|
84
133
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
85
134
|
const response = await interactInstance.askQuestion({
|
|
86
|
-
type:
|
|
87
|
-
name:
|
|
88
|
-
message:
|
|
89
|
-
default:
|
|
135
|
+
type: "list",
|
|
136
|
+
name: "action",
|
|
137
|
+
message: "What would you like to do?",
|
|
138
|
+
default: "show",
|
|
90
139
|
choices: [
|
|
91
|
-
{ name:
|
|
92
|
-
{ name:
|
|
93
|
-
{ name:
|
|
94
|
-
{ name:
|
|
95
|
-
{ name:
|
|
96
|
-
{ name:
|
|
97
|
-
{ name:
|
|
98
|
-
{ name:
|
|
140
|
+
{ name: "Show current configuration", value: "show" },
|
|
141
|
+
{ name: "Add a registry", value: "add" },
|
|
142
|
+
{ name: "Remove a registry", value: "remove" },
|
|
143
|
+
{ name: "Clear all registries", value: "clear" },
|
|
144
|
+
{ name: "Set access level (public/private)", value: "access" },
|
|
145
|
+
{ name: "Configure commit options", value: "commit" },
|
|
146
|
+
{ name: "Configure services", value: "services" },
|
|
147
|
+
{ name: "Show help", value: "help" },
|
|
99
148
|
],
|
|
100
149
|
});
|
|
101
150
|
|
|
102
151
|
const action = (response as any).value;
|
|
103
152
|
|
|
104
153
|
switch (action) {
|
|
105
|
-
case
|
|
106
|
-
await handleShow();
|
|
154
|
+
case "show":
|
|
155
|
+
await handleShow(defaultCliMode);
|
|
107
156
|
break;
|
|
108
|
-
case
|
|
109
|
-
await handleAdd();
|
|
157
|
+
case "add":
|
|
158
|
+
await handleAdd(undefined, defaultCliMode);
|
|
110
159
|
break;
|
|
111
|
-
case
|
|
112
|
-
await handleRemove();
|
|
160
|
+
case "remove":
|
|
161
|
+
await handleRemove(undefined, defaultCliMode);
|
|
113
162
|
break;
|
|
114
|
-
case
|
|
115
|
-
await handleClear();
|
|
163
|
+
case "clear":
|
|
164
|
+
await handleClear(defaultCliMode);
|
|
116
165
|
break;
|
|
117
|
-
case
|
|
118
|
-
await handleAccessLevel();
|
|
166
|
+
case "access":
|
|
167
|
+
await handleAccessLevel(undefined, defaultCliMode);
|
|
119
168
|
break;
|
|
120
|
-
case
|
|
121
|
-
await handleCommit();
|
|
169
|
+
case "commit":
|
|
170
|
+
await handleCommit(undefined, undefined, defaultCliMode);
|
|
122
171
|
break;
|
|
123
|
-
case
|
|
124
|
-
await handleServices();
|
|
172
|
+
case "services":
|
|
173
|
+
await handleServices(defaultCliMode);
|
|
125
174
|
break;
|
|
126
|
-
case
|
|
175
|
+
case "help":
|
|
127
176
|
showHelp();
|
|
128
177
|
break;
|
|
129
178
|
}
|
|
@@ -132,50 +181,69 @@ async function handleInteractiveMenu(): Promise<void> {
|
|
|
132
181
|
/**
|
|
133
182
|
* Show current registry configuration
|
|
134
183
|
*/
|
|
135
|
-
async function handleShow(): Promise<void> {
|
|
184
|
+
async function handleShow(mode: ICliMode): Promise<void> {
|
|
185
|
+
if (mode.json) {
|
|
186
|
+
const smartconfigData = await readSmartconfigFile();
|
|
187
|
+
printJson(getCliConfigValueFromData(smartconfigData, ""));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
136
191
|
const config = await ReleaseConfig.fromCwd();
|
|
137
192
|
const registries = config.getRegistries();
|
|
138
193
|
const accessLevel = config.getAccessLevel();
|
|
139
194
|
|
|
140
|
-
console.log(
|
|
141
|
-
console.log(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
console.log(
|
|
195
|
+
console.log("");
|
|
196
|
+
console.log(
|
|
197
|
+
"╭─────────────────────────────────────────────────────────────╮",
|
|
198
|
+
);
|
|
199
|
+
console.log(
|
|
200
|
+
"│ Release Configuration │",
|
|
201
|
+
);
|
|
202
|
+
console.log(
|
|
203
|
+
"╰─────────────────────────────────────────────────────────────╯",
|
|
204
|
+
);
|
|
205
|
+
console.log("");
|
|
145
206
|
|
|
146
207
|
// Show access level
|
|
147
|
-
plugins.logger.log(
|
|
148
|
-
console.log(
|
|
208
|
+
plugins.logger.log("info", `Access Level: ${accessLevel}`);
|
|
209
|
+
console.log("");
|
|
149
210
|
|
|
150
211
|
if (registries.length === 0) {
|
|
151
|
-
plugins.logger.log(
|
|
152
|
-
console.log(
|
|
153
|
-
console.log(
|
|
154
|
-
console.log(
|
|
212
|
+
plugins.logger.log("info", "No release registries configured.");
|
|
213
|
+
console.log("");
|
|
214
|
+
console.log(" Run `gitzone config add <registry-url>` to add one.");
|
|
215
|
+
console.log("");
|
|
155
216
|
} else {
|
|
156
|
-
plugins.logger.log(
|
|
157
|
-
console.log(
|
|
217
|
+
plugins.logger.log("info", `Configured registries (${registries.length}):`);
|
|
218
|
+
console.log("");
|
|
158
219
|
registries.forEach((url, index) => {
|
|
159
220
|
console.log(` ${index + 1}. ${url}`);
|
|
160
221
|
});
|
|
161
|
-
console.log(
|
|
222
|
+
console.log("");
|
|
162
223
|
}
|
|
163
224
|
}
|
|
164
225
|
|
|
165
226
|
/**
|
|
166
227
|
* Add a registry URL
|
|
167
228
|
*/
|
|
168
|
-
async function handleAdd(
|
|
229
|
+
async function handleAdd(
|
|
230
|
+
url: string | undefined,
|
|
231
|
+
mode: ICliMode,
|
|
232
|
+
): Promise<void> {
|
|
169
233
|
if (!url) {
|
|
234
|
+
if (!mode.interactive) {
|
|
235
|
+
throw new Error("Registry URL is required in non-interactive mode");
|
|
236
|
+
}
|
|
237
|
+
|
|
170
238
|
// Interactive mode
|
|
171
239
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
172
240
|
const response = await interactInstance.askQuestion({
|
|
173
|
-
type:
|
|
174
|
-
name:
|
|
175
|
-
message:
|
|
176
|
-
default:
|
|
241
|
+
type: "input",
|
|
242
|
+
name: "registryUrl",
|
|
243
|
+
message: "Enter registry URL:",
|
|
244
|
+
default: "https://registry.npmjs.org",
|
|
177
245
|
validate: (input: string) => {
|
|
178
|
-
return !!(input && input.trim() !==
|
|
246
|
+
return !!(input && input.trim() !== "");
|
|
179
247
|
},
|
|
180
248
|
});
|
|
181
249
|
url = (response as any).value;
|
|
@@ -186,32 +254,48 @@ async function handleAdd(url?: string): Promise<void> {
|
|
|
186
254
|
|
|
187
255
|
if (added) {
|
|
188
256
|
await config.save();
|
|
189
|
-
|
|
190
|
-
|
|
257
|
+
if (mode.json) {
|
|
258
|
+
printJson({
|
|
259
|
+
ok: true,
|
|
260
|
+
action: "add",
|
|
261
|
+
registry: url,
|
|
262
|
+
registries: config.getRegistries(),
|
|
263
|
+
});
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
plugins.logger.log("success", `Added registry: ${url}`);
|
|
267
|
+
await formatSmartconfigWithDiff(mode);
|
|
191
268
|
} else {
|
|
192
|
-
plugins.logger.log(
|
|
269
|
+
plugins.logger.log("warn", `Registry already exists: ${url}`);
|
|
193
270
|
}
|
|
194
271
|
}
|
|
195
272
|
|
|
196
273
|
/**
|
|
197
274
|
* Remove a registry URL
|
|
198
275
|
*/
|
|
199
|
-
async function handleRemove(
|
|
276
|
+
async function handleRemove(
|
|
277
|
+
url: string | undefined,
|
|
278
|
+
mode: ICliMode,
|
|
279
|
+
): Promise<void> {
|
|
200
280
|
const config = await ReleaseConfig.fromCwd();
|
|
201
281
|
const registries = config.getRegistries();
|
|
202
282
|
|
|
203
283
|
if (registries.length === 0) {
|
|
204
|
-
plugins.logger.log(
|
|
284
|
+
plugins.logger.log("warn", "No registries configured to remove.");
|
|
205
285
|
return;
|
|
206
286
|
}
|
|
207
287
|
|
|
208
288
|
if (!url) {
|
|
289
|
+
if (!mode.interactive) {
|
|
290
|
+
throw new Error("Registry URL is required in non-interactive mode");
|
|
291
|
+
}
|
|
292
|
+
|
|
209
293
|
// Interactive mode - show list to select from
|
|
210
294
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
211
295
|
const response = await interactInstance.askQuestion({
|
|
212
|
-
type:
|
|
213
|
-
name:
|
|
214
|
-
message:
|
|
296
|
+
type: "list",
|
|
297
|
+
name: "registryUrl",
|
|
298
|
+
message: "Select registry to remove:",
|
|
215
299
|
choices: registries,
|
|
216
300
|
default: registries[0],
|
|
217
301
|
});
|
|
@@ -222,99 +306,135 @@ async function handleRemove(url?: string): Promise<void> {
|
|
|
222
306
|
|
|
223
307
|
if (removed) {
|
|
224
308
|
await config.save();
|
|
225
|
-
|
|
226
|
-
|
|
309
|
+
if (mode.json) {
|
|
310
|
+
printJson({
|
|
311
|
+
ok: true,
|
|
312
|
+
action: "remove",
|
|
313
|
+
registry: url,
|
|
314
|
+
registries: config.getRegistries(),
|
|
315
|
+
});
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
plugins.logger.log("success", `Removed registry: ${url}`);
|
|
319
|
+
await formatSmartconfigWithDiff(mode);
|
|
227
320
|
} else {
|
|
228
|
-
plugins.logger.log(
|
|
321
|
+
plugins.logger.log("warn", `Registry not found: ${url}`);
|
|
229
322
|
}
|
|
230
323
|
}
|
|
231
324
|
|
|
232
325
|
/**
|
|
233
326
|
* Clear all registries
|
|
234
327
|
*/
|
|
235
|
-
async function handleClear(): Promise<void> {
|
|
328
|
+
async function handleClear(mode: ICliMode): Promise<void> {
|
|
236
329
|
const config = await ReleaseConfig.fromCwd();
|
|
237
330
|
|
|
238
331
|
if (!config.hasRegistries()) {
|
|
239
|
-
plugins.logger.log(
|
|
332
|
+
plugins.logger.log("info", "No registries to clear.");
|
|
240
333
|
return;
|
|
241
334
|
}
|
|
242
335
|
|
|
243
336
|
// Confirm before clearing
|
|
244
|
-
const confirmed =
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
337
|
+
const confirmed = mode.interactive
|
|
338
|
+
? await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
339
|
+
"Clear all configured registries?",
|
|
340
|
+
false,
|
|
341
|
+
)
|
|
342
|
+
: true;
|
|
248
343
|
|
|
249
344
|
if (confirmed) {
|
|
250
345
|
config.clearRegistries();
|
|
251
346
|
await config.save();
|
|
252
|
-
|
|
253
|
-
|
|
347
|
+
if (mode.json) {
|
|
348
|
+
printJson({ ok: true, action: "clear", registries: [] });
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
plugins.logger.log("success", "All registries cleared.");
|
|
352
|
+
await formatSmartconfigWithDiff(mode);
|
|
254
353
|
} else {
|
|
255
|
-
plugins.logger.log(
|
|
354
|
+
plugins.logger.log("info", "Operation cancelled.");
|
|
256
355
|
}
|
|
257
356
|
}
|
|
258
357
|
|
|
259
358
|
/**
|
|
260
359
|
* Set or toggle access level
|
|
261
360
|
*/
|
|
262
|
-
async function handleAccessLevel(
|
|
361
|
+
async function handleAccessLevel(
|
|
362
|
+
level: string | undefined,
|
|
363
|
+
mode: ICliMode,
|
|
364
|
+
): Promise<void> {
|
|
263
365
|
const config = await ReleaseConfig.fromCwd();
|
|
264
366
|
const currentLevel = config.getAccessLevel();
|
|
265
367
|
|
|
266
368
|
if (!level) {
|
|
369
|
+
if (!mode.interactive) {
|
|
370
|
+
throw new Error("Access level is required in non-interactive mode");
|
|
371
|
+
}
|
|
372
|
+
|
|
267
373
|
// Interactive mode - toggle or ask
|
|
268
374
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
269
375
|
const response = await interactInstance.askQuestion({
|
|
270
|
-
type:
|
|
271
|
-
name:
|
|
272
|
-
message:
|
|
273
|
-
choices: [
|
|
376
|
+
type: "list",
|
|
377
|
+
name: "accessLevel",
|
|
378
|
+
message: "Select npm access level for publishing:",
|
|
379
|
+
choices: ["public", "private"],
|
|
274
380
|
default: currentLevel,
|
|
275
381
|
});
|
|
276
382
|
level = (response as any).value;
|
|
277
383
|
}
|
|
278
384
|
|
|
279
385
|
// Validate the level
|
|
280
|
-
if (level !==
|
|
281
|
-
plugins.logger.log(
|
|
386
|
+
if (level !== "public" && level !== "private") {
|
|
387
|
+
plugins.logger.log(
|
|
388
|
+
"error",
|
|
389
|
+
`Invalid access level: ${level}. Must be 'public' or 'private'.`,
|
|
390
|
+
);
|
|
282
391
|
return;
|
|
283
392
|
}
|
|
284
393
|
|
|
285
394
|
if (level === currentLevel) {
|
|
286
|
-
plugins.logger.log(
|
|
395
|
+
plugins.logger.log("info", `Access level is already set to: ${level}`);
|
|
287
396
|
return;
|
|
288
397
|
}
|
|
289
398
|
|
|
290
|
-
config.setAccessLevel(level as
|
|
399
|
+
config.setAccessLevel(level as "public" | "private");
|
|
291
400
|
await config.save();
|
|
292
|
-
|
|
293
|
-
|
|
401
|
+
if (mode.json) {
|
|
402
|
+
printJson({ ok: true, action: "access", accessLevel: level });
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
plugins.logger.log("success", `Access level set to: ${level}`);
|
|
406
|
+
await formatSmartconfigWithDiff(mode);
|
|
294
407
|
}
|
|
295
408
|
|
|
296
409
|
/**
|
|
297
410
|
* Handle commit configuration
|
|
298
411
|
*/
|
|
299
|
-
async function handleCommit(
|
|
412
|
+
async function handleCommit(
|
|
413
|
+
setting: string | undefined,
|
|
414
|
+
value: string | undefined,
|
|
415
|
+
mode: ICliMode,
|
|
416
|
+
): Promise<void> {
|
|
300
417
|
const config = await CommitConfig.fromCwd();
|
|
301
418
|
|
|
302
419
|
// No setting = interactive mode
|
|
303
420
|
if (!setting) {
|
|
421
|
+
if (!mode.interactive) {
|
|
422
|
+
throw new Error("Commit setting is required in non-interactive mode");
|
|
423
|
+
}
|
|
304
424
|
await handleCommitInteractive(config);
|
|
305
425
|
return;
|
|
306
426
|
}
|
|
307
427
|
|
|
308
428
|
// Direct setting
|
|
309
429
|
switch (setting) {
|
|
310
|
-
case
|
|
311
|
-
await handleCommitSetting(config,
|
|
430
|
+
case "alwaysTest":
|
|
431
|
+
await handleCommitSetting(config, "alwaysTest", value, mode);
|
|
312
432
|
break;
|
|
313
|
-
case
|
|
314
|
-
await handleCommitSetting(config,
|
|
433
|
+
case "alwaysBuild":
|
|
434
|
+
await handleCommitSetting(config, "alwaysBuild", value, mode);
|
|
315
435
|
break;
|
|
316
436
|
default:
|
|
317
|
-
plugins.logger.log(
|
|
437
|
+
plugins.logger.log("error", `Unknown commit setting: ${setting}`);
|
|
318
438
|
showCommitHelp();
|
|
319
439
|
}
|
|
320
440
|
}
|
|
@@ -323,109 +443,297 @@ async function handleCommit(setting?: string, value?: string): Promise<void> {
|
|
|
323
443
|
* Interactive commit configuration
|
|
324
444
|
*/
|
|
325
445
|
async function handleCommitInteractive(config: CommitConfig): Promise<void> {
|
|
326
|
-
console.log(
|
|
327
|
-
console.log(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
console.log(
|
|
446
|
+
console.log("");
|
|
447
|
+
console.log(
|
|
448
|
+
"╭─────────────────────────────────────────────────────────────╮",
|
|
449
|
+
);
|
|
450
|
+
console.log(
|
|
451
|
+
"│ Commit Configuration │",
|
|
452
|
+
);
|
|
453
|
+
console.log(
|
|
454
|
+
"╰─────────────────────────────────────────────────────────────╯",
|
|
455
|
+
);
|
|
456
|
+
console.log("");
|
|
331
457
|
|
|
332
458
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
333
459
|
const response = await interactInstance.askQuestion({
|
|
334
|
-
type:
|
|
335
|
-
name:
|
|
336
|
-
message:
|
|
460
|
+
type: "checkbox",
|
|
461
|
+
name: "commitOptions",
|
|
462
|
+
message: "Select commit options to enable:",
|
|
337
463
|
choices: [
|
|
338
|
-
{ name:
|
|
339
|
-
{ name:
|
|
464
|
+
{ name: "Always run tests before commit (-t)", value: "alwaysTest" },
|
|
465
|
+
{ name: "Always build after commit (-b)", value: "alwaysBuild" },
|
|
340
466
|
],
|
|
341
467
|
default: [
|
|
342
|
-
...(config.getAlwaysTest() ? [
|
|
343
|
-
...(config.getAlwaysBuild() ? [
|
|
468
|
+
...(config.getAlwaysTest() ? ["alwaysTest"] : []),
|
|
469
|
+
...(config.getAlwaysBuild() ? ["alwaysBuild"] : []),
|
|
344
470
|
],
|
|
345
471
|
});
|
|
346
472
|
|
|
347
473
|
const selected = (response as any).value || [];
|
|
348
|
-
config.setAlwaysTest(selected.includes(
|
|
349
|
-
config.setAlwaysBuild(selected.includes(
|
|
474
|
+
config.setAlwaysTest(selected.includes("alwaysTest"));
|
|
475
|
+
config.setAlwaysBuild(selected.includes("alwaysBuild"));
|
|
350
476
|
await config.save();
|
|
351
477
|
|
|
352
|
-
plugins.logger.log(
|
|
353
|
-
await formatSmartconfigWithDiff();
|
|
478
|
+
plugins.logger.log("success", "Commit configuration updated");
|
|
479
|
+
await formatSmartconfigWithDiff(defaultCliMode);
|
|
354
480
|
}
|
|
355
481
|
|
|
356
482
|
/**
|
|
357
483
|
* Set a specific commit setting
|
|
358
484
|
*/
|
|
359
|
-
async function handleCommitSetting(
|
|
485
|
+
async function handleCommitSetting(
|
|
486
|
+
config: CommitConfig,
|
|
487
|
+
setting: string,
|
|
488
|
+
value: string | undefined,
|
|
489
|
+
mode: ICliMode,
|
|
490
|
+
): Promise<void> {
|
|
360
491
|
// Parse boolean value
|
|
361
|
-
const boolValue = value ===
|
|
492
|
+
const boolValue = value === "true" || value === "1" || value === "on";
|
|
362
493
|
|
|
363
|
-
if (setting ===
|
|
494
|
+
if (setting === "alwaysTest") {
|
|
364
495
|
config.setAlwaysTest(boolValue);
|
|
365
|
-
} else if (setting ===
|
|
496
|
+
} else if (setting === "alwaysBuild") {
|
|
366
497
|
config.setAlwaysBuild(boolValue);
|
|
367
498
|
}
|
|
368
499
|
|
|
369
500
|
await config.save();
|
|
370
|
-
|
|
371
|
-
|
|
501
|
+
if (mode.json) {
|
|
502
|
+
printJson({ ok: true, action: "commit", setting, value: boolValue });
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
plugins.logger.log("success", `Set ${setting} to ${boolValue}`);
|
|
506
|
+
await formatSmartconfigWithDiff(mode);
|
|
372
507
|
}
|
|
373
508
|
|
|
374
509
|
/**
|
|
375
510
|
* Show help for commit subcommand
|
|
376
511
|
*/
|
|
377
512
|
function showCommitHelp(): void {
|
|
378
|
-
console.log(
|
|
379
|
-
console.log(
|
|
380
|
-
console.log(
|
|
381
|
-
console.log(
|
|
382
|
-
console.log(
|
|
383
|
-
console.log(
|
|
384
|
-
console.log(
|
|
385
|
-
console.log(
|
|
386
|
-
console.log(
|
|
387
|
-
console.log(
|
|
388
|
-
console.log(
|
|
389
|
-
console.log(
|
|
513
|
+
console.log("");
|
|
514
|
+
console.log("Usage: gitzone config commit [setting] [value]");
|
|
515
|
+
console.log("");
|
|
516
|
+
console.log("Settings:");
|
|
517
|
+
console.log(" alwaysTest [true|false] Always run tests before commit");
|
|
518
|
+
console.log(" alwaysBuild [true|false] Always build after commit");
|
|
519
|
+
console.log("");
|
|
520
|
+
console.log("Examples:");
|
|
521
|
+
console.log(" gitzone config commit # Interactive mode");
|
|
522
|
+
console.log(" gitzone config commit alwaysTest true");
|
|
523
|
+
console.log(" gitzone config commit alwaysBuild false");
|
|
524
|
+
console.log("");
|
|
390
525
|
}
|
|
391
526
|
|
|
392
527
|
/**
|
|
393
528
|
* Handle services configuration
|
|
394
529
|
*/
|
|
395
|
-
async function handleServices(): Promise<void> {
|
|
530
|
+
async function handleServices(mode: ICliMode): Promise<void> {
|
|
531
|
+
if (!mode.interactive) {
|
|
532
|
+
throw new Error(
|
|
533
|
+
"Use `gitzone services config --json` or `gitzone services set ...` in non-interactive mode",
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
|
|
396
537
|
// Import and use ServiceManager's configureServices
|
|
397
|
-
const { ServiceManager } =
|
|
538
|
+
const { ServiceManager } =
|
|
539
|
+
await import("../mod_services/classes.servicemanager.js");
|
|
398
540
|
const serviceManager = new ServiceManager();
|
|
399
541
|
await serviceManager.init();
|
|
400
542
|
await serviceManager.configureServices();
|
|
401
543
|
}
|
|
402
544
|
|
|
545
|
+
async function handleGet(
|
|
546
|
+
configPath: string | undefined,
|
|
547
|
+
mode: ICliMode,
|
|
548
|
+
): Promise<void> {
|
|
549
|
+
if (!configPath) {
|
|
550
|
+
throw new Error("Configuration path is required");
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const smartconfigData = await readSmartconfigFile();
|
|
554
|
+
const value = getCliConfigValueFromData(smartconfigData, configPath);
|
|
555
|
+
|
|
556
|
+
if (mode.json) {
|
|
557
|
+
printJson({ path: configPath, value, exists: value !== undefined });
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (value === undefined) {
|
|
562
|
+
plugins.logger.log("warn", `No value set for ${configPath}`);
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (typeof value === "string") {
|
|
567
|
+
console.log(value);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
printJson(value);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
async function handleSet(
|
|
575
|
+
configPath: string | undefined,
|
|
576
|
+
rawValue: string | undefined,
|
|
577
|
+
mode: ICliMode,
|
|
578
|
+
): Promise<void> {
|
|
579
|
+
if (!configPath) {
|
|
580
|
+
throw new Error("Configuration path is required");
|
|
581
|
+
}
|
|
582
|
+
if (rawValue === undefined) {
|
|
583
|
+
throw new Error("Configuration value is required");
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const smartconfigData = await readSmartconfigFile();
|
|
587
|
+
const parsedValue = parseConfigValue(rawValue);
|
|
588
|
+
setCliConfigValueInData(smartconfigData, configPath, parsedValue);
|
|
589
|
+
await writeSmartconfigFile(smartconfigData);
|
|
590
|
+
|
|
591
|
+
if (mode.json) {
|
|
592
|
+
printJson({
|
|
593
|
+
ok: true,
|
|
594
|
+
action: "set",
|
|
595
|
+
path: configPath,
|
|
596
|
+
value: parsedValue,
|
|
597
|
+
});
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
plugins.logger.log("success", `Set ${configPath}`);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
async function handleUnset(
|
|
605
|
+
configPath: string | undefined,
|
|
606
|
+
mode: ICliMode,
|
|
607
|
+
): Promise<void> {
|
|
608
|
+
if (!configPath) {
|
|
609
|
+
throw new Error("Configuration path is required");
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
const smartconfigData = await readSmartconfigFile();
|
|
613
|
+
const removed = unsetCliConfigValueInData(smartconfigData, configPath);
|
|
614
|
+
if (!removed) {
|
|
615
|
+
if (mode.json) {
|
|
616
|
+
printJson({
|
|
617
|
+
ok: false,
|
|
618
|
+
action: "unset",
|
|
619
|
+
path: configPath,
|
|
620
|
+
removed: false,
|
|
621
|
+
});
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
plugins.logger.log("warn", `No value set for ${configPath}`);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
await writeSmartconfigFile(smartconfigData);
|
|
630
|
+
|
|
631
|
+
if (mode.json) {
|
|
632
|
+
printJson({ ok: true, action: "unset", path: configPath, removed: true });
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
plugins.logger.log("success", `Unset ${configPath}`);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function parseConfigValue(rawValue: string): any {
|
|
640
|
+
const trimmedValue = rawValue.trim();
|
|
641
|
+
if (trimmedValue === "true") {
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
644
|
+
if (trimmedValue === "false") {
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
if (trimmedValue === "null") {
|
|
648
|
+
return null;
|
|
649
|
+
}
|
|
650
|
+
if (/^-?\d+(\.\d+)?$/.test(trimmedValue)) {
|
|
651
|
+
return Number(trimmedValue);
|
|
652
|
+
}
|
|
653
|
+
if (
|
|
654
|
+
(trimmedValue.startsWith("{") && trimmedValue.endsWith("}")) ||
|
|
655
|
+
(trimmedValue.startsWith("[") && trimmedValue.endsWith("]")) ||
|
|
656
|
+
(trimmedValue.startsWith('"') && trimmedValue.endsWith('"'))
|
|
657
|
+
) {
|
|
658
|
+
return JSON.parse(trimmedValue);
|
|
659
|
+
}
|
|
660
|
+
return rawValue;
|
|
661
|
+
}
|
|
662
|
+
|
|
403
663
|
/**
|
|
404
664
|
* Show help for config command
|
|
405
665
|
*/
|
|
406
|
-
function showHelp(): void {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
666
|
+
export function showHelp(mode?: ICliMode): void {
|
|
667
|
+
if (mode?.json) {
|
|
668
|
+
printJson({
|
|
669
|
+
command: "config",
|
|
670
|
+
usage: "gitzone config <command> [options]",
|
|
671
|
+
commands: [
|
|
672
|
+
{
|
|
673
|
+
name: "show",
|
|
674
|
+
description: "Display current @git.zone/cli configuration",
|
|
675
|
+
},
|
|
676
|
+
{ name: "get <path>", description: "Read a single config value" },
|
|
677
|
+
{ name: "set <path> <value>", description: "Write a config value" },
|
|
678
|
+
{ name: "unset <path>", description: "Delete a config value" },
|
|
679
|
+
{ name: "add [url]", description: "Add a release registry" },
|
|
680
|
+
{ name: "remove [url]", description: "Remove a release registry" },
|
|
681
|
+
{ name: "clear", description: "Clear all release registries" },
|
|
682
|
+
{
|
|
683
|
+
name: "access [public|private]",
|
|
684
|
+
description: "Set npm publish access level",
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
name: "commit <setting> <value>",
|
|
688
|
+
description: "Set commit defaults",
|
|
689
|
+
},
|
|
690
|
+
],
|
|
691
|
+
examples: [
|
|
692
|
+
"gitzone config show --json",
|
|
693
|
+
"gitzone config get release.accessLevel",
|
|
694
|
+
"gitzone config set cli.interactive false",
|
|
695
|
+
"gitzone config set cli.output json",
|
|
696
|
+
],
|
|
697
|
+
});
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
console.log("");
|
|
702
|
+
console.log("Usage: gitzone config <command> [options]");
|
|
703
|
+
console.log("");
|
|
704
|
+
console.log("Commands:");
|
|
705
|
+
console.log(
|
|
706
|
+
" show Display current @git.zone/cli configuration",
|
|
707
|
+
);
|
|
708
|
+
console.log(" get <path> Read a single config value");
|
|
709
|
+
console.log(" set <path> <value> Write a config value");
|
|
710
|
+
console.log(" unset <path> Delete a config value");
|
|
711
|
+
console.log(" add [url] Add a registry URL");
|
|
712
|
+
console.log(" remove [url] Remove a registry URL");
|
|
713
|
+
console.log(" clear Clear all registries");
|
|
714
|
+
console.log(
|
|
715
|
+
" access [public|private] Set npm access level for publishing",
|
|
716
|
+
);
|
|
717
|
+
console.log(" commit [setting] [value] Configure commit options");
|
|
718
|
+
console.log(
|
|
719
|
+
" services Configure which services are enabled",
|
|
720
|
+
);
|
|
721
|
+
console.log("");
|
|
722
|
+
console.log("Examples:");
|
|
723
|
+
console.log(" gitzone config show");
|
|
724
|
+
console.log(" gitzone config show --json");
|
|
725
|
+
console.log(" gitzone config get release.accessLevel");
|
|
726
|
+
console.log(" gitzone config set cli.interactive false");
|
|
727
|
+
console.log(" gitzone config set cli.output json");
|
|
728
|
+
console.log(" gitzone config unset cli.output");
|
|
729
|
+
console.log(" gitzone config add https://registry.npmjs.org");
|
|
730
|
+
console.log(" gitzone config add https://verdaccio.example.com");
|
|
731
|
+
console.log(" gitzone config remove https://registry.npmjs.org");
|
|
732
|
+
console.log(" gitzone config clear");
|
|
733
|
+
console.log(" gitzone config access public");
|
|
734
|
+
console.log(" gitzone config access private");
|
|
735
|
+
console.log(" gitzone config commit # Interactive");
|
|
736
|
+
console.log(" gitzone config commit alwaysTest true");
|
|
737
|
+
console.log(" gitzone config services # Interactive");
|
|
738
|
+
console.log("");
|
|
431
739
|
}
|