fetchBreakingChangeDetail method

Future<String?> fetchBreakingChangeDetail(
  1. String path
)

Fetch the full Markdown content for a specific breaking-change detail page.

path should be the relative path or slug of the page (e.g. "buttons", "deprecated-api-removed-after-v3-16"). The method attempts several URL patterns to locate the page.

Returns null if the page cannot be found.

Implementation

Future<String?> fetchBreakingChangeDetail(String path) async {
  final cacheKey = 'flutter_breaking_change_detail_$path';
  final cached = await _cache.get(cacheKey);
  if (cached != null) {
    return cached['content'] as String?;
  }

  // Normalise: strip leading slashes and `.md` extension so we can
  // rebuild the URL predictably.
  var slug = path
      .replaceAll(RegExp(r'^/+'), '')
      .replaceAll(RegExp(r'\.md$'), '');

  // Also strip the leading path prefix if the caller passed a full
  // relative path from the index.
  slug = slug
      .replaceFirst(RegExp(r'^release/breaking-changes/'), '')
      .replaceFirst(RegExp(r'^breaking-changes/'), '');

  // Try several URL patterns — the directory structure has shifted between
  // website repo versions.
  final candidates = [
    '$_breakingChangesDetailBase/$slug.md',
    '$_breakingChangesDetailBase/$slug/index.md',
    'https://rawgit.flutter-io.cn/flutter/website/main/'
        'src/release/breaking-changes/$slug.md',
  ];

  for (final url in candidates) {
    final content = await _fetchMarkdown(url);
    if (content != null) {
      await _cache.set(
        cacheKey,
        {'content': content},
        CacheManager.flutterDocsTtl,
      );
      return content;
    }
  }

  Logger.warn('Could not fetch breaking-change detail for "$path"');
  return null;
}