import { $ } from "bun"; import type { Option } from "effect"; import { Array as FxArray, Console, Effect, Layer, ManagedRuntime, Order, pipe, Schema, ServiceMap } from "effect"; import type { UnknownError } from "effect/Cause"; import { readdir } from "node:fs/promises"; class PodmanError extends Schema.TaggedErrorClass()("PodmanError", { cause: Schema.Error, }) {} class FSError extends Schema.TaggedErrorClass()("FSError", { cause: Schema.Error, }) {} class Podman extends ServiceMap.Service< Podman, { launchContainers(): Effect.Effect; importLatestDbInWordPressContainer(exportPath: string): Effect.Effect; } >()("haikuatelier.fr/scripts/importe-dernier-export-bdd/Podman") { static readonly layer = Layer.effect( Podman, // oxlint-disable-next-line require-yield Effect.gen(function*() { const launchContainers = Effect.fn("launchContainers")(function*() { return yield* pipe( Effect.tryPromise(async () => $`podman compose up -d &> /dev/null`), Effect.map((shell: $.ShellOutput) => shell.text()), Effect.mapError((error: UnknownError) => new PodmanError({ cause: error })), ); }); const importLatestDbInWordPressContainer = Effect.fn("importLatestDbInWordPressContainer")(function*( exportPath: string, ) { return yield* pipe( Effect.tryPromise( async () => $`podman exec -it haikuatelier.fr-wordpress fish -c "cd web && wp --allow-root db import ${exportPath} > /dev/null"`, ), Effect.map((shell: $.ShellOutput) => shell.text()), Effect.mapError((error: UnknownError) => new PodmanError({ cause: error })), ); }); return Podman.of({ launchContainers, importLatestDbInWordPressContainer, }); }), ); } class FS extends ServiceMap.Service< FS, { getLatestDbExport(): Effect.Effect; } >()("haikuatelier.fr/scripts/importe-dernier-export-bdd/FS") { static readonly layer = Layer.effect( FS, // oxlint-disable-next-line require-yield Effect.gen(function*() { const getLatestDbExport = Effect.fn("getLatestDbExport")(function*() { return yield* pipe( Effect.tryPromise(async () => readdir(`./db`)), Effect.map((paths: ReadonlyArray) => FxArray.sort(paths, Order.String)), Effect.map((sortedPaths: ReadonlyArray) => FxArray.last(sortedPaths)), Effect.flatMap((path: Option.Option) => Effect.fromOption(path)), Effect.mapError(_ => new FSError({ cause: new Error("Aucun export de BDD n'est disponible.") })), ); }); return FS.of({ getLatestDbExport, }); }), ); } const mainLayer = Layer.mergeAll(Podman.layer, FS.layer); const runtime = ManagedRuntime.make(mainLayer); const program = Effect.fn("program")(function*() { yield* Podman.use(podman => podman.launchContainers()); yield* Console.log("Containers are launched."); const latestExportPath: string = pipe(yield* FS.use(fs => fs.getLatestDbExport()), path => `../db/${path}`); yield* Console.log(latestExportPath); yield* Podman.use(podman => podman.importLatestDbInWordPressContainer(latestExportPath)); yield* Console.log("Import done."); }); runtime.runFork(program().pipe(Effect.tapError(Console.error)));