run method
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;
}
}