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 firebase = context.yaml.getAsMap("firebase");
  final project = firebase.get("project_id", "");
  final expected = _option(context.args, "--auth-project");
  final account = _option(context.args, "--auth-account");
  if (isLocalApply ||
      context.flavorContext?.explicit != true ||
      context.flavorContext?.flavor != KatanaFlavor.dev ||
      project.isEmpty ||
      project != expected ||
      !RegExp(r"^[a-z][a-z0-9-]{4,28}[a-z0-9]$").hasMatch(project) ||
      !firebase.getAsMap("authentication").get("enable", false) ||
      account == null ||
      account.isEmpty) {
    throw StateError(
        "Auth config requires explicit dev flavor, matching --auth-project, enabled authentication, and --auth-account; --local is unsupported.");
  }
  // Capture credential output without printing or persisting it.
  final credential = await Process.run("gcloud", [
    "auth",
    "print-access-token",
    "--account=$account",
  ]).timeout(const Duration(seconds: 30));
  if (credential.exitCode != 0 ||
      credential.stdout.toString().trim().isEmpty) {
    throw StateError("Could not obtain the selected account credential.");
  }
  final token = credential.stdout.toString().trim();
  final client = HttpClient()
    ..connectionTimeout = const Duration(seconds: 30);
  try {
    final result = await configureFirebaseAnonymousAuth(
      project: project,
      initialize: context.args.contains("--initialize-auth"),
      enableAnonymous: context.args.contains("--enable-anonymous"),
      request: (method, path, body) async {
        final uri = Uri.https(
            "identitytoolkit.googleapis.com",
            path,
            method == "PATCH"
                ? {"updateMask": "signIn.anonymous.enabled"}
                : null);
        final request = await client.openUrl(method, uri);
        request.headers.set(HttpHeaders.authorizationHeader, "Bearer $token");
        request.headers.set("x-goog-user-project", project);
        if (body != null) {
          request.headers.contentType = ContentType.json;
          request.write(jsonEncode(body));
        }
        final response = await request.close();
        final text = await utf8.decoder.bind(response).join();
        final decoded =
            text.trim().isEmpty ? <String, dynamic>{} : jsonDecode(text);
        return AuthConfigResponse(response.statusCode,
            decoded is Map ? Map<String, dynamic>.from(decoded) : {});
      },
    ).timeout(const Duration(seconds: 90));
    stdout.writeln(jsonEncode(result));
  } finally {
    client.close(force: true);
  }
}