-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Summary
Basically, I'd like to create a new package that provides dax/zx/zurk's template literal api, but return Effects instead of promises (as Effects have to be passed to a runtime, so they can be reused, thus it doesn't need to be a thunk). Probably use tinyexec under the hood.
This doesn't entail a cli; injecting globals; ponyfilling fetch(), glob(), which(),1 etc; reexporting node:path, node:os, fs-extra, minimist, etc; etc. If it can be written using @effect/platform or straight in the shell, we shouldn't depend on an npm package, especially if we take the route Dax took of using deno_task_shell to paper over Windows compatibility. I'll need to investigate if Git Bash or deno_task_shell is more capable. Presumably Git Bash, so deno_task_shell would be a (slower?) fallack.
I'll want to ensure I support setting env variables VAR=1 cmd (zx doesn't). I need to think about logging. I don't want to depend on stuff like picocolors or picospinner, but supporting logging stdout is necessary, and at that point, I might as well include Effect-compatible loggers.
API example:
import { $, Script } from "@lishaduck/effect-script"
import { Effect, Option } from "effect"
import { DenoContext, DenoRuntime } from "@effect/platform-deno"
const program = Effect.gen(function* () {
// Interpolate.
const binary = "deno";
const args = ["run", "filename.js", "hi there"];
const command = $`DEBUG=true ${binary} ${args}`.nothrow().quiet();
// ^? const command: $.Command = `DEBUG=true deno run filename.js "hi there"`
// `type Script.Command = { () => Script.Subprocess, command: string }`
// Start a run.
const subprocess = yield* command;
// ^? const run: Script.Subprocess = {...}
// Get info.
const output = yield* subprocess.text();
// ^? const output: Option.Option<string>
// Echo to stdout.
yield* echo`Result: ${Option.getOrNull(output)}`;
// Run a side-effect command. Can fail with Script.ScriptException.
yield* $`rm -rf .cache`() // Shorthand for `$.run(command)`
// ^? Effect<void, Script.ScriptException, Script.ScriptContext>
})
DenoRuntime.runMain(program.pipe(Effect.provide(DenoContext.layer)));Footnotes
-
I'll want to investigate support for a
preferLocalequivalent to make npx redundant. ↩