| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // @effect-diagnostics nodeBuiltinImport:off |
| 2 | 2 | import { expect, it } from "@effect/vitest"; |
| 3 | 3 | import * as NodeFS from "node:fs"; |
| 4 | import * as NodeChildProcess from "node:child_process"; |
| 4 | 5 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 5 | 6 | import * as NodeOS from "node:os"; |
| 6 | 7 | import * as NodePath from "node:path"; |
| ... | ... | @@ -8,6 +9,7 @@ import { ProviderDriverKind, ProviderInstanceId, type ServerProvider } from "@t3 |
| 8 | 9 | import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; |
| 9 | 10 | import * as Crypto from "effect/Crypto"; |
| 10 | 11 | import * as Effect from "effect/Effect"; |
| 12 | import * as FileSystem from "effect/FileSystem"; |
| 11 | 13 | import { HttpClient } from "effect/unstable/http"; |
| 12 | 14 | import { |
| 13 | 15 | createProviderVersionAdvisory, |
| ... | ... | @@ -362,9 +364,9 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { |
| 362 | 364 | provider: driver("nativePackageTool"), |
| 363 | 365 | packageName: "@example/native-package-tool", |
| 364 | 366 | update: { |
| 365 | | command: "native-package-tool update", |
| 367 | command: `${nativePackageToolPath} update`, |
| 366 | 368 | |
| 367 | | executable: "native-package-tool", |
| 369 | executable: nativePackageToolPath, |
| 368 | 370 | |
| 369 | 371 | args: ["update"], |
| 370 | 372 | |
| ... | ... | @@ -399,9 +401,9 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { |
| 399 | 401 | provider: driver("scopedPackageTool"), |
| 400 | 402 | packageName: "@example/scoped-package-tool", |
| 401 | 403 | update: { |
| 402 | | command: "scoped-package-tool upgrade", |
| 404 | command: `${scopedPackageToolPath} upgrade`, |
| 403 | 405 | |
| 404 | | executable: "scoped-package-tool", |
| 406 | executable: scopedPackageToolPath, |
| 405 | 407 | |
| 406 | 408 | args: ["upgrade"], |
| 407 | 409 | |
| ... | ... | @@ -411,6 +413,50 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { |
| 411 | 413 | }), |
| 412 | 414 | ); |
| 413 | 415 | |
| 416 | it.effect.skipIf(windowsHost)("runs an explicit native updater outside PATH", () => |
| 417 | Effect.gen(function* () { |
| 418 | const fs = yield* FileSystem.FileSystem; |
| 419 | const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-native-update-" }); |
| 420 | const nativeBinDir = NodePath.join(tempDir, "with spaces", ".scoped-package-tool", "bin"); |
| 421 | yield* fs.makeDirectory(nativeBinDir, { recursive: true }); |
| 422 | const binaryPath = NodePath.join(nativeBinDir, "scoped-package-tool"); |
| 423 | yield* fs.writeFileString(binaryPath, "#!/bin/sh\nprintf '%s' \"$1\"\n"); |
| 424 | yield* fs.chmod(binaryPath, 0o755); |
| 425 | |
| 426 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect( |
| 427 | scopedPackageToolUpdate, |
| 428 | { binaryPath, env: { PATH: "" } }, |
| 429 | ); |
| 430 | const update = capabilities.update; |
| 431 | expect(update).not.toBeNull(); |
| 432 | if (!update) return; |
| 433 | const result = NodeChildProcess.spawnSync(update.executable, update.args, { |
| 434 | env: { PATH: "" }, |
| 435 | encoding: "utf8", |
| 436 | }); |
| 437 | expect(result.error).toBeUndefined(); |
| 438 | expect(result.status).toBe(0); |
| 439 | expect(result.stdout).toBe("upgrade"); |
| 440 | }).pipe(Effect.scoped), |
| 441 | ); |
| 442 | |
| 443 | it.each([ |
| 444 | "/Users/example/.local/bin/native-package-tool", |
| 445 | "C:\\Users\\Example User\\.local\\bin\\native-package-tool.exe", |
| 446 | ])("preserves a configured native executable path: %s", (binaryPath) => { |
| 447 | expect(nativePackageToolUpdate.resolve({ binaryPath }).update?.executable).toBe(binaryPath); |
| 448 | }); |
| 449 | |
| 450 | it("uses the resolved launcher when its symlink target identifies a native install", () => { |
| 451 | const launcher = "/custom tools/native-launcher"; |
| 452 | const capabilities = nativePackageToolUpdate.resolve({ |
| 453 | binaryPath: launcher, |
| 454 | resolvedCommandPath: launcher, |
| 455 | realCommandPath: "/Users/example/.local/bin/native-package-tool", |
| 456 | }); |
| 457 | expect(capabilities.update?.executable).toBe(launcher); |
| 458 | }); |
| 459 | |
| 414 | 460 | it("switches native-package-tool to Homebrew updates when the binary resolves through Homebrew", () => { |
| 415 | 461 | expect( |
| 416 | 462 | nativePackageToolUpdate.resolve({ |