listRepoContents method

  1. @override
Future<List<String>> listRepoContents(
  1. String repo, {
  2. String? token,
})
override

Lists the available Mason bricks in a GitHub repository.

repo The GitHub repository URL or identifier. token Optional authentication token for private repositories.

Returns a list of brick names found in the repository.

Implementation

@override
Future<List<String>> listRepoContents(String repo, {String? token}) async {
  // TODO: Use the urls from the config file
  final repoInfo = _parseGitHubURL(repo);
  if (repoInfo == null) {
    print('error parsing github url');
    return [];
  }
  final url = Uri.parse(
    'https://api.github.com/repos/${repoInfo.owner}/${repoInfo.repo}/contents',
  );

  // 2. Define Request Headers
  final headers = {
    'Accept':
        'application/vnd.github.v3+json', // Recommended GitHub API version
    'User-Agent': 'Dart-GitHub-Client', // Required by GitHub API
    if (token != null)
      'Authorization':
          'Bearer $token', // For private repos or higher rate limits
  };

  try {
    // 3. Make the GET Request
    final response = await http.get(url, headers: headers);
    //TODO: Adapt this to scan for mason.yaml file and read contents
    if (response.statusCode == 200) {
      // 4. Parse the JSON Response
      final List<dynamic> contents = json.decode(response.body);

      // 1. Find the 'mason.yaml' file object
      final masonYamlItem = contents.firstWhere(
        (item) => item['name'] == 'mason.yaml' && item['type'] == 'file',
        orElse: () => null, // Returns null if not found
      );

      if (masonYamlItem != null) {
        final String? downloadUrl = masonYamlItem['download_url'];

        if (downloadUrl != null) {
          // 2. Fetch the raw content from the download URL
          final http.Response response = await http.get(
            Uri.parse(downloadUrl),
          );

          if (response.statusCode == 200) {
            final String yamlContent = response.body;

            // 3. Format/Parse the YAML content for use in Dart
            try {
              // Use loadYaml to parse the string into a Dart object (YamlMap)
              final YamlMap yamlMap = loadYaml(yamlContent) as YamlMap;

              // Convert the YamlMap to a standard Dart Map<String, dynamic>
              // for easier use in the rest of your Dart application.
              final Map<String, dynamic> dartMap = json.decode(
                json.encode(yamlMap),
              );

              if (dartMap.containsKey('bricks') && dartMap['bricks'] is Map) {
                // Cast the 'bricks' value to a Map<String, dynamic>
                final Map<String, dynamic> bricksMap =
                    dartMap['bricks'] as Map<String, dynamic>;

                // Get the keys (the brick names) and convert them to a list
                final List<String> brickNamesList = bricksMap.keys.toList();

                return brickNamesList;
              } else {
                print(
                  '❌ Error: The parsed map does not contain the expected "bricks" map.',
                );
                return [];
              }
            } catch (e) {
              print('❌ Error parsing YAML: $e');
              return [];
            }
          } else {
            print(
              '❌ Failed to download mason.yaml. Status code: ${response.statusCode}',
            );
            return [];
          }
        } else {
          print('❌ mason.yaml item did not contain a download_url.');
          return [];
        }
      } else {
        print(
          '❌ The file mason.yaml was not found in the repository contents.',
        );
        return [];
      }
    } else {
      print('Error: Failed to fetch repository contents.');
      print('Status Code: ${response.statusCode}');
      if (response.statusCode == 404) {
        print('Check if the owner and repository names are correct.');
      }
      if (response.statusCode == 403) {
        print('Rate limit exceeded or token permissions insufficient.');
      }
      return [];
    }
  } catch (e) {
    print('An exception occurred during the API call: $e');
    return [];
  }
}