azdo-cli 0.2.0-003-cli-settings.15 → 0.2.0-003-cli-settings.19
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/index.js +110 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -201,7 +201,11 @@ function parseAzdoRemote(url) {
|
|
|
201
201
|
for (const pattern of patterns) {
|
|
202
202
|
const match = url.match(pattern);
|
|
203
203
|
if (match) {
|
|
204
|
-
|
|
204
|
+
const project = match[2];
|
|
205
|
+
if (/^DefaultCollection$/i.test(project)) {
|
|
206
|
+
return { org: match[1], project: "" };
|
|
207
|
+
}
|
|
208
|
+
return { org: match[1], project };
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
211
|
return null;
|
|
@@ -214,7 +218,7 @@ function detectAzdoContext() {
|
|
|
214
218
|
throw new Error("Not in a git repository. Provide --org and --project explicitly.");
|
|
215
219
|
}
|
|
216
220
|
const context = parseAzdoRemote(remoteUrl);
|
|
217
|
-
if (!context) {
|
|
221
|
+
if (!context || !context.org && !context.project) {
|
|
218
222
|
throw new Error('Git remote "origin" is not an Azure DevOps URL. Provide --org and --project explicitly.');
|
|
219
223
|
}
|
|
220
224
|
return context;
|
|
@@ -224,7 +228,30 @@ function detectAzdoContext() {
|
|
|
224
228
|
import fs from "fs";
|
|
225
229
|
import path from "path";
|
|
226
230
|
import os from "os";
|
|
227
|
-
var
|
|
231
|
+
var SETTINGS = [
|
|
232
|
+
{
|
|
233
|
+
key: "org",
|
|
234
|
+
description: "Azure DevOps organization name",
|
|
235
|
+
type: "string",
|
|
236
|
+
example: "mycompany",
|
|
237
|
+
required: true
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
key: "project",
|
|
241
|
+
description: "Azure DevOps project name",
|
|
242
|
+
type: "string",
|
|
243
|
+
example: "MyProject",
|
|
244
|
+
required: true
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
key: "fields",
|
|
248
|
+
description: "Extra work item fields to include (comma-separated reference names)",
|
|
249
|
+
type: "string[]",
|
|
250
|
+
example: "System.Tags,Custom.Priority",
|
|
251
|
+
required: false
|
|
252
|
+
}
|
|
253
|
+
];
|
|
254
|
+
var VALID_KEYS = SETTINGS.map((s) => s.key);
|
|
228
255
|
function getConfigPath() {
|
|
229
256
|
return path.join(os.homedir(), ".azdo", "config.json");
|
|
230
257
|
}
|
|
@@ -357,12 +384,19 @@ function createGetItemCommand() {
|
|
|
357
384
|
if (options.org && options.project) {
|
|
358
385
|
context = { org: options.org, project: options.project };
|
|
359
386
|
} else {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
387
|
+
const config = loadConfig();
|
|
388
|
+
if (config.org && config.project) {
|
|
389
|
+
context = { org: config.org, project: config.project };
|
|
390
|
+
} else {
|
|
391
|
+
let gitContext = null;
|
|
392
|
+
try {
|
|
393
|
+
gitContext = detectAzdoContext();
|
|
394
|
+
} catch {
|
|
395
|
+
}
|
|
396
|
+
const org = config.org || gitContext?.org;
|
|
397
|
+
const project = config.project || gitContext?.project;
|
|
398
|
+
if (org && project) {
|
|
399
|
+
context = { org, project };
|
|
366
400
|
} else {
|
|
367
401
|
throw new Error(
|
|
368
402
|
'Could not determine org/project. Use --org and --project flags, work from an Azure DevOps git repo, or run "azdo config set org/project".'
|
|
@@ -427,6 +461,7 @@ function createClearPatCommand() {
|
|
|
427
461
|
|
|
428
462
|
// src/commands/config.ts
|
|
429
463
|
import { Command as Command3 } from "commander";
|
|
464
|
+
import { createInterface as createInterface2 } from "readline";
|
|
430
465
|
function createConfigCommand() {
|
|
431
466
|
const config = new Command3("config");
|
|
432
467
|
config.description("Manage CLI settings");
|
|
@@ -480,18 +515,24 @@ function createConfigCommand() {
|
|
|
480
515
|
if (options.json) {
|
|
481
516
|
process.stdout.write(JSON.stringify(cfg) + "\n");
|
|
482
517
|
} else {
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
process.stdout.write(
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
518
|
+
const keyWidth = 10;
|
|
519
|
+
const valueWidth = 30;
|
|
520
|
+
for (const setting of SETTINGS) {
|
|
521
|
+
const raw = cfg[setting.key];
|
|
522
|
+
const value = raw === void 0 ? "(not set)" : Array.isArray(raw) ? raw.join(",") : raw;
|
|
523
|
+
const marker = raw === void 0 && setting.required ? " *" : "";
|
|
524
|
+
process.stdout.write(
|
|
525
|
+
`${setting.key.padEnd(keyWidth)}${String(value).padEnd(valueWidth)}${setting.description}${marker}
|
|
526
|
+
`
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
const hasUnset = SETTINGS.some(
|
|
530
|
+
(s) => s.required && cfg[s.key] === void 0
|
|
531
|
+
);
|
|
532
|
+
if (hasUnset) {
|
|
533
|
+
process.stdout.write(
|
|
534
|
+
'\n* = required but not configured. Run "azdo config wizard" to set up.\n'
|
|
535
|
+
);
|
|
495
536
|
}
|
|
496
537
|
}
|
|
497
538
|
});
|
|
@@ -512,10 +553,58 @@ function createConfigCommand() {
|
|
|
512
553
|
process.exit(1);
|
|
513
554
|
}
|
|
514
555
|
});
|
|
556
|
+
const wizard = new Command3("wizard");
|
|
557
|
+
wizard.description("Interactive wizard to configure all settings").action(async () => {
|
|
558
|
+
if (!process.stdin.isTTY) {
|
|
559
|
+
process.stderr.write(
|
|
560
|
+
"Error: Wizard requires an interactive terminal.\n"
|
|
561
|
+
);
|
|
562
|
+
process.exit(1);
|
|
563
|
+
}
|
|
564
|
+
const cfg = loadConfig();
|
|
565
|
+
const rl = createInterface2({
|
|
566
|
+
input: process.stdin,
|
|
567
|
+
output: process.stderr
|
|
568
|
+
});
|
|
569
|
+
const ask = (prompt) => new Promise((resolve2) => rl.question(prompt, resolve2));
|
|
570
|
+
process.stderr.write("Azure DevOps CLI - Configuration Wizard\n");
|
|
571
|
+
process.stderr.write("=======================================\n\n");
|
|
572
|
+
for (const setting of SETTINGS) {
|
|
573
|
+
const current = cfg[setting.key];
|
|
574
|
+
const currentDisplay = current === void 0 ? "" : Array.isArray(current) ? current.join(",") : current;
|
|
575
|
+
const requiredTag = setting.required ? " (required)" : " (optional)";
|
|
576
|
+
process.stderr.write(`${setting.description}${requiredTag}
|
|
577
|
+
`);
|
|
578
|
+
if (setting.example) {
|
|
579
|
+
process.stderr.write(` Example: ${setting.example}
|
|
580
|
+
`);
|
|
581
|
+
}
|
|
582
|
+
const defaultHint = currentDisplay ? ` [${currentDisplay}]` : "";
|
|
583
|
+
const answer = await ask(` ${setting.key}${defaultHint}: `);
|
|
584
|
+
const trimmed = answer.trim();
|
|
585
|
+
if (trimmed) {
|
|
586
|
+
setConfigValue(setting.key, trimmed);
|
|
587
|
+
process.stderr.write(` -> Set "${setting.key}" to "${trimmed}"
|
|
588
|
+
|
|
589
|
+
`);
|
|
590
|
+
} else if (currentDisplay) {
|
|
591
|
+
process.stderr.write(` -> Kept "${setting.key}" as "${currentDisplay}"
|
|
592
|
+
|
|
593
|
+
`);
|
|
594
|
+
} else {
|
|
595
|
+
process.stderr.write(` -> Skipped "${setting.key}"
|
|
596
|
+
|
|
597
|
+
`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
rl.close();
|
|
601
|
+
process.stderr.write("Configuration complete!\n");
|
|
602
|
+
});
|
|
515
603
|
config.addCommand(set);
|
|
516
604
|
config.addCommand(get);
|
|
517
605
|
config.addCommand(list);
|
|
518
606
|
config.addCommand(unset);
|
|
607
|
+
config.addCommand(wizard);
|
|
519
608
|
return config;
|
|
520
609
|
}
|
|
521
610
|
|