duoops 0.2.5 → 0.2.7

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.
@@ -24,10 +24,13 @@ const hasBinary = (command) => {
24
24
  const detectGlabToken = (host = 'gitlab.com') => {
25
25
  try {
26
26
  const token = execSync(`glab config get token --host ${host}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
27
- if (token)
27
+ if (!token)
28
+ return;
29
+ const status = execSync(`curl -sf -o /dev/null -w "%{http_code}" -H "Authorization: Bearer ${token}" "https://${host}/api/v4/user"`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'], timeout: 5000 }).trim();
30
+ if (status === '200')
28
31
  return { source: 'glab CLI', token };
29
32
  }
30
- catch { /* glab not installed or not authenticated */ }
33
+ catch { /* glab not installed, not authenticated, or token expired */ }
31
34
  };
32
35
  const detectGitRemotePath = () => {
33
36
  try {
@@ -43,6 +46,21 @@ const detectGitRemotePath = () => {
43
46
  }
44
47
  catch { /* ignore */ }
45
48
  };
49
+ const resolveProjectId = async (auth, pathOrId) => {
50
+ const base = normalizeGitLabUrl(auth.baseUrl);
51
+ const encoded = encodeURIComponent(normalizeProjectPath(pathOrId));
52
+ try {
53
+ const res = await axios.get(`${base}/api/v4/projects/${encoded}`, {
54
+ headers: gitlabAuthHeaders(auth.token),
55
+ timeout: 5000,
56
+ validateStatus: () => true,
57
+ });
58
+ if (res.status === 200 && res.data?.id) {
59
+ return { id: res.data.id, name: res.data.name_with_namespace, path: res.data.path_with_namespace };
60
+ }
61
+ }
62
+ catch { /* ignore */ }
63
+ };
46
64
  const normalizeProjectPath = (project) => project.replace(/^\/+/, '');
47
65
  const normalizeGitLabUrl = (url) => url.replace(/\/+$/, '');
48
66
  const setGitlabVariable = async (auth, projectPath, variable) => {
@@ -444,13 +462,44 @@ export default class Init extends Command {
444
462
  this.warn('GitLab credentials missing, skipping project configuration.');
445
463
  return;
446
464
  }
447
- const projectPath = await input({
448
- default: currentDefault ?? detectGitRemotePath(),
449
- message: 'GitLab project path (e.g., group/project)',
450
- });
465
+ const detectedPath = detectGitRemotePath();
466
+ let projectPath;
467
+ let resolvedProject;
468
+ if (detectedPath) {
469
+ resolvedProject = await resolveProjectId(auth, detectedPath);
470
+ }
471
+ if (resolvedProject) {
472
+ const useDetected = await confirm({
473
+ default: true,
474
+ message: `Detected project: ${resolvedProject.name} (ID: ${resolvedProject.id}). Use it?`,
475
+ });
476
+ if (useDetected) {
477
+ projectPath = resolvedProject.path;
478
+ }
479
+ else {
480
+ projectPath = await input({
481
+ default: currentDefault,
482
+ message: 'GitLab project path or URL',
483
+ });
484
+ resolvedProject = await resolveProjectId(auth, projectPath);
485
+ }
486
+ }
487
+ else {
488
+ projectPath = await input({
489
+ default: currentDefault ?? detectedPath,
490
+ message: 'GitLab project path or URL',
491
+ });
492
+ resolvedProject = await resolveProjectId(auth, projectPath);
493
+ }
451
494
  if (!projectPath) {
452
495
  this.warn('Project path is required to configure CI variables.');
453
496
  }
497
+ if (resolvedProject) {
498
+ this.log(gray(` Project: ${resolvedProject.name} (ID: ${resolvedProject.id})`));
499
+ }
500
+ else if (projectPath) {
501
+ this.warn(`Could not resolve project "${projectPath}". Continuing with path as-is.`);
502
+ }
454
503
  const setAsDefault = await confirm({
455
504
  default: !currentDefault,
456
505
  message: 'Use this project as the default for DuoOps commands?',
@@ -669,5 +669,5 @@
669
669
  ]
670
670
  }
671
671
  },
672
- "version": "0.2.5"
672
+ "version": "0.2.7"
673
673
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duoops",
3
3
  "description": "Toolset for Explainable and Sustainable CI on Gitlab.",
4
- "version": "0.2.5",
4
+ "version": "0.2.7",
5
5
  "author": "Younes Laaroussi",
6
6
  "bin": {
7
7
  "duoops": "./bin/run.js"