Fixed `RepositoriesService.listContributorStats`
MODIFY
CHANGELOG.md
CHANGELOG.md
- Fix return type of `RepositoriesService.listContributors`.
- Fix return type of `RepositoriesService.createRelease`.
+- Fixed `RepositoriesService.listContributorStats`.
+ - Removed unsupported `limit` parameter.
+ - Removed flaky retry logic. Instead, `NotReady` is thrown, which can be used
+ to decide to retry at the call site.
+ - Made associated classes `ContributorStatistics` and
+ `ContributorWeekStatistics` immutable. Since these classes are only meant as
+ return values, we're not treating this as a breaking change.
## v4.0.1

MODIFY
lib/src/common.g.dart
lib/src/common.g.dart
@@ -346,3 +346,23 @@ Map<String, dynamic> _$LinksToJson(Links instance) => <String, dynamic>{
'git': instance.git?.toString(),
'html': instance.html?.toString()
};
+
+ContributorStatistics _$ContributorStatisticsFromJson(
+ Map<String, dynamic> json) {
+ return ContributorStatistics(
+ json['author'] == null
+ ? null
+ : User.fromJson(json['author'] as Map<String, dynamic>),
+ json['total'] as int,
+ (json['weeks'] as List)
+ ?.map((e) => e == null
+ ? null
+ : ContributorWeekStatistics.fromJson(e as Map<String, dynamic>))
+ ?.toList());
+}
+
+ContributorWeekStatistics _$ContributorWeekStatisticsFromJson(
+ Map<String, dynamic> json) {
+ return ContributorWeekStatistics(
+ json['w'] as int, json['a'] as int, json['d'] as int, json['c'] as int);
+}

MODIFY
lib/src/common/model/repos_stats.dart
lib/src/common/model/repos_stats.dart
part of github.common;
/// Model class for a contributor's statistics for a repository.
+@JsonSerializable(createToJson: false)
class ContributorStatistics {
/// The Author
- User author;
+ final User author;
/// Total Commits
- int total;
+ final int total;
/// Weekly Statistics
- List<ContributorWeekStatistics> weeks;
+ final List<ContributorWeekStatistics> weeks;
- static ContributorStatistics fromJSON(Map<String, dynamic> input) {
- if (input == null) return null;
+ ContributorStatistics(this.author, this.total, this.weeks);
- return new ContributorStatistics()
- ..author = User.fromJson(input['author'] as Map<String, dynamic>)
- ..total = input['total']
- ..weeks = (input['weeks'] as List<Map<String, dynamic>>)
- .map((it) => ContributorWeekStatistics.fromJSON(it));
- }
+ factory ContributorStatistics.fromJson(Map<String, dynamic> json) =>
+ _$ContributorStatisticsFromJson(json);
}
/// Model class to represent the number of additions, deletions and commits
/// a contributor made in a given week.
+@JsonSerializable(createToJson: false)
class ContributorWeekStatistics {
/// Beginning of the Week (As a Unix Timestamp)
- String start;
+ @JsonKey(name: 'w')
+ final int start;
/// Number of Additions
- int additions;
+ @JsonKey(name: 'a')
+ final int additions;
/// Number of Deletions
- int deletions;
+ @JsonKey(name: 'd')
+ final int deletions;
/// Number of Commits
- int commits;
+ @JsonKey(name: 'c')
+ final int commits;
- static ContributorWeekStatistics fromJSON(Map<String, dynamic> input) {
- if (input == null) return null;
+ ContributorWeekStatistics(
+ this.start, this.additions, this.deletions, this.commits);
- return new ContributorWeekStatistics()
- ..additions = input['a']
- ..deletions = input['d']
- ..commits = input['c']
- ..start = input['w'];
- }
+ factory ContributorWeekStatistics.fromJson(Map<String, dynamic> json) =>
+ _$ContributorWeekStatisticsFromJson(json);
+
+ String toString() =>
+ 'ContributorWeekStatistics(start: $start, commits: $commits, additions: $additions, deletions: $deletions)';
}
/// Model class for contributor participation.

MODIFY
lib/src/common/repos_service.dart
lib/src/common/repos_service.dart
@@ -533,29 +533,27 @@ class RepositoriesService extends Service {
/// Lists repository contributor statistics.
///
+ /// It's possible that this API will throw [NotReady] in which case you should
+ /// try the call again later.
+ ///
/// API docs: https://developer.github.com/v3/repos/statistics/#contributors
- Future<List<ContributorStatistics>> listContributorStats(RepositorySlug slug,
- {int limit: 30}) {
- var completer = new Completer<List<ContributorStatistics>>();
+ Future<List<ContributorStatistics>> listContributorStats(
+ RepositorySlug slug,
+ ) async {
var path = "/repos/${slug.fullName}/stats/contributors";
- var handle;
- handle = (json) {
- if (json is Map) {
- new Future.delayed(new Duration(milliseconds: 200), () {
- _github.getJSON(path,
- statusCode: 200,
- convert: handle,
- params: {"per_page": limit.toString()});
- });
+ var response = await _github.request('GET', path,
+ headers: {"Accept": "application/vnd.github.v3+json"});
+
+ if (response.statusCode == 200) {
+ return (jsonDecode(response.body) as List)
+ .map((e) => ContributorStatistics.fromJson(e))
+ .toList();
+ } else if (response.statusCode == 202) {
+ throw NotReady(_github, path);
+ }
+ _github.handleStatusCode(response);
+ // will never get here!
return null;
- } else {
- completer.complete(json.map(
- (Map<String, dynamic> it) => ContributorStatistics.fromJSON(it)));
- }
- };
- _github
- .getJSON(path, convert: handle, params: {"per_page": limit.toString()});
- return completer.future;
}
/// Fetches commit counts for the past year.

MODIFY
lib/src/common/util/errors.dart
lib/src/common/util/errors.dart
@@ -13,6 +13,11 @@ class GitHubError implements Exception {
String toString() => "GitHub Error: $message";
}
+class NotReady extends GitHubError {
+ NotReady(GitHub github, String path)
+ : super(github, 'Not ready. Try again later', apiUrl: path);
+}
+
/// GitHub Entity was not found
class NotFound extends GitHubError {
NotFound(GitHub github, String msg) : super(github, msg);

Fixed `RepositoriesService.listContributorStats`