run method

  1. @override
Future<int> run()
override

Runs this command.

The return value is wrapped in a Future if necessary and returned by CommandRunner.runCommand.

Implementation

@override
Future<int> run() async {
  final path = argResults!['path'] as String;
  final filePath = argResults!['file'] as String;
  final idField = argResults!['id-field'] as String?;
  final merge = argResults!['merge'] as bool;
  final apply = argResults!['apply'] as bool;
  final verbose = argResults!['verbose'] as bool;

  final result = OperationResult();

  try {
    stdout.writeln('Loading JSON from $filePath...');
    final json = await JsonValidator.loadJsonFile(filePath);
    final data = JsonValidator.validateObject(json, 'Root JSON');

    String documentPath;
    final pathValidation = PathValidator.validatePath(path);

    if (pathValidation.isDocument) {
      documentPath = path;
    } else {
      String? docId;
      if (idField != null && data.containsKey(idField)) {
        docId = data[idField]?.toString();
        if (docId == null || docId.isEmpty) {
          throw ValidationException(
            'ID field "$idField" is present but empty or null',
          );
        }
      }

      if (docId == null) {
        throw ValidationException(
          'Path is a collection path but no document ID provided. '
          'Either provide a document path or specify --id-field',
        );
      }

      documentPath = pathValidation.documentPath(docId);
    }

    stdout
      ..writeln('\n=== Operation Plan ===')
      ..writeln('Document: $documentPath')
      ..writeln('Mode: ${merge ? 'Merge' : 'Replace'}')
      ..writeln('Data: ${_summarizeData(data, verbose)}');

    if (!apply) {
      stdout
        ..writeln('\n⚠️  DRY RUN MODE - No changes will be made')
        ..writeln('Use --apply to execute the operation');
      return 0;
    }

    stdout.writeln('\nConnecting to Firestore...');
    final client = await FirestoreClient.fromEnvironment();

    stdout.writeln('Writing document...');
    await _writeDocument(
      client: client,
      path: documentPath,
      data: data,
      merge: merge,
      result: result,
    );

    result.printSummary(verbose: verbose);
    return result.hasErrors ? 1 : 0;
  } on Exception catch (e) {
    stderr.writeln('Error: $e');
    return 2;
  }
}