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.toList();
  var backend = "tidb";
  final index = args.indexOf("--backend");
  if (index >= 0) {
    if (index + 1 >= args.length) {
      error(example);
      return;
    }
    backend = args[index + 1];
    args.removeRange(index, index + 2);
  }
  if (backend == "do") {
    await const DurableObjectMigrateCliCommand().exec(ExecContext(
        yaml: context.yaml,
        secrets: context.secrets,
        args: args,
        flavorContext: context.flavorContext));
    return;
  }
  if (backend == "tidb") {
    await const TidbMigrateCliCommand().exec(ExecContext(
        yaml: context.yaml,
        secrets: context.secrets,
        args: args,
        flavorContext: context.flavorContext));
    return;
  }
  if (backend != "d1" ||
      context.flavorContext?.explicit != true ||
      args.length < 2 ||
      !{"status", "diff", "generate", "apply", "mark"}.contains(args[1])) {
    error(example);
    return;
  }
  var apply = false;
  var local = false;
  String? version;
  for (var i = 2; i < args.length; i++) {
    if (args[i] == "--apply" && !apply) {
      apply = true;
    } else if (args[i] == "--local" && !local) {
      local = true;
    } else if (args[i] == "--version" &&
        version == null &&
        i + 1 < args.length) {
      version = args[++i];
    } else if (args[i] == "--flavor" && i + 1 < args.length) {
      i++;
    } else if (args[i].startsWith("--flavor=")) {
      continue;
    } else {
      error("不正または重複した引数です。");
      return;
    }
  }
  final config = context.yaml.getAsMap("cloudflare").getAsMap("d1");
  final input = {
    "command": args[1],
    "root": Directory.current.path,
    "schemaPath": config.get("schema", "d1/schema/schema.json"),
    "directory": config.get(
        "migrations", "d1/migrations/${context.flavorContext!.flavor.name}"),
    "target": {
      "accountId": config.get("account_id", ""),
      "databaseId": config.get("database_id", ""),
      "database": config.get("database", ""),
      "environment": context.flavorContext!.flavor.name
    },
    "version": version,
    "apply": apply,
    "local": local,
    "wrangler": context.yaml.getAsMap("bin").get("wrangler", "wrangler")
  };
  final process = await Process.start(
      context.yaml.getAsMap("bin").get("node", "node"),
      [
        "-e",
        '''
const {runMigrate} = require("@mathrunet/masamune_cloudflare_d1/dist/migrate.js");
let input="";process.stdin.setEncoding("utf8");process.stdin.on("data",c=>input+=c);
process.stdin.on("end",async()=>{try{console.log(JSON.stringify(await runMigrate(JSON.parse(input))));}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) {
    error((await failure).trim());
  } else {
    stdout.write(await output);
  }
}