diff --git a/apps/desktop/src/app/DesktopCliCommand.test.ts b/apps/desktop/src/app/DesktopCliCommand.test.ts index ebb32bda43ce..f6c38b5ecce1 100644 --- a/apps/desktop/src/app/DesktopCliCommand.test.ts +++ b/apps/desktop/src/app/DesktopCliCommand.test.ts @@ -147,6 +147,20 @@ it.layer(NodeServices.layer)("DesktopCliCommand", (it) => { }).pipe(Effect.scoped), ); + it.effect("removes its staging file when the launcher cannot be replaced", () => + Effect.gen(function* () { + const fs = yield* FileSystem.FileSystem; + const path = yield* Path.Path; + const home = yield* fs.makeTempDirectoryScoped(); + const command = yield* commandIn({ home }); + const launcher = path.join(home, ".t3", "bin", "t3"); + yield* fs.makeDirectory(path.join(launcher, "occupied"), { recursive: true }); + + expect((yield* Effect.flip(command.install)).message).toContain("Could not set up"); + expect(yield* fs.readDirectory(path.dirname(launcher))).toEqual(["t3"]); + }).pipe(Effect.scoped), + ); + it.effect("finds and removes a link left by a previous T3 home", () => Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; diff --git a/apps/desktop/src/app/DesktopCliShim.ts b/apps/desktop/src/app/DesktopCliShim.ts index 3d4b94abff46..f0f372425df1 100644 --- a/apps/desktop/src/app/DesktopCliShim.ts +++ b/apps/desktop/src/app/DesktopCliShim.ts @@ -148,8 +148,12 @@ export const install = Effect.gen(function* () { if (Option.getOrUndefined(existing) !== content) { yield* fs.makeDirectory(path.dirname(shimPath), { recursive: true }); const staging = `${shimPath}.${process.pid}.tmp`; - yield* fs.writeFileString(staging, content, { mode: 0o755 }); - yield* fs.rename(staging, shimPath); + yield* fs + .writeFileString(staging, content, { mode: 0o755 }) + .pipe( + Effect.andThen(fs.rename(staging, shimPath)), + Effect.ensuring(fs.remove(staging, { force: true }).pipe(Effect.ignore)), + ); yield* logInfo("installed t3 launcher", { shimPath }); } return Option.some(shimPath);