@optique/git 0.9.0-dev.266 → 0.9.0-dev.270
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.cjs +87 -28
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +87 -28
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -26,31 +26,40 @@ const __optique_core_nonempty = __toESM(require("@optique/core/nonempty"));
|
|
|
26
26
|
const isomorphic_git = __toESM(require("isomorphic-git"));
|
|
27
27
|
const node_fs_promises = __toESM(require("node:fs/promises"));
|
|
28
28
|
const node_process = __toESM(require("node:process"));
|
|
29
|
+
const __logtape_logtape = __toESM(require("@logtape/logtape"));
|
|
29
30
|
|
|
30
31
|
//#region src/index.ts
|
|
32
|
+
const logger = (0, __logtape_logtape.getLogger)(["optique", "git"]);
|
|
31
33
|
/**
|
|
32
|
-
*
|
|
34
|
+
* Read-only filesystem interface passed to isomorphic-git.
|
|
33
35
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* by our read-only operations.
|
|
36
|
+
* This package only performs read operations (validation and listing).
|
|
37
|
+
* Write methods are implemented as stubs that return rejected promises,
|
|
38
|
+
* enforcing the read-only contract and preventing accidental writes.
|
|
38
39
|
*/
|
|
39
40
|
const gitFs = {
|
|
40
41
|
readFile: node_fs_promises.readFile,
|
|
41
|
-
writeFile:
|
|
42
|
-
mkdir:
|
|
43
|
-
rmdir:
|
|
44
|
-
unlink:
|
|
42
|
+
writeFile: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: writeFile is disabled.")),
|
|
43
|
+
mkdir: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: mkdir is disabled.")),
|
|
44
|
+
rmdir: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: rmdir is disabled.")),
|
|
45
|
+
unlink: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: unlink is disabled.")),
|
|
45
46
|
readdir: node_fs_promises.readdir,
|
|
46
47
|
readlink: node_fs_promises.readlink,
|
|
47
|
-
symlink:
|
|
48
|
+
symlink: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: symlink is disabled.")),
|
|
48
49
|
stat: node_fs_promises.stat,
|
|
49
50
|
lstat: node_fs_promises.lstat
|
|
50
51
|
};
|
|
51
52
|
const METAVAR_BRANCH = "BRANCH";
|
|
52
53
|
const METAVAR_TAG = "TAG";
|
|
53
54
|
const METAVAR_REMOTE = "REMOTE";
|
|
55
|
+
/**
|
|
56
|
+
* Resolves the repository directory from the provided option or process.cwd().
|
|
57
|
+
*
|
|
58
|
+
* Note: This function does not validate that the directory exists or is
|
|
59
|
+
* accessible. Directory validation is deferred to the Git operations
|
|
60
|
+
* themselves, which will produce appropriate error messages if the directory
|
|
61
|
+
* is invalid or not a Git repository.
|
|
62
|
+
*/
|
|
54
63
|
function getRepoDir(dirOption) {
|
|
55
64
|
if (dirOption != null) return dirOption;
|
|
56
65
|
if (typeof node_process.default !== "undefined" && typeof node_process.default.cwd === "function") return node_process.default.cwd();
|
|
@@ -64,6 +73,8 @@ function listFailureMessage(error, dir, errors, fallback) {
|
|
|
64
73
|
if (hasErrorCode(error, "NotAGitRepositoryError") || hasErrorCode(error, "NotFoundError")) return __optique_core_message.message`${(0, __optique_core_message.value)(dir)} is not a git repository.`;
|
|
65
74
|
return fallback;
|
|
66
75
|
}
|
|
76
|
+
/** Default depth for commit suggestions. */
|
|
77
|
+
const DEFAULT_SUGGESTION_DEPTH = 15;
|
|
67
78
|
function createAsyncValueParser(options, metavar, parseFn, suggestFn) {
|
|
68
79
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
69
80
|
return {
|
|
@@ -78,7 +89,10 @@ function createAsyncValueParser(options, metavar, parseFn, suggestFn) {
|
|
|
78
89
|
},
|
|
79
90
|
async *suggest(prefix) {
|
|
80
91
|
const dir = getRepoDir(options?.dir);
|
|
81
|
-
if (suggestFn)
|
|
92
|
+
if (suggestFn) {
|
|
93
|
+
const depth = options?.suggestionDepth ?? DEFAULT_SUGGESTION_DEPTH;
|
|
94
|
+
yield* suggestFn(dir, prefix, depth);
|
|
95
|
+
}
|
|
82
96
|
}
|
|
83
97
|
};
|
|
84
98
|
}
|
|
@@ -127,7 +141,7 @@ function gitBranch(options) {
|
|
|
127
141
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
128
142
|
};
|
|
129
143
|
}
|
|
130
|
-
}, async function* suggestBranch(dir, prefix) {
|
|
144
|
+
}, async function* suggestBranch(dir, prefix, _depth) {
|
|
131
145
|
try {
|
|
132
146
|
const branches = await isomorphic_git.listBranches({
|
|
133
147
|
fs: gitFs,
|
|
@@ -137,7 +151,13 @@ function gitBranch(options) {
|
|
|
137
151
|
kind: "literal",
|
|
138
152
|
text: branch
|
|
139
153
|
};
|
|
140
|
-
} catch {
|
|
154
|
+
} catch (error) {
|
|
155
|
+
logger.debug("Failed to list branches for suggestions.", {
|
|
156
|
+
dir,
|
|
157
|
+
prefix,
|
|
158
|
+
error
|
|
159
|
+
});
|
|
160
|
+
}
|
|
141
161
|
});
|
|
142
162
|
}
|
|
143
163
|
/**
|
|
@@ -187,7 +207,7 @@ function gitRemoteBranch(remote, options) {
|
|
|
187
207
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
188
208
|
};
|
|
189
209
|
}
|
|
190
|
-
}, async function* suggestRemoteBranch(dir, prefix) {
|
|
210
|
+
}, async function* suggestRemoteBranch(dir, prefix, _depth) {
|
|
191
211
|
try {
|
|
192
212
|
const branches = await isomorphic_git.listBranches({
|
|
193
213
|
fs: gitFs,
|
|
@@ -198,7 +218,14 @@ function gitRemoteBranch(remote, options) {
|
|
|
198
218
|
kind: "literal",
|
|
199
219
|
text: branch
|
|
200
220
|
};
|
|
201
|
-
} catch {
|
|
221
|
+
} catch (error) {
|
|
222
|
+
logger.debug("Failed to list remote branches for suggestions.", {
|
|
223
|
+
dir,
|
|
224
|
+
remote,
|
|
225
|
+
prefix,
|
|
226
|
+
error
|
|
227
|
+
});
|
|
228
|
+
}
|
|
202
229
|
});
|
|
203
230
|
}
|
|
204
231
|
/**
|
|
@@ -235,7 +262,7 @@ function gitTag(options) {
|
|
|
235
262
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
236
263
|
};
|
|
237
264
|
}
|
|
238
|
-
}, async function* suggestTag(dir, prefix) {
|
|
265
|
+
}, async function* suggestTag(dir, prefix, _depth) {
|
|
239
266
|
try {
|
|
240
267
|
const tags = await isomorphic_git.listTags({
|
|
241
268
|
fs: gitFs,
|
|
@@ -245,7 +272,13 @@ function gitTag(options) {
|
|
|
245
272
|
kind: "literal",
|
|
246
273
|
text: tag
|
|
247
274
|
};
|
|
248
|
-
} catch {
|
|
275
|
+
} catch (error) {
|
|
276
|
+
logger.debug("Failed to list tags for suggestions.", {
|
|
277
|
+
dir,
|
|
278
|
+
prefix,
|
|
279
|
+
error
|
|
280
|
+
});
|
|
281
|
+
}
|
|
249
282
|
});
|
|
250
283
|
}
|
|
251
284
|
/**
|
|
@@ -283,7 +316,7 @@ function gitRemote(options) {
|
|
|
283
316
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
284
317
|
};
|
|
285
318
|
}
|
|
286
|
-
}, async function* suggestRemote(dir, prefix) {
|
|
319
|
+
}, async function* suggestRemote(dir, prefix, _depth) {
|
|
287
320
|
try {
|
|
288
321
|
const remotes = await isomorphic_git.listRemotes({
|
|
289
322
|
fs: gitFs,
|
|
@@ -293,7 +326,13 @@ function gitRemote(options) {
|
|
|
293
326
|
kind: "literal",
|
|
294
327
|
text: r.remote
|
|
295
328
|
};
|
|
296
|
-
} catch {
|
|
329
|
+
} catch (error) {
|
|
330
|
+
logger.debug("Failed to list remotes for suggestions.", {
|
|
331
|
+
dir,
|
|
332
|
+
prefix,
|
|
333
|
+
error
|
|
334
|
+
});
|
|
335
|
+
}
|
|
297
336
|
});
|
|
298
337
|
}
|
|
299
338
|
/**
|
|
@@ -316,7 +355,7 @@ function gitCommit(options) {
|
|
|
316
355
|
};
|
|
317
356
|
return {
|
|
318
357
|
success: false,
|
|
319
|
-
error: __optique_core_message.message`Invalid commit SHA: ${(0, __optique_core_message.value)(input)}.
|
|
358
|
+
error: __optique_core_message.message`Invalid commit SHA: ${(0, __optique_core_message.value)(input)}. Provide an abbreviated (4+) or full (40) hexadecimal commit SHA.`
|
|
320
359
|
};
|
|
321
360
|
}
|
|
322
361
|
try {
|
|
@@ -329,7 +368,11 @@ function gitCommit(options) {
|
|
|
329
368
|
success: true,
|
|
330
369
|
value: oid
|
|
331
370
|
};
|
|
332
|
-
} catch {
|
|
371
|
+
} catch (e) {
|
|
372
|
+
if (hasErrorCode(e, "AmbiguousShortOidError")) return {
|
|
373
|
+
success: false,
|
|
374
|
+
error: __optique_core_message.message`Commit SHA ${(0, __optique_core_message.value)(input)} is ambiguous. Provide more characters to disambiguate.`
|
|
375
|
+
};
|
|
333
376
|
if (errors?.notFound) return {
|
|
334
377
|
success: false,
|
|
335
378
|
error: errors.notFound(input)
|
|
@@ -339,12 +382,12 @@ function gitCommit(options) {
|
|
|
339
382
|
error: __optique_core_message.message`Commit ${(0, __optique_core_message.value)(input)} does not exist. Provide a valid commit SHA.`
|
|
340
383
|
};
|
|
341
384
|
}
|
|
342
|
-
}, async function* suggestCommit(dir, prefix) {
|
|
385
|
+
}, async function* suggestCommit(dir, prefix, depth) {
|
|
343
386
|
try {
|
|
344
387
|
const commits = await isomorphic_git.log({
|
|
345
388
|
fs: gitFs,
|
|
346
389
|
dir,
|
|
347
|
-
depth
|
|
390
|
+
depth
|
|
348
391
|
});
|
|
349
392
|
for (const commit of commits) if (commit.oid.startsWith(prefix)) {
|
|
350
393
|
const shortOid = commit.oid.slice(0, 7);
|
|
@@ -355,7 +398,13 @@ function gitCommit(options) {
|
|
|
355
398
|
description: __optique_core_message.message`${firstLine}`
|
|
356
399
|
};
|
|
357
400
|
}
|
|
358
|
-
} catch {
|
|
401
|
+
} catch (error) {
|
|
402
|
+
logger.debug("Failed to list commits for suggestions.", {
|
|
403
|
+
dir,
|
|
404
|
+
prefix,
|
|
405
|
+
error
|
|
406
|
+
});
|
|
407
|
+
}
|
|
359
408
|
});
|
|
360
409
|
}
|
|
361
410
|
/**
|
|
@@ -393,7 +442,11 @@ function gitRef(options) {
|
|
|
393
442
|
success: true,
|
|
394
443
|
value: oid
|
|
395
444
|
};
|
|
396
|
-
} catch {
|
|
445
|
+
} catch (e) {
|
|
446
|
+
if (hasErrorCode(e, "AmbiguousShortOidError")) return {
|
|
447
|
+
success: false,
|
|
448
|
+
error: __optique_core_message.message`Reference ${(0, __optique_core_message.value)(input)} is ambiguous. Provide more characters to disambiguate.`
|
|
449
|
+
};
|
|
397
450
|
if (errors?.notFound) return {
|
|
398
451
|
success: false,
|
|
399
452
|
error: errors.notFound(input)
|
|
@@ -403,7 +456,7 @@ function gitRef(options) {
|
|
|
403
456
|
error: __optique_core_message.message`Reference ${(0, __optique_core_message.value)(input)} does not exist. Provide a valid branch, tag, or commit SHA.`
|
|
404
457
|
};
|
|
405
458
|
}
|
|
406
|
-
}, async function* suggestRef(dir, prefix) {
|
|
459
|
+
}, async function* suggestRef(dir, prefix, depth) {
|
|
407
460
|
try {
|
|
408
461
|
const [branches, tags, commits] = await Promise.all([
|
|
409
462
|
isomorphic_git.listBranches({
|
|
@@ -417,7 +470,7 @@ function gitRef(options) {
|
|
|
417
470
|
isomorphic_git.log({
|
|
418
471
|
fs: gitFs,
|
|
419
472
|
dir,
|
|
420
|
-
depth
|
|
473
|
+
depth
|
|
421
474
|
})
|
|
422
475
|
]);
|
|
423
476
|
for (const branch of branches) if (branch.startsWith(prefix)) yield {
|
|
@@ -437,7 +490,13 @@ function gitRef(options) {
|
|
|
437
490
|
description: __optique_core_message.message`${firstLine}`
|
|
438
491
|
};
|
|
439
492
|
}
|
|
440
|
-
} catch {
|
|
493
|
+
} catch (error) {
|
|
494
|
+
logger.debug("Failed to list refs for suggestions.", {
|
|
495
|
+
dir,
|
|
496
|
+
prefix,
|
|
497
|
+
error
|
|
498
|
+
});
|
|
499
|
+
}
|
|
441
500
|
});
|
|
442
501
|
}
|
|
443
502
|
/**
|
package/dist/index.d.cts
CHANGED
|
@@ -27,6 +27,14 @@ interface GitParserOptions {
|
|
|
27
27
|
* @since 0.9.0
|
|
28
28
|
*/
|
|
29
29
|
errors?: GitParserErrors;
|
|
30
|
+
/**
|
|
31
|
+
* Maximum number of recent commits to include in shell completion suggestions.
|
|
32
|
+
* Only applies to `gitCommit()` and `gitRef()` parsers.
|
|
33
|
+
* Defaults to 15.
|
|
34
|
+
*
|
|
35
|
+
* @since 0.9.0
|
|
36
|
+
*/
|
|
37
|
+
suggestionDepth?: number;
|
|
30
38
|
}
|
|
31
39
|
/**
|
|
32
40
|
* Custom error messages for git value parsers.
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,14 @@ interface GitParserOptions {
|
|
|
27
27
|
* @since 0.9.0
|
|
28
28
|
*/
|
|
29
29
|
errors?: GitParserErrors;
|
|
30
|
+
/**
|
|
31
|
+
* Maximum number of recent commits to include in shell completion suggestions.
|
|
32
|
+
* Only applies to `gitCommit()` and `gitRef()` parsers.
|
|
33
|
+
* Defaults to 15.
|
|
34
|
+
*
|
|
35
|
+
* @since 0.9.0
|
|
36
|
+
*/
|
|
37
|
+
suggestionDepth?: number;
|
|
30
38
|
}
|
|
31
39
|
/**
|
|
32
40
|
* Custom error messages for git value parsers.
|
package/dist/index.js
CHANGED
|
@@ -4,31 +4,40 @@ import * as git from "isomorphic-git";
|
|
|
4
4
|
import { expandOid, listBranches, listRemotes, listTags, readObject, resolveRef } from "isomorphic-git";
|
|
5
5
|
import * as fs from "node:fs/promises";
|
|
6
6
|
import process from "node:process";
|
|
7
|
+
import { getLogger } from "@logtape/logtape";
|
|
7
8
|
|
|
8
9
|
//#region src/index.ts
|
|
10
|
+
const logger = getLogger(["optique", "git"]);
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Read-only filesystem interface passed to isomorphic-git.
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* by our read-only operations.
|
|
14
|
+
* This package only performs read operations (validation and listing).
|
|
15
|
+
* Write methods are implemented as stubs that return rejected promises,
|
|
16
|
+
* enforcing the read-only contract and preventing accidental writes.
|
|
16
17
|
*/
|
|
17
18
|
const gitFs = {
|
|
18
19
|
readFile: fs.readFile,
|
|
19
|
-
writeFile:
|
|
20
|
-
mkdir:
|
|
21
|
-
rmdir:
|
|
22
|
-
unlink:
|
|
20
|
+
writeFile: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: writeFile is disabled.")),
|
|
21
|
+
mkdir: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: mkdir is disabled.")),
|
|
22
|
+
rmdir: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: rmdir is disabled.")),
|
|
23
|
+
unlink: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: unlink is disabled.")),
|
|
23
24
|
readdir: fs.readdir,
|
|
24
25
|
readlink: fs.readlink,
|
|
25
|
-
symlink:
|
|
26
|
+
symlink: () => Promise.reject(/* @__PURE__ */ new Error("gitFs is read-only: symlink is disabled.")),
|
|
26
27
|
stat: fs.stat,
|
|
27
28
|
lstat: fs.lstat
|
|
28
29
|
};
|
|
29
30
|
const METAVAR_BRANCH = "BRANCH";
|
|
30
31
|
const METAVAR_TAG = "TAG";
|
|
31
32
|
const METAVAR_REMOTE = "REMOTE";
|
|
33
|
+
/**
|
|
34
|
+
* Resolves the repository directory from the provided option or process.cwd().
|
|
35
|
+
*
|
|
36
|
+
* Note: This function does not validate that the directory exists or is
|
|
37
|
+
* accessible. Directory validation is deferred to the Git operations
|
|
38
|
+
* themselves, which will produce appropriate error messages if the directory
|
|
39
|
+
* is invalid or not a Git repository.
|
|
40
|
+
*/
|
|
32
41
|
function getRepoDir(dirOption) {
|
|
33
42
|
if (dirOption != null) return dirOption;
|
|
34
43
|
if (typeof process !== "undefined" && typeof process.cwd === "function") return process.cwd();
|
|
@@ -42,6 +51,8 @@ function listFailureMessage(error, dir, errors, fallback) {
|
|
|
42
51
|
if (hasErrorCode(error, "NotAGitRepositoryError") || hasErrorCode(error, "NotFoundError")) return message`${value(dir)} is not a git repository.`;
|
|
43
52
|
return fallback;
|
|
44
53
|
}
|
|
54
|
+
/** Default depth for commit suggestions. */
|
|
55
|
+
const DEFAULT_SUGGESTION_DEPTH = 15;
|
|
45
56
|
function createAsyncValueParser(options, metavar, parseFn, suggestFn) {
|
|
46
57
|
ensureNonEmptyString(metavar);
|
|
47
58
|
return {
|
|
@@ -56,7 +67,10 @@ function createAsyncValueParser(options, metavar, parseFn, suggestFn) {
|
|
|
56
67
|
},
|
|
57
68
|
async *suggest(prefix) {
|
|
58
69
|
const dir = getRepoDir(options?.dir);
|
|
59
|
-
if (suggestFn)
|
|
70
|
+
if (suggestFn) {
|
|
71
|
+
const depth = options?.suggestionDepth ?? DEFAULT_SUGGESTION_DEPTH;
|
|
72
|
+
yield* suggestFn(dir, prefix, depth);
|
|
73
|
+
}
|
|
60
74
|
}
|
|
61
75
|
};
|
|
62
76
|
}
|
|
@@ -105,7 +119,7 @@ function gitBranch(options) {
|
|
|
105
119
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
106
120
|
};
|
|
107
121
|
}
|
|
108
|
-
}, async function* suggestBranch(dir, prefix) {
|
|
122
|
+
}, async function* suggestBranch(dir, prefix, _depth) {
|
|
109
123
|
try {
|
|
110
124
|
const branches = await git.listBranches({
|
|
111
125
|
fs: gitFs,
|
|
@@ -115,7 +129,13 @@ function gitBranch(options) {
|
|
|
115
129
|
kind: "literal",
|
|
116
130
|
text: branch
|
|
117
131
|
};
|
|
118
|
-
} catch {
|
|
132
|
+
} catch (error) {
|
|
133
|
+
logger.debug("Failed to list branches for suggestions.", {
|
|
134
|
+
dir,
|
|
135
|
+
prefix,
|
|
136
|
+
error
|
|
137
|
+
});
|
|
138
|
+
}
|
|
119
139
|
});
|
|
120
140
|
}
|
|
121
141
|
/**
|
|
@@ -165,7 +185,7 @@ function gitRemoteBranch(remote, options) {
|
|
|
165
185
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
166
186
|
};
|
|
167
187
|
}
|
|
168
|
-
}, async function* suggestRemoteBranch(dir, prefix) {
|
|
188
|
+
}, async function* suggestRemoteBranch(dir, prefix, _depth) {
|
|
169
189
|
try {
|
|
170
190
|
const branches = await git.listBranches({
|
|
171
191
|
fs: gitFs,
|
|
@@ -176,7 +196,14 @@ function gitRemoteBranch(remote, options) {
|
|
|
176
196
|
kind: "literal",
|
|
177
197
|
text: branch
|
|
178
198
|
};
|
|
179
|
-
} catch {
|
|
199
|
+
} catch (error) {
|
|
200
|
+
logger.debug("Failed to list remote branches for suggestions.", {
|
|
201
|
+
dir,
|
|
202
|
+
remote,
|
|
203
|
+
prefix,
|
|
204
|
+
error
|
|
205
|
+
});
|
|
206
|
+
}
|
|
180
207
|
});
|
|
181
208
|
}
|
|
182
209
|
/**
|
|
@@ -213,7 +240,7 @@ function gitTag(options) {
|
|
|
213
240
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
214
241
|
};
|
|
215
242
|
}
|
|
216
|
-
}, async function* suggestTag(dir, prefix) {
|
|
243
|
+
}, async function* suggestTag(dir, prefix, _depth) {
|
|
217
244
|
try {
|
|
218
245
|
const tags = await git.listTags({
|
|
219
246
|
fs: gitFs,
|
|
@@ -223,7 +250,13 @@ function gitTag(options) {
|
|
|
223
250
|
kind: "literal",
|
|
224
251
|
text: tag
|
|
225
252
|
};
|
|
226
|
-
} catch {
|
|
253
|
+
} catch (error) {
|
|
254
|
+
logger.debug("Failed to list tags for suggestions.", {
|
|
255
|
+
dir,
|
|
256
|
+
prefix,
|
|
257
|
+
error
|
|
258
|
+
});
|
|
259
|
+
}
|
|
227
260
|
});
|
|
228
261
|
}
|
|
229
262
|
/**
|
|
@@ -261,7 +294,7 @@ function gitRemote(options) {
|
|
|
261
294
|
error: listFailureMessage(error, dir, errors, fallback)
|
|
262
295
|
};
|
|
263
296
|
}
|
|
264
|
-
}, async function* suggestRemote(dir, prefix) {
|
|
297
|
+
}, async function* suggestRemote(dir, prefix, _depth) {
|
|
265
298
|
try {
|
|
266
299
|
const remotes = await git.listRemotes({
|
|
267
300
|
fs: gitFs,
|
|
@@ -271,7 +304,13 @@ function gitRemote(options) {
|
|
|
271
304
|
kind: "literal",
|
|
272
305
|
text: r.remote
|
|
273
306
|
};
|
|
274
|
-
} catch {
|
|
307
|
+
} catch (error) {
|
|
308
|
+
logger.debug("Failed to list remotes for suggestions.", {
|
|
309
|
+
dir,
|
|
310
|
+
prefix,
|
|
311
|
+
error
|
|
312
|
+
});
|
|
313
|
+
}
|
|
275
314
|
});
|
|
276
315
|
}
|
|
277
316
|
/**
|
|
@@ -294,7 +333,7 @@ function gitCommit(options) {
|
|
|
294
333
|
};
|
|
295
334
|
return {
|
|
296
335
|
success: false,
|
|
297
|
-
error: message`Invalid commit SHA: ${value(input)}.
|
|
336
|
+
error: message`Invalid commit SHA: ${value(input)}. Provide an abbreviated (4+) or full (40) hexadecimal commit SHA.`
|
|
298
337
|
};
|
|
299
338
|
}
|
|
300
339
|
try {
|
|
@@ -307,7 +346,11 @@ function gitCommit(options) {
|
|
|
307
346
|
success: true,
|
|
308
347
|
value: oid
|
|
309
348
|
};
|
|
310
|
-
} catch {
|
|
349
|
+
} catch (e) {
|
|
350
|
+
if (hasErrorCode(e, "AmbiguousShortOidError")) return {
|
|
351
|
+
success: false,
|
|
352
|
+
error: message`Commit SHA ${value(input)} is ambiguous. Provide more characters to disambiguate.`
|
|
353
|
+
};
|
|
311
354
|
if (errors?.notFound) return {
|
|
312
355
|
success: false,
|
|
313
356
|
error: errors.notFound(input)
|
|
@@ -317,12 +360,12 @@ function gitCommit(options) {
|
|
|
317
360
|
error: message`Commit ${value(input)} does not exist. Provide a valid commit SHA.`
|
|
318
361
|
};
|
|
319
362
|
}
|
|
320
|
-
}, async function* suggestCommit(dir, prefix) {
|
|
363
|
+
}, async function* suggestCommit(dir, prefix, depth) {
|
|
321
364
|
try {
|
|
322
365
|
const commits = await git.log({
|
|
323
366
|
fs: gitFs,
|
|
324
367
|
dir,
|
|
325
|
-
depth
|
|
368
|
+
depth
|
|
326
369
|
});
|
|
327
370
|
for (const commit of commits) if (commit.oid.startsWith(prefix)) {
|
|
328
371
|
const shortOid = commit.oid.slice(0, 7);
|
|
@@ -333,7 +376,13 @@ function gitCommit(options) {
|
|
|
333
376
|
description: message`${firstLine}`
|
|
334
377
|
};
|
|
335
378
|
}
|
|
336
|
-
} catch {
|
|
379
|
+
} catch (error) {
|
|
380
|
+
logger.debug("Failed to list commits for suggestions.", {
|
|
381
|
+
dir,
|
|
382
|
+
prefix,
|
|
383
|
+
error
|
|
384
|
+
});
|
|
385
|
+
}
|
|
337
386
|
});
|
|
338
387
|
}
|
|
339
388
|
/**
|
|
@@ -371,7 +420,11 @@ function gitRef(options) {
|
|
|
371
420
|
success: true,
|
|
372
421
|
value: oid
|
|
373
422
|
};
|
|
374
|
-
} catch {
|
|
423
|
+
} catch (e) {
|
|
424
|
+
if (hasErrorCode(e, "AmbiguousShortOidError")) return {
|
|
425
|
+
success: false,
|
|
426
|
+
error: message`Reference ${value(input)} is ambiguous. Provide more characters to disambiguate.`
|
|
427
|
+
};
|
|
375
428
|
if (errors?.notFound) return {
|
|
376
429
|
success: false,
|
|
377
430
|
error: errors.notFound(input)
|
|
@@ -381,7 +434,7 @@ function gitRef(options) {
|
|
|
381
434
|
error: message`Reference ${value(input)} does not exist. Provide a valid branch, tag, or commit SHA.`
|
|
382
435
|
};
|
|
383
436
|
}
|
|
384
|
-
}, async function* suggestRef(dir, prefix) {
|
|
437
|
+
}, async function* suggestRef(dir, prefix, depth) {
|
|
385
438
|
try {
|
|
386
439
|
const [branches, tags, commits] = await Promise.all([
|
|
387
440
|
git.listBranches({
|
|
@@ -395,7 +448,7 @@ function gitRef(options) {
|
|
|
395
448
|
git.log({
|
|
396
449
|
fs: gitFs,
|
|
397
450
|
dir,
|
|
398
|
-
depth
|
|
451
|
+
depth
|
|
399
452
|
})
|
|
400
453
|
]);
|
|
401
454
|
for (const branch of branches) if (branch.startsWith(prefix)) yield {
|
|
@@ -415,7 +468,13 @@ function gitRef(options) {
|
|
|
415
468
|
description: message`${firstLine}`
|
|
416
469
|
};
|
|
417
470
|
}
|
|
418
|
-
} catch {
|
|
471
|
+
} catch (error) {
|
|
472
|
+
logger.debug("Failed to list refs for suggestions.", {
|
|
473
|
+
dir,
|
|
474
|
+
prefix,
|
|
475
|
+
error
|
|
476
|
+
});
|
|
477
|
+
}
|
|
419
478
|
});
|
|
420
479
|
}
|
|
421
480
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/git",
|
|
3
|
-
"version": "0.9.0-dev.
|
|
3
|
+
"version": "0.9.0-dev.270+b5894625",
|
|
4
4
|
"description": "Git value parsers for Optique",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -57,8 +57,9 @@
|
|
|
57
57
|
},
|
|
58
58
|
"sideEffects": false,
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"
|
|
61
|
-
"@optique/core": ""
|
|
60
|
+
"@logtape/logtape": "^1.2.2",
|
|
61
|
+
"@optique/core": "",
|
|
62
|
+
"isomorphic-git": "^1.36.1"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
65
|
"@types/node": "^20.19.9",
|