dsherret / dax

Cross-platform shell tools for Deno and Node.js inspired by zx.
MIT License
965 stars 33 forks source link

Strange issue when upgrading Deno #255

Open Hexagon opened 3 months ago

Hexagon commented 3 months ago

See this example checking deno version each 5th second

import { Cron } from "jsr:@hexagon/croner";
import { $ } from "jsr:@david/dax";

// Check deno version every fifth second
new Cron("*/5 * * * * *", async () => {
    try {
        const result = await $`deno --version`.text();
        console.log("Success!");
        console.log(result); // 1
    } catch (e) {
        console.error("Failure!");
        console.log(e);
    }
});

After changing deno version while the script is running, e.g. deno upgrade --version 1.41.2 or similar

➜  test2 deno run -A dax_test.ts
Success!
deno 1.41.3 (release, x86_64-unknown-linux-gnu)
v8 12.3.219.9
typescript 5.3.3
Success!
deno 1.41.3 (release, x86_64-unknown-linux-gnu)
v8 12.3.219.9
typescript 5.3.3
Failure!
NotFound: Failed to spawn '/home/user/.deno/bin/deno (deleted)': No such file or directory (os error 2)
    at spawnChildInner (ext:runtime/40_process.js:185:17)
    at spawnChild (ext:runtime/40_process.js:206:10)
    at Command.spawn (ext:runtime/40_process.js:474:12)
    at spawnCommand (https://jsr.io/@david/dax/0.39.2/src/runtimes/process.deno.ts:4:49)
    at executeCommandArgs (https://jsr.io/@david/dax/0.39.2/src/shell.ts:930:9)
    at eventLoopTick (ext:core/01_core.js:208:9)
    at async executeSimpleCommand (https://jsr.io/@david/dax/0.39.2/src/shell.ts:896:10)
    at async executeSequentialList (https://jsr.io/@david/dax/0.39.2/src/shell.ts:512:20)
    at async spawn (https://jsr.io/@david/dax/0.39.2/src/shell.ts:501:18)
    at async CommandChild.pipedStdoutBuffer (https://jsr.io/@david/dax/0.39.2/src/command.ts:730:18) {
  name: "NotFound",
  code: "ENOENT"
}
Failure!

And it does not recover unless restarting the main process

drewbitt commented 3 months ago

Does this also happen if you write this same script in e.g. bash?

Hexagon commented 3 months ago

No, the problem seems to be related to Deno.execPath()

This works (using Deno.Command behind the scenes, and ["deno", "--version"] as command):

import { Cron } from "jsr:@hexagon/croner";
import { spawn } from "jsr:@cross/utils";

// Check deno version every fifth second
new Cron("*/10 * * * * *", async () => {
    try {
        const result = await spawn(["deno","--version"]);
        console.log("Success!");
        console.log(result);
    } catch (e) {
        console.error("Failure!");
        console.log(e);
    }
});

... but this gives the said error (using [Deno.execPath(), "--version"] as command);

import { Cron } from "jsr:@hexagon/croner";
import { spawn } from "jsr:@cross/utils";

// Check deno version every fifth second
new Cron("*/10 * * * * *", async () => {
    try {
        const result = await spawn([Deno.execPath(),"--version"]);
        console.log("Success!");
        console.log(result);
    } catch (e) {
        console.error("Failure!");
        console.log(e);
    }
});

Could it be that dax uses Deno.execPath() internally, and Deno.execPath() somehow get changed to /home/user/.deno/bin/deno (deleted) when deno is upgraded?

Edit: Yep, just removing (deleted) from Deno.execPath() resolves the problem in my example. This works [Deno.execPath().replace(" (deleted)",""),"--version"].