exec method

  1. @override
Future<void> exec(
  1. ExecContext context
)
override

Run command.

The contents of katana.yaml and the arguments of the command are passed to context.

コマンドを実行します。

contextにkatana.yamlの内容やコマンドの引数が渡されます。

Implementation

@override
Future<void> exec(ExecContext context) async {
  final args = context.args;
  if (context.flavorContext?.explicit != true || args.length < 2) {
    error(example);
    return;
  }
  final values = <String, String>{};
  var apply = false;
  for (var i = 2; i < args.length; i++) {
    if (args[i] == "--apply" && !apply) {
      apply = true;
      continue;
    }
    if (args[i].startsWith("--flavor=")) {
      continue;
    }
    if (!{"--version", "--endpoint", "--user-id", "--flavor"}
            .contains(args[i]) ||
        i + 1 >= args.length ||
        values.containsKey(args[i])) {
      error("引数が不正です。");
      return;
    }
    values[args[i]] = args[++i];
  }
  final config =
      context.yaml.getAsMap("cloudflare").getAsMap("durable_object");
  final input = {
    "command": args[1],
    "root": Directory.current.path,
    "schemaPath": config.get("schema", "do/schema/schema.json"),
    "directory": config.get(
        "migrations", "do/migrations/${context.flavorContext!.flavor.name}"),
    "approvedPath":
        config.get("approved", "cloudflare/src/do_revisions.json"),
    "database": config.get("database", ""),
    "environment": context.flavorContext!.flavor.name,
    "version": values["--version"],
    "apply": apply,
    "endpoint": values["--endpoint"],
    "userId": values["--user-id"]
  };
  final process = await Process.start(
      context.yaml.getAsMap("bin").get("node", "node"),
      [
        "-e",
        '''const {runMigrate}=require("@mathrunet/masamune_cloudflare_do/dist/migrate.js");let s="";process.stdin.setEncoding("utf8");process.stdin.on("data",c=>s+=c);process.stdin.on("end",async()=>{try{console.log(JSON.stringify(await runMigrate(JSON.parse(s))));}catch(e){console.error(e.message);process.exitCode=1;}});'''
      ],
      workingDirectory: "cloudflare");
  final output = process.stdout.transform(utf8.decoder).join();
  final failure = process.stderr.transform(utf8.decoder).join();
  process.stdin.write(jsonEncode(input));
  await process.stdin.close();
  if (await process.exitCode != 0) {
    throw StateError(await failure);
  }
  label(await output);
}