Skip to content

Commit 53d0f4f

Browse files
BlackHole1Copilot
andauthored
feat(install): support abort installing (#61)
Signed-off-by: Kevin Cui <bh@bugs.cc> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 4cbca43 commit 53d0f4f

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/cmd/install.test.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,50 @@ describe.sequential("install all", () => {
246246
"f-0.0.1/package.oo.yaml",
247247
]));
248248
});
249+
250+
it("should fail with cancel signal", async (ctx) => {
251+
const p = fixture("install_all");
252+
253+
// publish `remote_storage` to registry
254+
{
255+
const remoteStorage = path.join(p, "remote_storage");
256+
await Promise.all([
257+
publish(path.join(remoteStorage, "a-0.0.1"), ctx.registry.endpoint, "fake-token"),
258+
publish(path.join(remoteStorage, "b-0.0.1"), ctx.registry.endpoint, "fake-token"),
259+
publish(path.join(remoteStorage, "c-0.0.2"), ctx.registry.endpoint, "fake-token"),
260+
publish(path.join(remoteStorage, "d-0.0.1"), ctx.registry.endpoint, "fake-token"),
261+
publish(path.join(remoteStorage, "e-0.0.1"), ctx.registry.endpoint, "fake-token"),
262+
publish(path.join(remoteStorage, "e-0.0.2"), ctx.registry.endpoint, "fake-token"),
263+
publish(path.join(remoteStorage, "f-0.0.1"), ctx.registry.endpoint, "fake-token"),
264+
publish(path.join(remoteStorage, "e-0.0.3"), ctx.registry.endpoint, "fake-token"),
265+
]);
266+
}
267+
268+
// Copy `local_storage` to distDir
269+
const distDir = await tempDir();
270+
{
271+
const localStorage = path.join(p, "local_storage");
272+
await Promise.all([
273+
copyDir(path.join(localStorage, "c-0.0.1"), path.join(distDir, "c-0.0.1")),
274+
copyDir(path.join(localStorage, "e-0.0.1"), path.join(distDir, "e-0.0.1")),
275+
]);
276+
}
277+
278+
// Copy `entry` to workdir
279+
await copyDir(path.join(p, "entry"), ctx.workdir);
280+
281+
const controller = new AbortController();
282+
controller.abort();
283+
284+
await expect(install({
285+
all: true,
286+
token: "fake-token",
287+
workdir: ctx.workdir,
288+
distDir,
289+
registry: ctx.registry.endpoint,
290+
cancelSignal: controller.signal,
291+
})).rejects.toThrow("This operation was aborted");
292+
});
249293
});
250294

251295
describe.sequential("install deps", () => {
@@ -559,6 +603,49 @@ describe.sequential("install deps", () => {
559603
},
560604
});
561605
});
606+
607+
it("should fail with cancel signal", async (ctx) => {
608+
const p = fixture("install_deps");
609+
610+
// publish `remote_storage` to registry
611+
{
612+
const remoteStorage = path.join(p, "remote_storage");
613+
await Promise.all([
614+
publish(path.join(remoteStorage, "a-0.0.2"), ctx.registry.endpoint, "fake-token"),
615+
publish(path.join(remoteStorage, "b-0.0.1"), ctx.registry.endpoint, "fake-token"),
616+
publish(path.join(remoteStorage, "c-0.0.1"), ctx.registry.endpoint, "fake-token"),
617+
publish(path.join(remoteStorage, "d-0.0.1"), ctx.registry.endpoint, "fake-token"),
618+
]);
619+
await publish(path.join(remoteStorage, "b-0.0.2"), ctx.registry.endpoint, "fake-token");
620+
}
621+
622+
// Copy `local_storage` to distDir
623+
const distDir = await tempDir();
624+
{
625+
const localStorage = path.join(p, "local_storage");
626+
await copyDir(path.join(localStorage, "a-0.0.1"), path.join(distDir, "a-0.0.1"));
627+
}
628+
629+
// Copy `entry` to workdir
630+
await copyDir(path.join(p, "entry"), ctx.workdir);
631+
632+
const controller = new AbortController();
633+
controller.abort();
634+
635+
await expect(install({
636+
deps: [
637+
{ name: "a" },
638+
{ name: "b" },
639+
{ name: "c", version: "0.0.1" },
640+
],
641+
save: true,
642+
token: "fake-token",
643+
workdir: ctx.workdir,
644+
distDir,
645+
registry: ctx.registry.endpoint,
646+
cancelSignal: controller.signal,
647+
})).rejects.toThrow("This operation was aborted");
648+
});
562649
});
563650

564651
describe.sequential("unknown type", () => {

src/cmd/install.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515

1616
export interface InstallBasicOptions {
1717
distDir: string;
18+
19+
cancelSignal?: AbortSignal;
1820
}
1921

2022
export interface InstallAllOptions extends InstallBasicOptions {
@@ -170,6 +172,8 @@ export async function installPackage(options: InstallPackageOptions): Promise<In
170172
distDir: options.distDir,
171173
token: options.token,
172174
registry: options.registry,
175+
176+
cancelSignal: options.cancelSignal,
173177
});
174178

175179
return {
@@ -215,6 +219,8 @@ export async function installAll(options: InstallAllOptions): Promise<InstallAll
215219
distDir: options.distDir,
216220
token: options.token,
217221
registry: options.registry,
222+
223+
cancelSignal: options.cancelSignal,
218224
});
219225

220226
return {
@@ -231,6 +237,8 @@ interface _InstallOptions {
231237
alreadyInstalled: Deps;
232238
needInstall: Deps;
233239
registry: string;
240+
241+
cancelSignal?: AbortSignal;
234242
}
235243

236244
async function _install(options: _InstallOptions): Promise<InstallPackageResult["deps"]> {
@@ -242,6 +250,8 @@ async function _install(options: _InstallOptions): Promise<InstallPackageResult[
242250
env: env(options.registry),
243251
stdout: "inherit",
244252
stderr: "inherit",
253+
cancelSignal: options.cancelSignal,
254+
forceKillAfterDelay: 1000,
245255
})`npm install`;
246256

247257
const info = await transformNodeModules(temp);

0 commit comments

Comments
 (0)