glab-setup-git-identity 0.6.1 → 0.6.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 9f3ac16: Fix --version showing 'unknown' and fix auth flow for unauthenticated users
8
+ - Fix --version to explicitly read version from package.json (yargs auto-detection fails when installed globally with bun)
9
+ - Fix isGlabAuthenticated to detect invalid/missing tokens even when glab auth status exits with code 0
10
+ - Suppress noisy glab auth status output by using mirror: false with capture: true in command-stream
11
+ - Add mirror: false to all captured command executions to prevent output leaking to terminal
12
+
3
13
  ## 0.6.1
4
14
 
5
15
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glab-setup-git-identity",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "A tool to setup git identity based on current GitLab user",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/cli.js CHANGED
@@ -6,6 +6,7 @@
6
6
  * Command-line interface for setting up git identity based on GitLab user
7
7
  */
8
8
 
9
+ import { createRequire } from 'node:module';
9
10
  import { makeConfig } from 'lino-arguments';
10
11
  import {
11
12
  setupGitIdentity,
@@ -17,6 +18,11 @@ import {
17
18
  } from './index.js';
18
19
  import { $ } from 'command-stream';
19
20
 
21
+ // Read version from package.json explicitly (yargs auto-detection may fail when installed globally)
22
+ const require = createRequire(import.meta.url);
23
+ const packageJson = require('../package.json');
24
+ const packageVersion = packageJson.version;
25
+
20
26
  // Parse command-line arguments with environment variable and .lenv support
21
27
  const config = makeConfig({
22
28
  yargs: ({ yargs, getenv }) =>
@@ -145,7 +151,7 @@ const config = makeConfig({
145
151
  )
146
152
  .help('h')
147
153
  .alias('h', 'help')
148
- .version()
154
+ .version(packageVersion)
149
155
  .strict(),
150
156
  });
151
157
 
package/src/index.js CHANGED
@@ -62,7 +62,10 @@ export async function getGlabPath(options = {}) {
62
62
  const command = process.platform === 'win32' ? 'where' : 'which';
63
63
 
64
64
  try {
65
- const result = await $`${command} glab`.run({ capture: true });
65
+ const result = await $`${command} glab`.run({
66
+ capture: true,
67
+ mirror: false,
68
+ });
66
69
 
67
70
  if (result.code !== 0 || !result.stdout) {
68
71
  throw new Error(
@@ -238,7 +241,7 @@ export async function runGlabAuthSetupGit(options = {}) {
238
241
  try {
239
242
  const existingResult =
240
243
  await $`git config --global --get credential.${credentialUrl}.helper`.run(
241
- { capture: true }
244
+ { capture: true, mirror: false }
242
245
  );
243
246
 
244
247
  if (existingResult.code === 0 && existingResult.stdout && !force) {
@@ -262,6 +265,7 @@ export async function runGlabAuthSetupGit(options = {}) {
262
265
  try {
263
266
  await $`git config --global credential.${credentialUrl}.helper ""`.run({
264
267
  capture: true,
268
+ mirror: false,
265
269
  });
266
270
  } catch {
267
271
  // Ignore errors if not set
@@ -272,7 +276,7 @@ export async function runGlabAuthSetupGit(options = {}) {
272
276
 
273
277
  const result =
274
278
  await $`git config --global --add credential.${credentialUrl}.helper ${credentialHelper}`.run(
275
- { capture: true }
279
+ { capture: true, mirror: false }
276
280
  );
277
281
 
278
282
  if (result.code !== 0) {
@@ -312,13 +316,29 @@ export async function isGlabAuthenticated(options = {}) {
312
316
  }
313
317
 
314
318
  try {
315
- const result = await $`glab ${args}`.run({ capture: true });
319
+ const result = await $`glab ${args}`.run({
320
+ capture: true,
321
+ mirror: false,
322
+ });
316
323
 
317
324
  if (result.code !== 0) {
318
325
  log.debug(`GitLab CLI is not authenticated: ${result.stderr}`);
319
326
  return false;
320
327
  }
321
328
 
329
+ // glab auth status may exit with code 0 even when not properly authenticated.
330
+ // Check stderr for indicators of auth failure (e.g., "No token provided", "401 Unauthorized").
331
+ const output = (result.stderr || '') + (result.stdout || '');
332
+ if (
333
+ /no token provided/i.test(output) ||
334
+ /401\s*unauthorized/i.test(output)
335
+ ) {
336
+ log.debug(
337
+ `GitLab CLI reports success but token is missing or invalid: ${output.trim()}`
338
+ );
339
+ return false;
340
+ }
341
+
322
342
  log.debug('GitLab CLI is authenticated');
323
343
  return true;
324
344
  } catch (error) {
@@ -350,7 +370,7 @@ export async function getGitLabUsername(options = {}) {
350
370
  args.push('--hostname', hostname);
351
371
  }
352
372
 
353
- const result = await $`glab ${args}`.run({ capture: true });
373
+ const result = await $`glab ${args}`.run({ capture: true, mirror: false });
354
374
 
355
375
  if (result.code !== 0) {
356
376
  throw new Error(`Failed to get GitLab username: ${result.stderr}`);
@@ -401,7 +421,7 @@ export async function getGitLabEmail(options = {}) {
401
421
  args.push('--hostname', hostname);
402
422
  }
403
423
 
404
- const result = await $`glab ${args}`.run({ capture: true });
424
+ const result = await $`glab ${args}`.run({ capture: true, mirror: false });
405
425
 
406
426
  if (result.code !== 0) {
407
427
  throw new Error(`Failed to get GitLab email: ${result.stderr}`);
@@ -454,7 +474,7 @@ export async function getGitLabUserInfo(options = {}) {
454
474
  args.push('--hostname', hostname);
455
475
  }
456
476
 
457
- const result = await $`glab ${args}`.run({ capture: true });
477
+ const result = await $`glab ${args}`.run({ capture: true, mirror: false });
458
478
 
459
479
  if (result.code !== 0) {
460
480
  throw new Error(`Failed to get GitLab user info: ${result.stderr}`);
@@ -512,6 +532,7 @@ export async function setGitConfig(key, value, options = {}) {
512
532
 
513
533
  const result = await $`git config ${scopeFlag} ${key} ${value}`.run({
514
534
  capture: true,
535
+ mirror: false,
515
536
  });
516
537
 
517
538
  if (result.code !== 0) {
@@ -539,7 +560,10 @@ export async function getGitConfig(key, options = {}) {
539
560
 
540
561
  log.debug(`Getting git config ${key} (${scope})`);
541
562
 
542
- const result = await $`git config ${scopeFlag} ${key}`.run({ capture: true });
563
+ const result = await $`git config ${scopeFlag} ${key}`.run({
564
+ capture: true,
565
+ mirror: false,
566
+ });
543
567
 
544
568
  if (result.code !== 0) {
545
569
  log.debug(`Git config ${key} not set`);
@@ -4,15 +4,19 @@
4
4
  */
5
5
 
6
6
  import { describe, it, expect } from 'test-anywhere';
7
+ import { createRequire } from 'node:module';
7
8
  import {
8
9
  defaultAuthOptions,
9
10
  getGitConfig,
10
11
  setGitConfig,
11
12
  verifyGitIdentity,
12
13
  getGlabPath,
14
+ isGlabAuthenticated,
13
15
  runGlabAuthSetupGit,
14
16
  } from '../src/index.js';
15
17
 
18
+ const require = createRequire(import.meta.url);
19
+
16
20
  describe('defaultAuthOptions', () => {
17
21
  it('should have correct default hostname', () => {
18
22
  expect(defaultAuthOptions.hostname).toBe('gitlab.com');
@@ -131,7 +135,65 @@ describe('runGlabAuthSetupGit', () => {
131
135
  });
132
136
  });
133
137
 
134
- // Note: Tests for isGlabAuthenticated, getGitLabUsername, getGitLabEmail,
138
+ describe('CLI --version', () => {
139
+ it('should output the version from package.json', async () => {
140
+ const pkg = require('../package.json');
141
+ const { execSync } = await import('node:child_process');
142
+ const output = execSync('node src/cli.js --version', {
143
+ encoding: 'utf8',
144
+ }).trim();
145
+ expect(output).toBe(pkg.version);
146
+ });
147
+ });
148
+
149
+ describe('isGlabAuthenticated', () => {
150
+ it('should be a function', () => {
151
+ expect(typeof isGlabAuthenticated).toBe('function');
152
+ });
153
+
154
+ it('should return false when glab has no valid token', async () => {
155
+ // In this test environment, glab is not properly authenticated
156
+ // so isGlabAuthenticated should return false
157
+ try {
158
+ const result = await isGlabAuthenticated();
159
+ expect(typeof result).toBe('boolean');
160
+ } catch {
161
+ // If glab is not installed, it should handle gracefully
162
+ expect(true).toBe(true);
163
+ }
164
+ });
165
+
166
+ it('should not produce visible output when checking auth status', async () => {
167
+ // Ensure isGlabAuthenticated does not leak glab output to the console
168
+ const originalStdoutWrite = process.stdout.write;
169
+ const originalStderrWrite = process.stderr.write;
170
+ let capturedOutput = '';
171
+
172
+ process.stdout.write = (chunk) => {
173
+ capturedOutput += chunk.toString();
174
+ return true;
175
+ };
176
+ process.stderr.write = (chunk) => {
177
+ capturedOutput += chunk.toString();
178
+ return true;
179
+ };
180
+
181
+ try {
182
+ await isGlabAuthenticated({ verbose: false });
183
+ } catch {
184
+ // ignore errors
185
+ } finally {
186
+ process.stdout.write = originalStdoutWrite;
187
+ process.stderr.write = originalStderrWrite;
188
+ }
189
+
190
+ // Should not contain glab auth status output
191
+ expect(capturedOutput.includes('No token provided')).toBe(false);
192
+ expect(capturedOutput.includes('401 Unauthorized')).toBe(false);
193
+ });
194
+ });
195
+
196
+ // Note: Tests for getGitLabUsername, getGitLabEmail,
135
197
  // getGitLabUserInfo, runGlabAuthLogin, and setupGitIdentity require
136
198
  // an authenticated glab CLI environment and are better suited for
137
199
  // integration tests or manual testing.