dsh-gitbar-lite 0.1.0 → 0.1.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/README.en.md +1 -1
- package/README.md +1 -1
- package/docs/CONTRACT.md +17 -6
- package/lib/host/git.js +44 -14
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -189,7 +189,7 @@ are in [`docs/CONTRACT.md`](./docs/CONTRACT.md).
|
|
|
189
189
|
|
|
190
190
|
```sh
|
|
191
191
|
npm test # unit + real-git e2e + artifact self-check
|
|
192
|
-
npm run test:e2e # the real-git suite alone (
|
|
192
|
+
npm run test:e2e # the real-git suite alone (20 sections building their own fixtures, 241 assertions)
|
|
193
193
|
npm run check # artifact self-check alone (catches boot-breaking mistakes without restarting DSH)
|
|
194
194
|
npm run test:live # probe a running DSH (not part of npm test; needs the app running)
|
|
195
195
|
```
|
package/README.md
CHANGED
|
@@ -176,7 +176,7 @@ lib/client.js 浏览器半边:三个 tab 类型 + 面板/回收站/di
|
|
|
176
176
|
|
|
177
177
|
```sh
|
|
178
178
|
npm test # 单测 + 真 git 的 e2e + 产物自检
|
|
179
|
-
npm run test:e2e # 只跑真 git 的 e2e(
|
|
179
|
+
npm run test:e2e # 只跑真 git 的 e2e(20 个小节,各自造自己的夹具,241 项断言)
|
|
180
180
|
npm run check # 只用产物自检(不启 DSH 也能发现会让 DSH 起不来的问题)
|
|
181
181
|
npm run test:live # 探测一个正在运行的 DSH(不在 npm test 里,需要跑着应用)
|
|
182
182
|
```
|
package/docs/CONTRACT.md
CHANGED
|
@@ -326,7 +326,7 @@ this package on the next upgrade.
|
|
|
326
326
|
| state files, the binding key, corruption tolerance, write serialization | `test/store.test.mjs` |
|
|
327
327
|
| the route carrier, single registration under a hostile service order, error classification | `test/index.test.mjs` |
|
|
328
328
|
| every registration identity, the wire literals, the dictionaries, and the hook-free components' rendered trees | `test/client.test.mjs` |
|
|
329
|
-
| the whole host stack against **real git**, mutation by mutation | `test/e2e.mjs`,
|
|
329
|
+
| the whole host stack against **real git**, mutation by mutation | `test/e2e.mjs`, 241 assertions over 20 sections that build their own fixtures |
|
|
330
330
|
| the manifest, the patch layer, the tarball's contents, the two copies of the wire contract, the dictionaries, the workflow | `test/check.mjs` |
|
|
331
331
|
| that the client bundle would not abort the Host boot | `scripts/check-client-bundle.mjs` |
|
|
332
332
|
|
|
@@ -338,11 +338,22 @@ show the index claim rather than assume it.
|
|
|
338
338
|
|
|
339
339
|
- **`ctx.subprocess` is doubled in the tests.** The shipped service lives inside
|
|
340
340
|
DSH's own bundle and is not importable from a plugin repository, so
|
|
341
|
-
`test/helpers/subprocess.mjs` reproduces its
|
|
342
|
-
`
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
341
|
+
`test/helpers/subprocess.mjs` reproduces its shapes on top of
|
|
342
|
+
`node:child_process`. Those shapes are not guessed: the live contract was read
|
|
343
|
+
off a running DSH (Cordis Inspect, host provider `Service`, key `subprocess`)
|
|
344
|
+
and the double is pinned to it — including the part that is easy to get wrong,
|
|
345
|
+
that `spawn` **throws synchronously** for an already-aborted signal, or for an
|
|
346
|
+
argv/cwd/env/grace it rejects, instead of returning a handle. `S20` exists
|
|
347
|
+
because a caller that only `await`s the handle never sees that throw, and it
|
|
348
|
+
used to reach the route layer unclassified. What the double still does **not**
|
|
349
|
+
reproduce: Windows Job containment, the environment scrubbing, spill files
|
|
350
|
+
(`readFrom`'s `spillPath`), and the `control` duplex.
|
|
351
|
+
- **What the live run established.** The plugin loads into a running DSH and all
|
|
352
|
+
three right-sidebar seats register and are active — `dsh-gitbar-lite/git` and
|
|
353
|
+
`dsh-gitbar-lite/trash` (pages) and `dsh-gitbar-lite/diff` (resource) — read
|
|
354
|
+
off the live client slot tree at `sidebar.right.pane.tab`, next to the shipped
|
|
355
|
+
occupants. That is evidence about *mounting*; the behaviour claims are the e2e
|
|
356
|
+
suite's job, and the seam between them is the doubled `ctx.subprocess` above.
|
|
346
357
|
- **No headless-DOM render test.** The panel, the trash and the diff are driven
|
|
347
358
|
by hooks, and the three components with no hooks in them (the row, the
|
|
348
359
|
confirmation, the picker) *are* asserted on their element trees. What is not
|
package/lib/host/git.js
CHANGED
|
@@ -66,6 +66,23 @@ export class GitFailure extends Error {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Why a command ended without a verdict, when the reason was cancellation.
|
|
71
|
+
*
|
|
72
|
+
* Used for both ways a command can be cancelled — before the child exists (the
|
|
73
|
+
* provider refuses the spec synchronously) and after it starts — so that the two
|
|
74
|
+
* report the same sentence instead of one of them reading as an internal error.
|
|
75
|
+
*
|
|
76
|
+
* @param {AbortSignal | undefined} signal the combined signal handed to `spawn`
|
|
77
|
+
* @param {AbortSignal | undefined} timeout our own deadline, when one was set
|
|
78
|
+
* @param {number} timeoutMs that deadline in milliseconds, for the message
|
|
79
|
+
* @returns {string | undefined} the reason, or `undefined` when nothing aborted
|
|
80
|
+
*/
|
|
81
|
+
function abortReason(signal, timeout, timeoutMs) {
|
|
82
|
+
if (signal === undefined || !signal.aborted) return undefined
|
|
83
|
+
return timeout !== undefined && timeout.aborted ? `timed out after ${timeoutMs}ms` : 'was aborted'
|
|
84
|
+
}
|
|
85
|
+
|
|
69
86
|
/**
|
|
70
87
|
* Build the git runner for one plugin instance.
|
|
71
88
|
*
|
|
@@ -131,24 +148,37 @@ export function createGit(ctx, config) {
|
|
|
131
148
|
? timeout
|
|
132
149
|
: AbortSignal.any([options.signal, timeout])
|
|
133
150
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
let handle
|
|
152
|
+
try {
|
|
153
|
+
handle = ctx.subprocess.spawn({
|
|
154
|
+
argv: [executablePath, ...args],
|
|
155
|
+
cwd: options.cwd,
|
|
156
|
+
stdio: {
|
|
157
|
+
stdin: options.stdin === undefined ? 'ignore' : { data: options.stdin },
|
|
158
|
+
stdout: { maxBytes: options.maxBytes ?? DEFAULT_MAX_OUTPUT_BYTES },
|
|
159
|
+
stderr: { maxBytes: STDERR_TAIL_BYTES },
|
|
160
|
+
},
|
|
161
|
+
graceMs: TERMINATE_GRACE_MS,
|
|
162
|
+
...(signal === undefined ? {} : { signal }),
|
|
163
|
+
env: { ...GIT_ENV, ...(options.env ?? {}) },
|
|
164
|
+
})
|
|
165
|
+
} catch (error) {
|
|
166
|
+
// `spawn` refuses a spec it cannot honour *synchronously*: a signal that is
|
|
167
|
+
// already aborted, or a cwd/env/grace it considers invalid. Neither is a
|
|
168
|
+
// git verdict, and letting the throw escape would reach the route layer
|
|
169
|
+
// unclassified -- a generic internal error for a request that was simply
|
|
170
|
+
// abandoned. Report it the way the asynchronous abort below does.
|
|
171
|
+
throw new GitFailure(`git ${args[0] ?? ''}`.trim(), {
|
|
172
|
+
exitCode: null,
|
|
173
|
+
stdout: '',
|
|
174
|
+
stderr: abortReason(signal, timeout, timeoutMs) ?? String(error?.message ?? error),
|
|
175
|
+
})
|
|
176
|
+
}
|
|
146
177
|
|
|
147
178
|
const outcome = await handle.done
|
|
148
179
|
|
|
149
180
|
if (signal !== undefined && signal.aborted) {
|
|
150
|
-
|
|
151
|
-
throw new GitFailure(`git ${args[0] ?? ''}`.trim(), { exitCode: null, stdout: '', stderr: why })
|
|
181
|
+
throw new GitFailure(`git ${args[0] ?? ''}`.trim(), { exitCode: null, stdout: '', stderr: abortReason(signal, timeout, timeoutMs) })
|
|
152
182
|
}
|
|
153
183
|
|
|
154
184
|
const out = handle.collected.stdout?.readFrom(0) ?? { text: '', lossy: false }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-gitbar-lite",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A GitHub Desktop-style Git panel for DSH: changed files, tick-to-stage, Summary + Description, Commit and Commit and Push, discard-to-trash, and diff preview, in the built-in right sidebar.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|