42 lines
1.7 KiB
TypeScript
42 lines
1.7 KiB
TypeScript
import { BunFile, YAML } from "bun";
|
|
import { Array, Console, Effect, Option, pipe, Record, Schema } from "effect";
|
|
import { type UnknownException } from "effect/Cause";
|
|
import { type ParseError } from "effect/ParseResult";
|
|
import { type ReadonlyRecord } from "effect/Record";
|
|
|
|
const COMPOSE_PATH = "compose.yaml";
|
|
|
|
const getServicesKey = (
|
|
yaml: ReadonlyRecord<string | symbol, any>,
|
|
): Option.Option<ReadonlyArray<string>> =>
|
|
pipe(
|
|
Record.get("services")(yaml),
|
|
Option.andThen(yaml => Record.keys(yaml)),
|
|
);
|
|
|
|
const getComposeYaml = <A, I, R>(
|
|
filePath: string,
|
|
schema: Schema.Schema<A, I, R>,
|
|
): Effect.Effect<A, UnknownException | ParseError, R> =>
|
|
pipe(
|
|
Effect.try(() => Bun.file(filePath)),
|
|
Effect.andThen((file: BunFile) => Effect.tryPromise(() => file.text())),
|
|
Effect.andThen((text: string) => Effect.try(() => YAML.parse(text))),
|
|
Effect.andThen((yaml: unknown) => Schema.decodeUnknown(schema)(yaml)),
|
|
);
|
|
|
|
const programEffect: Effect.Effect<ReadonlyArray<string>> = Effect.gen(function*() {
|
|
return yield* pipe(
|
|
// Récupère le contenu du fichier compose.yaml sous forme de Record.
|
|
getComposeYaml(COMPOSE_PATH, Schema.Record({ key: Schema.String, value: Schema.Unknown })),
|
|
// Récupère la clé des services.
|
|
Effect.andThen((yaml: ReadonlyRecord<string | symbol, unknown>) => getServicesKey(yaml)),
|
|
// Retire la clé de l'image WordPress.
|
|
Effect.andThen((keys: ReadonlyArray<string>) => Array.filter(keys, key => key !== "wordpress")),
|
|
Effect.orElseSucceed(() => [""]),
|
|
// Exécute la commande podman.
|
|
Effect.tap(services => Bun.spawn({ cmd: ["podman", "compose", "pull", ...services], timeout: 10000 })),
|
|
);
|
|
});
|
|
|
|
Effect.runFork(programEffect).pipe(Effect.tapErrorCause(Console.error));
|