1import * as Effect from "effect/Effect";
2import * as Option from "effect/Option";
3import { Command, Flag } from "effect/cli";
4
5import * as Provider from "../../Alchemist/routes/provider.ts";
6import { CliKit } from "../CliKit/CliKit.ts";
7
8import { awsCommand } from "./aws.ts";
9import { cloudflareCommand } from "./cloudflare.ts";
10import { setExitCode } from "./errors.ts";
11import { config, envFile, profile } from "./flags.ts";
12import { instrumentCommand } from "./instrument.ts";
13
14/** Optional repeatable filter for checking a subset of registered providers. */
15const checkedProviders = Flag.String("provider").pipe(
16 Flag.withDescription(
17 "Check only this provider (repeatable; defaults to every provider the stack registers)",
18 ),
19 Flag.atLeast(0),
20);
21
22const checkEnvCommand = Command.make(
23 "check-env",
24 { provider: checkedProviders, main: config, envFile, profile },
25 instrumentCommand("provider.check-env")(
26 Effect.fn(function* ({ provider: requested, main, envFile, profile }) {
27 const cli = yield* CliKit;
28 const result = yield* Provider.checkEnvironment({
29 entrypoint: main,
30 envFile: Option.getOrUndefined(envFile),
31 profile,
32 providers: requested,
33 });
34 for (const check of result.checks) {
35 if (check.status === "no-contract") {
36 yield* cli.output.info({
37 message: check.provider,
38 detail: "No CI environment contract",
39 });
40 } else if (check.status === "satisfied") {
41 yield* cli.output.success(check.provider);
42 } else {
43 yield* cli.output.error({
44 message: check.provider,
45 detail: `Missing: ${check.missing
46 .map(({ alternatives }) => alternatives.join(" | "))
47 .join(", ")}`,
48 });
49 }
50 }
51 if (!result.satisfied) yield* setExitCode(1);
52 }),
53 ),
54).pipe(
55 Command.withDescription(
56 "Verify the required environment variables for the stack's providers are set (CI preflight; exits 1 when any are missing)",
57 ),
58);
59
60export const providerCommand = Command.make("provider", {}).pipe(
61 Command.withDescription("Manage cloud provider prerequisites and utilities"),
62 Command.withSubcommands([checkEnvCommand, awsCommand, cloudflareCommand]),
63);