ensureFlutterLocalizationsDependencySafe function

bool ensureFlutterLocalizationsDependencySafe(
  1. String directoryPath
)

Enhanced version using yaml_edit for safer YAML manipulation Checks if flutter_localizations and intl dependencies exist in pubspec.yaml If not, adds them automatically using structured YAML editing

Implementation

bool ensureFlutterLocalizationsDependencySafe(String directoryPath) {
  try {
    // Find pubspec.yaml file using the existing function
    final pubspecFile = _findPubspecFile(directoryPath);

    if (pubspecFile == null) {
      print('\u001b[31mError: Could not find pubspec.yaml file\u001b[0m');
      print('\u001b[33mSearched in directory: $directoryPath\u001b[0m');
      return false;
    }

    print('\u001b[36mℹ️  Found pubspec.yaml at: ${pubspecFile.path}\u001b[0m');

    final content = pubspecFile.readAsStringSync();

    // Parse the YAML content to check existing dependencies
    final yamlDoc = loadYaml(content);

    // Check if dependencies section exists
    if (yamlDoc is! Map || !yamlDoc.containsKey('dependencies')) {
      print(
          '\u001b[31mError: Could not find dependencies section in pubspec.yaml\u001b[0m');
      return false;
    }

    final dependencies = yamlDoc['dependencies'] as Map<dynamic, dynamic>;

    // Check existing dependencies
    final hasFlutter = dependencies.containsKey('flutter');
    final hasFlutterLocalizations =
        dependencies.containsKey('flutter_localizations');
    final hasIntl = dependencies.containsKey('intl');

    // Check intl version if it exists
    String? intlVersion;
    if (hasIntl) {
      final intlDep = dependencies['intl'];
      if (intlDep is String) {
        final versionMatch =
            RegExp(r'[\^~]?(\d+\.\d+\.\d+)').firstMatch(intlDep);
        if (versionMatch != null) {
          intlVersion = versionMatch.group(1);
        }
      }
    }

    // Print current status
    print('\u001b[36mDependency status:\u001b[0m');
    print('\u001b[36m  flutter: ${hasFlutter ? "✓" : "✗"}\u001b[0m');
    print(
        '\u001b[36m  flutter_localizations: ${hasFlutterLocalizations ? "✓" : "✗"}\u001b[0m');
    print(
        '\u001b[36m  intl: ${hasIntl ? "✓" : "✗"}${intlVersion != null ? " (v$intlVersion)" : ""}\u001b[0m');

    bool needsWrite = false;

    // Create YAML editor for safe modifications
    final yamlEditor = YamlEditor(content);

    // Add flutter dependency if missing
    if (!hasFlutter) {
      yamlEditor.update(['dependencies', 'flutter'], {'sdk': 'flutter'});
      needsWrite = true;
      print('\u001b[32m✓ Added flutter SDK dependency\u001b[0m');
    }

    // Add flutter_localizations if missing
    if (!hasFlutterLocalizations) {
      yamlEditor.update(
          ['dependencies', 'flutter_localizations'], {'sdk': 'flutter'});
      needsWrite = true;
      print('\u001b[32m✓ Added flutter_localizations dependency\u001b[0m');
    }

    // Add or update intl dependency if missing or outdated
    bool needsIntlUpdate = !hasIntl;
    if (hasIntl && intlVersion != null) {
      // Parse version numbers for proper comparison - need at least 0.18.0
      final currentVersion = _parseVersion(intlVersion);
      final minVersion = _parseVersion('0.20.2');
      needsIntlUpdate = _compareVersions(currentVersion, minVersion) < 0;
    }

    if (needsIntlUpdate) {
      yamlEditor.update(['dependencies', 'intl'], '^0.20.2');
      needsWrite = true;
      print(
          '\u001b[32m✓ ${hasIntl ? "Updated" : "Added"} intl dependency to v0.20.2\u001b[0m');
    }

    if (needsWrite) {
      try {
        // Write the updated YAML content
        pubspecFile.writeAsStringSync(yamlEditor.toString());
        print(
            '\u001b[32m✓ Dependencies updated successfully using YAML editor in ${pubspecFile.path}\u001b[0m');
        print(
            '\u001b[36mℹ️  Run "flutter pub get" to update dependencies\u001b[0m');

        // Verify the write was successful by reading back and checking
        final verifyContent = pubspecFile.readAsStringSync();
        final hasIntlCheck = verifyContent.contains('intl:');
        final hasFlutterLocCheck =
            verifyContent.contains('flutter_localizations:');

        if (hasIntlCheck && hasFlutterLocCheck) {
          print(
              '\u001b[32m✓ Verified: Dependencies successfully written to file\u001b[0m');
        } else {
          print(
              '\u001b[33m⚠️  Warning: Dependencies may not have been written correctly\u001b[0m');
          print(
              '\u001b[33m   intl found: $hasIntlCheck, flutter_localizations found: $hasFlutterLocCheck\u001b[0m');
        }
      } catch (writeError) {
        print(
            '\u001b[31mError writing to pubspec.yaml with YAML editor: $writeError\u001b[0m');
        print('\u001b[33mFile path: ${pubspecFile.path}\u001b[0m');
        print('\u001b[36mℹ️  Falling back to string-based method...\u001b[0m');

        // Fallback to the original string-based method
        return ensureFlutterLocalizationsDependency(directoryPath);
      }
    } else {
      print(
          '\u001b[32m✓ All required dependencies are already present\u001b[0m');
    }

    return true;
  } catch (e) {
    print('\u001b[31mError adding dependencies with YAML editor: $e\u001b[0m');
    print('\u001b[33mDirectory: $directoryPath\u001b[0m');
    print('\u001b[36mℹ️  Falling back to string-based method...\u001b[0m');

    // Fallback to the original string-based method
    return ensureFlutterLocalizationsDependency(directoryPath);
  }
}