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 +10 -0
- package/package.json +1 -1
- package/src/cli.js +7 -1
- package/src/index.js +32 -8
- package/tests/index.test.js +63 -1
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
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({
|
|
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({
|
|
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({
|
|
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`);
|
package/tests/index.test.js
CHANGED
|
@@ -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
|
-
|
|
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.
|