listRepoContents method
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 [];
}
}