| // Copyright 2019 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:convert' show json; |
| |
| import 'package:github/github.dart'; |
| import 'package:http/http.dart'; |
| |
| class GithubService { |
| const GithubService(this.github); |
| |
| final GitHub github; |
| |
| /// Lists commits of the provided repository [slug] and [branch]. When |
| /// [lastCommitTimestampMills] equals 0, it means a new release branch is |
| /// found and only the branched commit will be returned for now, though the |
| /// rare case that multiple commits exist. For other cases, it returns all |
| /// newer commits since [lastCommitTimestampMills]. |
| Future<List<RepositoryCommit>> listCommits( |
| RepositorySlug slug, String branch, int lastCommitTimestampMills) async { |
| ArgumentError.checkNotNull(slug); |
| final PaginationHelper paginationHelper = PaginationHelper(github); |
| |
| /// The [pages] defines the number of pages of returned http request |
| /// results. Return only one page when this is a new branch. Otherwise |
| /// it will return all commits prior to this release branch commit, |
| /// leading to heavy workload. |
| int pages; |
| if (lastCommitTimestampMills == 0) { |
| pages = 1; |
| } |
| |
| List<Map<String, dynamic>> commits = <Map<String, dynamic>>[]; |
| |
| /// [lastCommitTimestamp+1] excludes last commit itself. |
| /// Github api url: https://developer.github.com/v3/repos/commits/#list-commits |
| await for (Response response in paginationHelper.fetchStreamed( |
| 'GET', |
| '/repos/${slug.fullName}/commits', |
| params: <String, dynamic>{ |
| 'sha': branch, |
| 'since': |
| DateTime.fromMillisecondsSinceEpoch(lastCommitTimestampMills + 1) |
| .toUtc() |
| .toIso8601String(), |
| }, |
| pages: pages, |
| )) { |
| commits.addAll((json.decode(response.body) as List<dynamic>) |
| .cast<Map<String, dynamic>>()); |
| } |
| |
| /// When a release branch is first detected only the most recent commit would be needed. |
| /// |
| /// If for the worst case, a new release branch consists of a useful cherry pick commit |
| /// which should be considered as well, here is the todo. |
| // TODO(keyonghan): https://github.com/flutter/flutter/issues/59275 |
| if (lastCommitTimestampMills == 0) { |
| commits = commits.take(1).toList(); |
| } |
| |
| return commits.map((dynamic commit) { |
| return RepositoryCommit() |
| ..sha = commit['sha'] as String |
| ..author = (User() |
| ..login = commit['author']['login'] as String |
| ..avatarUrl = commit['author']['avatar_url'] as String) |
| ..commit = (GitCommit() |
| ..committer = (GitCommitUser( |
| commit['commit']['author']['name'] as String, |
| commit['commit']['author']['email'] as String, |
| DateTime.parse(commit['commit']['author']['date'] as String)))); |
| }).toList(); |
| } |
| |
| Future<List<PullRequest>> listPullRequests( |
| RepositorySlug slug, String branch) async { |
| ArgumentError.checkNotNull(slug); |
| final PaginationHelper paginationHelper = PaginationHelper(github); |
| |
| final List<Map<String, dynamic>> pullRequests = <Map<String, dynamic>>[]; |
| await for (Response response in paginationHelper.fetchStreamed( |
| 'GET', |
| '/repos/${slug.fullName}/pulls', |
| params: <String, dynamic>{ |
| 'base': branch, |
| 'direction': 'desc', |
| 'sort': 'created', |
| 'state': 'open', |
| }, |
| )) { |
| pullRequests.addAll((json.decode(response.body) as List<dynamic>) |
| .cast<Map<String, dynamic>>()); |
| } |
| |
| return pullRequests.map((dynamic commit) { |
| return PullRequest() |
| ..number = commit['number'] as int |
| ..head = (PullRequestHead()..sha = commit['head']['sha'] as String); |
| }).toList(); |
| } |
| } |