From d5ac9e2509f429adce08f9ba3b65f8f5b5b3b427 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Tue, 14 Sep 2021 17:52:03 +0200 Subject: [PATCH 001/139] Don't add state query param twice --- lib/src/common/pulls_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index 0f317745..9ca050e4 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -32,7 +32,7 @@ class PullRequestsService extends Service { return PaginationHelper(github).objects( 'GET', - '/repos/${slug.fullName}/pulls?state=$state', + '/repos/${slug.fullName}/pulls', (dynamic i) => PullRequest.fromJson(i), pages: pages, params: params); From e631e50e4067ca96f0e471d00355e85e092149a8 Mon Sep 17 00:00:00 2001 From: keyonghan <54558023+keyonghan@users.noreply.github.com> Date: Thu, 16 Dec 2021 09:18:46 -0800 Subject: [PATCH 002/139] Add files field in Git commit comparison (#285) --- CHANGELOG.md | 3 +++ lib/src/common/model/repos.dart | 5 +++-- lib/src/common/model/repos.g.dart | 3 +++ pubspec.yaml | 2 +- test/src/mocks.mocks.dart | 1 - 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8822a493..0a4d48c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 8.3.0 +- Support `files` field in class `GitHubComparison` + ## 8.2.5 - no library code changes - Add auto pub publish on new releases diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index 6d9c5dda..f7140e13 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -12,9 +12,10 @@ class GitHubComparison { final int? aheadBy; final int? behindBy; final int? totalCommits; + final List? files; - GitHubComparison( - this.url, this.status, this.aheadBy, this.behindBy, this.totalCommits); + GitHubComparison(this.url, this.status, this.aheadBy, this.behindBy, + this.totalCommits, this.files); factory GitHubComparison.fromJson(Map json) => _$GitHubComparisonFromJson(json); diff --git a/lib/src/common/model/repos.g.dart b/lib/src/common/model/repos.g.dart index 9809a166..c3f9cec8 100644 --- a/lib/src/common/model/repos.g.dart +++ b/lib/src/common/model/repos.g.dart @@ -13,6 +13,9 @@ GitHubComparison _$GitHubComparisonFromJson(Map json) => json['ahead_by'] as int?, json['behind_by'] as int?, json['total_commits'] as int?, + (json['files'] as List?) + ?.map((e) => CommitFile.fromJson(e as Map)) + .toList(), ); Repository _$RepositoryFromJson(Map json) => Repository( diff --git a/pubspec.yaml b/pubspec.yaml index 3fdffd75..594ed886 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 8.2.5 +version: 8.3.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index f8647b26..3400efad 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -14,7 +14,6 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors -// ignore_for_file: unnecessary_overrides // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types From 038001e77d840cfc341244b093fa147d7eb046bc Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Fri, 17 Dec 2021 20:37:13 +0300 Subject: [PATCH 003/139] feat: update an issue comment --- lib/src/common/github.dart | 43 ++++++++++++++++++++++++++++++ lib/src/common/issues_service.dart | 13 ++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index f69288a6..b92749f0 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; import 'package:github/src/common/util/utils.dart'; import 'package:http/http.dart' as http; @@ -245,6 +246,48 @@ class GitHub { preview: preview, ); + /// Handles PATCH Requests that respond with JSON + /// + /// [path] can either be a path like '/repos' or a full url. + /// [statusCode] is the expected status code. If it is null, it is ignored. + /// If the status code that the response returns is not the status code you provide + /// then the [fail] function will be called with the HTTP Response. + /// + /// If you don't throw an error or break out somehow, it will go into some error checking + /// that throws exceptions when it finds a 404 or 401. If it doesn't find a general HTTP Status Code + /// for errors, it throws an Unknown Error. + /// + /// [headers] are HTTP Headers. If it doesn't exist, the 'Accept' and 'Authorization' headers are added. + /// [params] are query string parameters. + /// [convert] is a simple function that is passed this [GitHub] instance and a JSON object. + /// + /// The future will pass the object returned from this function to the then method. + /// The default [convert] function returns the input object. + /// [body] is the data to send to the server. Pass in a List if you want to post binary body data. Everything else will have .toString() called on it and set as text content + /// [S] represents the input type. + /// [T] represents the type return from this function after conversion + Future patchJSON( + String path, { + int? statusCode, + void Function(http.Response response)? fail, + Map? headers, + Map? params, + JSONConverter? convert, + dynamic body, + String? preview, + }) => + requestJson( + 'PATCH', + path, + statusCode: statusCode, + fail: fail, + headers: headers, + params: params, + convert: convert, + body: body, + preview: preview, + ); + Future requestJson( String method, String path, { diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index 448da36f..8fcc9a1a 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -251,7 +251,18 @@ class IssuesService extends Service { ); } - // TODO: Implement editComment: https://developer.github.com/v3/issues/comments/#edit-a-comment + /// Update an issue comment. + /// + /// API docs: https://docs.github.com/en/rest/reference/issues#update-an-issue-comment + Future updateComment(RepositorySlug slug, int id, String body) { + final it = GitHubJson.encode({'body': body}); + return github.postJSON( + '/repos/${slug.fullName}/issues/comments/$id', + body: it, + convert: (dynamic i) => IssueComment.fromJson(i), + statusCode: StatusCodes.OK, + ); + } /// Deletes an issue comment. /// From 3ef3fbda58c02a30d49571a641a9d7117987cda3 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 19 Dec 2021 13:04:29 -0700 Subject: [PATCH 004/139] prep 8.4.0 --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a4d48c0..8f2f7474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 8.4.0 +- added `updateComment` to update issue comments https://github.com/SpinlockLabs/github.dart/pull/286 + ## 8.3.0 - Support `files` field in class `GitHubComparison` diff --git a/pubspec.yaml b/pubspec.yaml index 594ed886..fa792e79 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 8.3.0 +version: 8.4.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 8d50289828816a323f1ac580d24d0140b39190f8 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 19 Dec 2021 13:16:48 -0700 Subject: [PATCH 005/139] require semver label on PRs --- .github/workflows/require_semver_label.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/require_semver_label.yml diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml new file mode 100644 index 00000000..5de414a6 --- /dev/null +++ b/.github/workflows/require_semver_label.yml @@ -0,0 +1,13 @@ +name: Require Semver Pull Request Label +on: + pull_request: + types: [opened, labeled, unlabeled, synchronize] +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: mheap/github-action-required-labels@v1 + with: + mode: exactly + count: 1 + labels: "semver:patch, semver:minor, semver:major" \ No newline at end of file From a8e59521e910b8978d5ec7f0b15c9a9599ffce50 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 23 Dec 2021 16:42:48 -0700 Subject: [PATCH 006/139] Fixes --- lib/src/common/model/pulls.dart | 44 +++++++++++++++++++++++++ lib/src/common/model/pulls.g.dart | 53 ++++++++++++++++++++++++++++++- lib/src/common/orgs_service.dart | 8 +++++ lib/src/common/pulls_service.dart | 22 +++++++++++++ test/src/mocks.mocks.dart | 25 +++++++++++++-- 5 files changed, 149 insertions(+), 3 deletions(-) diff --git a/lib/src/common/model/pulls.dart b/lib/src/common/model/pulls.dart index 31a6014d..456e5a39 100644 --- a/lib/src/common/model/pulls.dart +++ b/lib/src/common/model/pulls.dart @@ -143,6 +143,8 @@ class PullRequest { /// Ex: CONTRIBUTOR, NONE, OWNER String? authorAssociation; + Repository? repo; + factory PullRequest.fromJson(Map input) => _$PullRequestFromJson(input); Map toJson() => _$PullRequestToJson(this); @@ -297,3 +299,45 @@ class PullRequestFile { _$PullRequestFileFromJson(input); Map toJson() => _$PullRequestFileToJson(this); } + +@JsonSerializable() +class PullRequestReview { + PullRequestReview( + {required this.id, + required this.user, + this.body, + this.state, + this.htmlUrl, + this.pullRequestUrl}); + int id; + User user; + String? body; + String? state; + String? htmlUrl; + String? pullRequestUrl; + DateTime? submittedAt; + String? authorAssociation; + String? commitId; + + factory PullRequestReview.fromJson(Map input) => + _$PullRequestReviewFromJson(input); + Map toJson() => _$PullRequestReviewToJson(this); +} + +@JsonSerializable() +class CreatePullRequestReview { + CreatePullRequestReview(this.owner, this.repo, this.pullNumber, this.event, + {this.body}); + + String owner; + String repo; + String event; + String? body; + int pullNumber; + // TODO List comments; + + factory CreatePullRequestReview.fromJson(Map input) => + _$CreatePullRequestReviewFromJson(input); + Map toJson() => _$CreatePullRequestReviewToJson(this); +} +// TODO PullRequestReviewComment https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request diff --git a/lib/src/common/model/pulls.g.dart b/lib/src/common/model/pulls.g.dart index 359911f0..62d2bba6 100644 --- a/lib/src/common/model/pulls.g.dart +++ b/lib/src/common/model/pulls.g.dart @@ -62,7 +62,9 @@ PullRequest _$PullRequestFromJson(Map json) => PullRequest( mergeableState: json['mergeable_state'] as String? ?? '', maintainerCanModify: json['maintainer_can_modify'] as bool? ?? false, authorAssociation: json['author_association'] as String? ?? '', - ); + )..repo = json['repo'] == null + ? null + : Repository.fromJson(json['repo'] as Map); Map _$PullRequestToJson(PullRequest instance) => { @@ -99,6 +101,7 @@ Map _$PullRequestToJson(PullRequest instance) => 'mergeable_state': instance.mergeableState, 'maintainer_can_modify': instance.maintainerCanModify, 'author_association': instance.authorAssociation, + 'repo': instance.repo, }; PullRequestMerge _$PullRequestMergeFromJson(Map json) => @@ -244,3 +247,51 @@ Map _$PullRequestFileToJson(PullRequestFile instance) => 'contents_url': instance.contentsUrl, 'patch': instance.patch, }; + +PullRequestReview _$PullRequestReviewFromJson(Map json) => + PullRequestReview( + id: json['id'] as int, + user: User.fromJson(json['user'] as Map), + body: json['body'] as String?, + state: json['state'] as String?, + htmlUrl: json['html_url'] as String?, + pullRequestUrl: json['pull_request_url'] as String?, + ) + ..submittedAt = json['submitted_at'] == null + ? null + : DateTime.parse(json['submitted_at'] as String) + ..authorAssociation = json['author_association'] as String? + ..commitId = json['commit_id'] as String?; + +Map _$PullRequestReviewToJson(PullRequestReview instance) => + { + 'id': instance.id, + 'user': instance.user, + 'body': instance.body, + 'state': instance.state, + 'html_url': instance.htmlUrl, + 'pull_request_url': instance.pullRequestUrl, + 'submitted_at': instance.submittedAt?.toIso8601String(), + 'author_association': instance.authorAssociation, + 'commit_id': instance.commitId, + }; + +CreatePullRequestReview _$CreatePullRequestReviewFromJson( + Map json) => + CreatePullRequestReview( + json['owner'] as String, + json['repo'] as String, + json['pull_number'] as int, + json['event'] as String, + body: json['body'] as String?, + ); + +Map _$CreatePullRequestReviewToJson( + CreatePullRequestReview instance) => + { + 'owner': instance.owner, + 'repo': instance.repo, + 'event': instance.event, + 'body': instance.body, + 'pull_number': instance.pullNumber, + }; diff --git a/lib/src/common/orgs_service.dart b/lib/src/common/orgs_service.dart index 86ebc0b6..a8a54b25 100644 --- a/lib/src/common/orgs_service.dart +++ b/lib/src/common/orgs_service.dart @@ -238,6 +238,14 @@ class OrganizationsService extends Service { .objects('GET', '/user/teams', (dynamic i) => Team.fromJson(i)); } + /// Lists all of the users in an organization + /// + /// API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams + Stream listUsers(String org) { + return PaginationHelper(github) + .objects('GET', '/orgs/$org/members', (dynamic i) => User.fromJson(i)); + } + /// Lists the hooks for the specified organization. /// /// API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index 0f317745..01f51722 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -100,6 +100,16 @@ class PullRequestsService extends Service { (dynamic i) => PullRequestFile.fromJson(i)); } + /// Lists the reviews for a pull request. + /// + /// API docs: https://docs.github.com/en/rest/reference/pulls#list-reviews-for-a-pull-request + Stream listReviews(RepositorySlug slug, int number) { + return PaginationHelper(github).objects( + 'GET', + '/repos/${slug.fullName}/pulls/$number/reviews', + (dynamic i) => PullRequestReview.fromJson(i)); + } + Future isMerged(RepositorySlug slug, int number) { return github .request('GET', '/repos/${slug.fullName}/pulls/$number/merge') @@ -165,4 +175,16 @@ class PullRequestsService extends Service { // TODO: Implement editComment: https://developer.github.com/v3/pulls/comments/#edit-a-comment // TODO: Implement deleteComment: https://developer.github.com/v3/pulls/comments/#delete-a-comment + + /// Creates a new pull request comment. + /// + /// API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment + Future createReview( + RepositorySlug slug, CreatePullRequestReview review) { + return github.postJSON( + '/repos/${slug.fullName}/pulls/${review.pullNumber}/reviews', + body: GitHubJson.encode(review), + convert: (dynamic i) => PullRequestReview.fromJson(i)) + as Future; + } } diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index 3400efad..6a673895 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.0.16 from annotations +// Mocks generated by Mockito 5.0.15 from annotations // in github/test/src/mocks.dart. // Do not manually edit this file. @@ -15,7 +15,6 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors // ignore_for_file: unnecessary_parenthesis -// ignore_for_file: camel_case_types class _FakeClient_0 extends _i1.Fake implements _i2.Client {} @@ -185,6 +184,28 @@ class MockGitHub extends _i1.Mock implements _i3.GitHub { }), returnValue: Future.value(null)) as _i4.Future); @override + _i4.Future patchJSON(String? path, + {int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview}) => + (super.noSuchMethod( + Invocation.method(#patchJSON, [ + path + ], { + #statusCode: statusCode, + #fail: fail, + #headers: headers, + #params: params, + #convert: convert, + #body: body, + #preview: preview + }), + returnValue: Future.value(null)) as _i4.Future); + @override _i4.Future requestJson(String? method, String? path, {int? statusCode, void Function(_i2.Response)? fail, From b9665927cf1e597e9b8f6a9c2ea6193b0d09cb79 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 23 Dec 2021 16:52:59 -0700 Subject: [PATCH 007/139] renamed Dart CI --- .github/workflows/dart.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 250e2000..0a4012c0 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -1,4 +1,4 @@ -name: Dart CI +name: Dart Checks (analyze,format,publishable) on: [push] From d4325c1fe9b2a1db26c0595283d6042d1e6a48e7 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 23 Dec 2021 17:14:29 -0700 Subject: [PATCH 008/139] auto prep 8.5.0 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f2f7474..fd6470b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 8.5.0 + +* Adds listing and creating PR Reviews, listing users in an org by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/287 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/8.4.0...8.5.0 + ## 8.4.0 - added `updateComment` to update issue comments https://github.com/SpinlockLabs/github.dart/pull/286 diff --git a/pubspec.yaml b/pubspec.yaml index fa792e79..8dba5227 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 8.4.0 +version: 8.5.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 0a1db651bc28f6c1f735b210619be75bceb617dd Mon Sep 17 00:00:00 2001 From: Scott Horn Date: Mon, 3 Jan 2022 08:48:43 +0100 Subject: [PATCH 009/139] Added assignees to Issue model --- lib/src/common/model/issues.dart | 6 ++++++ lib/src/common/model/issues.g.dart | 8 ++++++++ pubspec.yaml | 2 +- test/src/mocks.mocks.dart | 5 ++--- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/src/common/model/issues.dart b/lib/src/common/model/issues.dart index 4138e9d4..4a86f62b 100644 --- a/lib/src/common/model/issues.dart +++ b/lib/src/common/model/issues.dart @@ -17,6 +17,7 @@ class Issue { this.user, List? labels, this.assignee, + this.assignees, this.milestone, this.commentsCount = 0, this.pullRequest, @@ -58,6 +59,9 @@ class Issue { /// The User that the issue is assigned to User? assignee; + /// The User that the issue is assigned to + List? assignees; + /// The Milestone Milestone? milestone; @@ -97,12 +101,14 @@ class IssueRequest { this.body, this.labels, this.assignee, + this.assignees, this.state, this.milestone}); String? title; String? body; List? labels; String? assignee; + List? assignees; String? state; int? milestone; diff --git a/lib/src/common/model/issues.g.dart b/lib/src/common/model/issues.g.dart index 30f1048a..0b6b8a3f 100644 --- a/lib/src/common/model/issues.g.dart +++ b/lib/src/common/model/issues.g.dart @@ -23,6 +23,9 @@ Issue _$IssueFromJson(Map json) => Issue( assignee: json['assignee'] == null ? null : User.fromJson(json['assignee'] as Map), + assignees: (json['assignees'] as List?) + ?.map((e) => User.fromJson(e as Map)) + .toList(), milestone: json['milestone'] == null ? null : Milestone.fromJson(json['milestone'] as Map), @@ -56,6 +59,7 @@ Map _$IssueToJson(Issue instance) => { 'user': instance.user, 'labels': instance.labels, 'assignee': instance.assignee, + 'assignees': instance.assignees, 'milestone': instance.milestone, 'comments': instance.commentsCount, 'pull_request': instance.pullRequest, @@ -72,6 +76,9 @@ IssueRequest _$IssueRequestFromJson(Map json) => IssueRequest( labels: (json['labels'] as List?)?.map((e) => e as String).toList(), assignee: json['assignee'] as String?, + assignees: (json['assignees'] as List?) + ?.map((e) => e as String) + .toList(), state: json['state'] as String?, milestone: json['milestone'] as int?, ); @@ -82,6 +89,7 @@ Map _$IssueRequestToJson(IssueRequest instance) => 'body': instance.body, 'labels': instance.labels, 'assignee': instance.assignee, + 'assignees': instance.assignees, 'state': instance.state, 'milestone': instance.milestone, }; diff --git a/pubspec.yaml b/pubspec.yaml index 8dba5227..19575c71 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: collection: ^1.15.0 http: ^0.13.0 http_parser: ^4.0.0 - json_annotation: ^4.3.0 + json_annotation: ^4.4.0 meta: ^1.3.0 dev_dependencies: diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index 6a673895..0b3d8735 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.0.15 from annotations +// Mocks generated by Mockito 5.0.17 from annotations // in github/test/src/mocks.dart. // Do not manually edit this file. @@ -15,6 +15,7 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors // ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types class _FakeClient_0 extends _i1.Fake implements _i2.Client {} @@ -257,6 +258,4 @@ class MockGitHub extends _i1.Mock implements _i3.GitHub { @override void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), returnValueForMissingStub: null); - @override - String toString() => super.toString(); } From 2710c7f5b623b321ef4a9ac38243ffbe364344d0 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Fri, 7 Jan 2022 08:44:35 -0600 Subject: [PATCH 010/139] Fix getting gists --- lib/src/common/model/gists.dart | 18 ++++---- lib/src/common/model/gists.g.dart | 50 +++++++++++++++++++++-- lib/src/common/model/misc.dart | 3 +- lib/src/common/model/misc.g.dart | 6 +++ lib/src/common/model/notifications.dart | 6 ++- lib/src/common/model/notifications.g.dart | 22 ++++++++++ lib/src/common/model/orgs.dart | 9 ++-- lib/src/common/model/orgs.g.dart | 26 ++++++++++++ lib/src/common/model/repos.dart | 10 ++--- lib/src/common/model/repos.g.dart | 17 ++++++++ lib/src/common/model/search.dart | 10 +++-- lib/src/common/model/search.g.dart | 18 ++++++++ lib/src/common/model/users.dart | 5 +-- lib/src/common/model/users.g.dart | 10 +++++ 14 files changed, 179 insertions(+), 31 deletions(-) diff --git a/lib/src/common/model/gists.dart b/lib/src/common/model/gists.dart index dc225eb4..cd89deac 100644 --- a/lib/src/common/model/gists.dart +++ b/lib/src/common/model/gists.dart @@ -5,7 +5,7 @@ import 'package:json_annotation/json_annotation.dart'; part 'gists.g.dart'; /// Model class for gists. -@JsonSerializable(createToJson: false) +@JsonSerializable() class Gist { Gist({ this.id, @@ -26,7 +26,7 @@ class Gist { bool? public; User? owner; User? user; - List? files; + Map? files; @JsonKey(name: 'html_url') String? htmlUrl; @@ -50,10 +50,10 @@ class Gist { } /// Model class for a gist file. -@JsonSerializable(createToJson: false) +@JsonSerializable() class GistFile { GistFile({ - this.name, + this.filename, this.size, this.rawUrl, this.type, @@ -61,10 +61,9 @@ class GistFile { this.truncated, this.content, }); - String? name; - int? size; - @JsonKey(name: 'raw_url') + String? filename; + int? size; String? rawUrl; String? type; String? language; @@ -73,10 +72,11 @@ class GistFile { factory GistFile.fromJson(Map input) => _$GistFileFromJson(input); + Map toJson() => _$GistFileToJson(this); } /// Model class for a gist fork. -@JsonSerializable(createToJson: false) +@JsonSerializable() class GistFork { GistFork({this.user, this.id, this.createdAt, this.updatedAt}); User? user; @@ -93,7 +93,7 @@ class GistFork { } /// Model class for a gits history entry. -@JsonSerializable(createToJson: false) +@JsonSerializable() class GistHistoryEntry { GistHistoryEntry({ this.version, diff --git a/lib/src/common/model/gists.g.dart b/lib/src/common/model/gists.g.dart index 15f648b0..e1d6db23 100644 --- a/lib/src/common/model/gists.g.dart +++ b/lib/src/common/model/gists.g.dart @@ -16,9 +16,9 @@ Gist _$GistFromJson(Map json) => Gist( user: json['user'] == null ? null : User.fromJson(json['user'] as Map), - files: (json['files'] as List?) - ?.map((e) => GistFile.fromJson(e as Map)) - .toList(), + files: (json['files'] as Map?)?.map( + (k, e) => MapEntry(k, GistFile.fromJson(e as Map)), + ), htmlUrl: json['html_url'] as String?, commentsCount: json['comments'] as int?, gitPullUrl: json['git_pull_url'] as String?, @@ -31,8 +31,23 @@ Gist _$GistFromJson(Map json) => Gist( : DateTime.parse(json['updated_at'] as String), ); +Map _$GistToJson(Gist instance) => { + 'id': instance.id, + 'description': instance.description, + 'public': instance.public, + 'owner': instance.owner, + 'user': instance.user, + 'files': instance.files, + 'html_url': instance.htmlUrl, + 'comments': instance.commentsCount, + 'git_pull_url': instance.gitPullUrl, + 'git_push_url': instance.gitPushUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'updated_at': instance.updatedAt?.toIso8601String(), + }; + GistFile _$GistFileFromJson(Map json) => GistFile( - name: json['name'] as String?, + filename: json['filename'] as String?, size: json['size'] as int?, rawUrl: json['raw_url'] as String?, type: json['type'] as String?, @@ -41,6 +56,16 @@ GistFile _$GistFileFromJson(Map json) => GistFile( content: json['content'] as String?, ); +Map _$GistFileToJson(GistFile instance) => { + 'filename': instance.filename, + 'size': instance.size, + 'raw_url': instance.rawUrl, + 'type': instance.type, + 'language': instance.language, + 'truncated': instance.truncated, + 'content': instance.content, + }; + GistFork _$GistForkFromJson(Map json) => GistFork( user: json['user'] == null ? null @@ -54,6 +79,13 @@ GistFork _$GistForkFromJson(Map json) => GistFork( : DateTime.parse(json['updated_at'] as String), ); +Map _$GistForkToJson(GistFork instance) => { + 'user': instance.user, + 'id': instance.id, + 'created_at': instance.createdAt?.toIso8601String(), + 'updated_at': instance.updatedAt?.toIso8601String(), + }; + GistHistoryEntry _$GistHistoryEntryFromJson(Map json) => GistHistoryEntry( version: json['version'] as String?, @@ -68,6 +100,16 @@ GistHistoryEntry _$GistHistoryEntryFromJson(Map json) => : DateTime.parse(json['committed_at'] as String), ); +Map _$GistHistoryEntryToJson(GistHistoryEntry instance) => + { + 'version': instance.version, + 'user': instance.user, + 'change_status/deletions': instance.deletions, + 'change_status/additions': instance.additions, + 'change_status/total': instance.totalChanges, + 'committed_at': instance.committedAt?.toIso8601String(), + }; + GistComment _$GistCommentFromJson(Map json) => GistComment( id: json['id'] as int?, user: json['user'] == null diff --git a/lib/src/common/model/misc.dart b/lib/src/common/model/misc.dart index 4f3166a9..ad693d34 100644 --- a/lib/src/common/model/misc.dart +++ b/lib/src/common/model/misc.dart @@ -3,7 +3,7 @@ import 'package:json_annotation/json_annotation.dart'; part 'misc.g.dart'; /// Model class for a Gitignore Template. -@JsonSerializable(createToJson: false) +@JsonSerializable() class GitignoreTemplate { GitignoreTemplate({this.name, this.source}); @@ -15,6 +15,7 @@ class GitignoreTemplate { factory GitignoreTemplate.fromJson(Map input) => _$GitignoreTemplateFromJson(input); + Map toJson() => _$GitignoreTemplateToJson(this); } /// Model class for GitHub Rate Limit Information. diff --git a/lib/src/common/model/misc.g.dart b/lib/src/common/model/misc.g.dart index fc40fa65..34362c50 100644 --- a/lib/src/common/model/misc.g.dart +++ b/lib/src/common/model/misc.g.dart @@ -12,6 +12,12 @@ GitignoreTemplate _$GitignoreTemplateFromJson(Map json) => source: json['source'] as String?, ); +Map _$GitignoreTemplateToJson(GitignoreTemplate instance) => + { + 'name': instance.name, + 'source': instance.source, + }; + RateLimit _$RateLimitFromJson(Map json) => RateLimit( json['limit'] as int?, json['remaining'] as int?, diff --git a/lib/src/common/model/notifications.dart b/lib/src/common/model/notifications.dart index 6032549b..0fd0477a 100644 --- a/lib/src/common/model/notifications.dart +++ b/lib/src/common/model/notifications.dart @@ -4,7 +4,7 @@ import 'package:json_annotation/json_annotation.dart'; part 'notifications.g.dart'; /// Model class for notifications. -@JsonSerializable(createToJson: false) +@JsonSerializable() class Notification { Notification({ this.id, @@ -36,10 +36,11 @@ class Notification { factory Notification.fromJson(Map input) => _$NotificationFromJson(input); + Map toJson() => _$NotificationToJson(this); } /// Model class for a notification subject. -@JsonSerializable(createToJson: false) +@JsonSerializable() class NotificationSubject { NotificationSubject({this.title, this.type, this.url, this.latestCommentUrl}); final String? title; @@ -51,4 +52,5 @@ class NotificationSubject { factory NotificationSubject.fromJson(Map input) => _$NotificationSubjectFromJson(input); + Map toJson() => _$NotificationSubjectToJson(this); } diff --git a/lib/src/common/model/notifications.g.dart b/lib/src/common/model/notifications.g.dart index 82c74573..70dfde07 100644 --- a/lib/src/common/model/notifications.g.dart +++ b/lib/src/common/model/notifications.g.dart @@ -27,6 +27,19 @@ Notification _$NotificationFromJson(Map json) => Notification( subscriptionUrl: json['subscription_url'] as String?, ); +Map _$NotificationToJson(Notification instance) => + { + 'id': instance.id, + 'repository': instance.repository, + 'subject': instance.subject, + 'reason': instance.reason, + 'unread': instance.unread, + 'updated_at': instance.updatedAt?.toIso8601String(), + 'last_read_at': instance.lastReadAt?.toIso8601String(), + 'url': instance.url, + 'subscription_url': instance.subscriptionUrl, + }; + NotificationSubject _$NotificationSubjectFromJson(Map json) => NotificationSubject( title: json['title'] as String?, @@ -34,3 +47,12 @@ NotificationSubject _$NotificationSubjectFromJson(Map json) => url: json['url'] as String?, latestCommentUrl: json['latest_comment_url'] as String?, ); + +Map _$NotificationSubjectToJson( + NotificationSubject instance) => + { + 'title': instance.title, + 'type': instance.type, + 'url': instance.url, + 'latest_comment_url': instance.latestCommentUrl, + }; diff --git a/lib/src/common/model/orgs.dart b/lib/src/common/model/orgs.dart index 0a28ea42..21f7b417 100644 --- a/lib/src/common/model/orgs.dart +++ b/lib/src/common/model/orgs.dart @@ -82,7 +82,7 @@ class Organization { } /// Model class for organization membership. -@JsonSerializable(createToJson: false) +@JsonSerializable() class OrganizationMembership { OrganizationMembership({ this.state, @@ -94,10 +94,11 @@ class OrganizationMembership { factory OrganizationMembership.fromJson(Map input) { return _$OrganizationMembershipFromJson(input); } + Map toJson() => _$OrganizationMembershipToJson(this); } /// Model class for a GitHub team. -@JsonSerializable(createToJson: false) +@JsonSerializable() class Team { Team({ this.name, @@ -131,6 +132,7 @@ class Team { factory Team.fromJson(Map input) { return _$TeamFromJson(input); } + Map toJson() => _$TeamToJson(this); } /// Model class for the team membership state. @@ -145,7 +147,7 @@ class TeamMembershipState { } /// Model class for a team member. -@JsonSerializable(createToJson: false) +@JsonSerializable() class TeamMember { TeamMember( {this.login, @@ -179,4 +181,5 @@ class TeamMember { factory TeamMember.fromJson(Map input) { return _$TeamMemberFromJson(input); } + Map toJson() => _$TeamMemberToJson(this); } diff --git a/lib/src/common/model/orgs.g.dart b/lib/src/common/model/orgs.g.dart index 52ffea0d..0e19f2cf 100644 --- a/lib/src/common/model/orgs.g.dart +++ b/lib/src/common/model/orgs.g.dart @@ -56,6 +56,13 @@ OrganizationMembership _$OrganizationMembershipFromJson( : Organization.fromJson(json['organization'] as Map), ); +Map _$OrganizationMembershipToJson( + OrganizationMembership instance) => + { + 'state': instance.state, + 'organization': instance.organization, + }; + Team _$TeamFromJson(Map json) => Team( name: json['name'] as String?, id: json['id'] as int?, @@ -67,6 +74,15 @@ Team _$TeamFromJson(Map json) => Team( : Organization.fromJson(json['organization'] as Map), ); +Map _$TeamToJson(Team instance) => { + 'name': instance.name, + 'id': instance.id, + 'permission': instance.permission, + 'members_count': instance.membersCount, + 'repos_count': instance.reposCount, + 'organization': instance.organization, + }; + TeamMember _$TeamMemberFromJson(Map json) => TeamMember( login: json['login'] as String?, id: json['id'] as int?, @@ -75,3 +91,13 @@ TeamMember _$TeamMemberFromJson(Map json) => TeamMember( siteAdmin: json['site_admin'] as bool?, htmlUrl: json['html_url'] as String?, ); + +Map _$TeamMemberToJson(TeamMember instance) => + { + 'login': instance.login, + 'id': instance.id, + 'avatar_url': instance.avatarUrl, + 'type': instance.type, + 'site_admin': instance.siteAdmin, + 'html_url': instance.htmlUrl, + }; diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index f7140e13..4a3c65e3 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -3,9 +3,7 @@ import 'package:json_annotation/json_annotation.dart'; part 'repos.g.dart'; -@JsonSerializable( - createToJson: false, -) +@JsonSerializable() class GitHubComparison { final String? url; final String? status; @@ -19,6 +17,7 @@ class GitHubComparison { factory GitHubComparison.fromJson(Map json) => _$GitHubComparisonFromJson(json); + Map toJson() => _$GitHubComparisonToJson(this); @override String toString() { @@ -201,7 +200,7 @@ class RepositoryPermissions { Map toJson() => _$RepositoryPermissionsToJson(this); } -@JsonSerializable(createToJson: false) +@JsonSerializable() class Tag { final String name; final CommitInfo commit; @@ -213,7 +212,8 @@ class Tag { Tag(this.name, this.commit, this.zipUrl, this.tarUrl); factory Tag.fromJson(Map input) => _$TagFromJson(input); - + Map toJson() => _$TagToJson(this); + @override String toString() => 'Tag: $name'; } diff --git a/lib/src/common/model/repos.g.dart b/lib/src/common/model/repos.g.dart index c3f9cec8..78184d6f 100644 --- a/lib/src/common/model/repos.g.dart +++ b/lib/src/common/model/repos.g.dart @@ -18,6 +18,16 @@ GitHubComparison _$GitHubComparisonFromJson(Map json) => .toList(), ); +Map _$GitHubComparisonToJson(GitHubComparison instance) => + { + 'url': instance.url, + 'status': instance.status, + 'ahead_by': instance.aheadBy, + 'behind_by': instance.behindBy, + 'total_commits': instance.totalCommits, + 'files': instance.files, + }; + Repository _$RepositoryFromJson(Map json) => Repository( name: json['name'] as String? ?? '', id: json['id'] as int? ?? 0, @@ -127,6 +137,13 @@ Tag _$TagFromJson(Map json) => Tag( json['tarball_url'] as String, ); +Map _$TagToJson(Tag instance) => { + 'name': instance.name, + 'commit': instance.commit, + 'zipball_url': instance.zipUrl, + 'tarball_url': instance.tarUrl, + }; + CommitData _$CommitDataFromJson(Map json) => CommitData( json['sha'] as String?, json['commit'] == null diff --git a/lib/src/common/model/search.dart b/lib/src/common/model/search.dart index 1735a465..532551f6 100644 --- a/lib/src/common/model/search.dart +++ b/lib/src/common/model/search.dart @@ -9,7 +9,7 @@ abstract class SearchResults { List? items; } -@JsonSerializable(createToJson: false) +@JsonSerializable() class CodeSearchResults implements SearchResults { @JsonKey(name: 'total_count') @override @@ -25,9 +25,10 @@ class CodeSearchResults implements SearchResults { static CodeSearchResults fromJson(Map input) => _$CodeSearchResultsFromJson(input); + Map toJson() => _$CodeSearchResultsToJson(this); } -@JsonSerializable(createToJson: false) +@JsonSerializable() class CodeSearchItem { String? name; String? path; @@ -57,11 +58,12 @@ class CodeSearchItem { } return result; } + Map toJson() => _$CodeSearchItemToJson(this); } // TODO: Issue Search -// @JsonSerializable(createToJson: false) +// @JsonSerializable() // class IssueSearchResults extends SearchResults {} -// @JsonSerializable(createToJson: false) +// @JsonSerializable() // class IssueSearchItem {} diff --git a/lib/src/common/model/search.g.dart b/lib/src/common/model/search.g.dart index e50161a6..d24fa9cb 100644 --- a/lib/src/common/model/search.g.dart +++ b/lib/src/common/model/search.g.dart @@ -12,6 +12,13 @@ CodeSearchResults _$CodeSearchResultsFromJson(Map json) => ..incompleteResults = json['incomplete_results'] as bool? ..items = CodeSearchItem.fromJsonList(json['items'] as List); +Map _$CodeSearchResultsToJson(CodeSearchResults instance) => + { + 'total_count': instance.totalCount, + 'incomplete_results': instance.incompleteResults, + 'items': instance.items, + }; + CodeSearchItem _$CodeSearchItemFromJson(Map json) => CodeSearchItem() ..name = json['name'] as String? @@ -23,3 +30,14 @@ CodeSearchItem _$CodeSearchItemFromJson(Map json) => ..repository = json['repository'] == null ? null : Repository.fromJson(json['repository'] as Map); + +Map _$CodeSearchItemToJson(CodeSearchItem instance) => + { + 'name': instance.name, + 'path': instance.path, + 'sha': instance.sha, + 'url': instance.url?.toString(), + 'git_url': instance.gitUrl?.toString(), + 'html_url': instance.htmlUrl?.toString(), + 'repository': instance.repository, + }; diff --git a/lib/src/common/model/users.dart b/lib/src/common/model/users.dart index 4c3245a4..766f6185 100644 --- a/lib/src/common/model/users.dart +++ b/lib/src/common/model/users.dart @@ -96,9 +96,7 @@ class User { /// The response from listing collaborators on a repo. // https://developer.github.com/v3/repos/collaborators/#response -@JsonSerializable( - createToJson: false, -) +@JsonSerializable() class Collaborator { final String? login; final int? id; @@ -118,6 +116,7 @@ class Collaborator { factory Collaborator.fromJson(Map json) => _$CollaboratorFromJson(json); + Map toJson() => _$CollaboratorToJson(this); } /// The response from listing contributors on a repo. diff --git a/lib/src/common/model/users.g.dart b/lib/src/common/model/users.g.dart index fde0c3cf..2713125a 100644 --- a/lib/src/common/model/users.g.dart +++ b/lib/src/common/model/users.g.dart @@ -64,6 +64,16 @@ Collaborator _$CollaboratorFromJson(Map json) => Collaborator( ), ); +Map _$CollaboratorToJson(Collaborator instance) => + { + 'login': instance.login, + 'id': instance.id, + 'html_url': instance.htmlUrl, + 'type': instance.type, + 'site_admin': instance.siteAdmin, + 'permissions': instance.permissions, + }; + Contributor _$ContributorFromJson(Map json) => Contributor( id: json['id'] as int?, login: json['login'] as String?, From 027ca8e03ca7ce8e1f45580278131c41daeb02fe Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 8 Jan 2022 16:35:29 -0700 Subject: [PATCH 011/139] format --- lib/src/common/model/repos.dart | 2 +- lib/src/common/model/search.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index 4a3c65e3..0a00f26a 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -213,7 +213,7 @@ class Tag { factory Tag.fromJson(Map input) => _$TagFromJson(input); Map toJson() => _$TagToJson(this); - + @override String toString() => 'Tag: $name'; } diff --git a/lib/src/common/model/search.dart b/lib/src/common/model/search.dart index 532551f6..c61f39e5 100644 --- a/lib/src/common/model/search.dart +++ b/lib/src/common/model/search.dart @@ -58,6 +58,7 @@ class CodeSearchItem { } return result; } + Map toJson() => _$CodeSearchItemToJson(this); } From 5f4a2212b485149fe1e63a03d8ed3ea1bf7dabaf Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 8 Jan 2022 17:24:37 -0700 Subject: [PATCH 012/139] add a few more toJson methods --- lib/src/common/model/gists.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/common/model/gists.dart b/lib/src/common/model/gists.dart index cd89deac..e5360d70 100644 --- a/lib/src/common/model/gists.dart +++ b/lib/src/common/model/gists.dart @@ -47,6 +47,7 @@ class Gist { DateTime? updatedAt; factory Gist.fromJson(Map input) => _$GistFromJson(input); + Map toJson() => _$GistToJson(this); } /// Model class for a gist file. @@ -90,6 +91,7 @@ class GistFork { factory GistFork.fromJson(Map input) => _$GistForkFromJson(input); + Map toJson() => _$GistForkToJson(this); } /// Model class for a gits history entry. @@ -121,6 +123,7 @@ class GistHistoryEntry { factory GistHistoryEntry.fromJson(Map input) => _$GistHistoryEntryFromJson(input); + Map toJson() => _$GistHistoryEntryToJson(this); } /// Model class for gist comments. From 71f9e1e502f820ad18846e3d653651dc91dee5f7 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 8 Jan 2022 17:33:56 -0700 Subject: [PATCH 013/139] prep 9.0.0 changelog --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd6470b5..568d2082 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +## 9.0.0 + +**Breaking change:** In the Gist class, the old type of files was +```dart +List? files; +``` +and the new type is +```dart +Map? files; +``` + +**Breaking change:** In the GistFile class, the name property is now filename + +* Fix getting gists by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/294 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/8.5.0...9.0.0 + ## 8.5.0 * Adds listing and creating PR Reviews, listing users in an org by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/287 From 45df396df11691af02a9a0045371bbd8c50e02fe Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 8 Jan 2022 17:38:35 -0700 Subject: [PATCH 014/139] update pubspec to 9.0.0 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 8dba5227..f8b3ebf4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 8.5.0 +version: 9.0.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 1722442e9f8eb4f2f705c3c06e83b7ffc653b5e8 Mon Sep 17 00:00:00 2001 From: Kristin Bi Date: Wed, 9 Mar 2022 11:03:45 -0800 Subject: [PATCH 015/139] upstream checkRun to include conclusion --- lib/src/common/model/checks.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index 848a3bec..8d497540 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -94,6 +94,7 @@ class CheckRun { final int? checkSuiteId; final String? detailsUrl; final DateTime startedAt; + final CheckRunConclusion conclusion; const CheckRun._({ required this.id, @@ -104,6 +105,7 @@ class CheckRun { required this.name, required this.detailsUrl, required this.startedAt, + required this.conclusion, }); factory CheckRun.fromJson(Map input) { @@ -127,6 +129,7 @@ class CheckRun { checkSuiteId: input['check_suite']['id'], detailsUrl: input['details_url'], startedAt: DateTime.parse(input['started_at']), + conclusion: CheckRunConclusion._fromValue(input['conclusion']), ); } @@ -142,6 +145,7 @@ class CheckRun { }, 'details_url': detailsUrl, 'started_at': startedAt.toIso8601String(), + 'conclusion': conclusion, }; } } From c99a357a89d422f45551b99aa6ce1a2283237c1b Mon Sep 17 00:00:00 2001 From: Kristin Bi Date: Wed, 9 Mar 2022 11:23:34 -0800 Subject: [PATCH 016/139] update changelog --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 568d2082..85c3a591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ Map? files; **Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/8.5.0...9.0.0 +## 9.0.1 +- Add `conclusion` property in class `CheckRun` + ## 8.5.0 * Adds listing and creating PR Reviews, listing users in an org by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/287 diff --git a/pubspec.yaml b/pubspec.yaml index f8b3ebf4..6c039ca0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.0.0 +version: 9.0.1 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 8c9b5b0321eb82b29e595116b19dd995ded54369 Mon Sep 17 00:00:00 2001 From: Kristin Bi Date: Wed, 9 Mar 2022 13:47:08 -0800 Subject: [PATCH 017/139] add check test --- test/unit/checks_test.dart | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/unit/checks_test.dart diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart new file mode 100644 index 00000000..498285ad --- /dev/null +++ b/test/unit/checks_test.dart @@ -0,0 +1,30 @@ +import 'dart:convert'; + +import 'package:github/src/common/model/checks.dart'; +import 'package:test/test.dart'; + +void main() { + group('Check run', () { + test('CheckRun fromJson', () { + // This is a truncated version of the response + const checkRunJson = '''{ + "id": 4, + "head_sha": "ce587453ced02b1526dfb4cb910479d431683101", + "external_id": "", + "details_url": "https://example.com", + "status": "completed", + "conclusion": "neutral", + "started_at": "2018-05-04T01:14:52Z", + "name": "mighty_readme", + "check_suite": { + "id": 5 + } + }'''; + final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); + + expect(checkRun.id, 4); + expect(checkRun.name, 'mighty_readme'); + expect(checkRun.conclusion, CheckRunConclusion.neutral); + }); + }); +} From 6595153e89ee7012c86e51fcbc652bbe27c0a0d2 Mon Sep 17 00:00:00 2001 From: Kristin Bi Date: Wed, 9 Mar 2022 13:54:56 -0800 Subject: [PATCH 018/139] use official value --- test/unit/checks_test.dart | 83 +++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart index 498285ad..15c8f9d8 100644 --- a/test/unit/checks_test.dart +++ b/test/unit/checks_test.dart @@ -6,19 +6,98 @@ import 'package:test/test.dart'; void main() { group('Check run', () { test('CheckRun fromJson', () { - // This is a truncated version of the response + /// The checkRun Json is the official Github values + /// + /// Github api url: https://docs.github.com/en/rest/reference/checks#get-a-check-run const checkRunJson = '''{ "id": 4, "head_sha": "ce587453ced02b1526dfb4cb910479d431683101", + "node_id": "MDg6Q2hlY2tSdW40", "external_id": "", + "url": "https://api.github.com/repos/github/hello-world/check-runs/4", + "html_url": "https://github.com/github/hello-world/runs/4", "details_url": "https://example.com", "status": "completed", "conclusion": "neutral", "started_at": "2018-05-04T01:14:52Z", + "completed_at": "2018-05-04T01:14:52Z", + "output": { + "title": "Mighty Readme report", + "summary": "There are 0 failures, 2 warnings, and 1 notice.", + "text": "You may have some misspelled words on lines 2 and 4. You also may want to add a section in your README about how to install your app.", + "annotations_count": 2, + "annotations_url": "https://api.github.com/repos/github/hello-world/check-runs/4/annotations" + }, "name": "mighty_readme", "check_suite": { "id": 5 - } + }, + "app": { + "id": 1, + "slug": "octoapp", + "node_id": "MDExOkludGVncmF0aW9uMQ==", + "owner": { + "login": "github", + "id": 1, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", + "url": "https://api.github.com/orgs/github", + "repos_url": "https://api.github.com/orgs/github/repos", + "events_url": "https://api.github.com/orgs/github/events", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": true + }, + "name": "Octocat App", + "description": "", + "external_url": "https://example.com", + "html_url": "https://github.com/apps/octoapp", + "created_at": "2017-07-08T16:18:44-04:00", + "updated_at": "2017-07-08T16:18:44-04:00", + "permissions": { + "metadata": "read", + "contents": "read", + "issues": "write", + "single_file": "write" + }, + "events": [ + "push", + "pull_request" + ] + }, + "pull_requests": [ + { + "url": "https://api.github.com/repos/github/hello-world/pulls/1", + "id": 1934, + "number": 3956, + "head": { + "ref": "say-hello", + "sha": "3dca65fa3e8d4b3da3f3d056c59aee1c50f41390", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + }, + "base": { + "ref": "master", + "sha": "e7fdf7640066d71ad16a86fbcbb9c6a10a18af4f", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + } + } + ] }'''; final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); From c7f0bb30caceb75f0a4736ca2fc99008b48da1aa Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 27 Jan 2022 10:31:32 -0800 Subject: [PATCH 019/139] Move to pkg:lints --- CHANGELOG.md | 8 +++++--- analysis_options.yaml | 2 +- example/languages.dart | 15 ++++++++------- example/organization.dart | 1 - example/pr.dart | 2 -- example/readme.dart | 2 -- example/releases.dart | 2 -- example/repos.dart | 6 ++---- example/stars.dart | 1 - example/user_info.dart | 1 - example/users.dart | 2 -- lib/src/common/activity_service.dart | 4 +--- lib/src/common/authorizations_service.dart | 2 +- lib/src/common/checks_service.dart | 1 - lib/src/common/gists_service.dart | 2 +- lib/src/common/git_service.dart | 2 +- lib/src/common/github.dart | 1 - lib/src/common/issues_service.dart | 2 -- lib/src/common/model/activity.dart | 1 - lib/src/common/model/git.dart | 1 - lib/src/common/model/pulls.dart | 1 - lib/src/common/model/repos.dart | 4 ++-- lib/src/common/model/repos_commits.dart | 1 - lib/src/common/orgs_service.dart | 3 +-- lib/src/common/pulls_service.dart | 11 +++++------ lib/src/common/repos_service.dart | 5 +---- lib/src/common/search_service.dart | 3 +-- lib/src/common/users_service.dart | 4 +--- lib/src/common/util/utils.dart | 2 ++ lib/src/const/token_env_keys.dart | 1 + pubspec.yaml | 4 ++-- test/experiment/limit_pager.dart | 10 +++++----- test/src/mocks.mocks.dart | 2 ++ 33 files changed, 43 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85c3a591..19f36604 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.0.2-dev + +## 9.0.1 +- Add `conclusion` property in class `CheckRun` + ## 9.0.0 **Breaking change:** In the Gist class, the old type of files was @@ -15,9 +20,6 @@ Map? files; **Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/8.5.0...9.0.0 -## 9.0.1 -- Add `conclusion` property in class `CheckRun` - ## 8.5.0 * Adds listing and creating PR Reviews, listing users in an org by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/287 diff --git a/analysis_options.yaml b/analysis_options.yaml index 442b7c0c..1b107aa5 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml analyzer: strong-mode: diff --git a/example/languages.dart b/example/languages.dart index 526950ed..02da85e0 100644 --- a/example/languages.dart +++ b/example/languages.dart @@ -1,6 +1,5 @@ import 'dart:html'; -import 'package:github/github.dart'; import 'common.dart'; DivElement? tableDiv; @@ -49,15 +48,17 @@ String generateMarkdown(int accuracy) { final total = totalBytes(breakdown); final data = breakdown.toList(); - var md = '|Name|Bytes|Percentage|\n'; - md += '|-----|-----|-----|\n'; + var md = StringBuffer(''' +|Name|Bytes|Percentage| +|-----|-----|-----| +'''); data.sort((a, b) => b[1].compareTo(a[1])); - data.forEach((info) { + for (final info in data) { final String? name = info[0]; final int bytes = info[1]; final num percentage = (bytes / total) * 100; - md += '|$name|$bytes|${percentage.toStringAsFixed(accuracy)}|\n'; - }); - return md; + md.writeln('|$name|$bytes|${percentage.toStringAsFixed(accuracy)}|'); + } + return md.toString(); } diff --git a/example/organization.dart b/example/organization.dart index fdea07d3..ef7135f8 100644 --- a/example/organization.dart +++ b/example/organization.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:html'; -import 'package:github/github.dart'; import 'common.dart'; DivElement? $output; diff --git a/example/pr.dart b/example/pr.dart index 2805646a..15e18180 100644 --- a/example/pr.dart +++ b/example/pr.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'dart:html'; -import 'package:github/github.dart'; - import 'common.dart'; Future main() async { diff --git a/example/readme.dart b/example/readme.dart index fb6c29e0..ad9ec300 100644 --- a/example/readme.dart +++ b/example/readme.dart @@ -1,7 +1,5 @@ import 'dart:html'; -import 'package:github/github.dart'; - import 'common.dart'; Future main() async { diff --git a/example/releases.dart b/example/releases.dart index 62db5136..ddd19570 100644 --- a/example/releases.dart +++ b/example/releases.dart @@ -1,7 +1,5 @@ import 'dart:html'; -import 'package:github/github.dart'; - import 'common.dart'; DivElement? releasesDiv; diff --git a/example/repos.dart b/example/repos.dart index 4fdd085c..e7b21da4 100644 --- a/example/repos.dart +++ b/example/repos.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'dart:html'; -import 'package:github/github.dart'; - import 'common.dart'; DivElement? repositoriesDiv; @@ -29,14 +27,14 @@ Future main() async { loadRepos(); }); - sorts.keys.forEach((name) { + for (final name in sorts.keys) { querySelector('#sort-$name')!.onClick.listen((event) { if (_reposCache == null) { loadRepos(sorts[name]); } updateRepos(_reposCache!, sorts[name]); }); - }); + } } List? _reposCache; diff --git a/example/stars.dart b/example/stars.dart index 16767cfe..a7c96bc4 100644 --- a/example/stars.dart +++ b/example/stars.dart @@ -1,6 +1,5 @@ import 'dart:html'; -import 'package:github/github.dart'; import 'common.dart'; DivElement? $stars; diff --git a/example/user_info.dart b/example/user_info.dart index 074f645c..a5113646 100644 --- a/example/user_info.dart +++ b/example/user_info.dart @@ -1,6 +1,5 @@ import 'dart:html'; -import 'package:github/github.dart'; import 'common.dart'; DivElement? info; diff --git a/example/users.dart b/example/users.dart index 7f9428c8..ab75a061 100644 --- a/example/users.dart +++ b/example/users.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'dart:html'; -import 'package:github/github.dart'; - import 'common.dart'; DivElement? usersDiv; diff --git a/lib/src/common/activity_service.dart b/lib/src/common/activity_service.dart index 12420eba..16b7b84a 100644 --- a/lib/src/common/activity_service.dart +++ b/lib/src/common/activity_service.dart @@ -1,9 +1,7 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; -import 'package:github/src/common/util/pagination.dart'; -import 'package:github/src/common/util/utils.dart'; import 'package:http/http.dart' as http; /// The [ActivityService] handles communication with activity related methods diff --git a/lib/src/common/authorizations_service.dart b/lib/src/common/authorizations_service.dart index 5673001f..7e714afb 100644 --- a/lib/src/common/authorizations_service.dart +++ b/lib/src/common/authorizations_service.dart @@ -1,6 +1,6 @@ import 'dart:async'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/util/pagination.dart'; /// The [AuthorizationsService] handles communication with authorizations related methods /// of the GitHub API. diff --git a/lib/src/common/checks_service.dart b/lib/src/common/checks_service.dart index b0a269ee..d3b63f77 100644 --- a/lib/src/common/checks_service.dart +++ b/lib/src/common/checks_service.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:github/github.dart'; -import 'package:github/src/common/util/utils.dart'; const _previewHeader = 'application/vnd.github.antiope-preview+json'; diff --git a/lib/src/common/gists_service.dart b/lib/src/common/gists_service.dart index dc0f7316..9f64717e 100644 --- a/lib/src/common/gists_service.dart +++ b/lib/src/common/gists_service.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/util/pagination.dart'; /// The [GistsService] handles communication with gist /// methods of the GitHub API. diff --git a/lib/src/common/git_service.dart b/lib/src/common/git_service.dart index d3541ed8..1165eeb0 100644 --- a/lib/src/common/git_service.dart +++ b/lib/src/common/git_service.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/util/pagination.dart'; /// The [GitService] handles communication with git related methods of the /// GitHub API. diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index b92749f0..31605c91 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; import 'package:github/src/common.dart'; -import 'package:github/src/common/util/utils.dart'; import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart' as http_parser; import 'package:meta/meta.dart'; diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index 8fcc9a1a..b20d809a 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -2,8 +2,6 @@ import 'dart:async'; import 'dart:convert'; import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; -import 'package:github/src/common/util/pagination.dart'; /// The [IssuesService] handles communication with issues related methods of the /// GitHub API. diff --git a/lib/src/common/model/activity.dart b/lib/src/common/model/activity.dart index ee517ed5..cdb873ec 100644 --- a/lib/src/common/model/activity.dart +++ b/lib/src/common/model/activity.dart @@ -1,5 +1,4 @@ import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; import 'package:json_annotation/json_annotation.dart'; part 'activity.g.dart'; diff --git a/lib/src/common/model/git.dart b/lib/src/common/model/git.dart index 861a7028..136c01c4 100644 --- a/lib/src/common/model/git.dart +++ b/lib/src/common/model/git.dart @@ -1,5 +1,4 @@ import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; import 'package:json_annotation/json_annotation.dart'; part 'git.g.dart'; diff --git a/lib/src/common/model/pulls.dart b/lib/src/common/model/pulls.dart index 456e5a39..fd6e8d70 100644 --- a/lib/src/common/model/pulls.dart +++ b/lib/src/common/model/pulls.dart @@ -1,5 +1,4 @@ import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:meta/meta.dart'; diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index 0a00f26a..739d6ca2 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -309,8 +309,8 @@ class RepositorySlug { String get fullName => '$owner/$name'; @override - bool operator ==(Object obj) => - obj is RepositorySlug && obj.fullName == fullName; + bool operator ==(Object other) => + other is RepositorySlug && other.fullName == fullName; @override int get hashCode => fullName.hashCode; diff --git a/lib/src/common/model/repos_commits.dart b/lib/src/common/model/repos_commits.dart index e3698663..940917ab 100644 --- a/lib/src/common/model/repos_commits.dart +++ b/lib/src/common/model/repos_commits.dart @@ -1,5 +1,4 @@ import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; import 'package:json_annotation/json_annotation.dart'; part 'repos_commits.g.dart'; diff --git a/lib/src/common/orgs_service.dart b/lib/src/common/orgs_service.dart index a8a54b25..f72f93b1 100644 --- a/lib/src/common/orgs_service.dart +++ b/lib/src/common/orgs_service.dart @@ -1,8 +1,7 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/util/pagination.dart'; -import 'package:github/src/common/util/utils.dart'; import 'package:http/http.dart' as http; /// The [OrganizationsService] handles communication with organization diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index 01f51722..8c1d3633 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -1,8 +1,7 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/util/pagination.dart'; -import 'package:github/src/common/util/utils.dart'; /// The [PullRequestsService] handles communication with pull request /// methods of the GitHub API. @@ -182,9 +181,9 @@ class PullRequestsService extends Service { Future createReview( RepositorySlug slug, CreatePullRequestReview review) { return github.postJSON( - '/repos/${slug.fullName}/pulls/${review.pullNumber}/reviews', - body: GitHubJson.encode(review), - convert: (dynamic i) => PullRequestReview.fromJson(i)) - as Future; + '/repos/${slug.fullName}/pulls/${review.pullNumber}/reviews', + body: GitHubJson.encode(review), + convert: (dynamic i) => PullRequestReview.fromJson(i), + ); } } diff --git a/lib/src/common/repos_service.dart b/lib/src/common/repos_service.dart index 16e573f8..04163260 100644 --- a/lib/src/common/repos_service.dart +++ b/lib/src/common/repos_service.dart @@ -1,10 +1,7 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/model/repos_releases.dart'; -import 'package:github/src/common/model/users.dart'; -import 'package:github/src/common/util/pagination.dart'; -import 'package:github/src/common/util/utils.dart'; import 'package:http/http.dart' as http; /// The [RepositoriesService] handles communication with repository related diff --git a/lib/src/common/search_service.dart b/lib/src/common/search_service.dart index 72da0465..e98344a6 100644 --- a/lib/src/common/search_service.dart +++ b/lib/src/common/search_service.dart @@ -1,8 +1,7 @@ import 'dart:async'; import 'dart:convert'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; -import 'package:github/src/common/util/pagination.dart'; /// The [SearchService] handles communication with search related methods of /// the GitHub API. diff --git a/lib/src/common/users_service.dart b/lib/src/common/users_service.dart index ac19ae69..3a469401 100644 --- a/lib/src/common/users_service.dart +++ b/lib/src/common/users_service.dart @@ -1,8 +1,6 @@ import 'dart:async'; + import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; -import 'package:github/src/common/util/pagination.dart'; -import 'package:github/src/common/util/utils.dart'; import 'package:http/http.dart' as http; /// The [UsersService] handles communication with user related methods of the diff --git a/lib/src/common/util/utils.dart b/lib/src/common/util/utils.dart index 23dd5307..57bd6712 100644 --- a/lib/src/common/util/utils.dart +++ b/lib/src/common/util/utils.dart @@ -1,3 +1,5 @@ +// ignore_for_file: constant_identifier_names + import 'package:github/src/common.dart'; import 'package:meta/meta.dart'; diff --git a/lib/src/const/token_env_keys.dart b/lib/src/const/token_env_keys.dart index 15d23a83..7a65804e 100644 --- a/lib/src/const/token_env_keys.dart +++ b/lib/src/const/token_env_keys.dart @@ -1,3 +1,4 @@ +// ignore: constant_identifier_names const List COMMON_GITHUB_TOKEN_ENV_KEYS = [ 'GITHUB_ADMIN_TOKEN', 'GITHUB_DART_TOKEN', diff --git a/pubspec.yaml b/pubspec.yaml index 6c039ca0..5ca5bfbd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.0.1 +version: 9.0.2-dev description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart @@ -18,7 +18,7 @@ dev_dependencies: build_test: any build_web_compilers: any json_serializable: ^6.0.0 + lints: ^1.0.0 mockito: ^5.0.0 - pedantic: ^1.10.0 test: ^1.16.0 yaml: ^3.0.0 diff --git a/test/experiment/limit_pager.dart b/test/experiment/limit_pager.dart index c8b14739..05654bfa 100755 --- a/test/experiment/limit_pager.dart +++ b/test/experiment/limit_pager.dart @@ -5,8 +5,8 @@ void main() { print(solve(201)); } -const int MAX_PER_PAGE = 100; -const int ACCURACY_RANGE = 5; +const int maxPerPage = 100; +const int accuracyRange = 5; /// Solves the most efficient way to fetch the number of objects [limit] with the least requests. PaginationInformation solve(int limit) { @@ -14,12 +14,12 @@ PaginationInformation solve(int limit) { throw RangeError('limit cannot be less than zero (was $limit)'); } - if (limit < MAX_PER_PAGE) { + if (limit < maxPerPage) { return PaginationInformation(limit, 1, limit); } - if ((limit % MAX_PER_PAGE) == 0) { - return PaginationInformation(limit, limit ~/ MAX_PER_PAGE, MAX_PER_PAGE); + if ((limit % maxPerPage) == 0) { + return PaginationInformation(limit, limit ~/ maxPerPage, maxPerPage); } const itemsPerPage = 100; diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index 6a673895..bd1c1b8c 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -10,10 +10,12 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters +// ignore_for_file: camel_case_types // ignore_for_file: comment_references // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_overrides // ignore_for_file: unnecessary_parenthesis class _FakeClient_0 extends _i1.Fake implements _i2.Client {} From e91bdd823fe28de7c521b4632208d98fba717e8d Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 13 Mar 2022 08:42:44 -0600 Subject: [PATCH 020/139] prep 9.0.2 --- CHANGELOG.md | 3 ++- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19f36604..afffef1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ -## 9.0.2-dev +## 9.0.2 +- Switched to use the lints package instead of pedantic https://github.com/SpinlockLabs/github.dart/pull/301 ## 9.0.1 - Add `conclusion` property in class `CheckRun` diff --git a/pubspec.yaml b/pubspec.yaml index 5ca5bfbd..4a035a95 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.0.2-dev +version: 9.0.2 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From e6057d6a5a525b797b708459812294001b71bae9 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 13 Mar 2022 22:33:04 -0600 Subject: [PATCH 021/139] Adding auto-release on PR merge --- .github/workflows/auto_release_on_merge.yml | 33 ++++++ tool/auto_release_on_merge.dart | 113 ++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 .github/workflows/auto_release_on_merge.yml create mode 100644 tool/auto_release_on_merge.dart diff --git a/.github/workflows/auto_release_on_merge.yml b/.github/workflows/auto_release_on_merge.yml new file mode 100644 index 00000000..21a6f293 --- /dev/null +++ b/.github/workflows/auto_release_on_merge.yml @@ -0,0 +1,33 @@ +name: Auto-Release on PR Merge + +# Runs when a PR merges. See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges +on: + pull_request: + types: + - closed + +jobs: + release: + if: github.event.pull_request.merged == true + permissions: + contents: write + runs-on: ubuntu-latest + container: dart:2.14.4 + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 2 + ref: master + - name: Release + run: | + git config --global user.name ${{ secrets.USER_NAME }} + git config --global user.email ${{ secrets.USER_EMAIL }} + export PATH="$PATH":"$HOME/.pub-cache/bin" + export GITHUB_TOKEN=${{secrets.GITHUB_TOKEN}} + export MACHINE_GITHUB_API_TOKEN=${{secrets.MACHINE_GITHUB_API_TOKEN}} + pub get + pub global activate cider + dart tool/auto_release_on_merge.dart ${{github.repository}} ${{github.event.pull_request.number}} + \ No newline at end of file diff --git a/tool/auto_release_on_merge.dart b/tool/auto_release_on_merge.dart new file mode 100644 index 00000000..8510229a --- /dev/null +++ b/tool/auto_release_on_merge.dart @@ -0,0 +1,113 @@ +import 'dart:io'; +import 'package:github/github.dart'; +import 'package:yaml/yaml.dart'; + +const semvers = ['major', 'minor', 'patch']; + +/// Meant to be run from the github workflow. +/// Expected arguments of: +/// [repo] the full repo owner/name format +/// [pr number] PR number of which to release +/// the semver label is expected to be on the PR +void main(List args) async { + if (args.length < 2) { + print('Usage: dart tool/auto_release_on_merge owner_and_repo pull_number'); + exit(1); + } + + final fullrepo = args[0]; + final pullnumber = int.parse(args[1]); + final currentVersion = getVersion(); + var slug = RepositorySlug.full(fullrepo); + var gh = GitHub(auth: findAuthenticationFromEnvironment()); + + print('Loading PR $pullnumber from $slug'); + var pr = await gh.pullRequests.get(slug, pullnumber); + if (!(pr.merged ?? false)) { + print('PR not merged. skipping.'); + exit(0); + } + print('PR $pullnumber loaded'); + + var labels = pr.labels ?? []; + var semverLabel = labels + .map((e) => e.name) + .firstWhere((label) => label.startsWith('semver'), orElse: () => ''); + if (semverLabel.isEmpty) { + print('No semver label found'); + exit(2); + } + semverLabel = semverLabel.toLowerCase().replaceAll('semver:', '').trim(); + // ensure the semver label is valid + if (!semvers.contains(semverLabel)) { + print('semver label [$semverLabel] is not one of $semvers'); + exit(3); + } + print('Semver label: $semverLabel'); + + + run('cider bump $semverLabel'); + var newVersion = getVersion(); + print('Current Version: $currentVersion'); + print('New Version : $newVersion'); + + var rn = await gh.repositories.generateReleaseNotes(CreateReleaseNotes( + slug.owner, slug.name, newVersion, + previousTagName: currentVersion)); + + var releaseNotes = rn.body.replaceFirst('## What\'s Changed',''); + releaseNotes = '## $newVersion\n$releaseNotes'; + + print(releaseNotes); + + var log = File('CHANGELOG.md'); + var logdata = log.existsSync() ? log.readAsStringSync() : ''; + log.writeAsStringSync('${releaseNotes}\n\n$logdata'); + + run('git add pubspec.yaml CHANGELOG.md'); + run('git', rest: ['commit', '-m', 'prep $newVersion']); + run('git push'); + // var commit = run('git rev-parse HEAD'); + // print('autoprep commit: $commit'); + + var release = await gh.repositories.createRelease( + slug, + CreateRelease.from( + tagName: newVersion, + name: newVersion, + generateReleaseNotes: true, + targetCommitish: 'master', + isDraft: false, + isPrerelease: false)); + + print('$newVersion release created at ${release.createdAt}'); + exit(0); +} + +String getVersion() { + var y = loadYaml(File('pubspec.yaml').readAsStringSync()); + var newVersion = y['version'].toString(); + return newVersion; +} + +String run(String cmd, {List? rest}) { + var args = []; + if (rest != null) { + args = rest; + } else { + args = cmd.split(' '); + if (args.isEmpty) return ''; + cmd = args.removeAt(0); + } + var result = Process.runSync(cmd, args); + if (result.exitCode != 0) { + print('Command failed'); + } + if (result.stdout != null) print(result.stdout); + if (result.stderr != null) print(result.stderr); + if (result.exitCode != 0) { + exit(6); + } + + return result.stdout; +} \ No newline at end of file From c4ac82fae50e17743e66fb0686d21b946db52781 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 13 Mar 2022 22:35:45 -0600 Subject: [PATCH 022/139] dart format --- tool/auto_release_on_merge.dart | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tool/auto_release_on_merge.dart b/tool/auto_release_on_merge.dart index 8510229a..2b762bd0 100644 --- a/tool/auto_release_on_merge.dart +++ b/tool/auto_release_on_merge.dart @@ -45,7 +45,6 @@ void main(List args) async { } print('Semver label: $semverLabel'); - run('cider bump $semverLabel'); var newVersion = getVersion(); print('Current Version: $currentVersion'); @@ -55,15 +54,15 @@ void main(List args) async { slug.owner, slug.name, newVersion, previousTagName: currentVersion)); - var releaseNotes = rn.body.replaceFirst('## What\'s Changed',''); + var releaseNotes = rn.body.replaceFirst('## What\'s Changed', ''); releaseNotes = '## $newVersion\n$releaseNotes'; - + print(releaseNotes); var log = File('CHANGELOG.md'); var logdata = log.existsSync() ? log.readAsStringSync() : ''; log.writeAsStringSync('${releaseNotes}\n\n$logdata'); - + run('git add pubspec.yaml CHANGELOG.md'); run('git', rest: ['commit', '-m', 'prep $newVersion']); run('git push'); @@ -110,4 +109,4 @@ String run(String cmd, {List? rest}) { } return result.stdout; -} \ No newline at end of file +} From 92711184caf18d83b315f8c2f33fb3eba28b2c55 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 13 Mar 2022 22:42:53 -0600 Subject: [PATCH 023/139] Update Language Colors March 13th 2022 --- lib/src/const/language_color.dart | 359 +++++++++++++++++------------- 1 file changed, 206 insertions(+), 153 deletions(-) diff --git a/lib/src/const/language_color.dart b/lib/src/const/language_color.dart index d3546670..95bfc175 100644 --- a/lib/src/const/language_color.dart +++ b/lib/src/const/language_color.dart @@ -1,13 +1,15 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -// VERSION OF 2021-02-14T13:29:43.072192 +// VERSION OF 2022-03-13T22:39:42.882755 const languageColors = { '1C Enterprise': '#814CCC', - '4D': '#EDEDED', + '2-Dimensional Array': '#38761D', + '4D': '#004289', 'ABAP': '#E8274B', 'ABAP CDS': '#555E25', 'ABNF': '#EDEDED', 'AGS Script': '#B9D9FF', + 'AIDL': '#34EB6B', 'AL': '#3AA2B5', 'AMPL': '#E6EFBB', 'ANTLR': '#9DC3FF', @@ -19,73 +21,81 @@ const languageColors = { 'ATS': '#1AC620', 'ActionScript': '#882B0F', 'Ada': '#02F88C', - 'Adobe Font Metrics': '#EDEDED', + 'Adobe Font Metrics': '#FA0F00', 'Agda': '#315665', 'Alloy': '#64C800', - 'Alpine Abuild': '#EDEDED', - 'Altium Designer': '#EDEDED', + 'Alpine Abuild': '#0D597F', + 'Altium Designer': '#A89663', 'AngelScript': '#C7D7DC', - 'Ant Build System': '#EDEDED', - 'ApacheConf': '#EDEDED', + 'Ant Build System': '#A9157E', + 'ApacheConf': '#D12127', 'Apex': '#1797C0', 'Apollo Guidance Computer': '#0B3D91', 'AppleScript': '#101F1F', 'Arc': '#AA2AFE', - 'AsciiDoc': '#EDEDED', + 'AsciiDoc': '#73A0C5', 'AspectJ': '#A957B0', 'Assembly': '#6E4C13', + 'Astro': '#FF5A03', 'Asymptote': '#FF0000', - 'Augeas': '#EDEDED', + 'Augeas': '#9CC134', 'AutoHotkey': '#6594B9', 'AutoIt': '#1C3552', - 'Avro IDL': '#EDEDED', - 'Awk': '#EDEDED', + 'Avro IDL': '#0040FF', + 'Awk': '#C30E9B', + 'BASIC': '#FF0000', 'Ballerina': '#FF5000', 'Batchfile': '#C1F12E', 'Beef': '#A52F4E', 'Befunge': '#EDEDED', - 'BibTeX': '#EDEDED', + 'BibTeX': '#778899', + 'Bicep': '#519ABA', 'Bison': '#6A463F', - 'BitBake': '#EDEDED', + 'BitBake': '#00BCE4', 'Blade': '#F7523F', - 'BlitzBasic': '#EDEDED', + 'BlitzBasic': '#00FFAE', 'BlitzMax': '#CD6400', - 'Bluespec': '#EDEDED', + 'Bluespec': '#12223C', 'Boo': '#D4BEC1', 'Boogie': '#C80FA0', 'Brainfuck': '#2F2530', - 'Brightscript': '#EDEDED', + 'Brightscript': '#662D91', 'Browserslist': '#FFD539', 'C': '#555555', 'C#': '#178600', 'C++': '#F34B7D', 'C-ObjDump': '#EDEDED', 'C2hs Haskell': '#EDEDED', - 'CLIPS': '#EDEDED', - 'CMake': '#EDEDED', + 'CIL': '#EDEDED', + 'CLIPS': '#00A300', + 'CMake': '#DA3434', 'COBOL': '#EDEDED', - 'COLLADA': '#EDEDED', + 'CODEOWNERS': '#EDEDED', + 'COLLADA': '#F1A42B', 'CSON': '#244776', 'CSS': '#563D7C', - 'CSV': '#EDEDED', - 'CWeb': '#EDEDED', - 'Cabal Config': '#EDEDED', - 'Cap\'n Proto': '#EDEDED', + 'CSV': '#237346', + 'CUE': '#5886E1', + 'CWeb': '#00007A', + 'Cabal Config': '#483465', + 'Cairo': '#FF4A48', + 'Cap\'n Proto': '#C42727', 'CartoCSS': '#EDEDED', 'Ceylon': '#DFA535', 'Chapel': '#8DC63F', 'Charity': '#EDEDED', - 'ChucK': '#EDEDED', + 'ChucK': '#3F8000', 'Cirru': '#CCCCFF', 'Clarion': '#DB901E', + 'Clarity': '#5546FF', 'Classic ASP': '#6A40FD', 'Clean': '#3F85AF', 'Click': '#E4E6F3', 'Clojure': '#DB5855', 'Closure Templates': '#0D948F', - 'Cloud Firestore Security Rules': '#EDEDED', + 'Cloud Firestore Security Rules': '#FFA000', 'CoNLL-U': '#EDEDED', - 'CodeQL': '#EDEDED', + 'CodeQL': '#140F46', 'CoffeeScript': '#244776', 'ColdFusion': '#ED2CD6', 'ColdFusion CFC': '#ED2CD6', @@ -93,16 +103,18 @@ const languageColors = { 'Common Workflow Language': '#B5314C', 'Component Pascal': '#B0CE4E', 'Cool': '#EDEDED', - 'Coq': '#EDEDED', + 'Coq': '#D0B68C', 'Cpp-ObjDump': '#EDEDED', 'Creole': '#EDEDED', 'Crystal': '#000100', - 'Csound': '#EDEDED', - 'Csound Document': '#EDEDED', - 'Csound Score': '#EDEDED', + 'Csound': '#1A1A1A', + 'Csound Document': '#1A1A1A', + 'Csound Score': '#1A1A1A', 'Cuda': '#3A4E3A', + 'Cue Sheet': '#EDEDED', + 'Curry': '#531242', 'Cycript': '#EDEDED', - 'Cython': '#EDEDED', + 'Cython': '#FEDF5B', 'D': '#BA595E', 'D-ObjDump': '#EDEDED', 'DIGITAL Command Language': '#EDEDED', @@ -110,26 +122,29 @@ const languageColors = { 'DNS Zone': '#EDEDED', 'DTrace': '#EDEDED', 'Dafny': '#FFEC25', - 'Darcs Patch': '#EDEDED', + 'Darcs Patch': '#8EFF23', 'Dart': '#00B4AB', 'DataWeave': '#003A52', + 'Debian Package Control File': '#D70751', + 'DenizenScript': '#FBEE96', 'Dhall': '#DFAFFF', 'Diff': '#EDEDED', - 'DirectX 3D File': '#EDEDED', + 'DirectX 3D File': '#AACE60', 'Dockerfile': '#384D54', 'Dogescript': '#CCA760', 'Dylan': '#6C616E', 'E': '#CCCE35', + 'E-mail': '#EDEDED', 'EBNF': '#EDEDED', 'ECL': '#8A1267', - 'ECLiPSe': '#EDEDED', + 'ECLiPSe': '#001D9D', 'EJS': '#A91E50', - 'EML': '#EDEDED', 'EQ': '#A78649', 'Eagle': '#EDEDED', - 'Easybuild': '#EDEDED', - 'Ecere Projects': '#EDEDED', - 'EditorConfig': '#EDEDED', + 'Earthly': '#2AF0FF', + 'Easybuild': '#069406', + 'Ecere Projects': '#913960', + 'EditorConfig': '#FFF1F2', 'Edje Data Collection': '#EDEDED', 'Eiffel': '#4D6977', 'Elixir': '#6E4A7E', @@ -137,69 +152,77 @@ const languageColors = { 'Emacs Lisp': '#C065DB', 'EmberScript': '#FFF4F3', 'Erlang': '#B83998', + 'Euphoria': '#FF790B', 'F#': '#B845FC', 'F*': '#572E30', - 'FIGlet Font': '#EDEDED', + 'FIGlet Font': '#FFDDBB', 'FLUX': '#88CCFF', 'Factor': '#636746', 'Fancy': '#7B9DB4', 'Fantom': '#14253C', 'Faust': '#C37240', - 'Filebench WML': '#EDEDED', + 'Fennel': '#FFF3D7', + 'Filebench WML': '#F6B900', 'Filterscript': '#EDEDED', + 'Fluent': '#FFCC33', 'Formatted': '#EDEDED', 'Forth': '#341708', 'Fortran': '#4D41B1', - 'Fortran Free Form': '#EDEDED', + 'Fortran Free Form': '#4D41B1', + 'FreeBasic': '#867DB1', 'FreeMarker': '#0050B2', 'Frege': '#00CAFE', 'Futhark': '#5F021F', 'G-code': '#D08CF2', 'GAML': '#FFC766', - 'GAMS': '#EDEDED', - 'GAP': '#EDEDED', - 'GCC Machine Description': '#EDEDED', + 'GAMS': '#F49A22', + 'GAP': '#0000CC', + 'GCC Machine Description': '#FFCFAB', 'GDB': '#EDEDED', 'GDScript': '#355570', - 'GEDCOM': '#EDEDED', - 'GLSL': '#EDEDED', + 'GEDCOM': '#003058', + 'GLSL': '#5686A5', 'GN': '#EDEDED', + 'GSC': '#FF6800', 'Game Maker Language': '#71B417', + 'Gemfile.lock': '#701516', 'Genie': '#FB855D', - 'Genshi': '#EDEDED', - 'Gentoo Ebuild': '#EDEDED', - 'Gentoo Eclass': '#EDEDED', - 'Gerber Image': '#EDEDED', + 'Genshi': '#951531', + 'Gentoo Ebuild': '#9400FF', + 'Gentoo Eclass': '#9400FF', + 'Gerber Image': '#D20B00', 'Gettext Catalog': '#EDEDED', 'Gherkin': '#5B2063', - 'Git Attributes': '#EDEDED', - 'Git Config': '#EDEDED', + 'Git Attributes': '#F44D27', + 'Git Config': '#F44D27', + 'Gleam': '#FFAFF3', 'Glyph': '#C1AC7F', 'Glyph Bitmap Distribution Format': '#EDEDED', 'Gnuplot': '#F0A9F0', 'Go': '#00ADD8', + 'Go Checksums': '#00ADD8', + 'Go Module': '#00ADD8', 'Golo': '#88562A', 'Gosu': '#82937F', - 'Grace': '#EDEDED', - 'Gradle': '#EDEDED', + 'Grace': '#615F8B', + 'Gradle': '#02303A', 'Grammatical Framework': '#FF0000', 'Graph Modeling Language': '#EDEDED', 'GraphQL': '#E10098', - 'Graphviz (DOT)': '#EDEDED', - 'Groovy': '#E69F56', - 'Groovy Server Pages': '#EDEDED', - 'HAProxy': '#EDEDED', + 'Graphviz (DOT)': '#2596BE', + 'Groovy': '#4298B8', + 'Groovy Server Pages': '#4298B8', + 'HAProxy': '#106DA9', 'HCL': '#EDEDED', - 'HLSL': '#EDEDED', + 'HLSL': '#AACE60', 'HTML': '#E34C26', - 'HTML+Django': '#EDEDED', - 'HTML+ECR': '#EDEDED', - 'HTML+EEX': '#EDEDED', - 'HTML+ERB': '#EDEDED', - 'HTML+PHP': '#EDEDED', - 'HTML+Razor': '#EDEDED', - 'HTTP': '#EDEDED', - 'HXML': '#EDEDED', + 'HTML+ECR': '#2E1052', + 'HTML+EEX': '#6E4A7E', + 'HTML+ERB': '#701516', + 'HTML+PHP': '#4F5D95', + 'HTML+Razor': '#512BE4', + 'HTTP': '#005C9C', + 'HXML': '#F68712', 'Hack': '#878787', 'Haml': '#ECE2A9', 'Handlebars': '#F7931E', @@ -212,66 +235,72 @@ const languageColors = { 'HyPhy': '#EDEDED', 'IDL': '#A3522F', 'IGOR Pro': '#0000CC', - 'INI': '#EDEDED', + 'INI': '#D1DBE0', 'IRC log': '#EDEDED', 'Idris': '#B30000', - 'Ignore List': '#EDEDED', + 'Ignore List': '#000000', 'ImageJ Macro': '#99AAFF', 'Inform 7': '#EDEDED', - 'Inno Setup': '#EDEDED', + 'Inno Setup': '#264B99', 'Io': '#A9188D', 'Ioke': '#078193', 'Isabelle': '#FEFE00', - 'Isabelle ROOT': '#EDEDED', + 'Isabelle ROOT': '#FEFE00', 'J': '#9EEDFF', + 'JAR Manifest': '#B07219', 'JFlex': '#DBCA00', - 'JSON': '#EDEDED', - 'JSON with Comments': '#EDEDED', - 'JSON5': '#EDEDED', - 'JSONLD': '#EDEDED', + 'JSON': '#292929', + 'JSON with Comments': '#292929', + 'JSON5': '#267CB9', + 'JSONLD': '#0C479C', 'JSONiq': '#40D47E', - 'Jasmin': '#EDEDED', + 'Janet': '#0886A5', + 'Jasmin': '#D03600', 'Java': '#B07219', - 'Java Properties': '#EDEDED', - 'Java Server Pages': '#EDEDED', + 'Java Properties': '#2A6277', + 'Java Server Pages': '#2A6277', 'JavaScript': '#F1E05A', - 'JavaScript+ERB': '#EDEDED', - 'Jison': '#EDEDED', - 'Jison Lex': '#EDEDED', + 'JavaScript+ERB': '#F1E05A', + 'Jest Snapshot': '#15C213', + 'Jinja': '#A52A22', + 'Jison': '#56B3CB', + 'Jison Lex': '#56B3CB', 'Jolie': '#843179', 'Jsonnet': '#0064BD', 'Julia': '#A270BA', 'Jupyter Notebook': '#DA5B0B', 'KRL': '#28430A', 'Kaitai Struct': '#773B37', - 'KiCad Layout': '#EDEDED', - 'KiCad Legacy Layout': '#EDEDED', - 'KiCad Schematic': '#EDEDED', + 'KakouneScript': '#6F8042', + 'KiCad Layout': '#2F4AAB', + 'KiCad Legacy Layout': '#2F4AAB', + 'KiCad Schematic': '#2F4AAB', 'Kit': '#EDEDED', - 'Kotlin': '#F18E33', + 'Kotlin': '#A97BFF', + 'Kusto': '#EDEDED', 'LFE': '#4C3023', 'LLVM': '#185619', 'LOLCODE': '#CC9900', 'LSL': '#3D9970', 'LTspice Symbol': '#EDEDED', - 'LabVIEW': '#EDEDED', - 'Lark': '#0B130F', + 'LabVIEW': '#FEDE06', + 'Lark': '#2980B9', 'Lasso': '#999999', 'Latte': '#F2A542', 'Lean': '#EDEDED', 'Less': '#1D365D', 'Lex': '#DBCA00', - 'LilyPond': '#EDEDED', + 'LilyPond': '#9CCC7C', 'Limbo': '#EDEDED', 'Linker Script': '#EDEDED', 'Linux Kernel Module': '#EDEDED', 'Liquid': '#67B8DE', - 'Literate Agda': '#EDEDED', - 'Literate CoffeeScript': '#EDEDED', - 'Literate Haskell': '#EDEDED', + 'Literate Agda': '#315665', + 'Literate CoffeeScript': '#244776', + 'Literate Haskell': '#5E5086', 'LiveScript': '#499886', 'Logos': '#EDEDED', - 'Logtalk': '#EDEDED', + 'Logtalk': '#295B9A', 'LookML': '#652B81', 'LoomScript': '#EDEDED', 'Lua': '#000080', @@ -287,28 +316,31 @@ const languageColors = { 'MUF': '#EDEDED', 'Macaulay2': '#D8FFFF', 'Makefile': '#427819', - 'Mako': '#EDEDED', + 'Mako': '#7E858D', 'Markdown': '#083FA1', 'Marko': '#42BFF2', 'Mask': '#F97732', - 'Mathematica': '#EDEDED', + 'Mathematica': '#DD1100', 'Maven POM': '#EDEDED', 'Max': '#C4A79C', - 'MediaWiki': '#EDEDED', 'Mercury': '#FF2B2B', 'Meson': '#007800', 'Metal': '#8F14E9', 'Microsoft Developer Studio Project': '#EDEDED', + 'Microsoft Visual Studio Solution': '#EDEDED', 'MiniD': '#EDEDED', + 'MiniYAML': '#FF1111', + 'Mint': '#02B046', 'Mirah': '#C7A938', - 'Modelica': '#EDEDED', - 'Modula-2': '#EDEDED', + 'Modelica': '#DE1D31', + 'Modula-2': '#10253F', 'Modula-3': '#223388', 'Module Management System': '#EDEDED', 'Monkey': '#EDEDED', 'Moocode': '#EDEDED', - 'MoonScript': '#EDEDED', - 'Motorola 68K Assembly': '#EDEDED', + 'MoonScript': '#FF4585', + 'Motoko': '#FBB03B', + 'Motorola 68K Assembly': '#005DAA', 'Muse': '#EDEDED', 'Mustache': '#724B3B', 'Myghty': '#EDEDED', @@ -316,7 +348,7 @@ const languageColors = { 'NCL': '#28431F', 'NEON': '#EDEDED', 'NL': '#EDEDED', - 'NPM Config': '#EDEDED', + 'NPM Config': '#CB3837', 'NSIS': '#EDEDED', 'NWScript': '#111522', 'Nearley': '#990000', @@ -326,7 +358,7 @@ const languageColors = { 'NetLogo': '#FF6375', 'NewLisp': '#87AED7', 'Nextflow': '#3AC486', - 'Nginx': '#EDEDED', + 'Nginx': '#009639', 'Nim': '#FFC200', 'Ninja': '#EDEDED', 'Nit': '#009917', @@ -345,12 +377,12 @@ const languageColors = { 'Omgrofl': '#CABBFF', 'Opa': '#EDEDED', 'Opal': '#F7EDE0', - 'Open Policy Agent': '#EDEDED', - 'OpenCL': '#EDEDED', - 'OpenEdge ABL': '#EDEDED', + 'Open Policy Agent': '#7D9199', + 'OpenCL': '#ED2E2D', + 'OpenEdge ABL': '#5CE600', 'OpenQASM': '#AA70FF', 'OpenRC runscript': '#EDEDED', - 'OpenSCAD': '#EDEDED', + 'OpenSCAD': '#E5CD45', 'OpenStep Property List': '#EDEDED', 'OpenType Feature File': '#EDEDED', 'Org': '#77AA99', @@ -358,10 +390,11 @@ const languageColors = { 'Oxygene': '#CDD0E3', 'Oz': '#FAB738', 'P4': '#7055B5', + 'PEG.js': '#234D6B', 'PHP': '#4F5D95', 'PLSQL': '#DAD8D8', - 'PLpgSQL': '#EDEDED', - 'POV-Ray SDL': '#EDEDED', + 'PLpgSQL': '#336790', + 'POV-Ray SDL': '#6BAC65', 'Pan': '#CC0000', 'Papyrus': '#6600CC', 'Parrot': '#F3CA0A', @@ -373,7 +406,7 @@ const languageColors = { 'Perl': '#0298C3', 'Pic': '#EDEDED', 'Pickle': '#EDEDED', - 'PicoLisp': '#EDEDED', + 'PicoLisp': '#6067AF', 'PigLatin': '#FCD7DE', 'Pike': '#005390', 'PlantUML': '#EDEDED', @@ -381,16 +414,19 @@ const languageColors = { 'Pod 6': '#EDEDED', 'PogoScript': '#D80074', 'Pony': '#EDEDED', - 'PostCSS': '#EDEDED', + 'PostCSS': '#DC3A0C', 'PostScript': '#DA291C', 'PowerBuilder': '#8F0F8D', 'PowerShell': '#012456', 'Prisma': '#0C344B', 'Processing': '#0096D8', + 'Procfile': '#3B2F63', 'Proguard': '#EDEDED', 'Prolog': '#74283C', + 'Promela': '#DE0000', 'Propeller Spin': '#7FA2A7', 'Protocol Buffer': '#EDEDED', + 'Protocol Buffer Text Format': '#EDEDED', 'Public Key': '#EDEDED', 'Pug': '#A86454', 'Puppet': '#302B6D', @@ -398,8 +434,8 @@ const languageColors = { 'PureBasic': '#5A6986', 'PureScript': '#1D222D', 'Python': '#3572A5', - 'Python console': '#EDEDED', - 'Python traceback': '#EDEDED', + 'Python console': '#3572A5', + 'Python traceback': '#3572A5', 'Q#': '#FED659', 'QML': '#44A51C', 'QMake': '#EDEDED', @@ -407,11 +443,12 @@ const languageColors = { 'Quake': '#882233', 'R': '#198CE7', 'RAML': '#77D9FB', - 'RDoc': '#EDEDED', + 'RDoc': '#701516', 'REALbasic': '#EDEDED', - 'REXX': '#EDEDED', - 'RMarkdown': '#EDEDED', + 'REXX': '#D90E09', + 'RMarkdown': '#198CE7', 'RPC': '#EDEDED', + 'RPGLE': '#2BDE21', 'RPM Spec': '#EDEDED', 'RUNOFF': '#665A4E', 'Racket': '#3C5CAA', @@ -426,25 +463,27 @@ const languageColors = { 'Record Jar': '#0673BA', 'Red': '#F50000', 'Redcode': '#EDEDED', - 'Regular Expression': '#EDEDED', + 'Redirect Rules': '#EDEDED', + 'Regular Expression': '#009A00', 'Ren\'Py': '#FF7F7F', 'RenderScript': '#EDEDED', 'Rich Text Format': '#EDEDED', 'Ring': '#2D54CB', 'Riot': '#A71E49', - 'RobotFramework': '#EDEDED', + 'RobotFramework': '#00C0B5', 'Roff': '#ECDEBE', - 'Roff Manpage': '#EDEDED', + 'Roff Manpage': '#ECDEBE', 'Rouge': '#CC0088', 'Ruby': '#701516', 'Rust': '#DEA584', 'SAS': '#B34936', 'SCSS': '#C6538C', + 'SELinux Policy': '#EDEDED', 'SMT': '#EDEDED', - 'SPARQL': '#EDEDED', + 'SPARQL': '#0C4597', 'SQF': '#3F3F3F', - 'SQL': '#EDEDED', - 'SQLPL': '#EDEDED', + 'SQL': '#E38C00', + 'SQLPL': '#E38C00', 'SRecode Template': '#348A34', 'SSH Config': '#EDEDED', 'STON': '#EDEDED', @@ -456,42 +495,46 @@ const languageColors = { 'Scala': '#C22D40', 'Scaml': '#BD181A', 'Scheme': '#1E4AEC', - 'Scilab': '#EDEDED', + 'Scilab': '#CA0F21', 'Self': '#0579AA', - 'ShaderLab': '#EDEDED', + 'ShaderLab': '#222C37', 'Shell': '#89E051', + 'ShellCheck Config': '#CECFCB', 'ShellSession': '#EDEDED', 'Shen': '#120F14', 'Sieve': '#EDEDED', + 'Singularity': '#64E6AD', 'Slash': '#007EFF', 'Slice': '#003FA2', 'Slim': '#2B2B2B', 'SmPL': '#C94949', 'Smali': '#EDEDED', 'Smalltalk': '#596706', - 'Smarty': '#EDEDED', + 'Smarty': '#F0C040', 'Solidity': '#AA6746', + 'Soong': '#EDEDED', 'SourcePawn': '#F69E1D', 'Spline Font Database': '#EDEDED', 'Squirrel': '#800000', 'Stan': '#B2011D', 'Standard ML': '#DC566D', 'Starlark': '#76D275', - 'Stata': '#EDEDED', + 'Stata': '#1A5F91', + 'StringTemplate': '#3FB34F', 'Stylus': '#FF6347', - 'SubRip Text': '#EDEDED', - 'SugarSS': '#EDEDED', + 'SubRip Text': '#9E0101', + 'SugarSS': '#2FCC9F', 'SuperCollider': '#46390B', 'Svelte': '#FF3E00', - 'Swift': '#FFAC45', + 'Swift': '#F05138', 'SystemVerilog': '#DAE1C2', 'TI Program': '#A0AA87', - 'TLA': '#EDEDED', - 'TOML': '#EDEDED', - 'TSQL': '#EDEDED', - 'TSV': '#EDEDED', - 'TSX': '#EDEDED', - 'TXL': '#EDEDED', + 'TLA': '#4B0079', + 'TOML': '#9C4221', + 'TSQL': '#E38C00', + 'TSV': '#237346', + 'TSX': '#2B7489', + 'TXL': '#0178B8', 'Tcl': '#E4CC98', 'Tcsh': '#EDEDED', 'TeX': '#3D6117', @@ -499,57 +542,63 @@ const languageColors = { 'Terra': '#00004C', 'Texinfo': '#EDEDED', 'Text': '#EDEDED', - 'Textile': '#EDEDED', - 'Thrift': '#EDEDED', + 'TextMate Properties': '#DF66E4', + 'Textile': '#FFE7AC', + 'Thrift': '#D12127', 'Turing': '#CF142B', 'Turtle': '#EDEDED', 'Twig': '#C1D026', 'Type Language': '#EDEDED', 'TypeScript': '#2B7489', 'Unified Parallel C': '#4E3617', - 'Unity3D Asset': '#EDEDED', + 'Unity3D Asset': '#222C37', 'Unix Assembly': '#EDEDED', 'Uno': '#9933CC', 'UnrealScript': '#A54C4D', - 'UrWeb': '#EDEDED', + 'UrWeb': '#CCCCEE', 'V': '#4F87C4', 'VBA': '#867DB1', 'VBScript': '#15DCDC', 'VCL': '#148AA8', 'VHDL': '#ADB2CB', 'Vala': '#FBE5CD', + 'Valve Data Format': '#F26025', 'Verilog': '#B2B7F8', - 'Vim Help File': '#EDEDED', - 'Vim Snippet': '#EDEDED', - 'Vim script': '#199F4B', + 'Vim Help File': '#199F4B', + 'Vim Script': '#199F4B', + 'Vim Snippet': '#199F4B', 'Visual Basic .NET': '#945DB7', 'Volt': '#1F1F1F', - 'Vue': '#2C3E50', + 'Vue': '#41B883', + 'Vyper': '#2980B9', 'Wavefront Material': '#EDEDED', 'Wavefront Object': '#EDEDED', - 'Web Ontology Language': '#EDEDED', + 'Web Ontology Language': '#5B70BD', 'WebAssembly': '#04133B', 'WebIDL': '#EDEDED', 'WebVTT': '#EDEDED', 'Wget Config': '#EDEDED', - 'Windows Registry Entries': '#EDEDED', + 'Wikitext': '#FC5757', + 'Windows Registry Entries': '#52D5FF', + 'Witcher Script': '#FF0000', 'Wollok': '#A23738', - 'World of Warcraft Addon Data': '#EDEDED', + 'World of Warcraft Addon Data': '#F7E43F', 'X BitMap': '#EDEDED', 'X Font Directory Index': '#EDEDED', 'X PixMap': '#EDEDED', 'X10': '#4B6BEF', 'XC': '#99DA07', 'XCompose': '#EDEDED', - 'XML': '#EDEDED', - 'XML Property List': '#EDEDED', + 'XML': '#0060AC', + 'XML Property List': '#0060AC', 'XPages': '#EDEDED', 'XProc': '#EDEDED', 'XQuery': '#5232E7', 'XS': '#EDEDED', 'XSLT': '#EB8CEB', - 'Xojo': '#EDEDED', - 'Xtend': '#EDEDED', + 'Xojo': '#81BD41', + 'Xonsh': '#285EEF', + 'Xtend': '#24255D', 'YAML': '#CB171E', 'YANG': '#EDEDED', 'YARA': '#220000', @@ -561,21 +610,25 @@ const languageColors = { 'ZenScript': '#00BCD1', 'Zephir': '#118F9E', 'Zig': '#EC915C', - 'Zimpl': '#EDEDED', + 'Zimpl': '#D67711', 'cURL Config': '#EDEDED', 'desktop': '#EDEDED', 'dircolors': '#EDEDED', 'eC': '#913960', 'edn': '#EDEDED', - 'fish': '#EDEDED', + 'fish': '#4AAE47', + 'hoon': '#00B171', + 'jq': '#C7254E', + 'kvlang': '#1DA6E0', 'mIRC Script': '#3D57C3', 'mcfunction': '#E22837', - 'mupad': '#EDEDED', - 'nanorc': '#EDEDED', + 'mupad': '#244963', + 'nanorc': '#2D004D', 'nesC': '#94B0C7', 'ooc': '#B0B77E', 'q': '#0040CD', - 'reStructuredText': '#EDEDED', + 'reStructuredText': '#141414', + 'robots.txt': '#EDEDED', 'sed': '#64B970', 'wdl': '#42F1F4', 'wisp': '#7582D1', From 46a06fec3c12596b460ed56a08ab576731bc2fc0 Mon Sep 17 00:00:00 2001 From: robrbecker Date: Mon, 14 Mar 2022 04:46:34 +0000 Subject: [PATCH 024/139] prep 9.0.3 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afffef1d..7813d830 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.0.3 + +* Update Language Colors March 13th 2022 by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/302 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.0.2...9.0.3 + ## 9.0.2 - Switched to use the lints package instead of pedantic https://github.com/SpinlockLabs/github.dart/pull/301 diff --git a/pubspec.yaml b/pubspec.yaml index 4a035a95..7065b6fa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.0.2 +version: 9.0.3 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From e79e5e7a2ae9f29796a9d6dfd39b84106f23b2e8 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 14 Mar 2022 17:25:47 -0600 Subject: [PATCH 025/139] update contributing guide --- CONTRIBUTING.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ddf07a0a..d9a74cae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,3 +38,12 @@ Pull Request rejections are not a bad thing. It just means you need to fix somet ## Becoming a Committer If you get on IRC and ask us, we can review your work and add you as a committer if we think you should have it. + +## Releasing & Publishing + +This repo is now configured to release after every PR merge. This means a couple things for PRs that are put up: + +1. A semver label is required. A github check will remind you that you need one. Reviewers should check that it is correct. +2. There is no need to modify the version in the pubspec.yaml in your PRs. The tooling will update the version according to the semver label applied to your PR. +3. Same thing for the CHANGELOG.md. Tooling will update it automatically after merge. +4. A github release will be created and published ot pub.dev for you. \ No newline at end of file From 55b7aef3c3c9e1609466596d24e6d6253614fae9 Mon Sep 17 00:00:00 2001 From: Xilai Zhang Date: Mon, 28 Mar 2022 11:28:21 -0700 Subject: [PATCH 026/139] create event from githhub webhook event --- lib/src/server/hooks.dart | 21 +++++++++++++++++++++ lib/src/server/hooks.g.dart | 21 +++++++++++++++++++++ test/src/mocks.mocks.dart | 8 +++----- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index 8c8ac396..b33a5b8e 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -214,3 +214,24 @@ class PullRequestEvent extends HookEvent { _$PullRequestEventFromJson(input); Map toJson() => _$PullRequestEventToJson(this); } + +@JsonSerializable(fieldRename: FieldRename.snake) +class CreateEvent extends HookEvent { + CreateEvent({ + this.ref, + this.refType, + this.pusherType, + this.repository, + this.sender, + }); + + factory CreateEvent.fromJson(Map input) => _$CreateEventFromJson(input); + String? ref; + String? refType; + String? pusherType; + Repository? repository; + User? sender; + + Map toJson() => _$CreateEventToJson(this); +} + diff --git a/lib/src/server/hooks.g.dart b/lib/src/server/hooks.g.dart index 108b0e7a..3babd5cf 100644 --- a/lib/src/server/hooks.g.dart +++ b/lib/src/server/hooks.g.dart @@ -152,3 +152,24 @@ Map _$PullRequestEventToJson(PullRequestEvent instance) => 'sender': instance.sender, 'repository': instance.repository, }; + +CreateEvent _$CreateEventFromJson(Map json) => CreateEvent( + ref: json['ref'] as String?, + refType: json['ref_type'] as String?, + pusherType: json['pusher_type'] as String?, + repository: json['repository'] == null + ? null + : Repository.fromJson(json['repository'] as Map), + sender: json['sender'] == null + ? null + : User.fromJson(json['sender'] as Map), + ); + +Map _$CreateEventToJson(CreateEvent instance) => + { + 'ref': instance.ref, + 'ref_type': instance.refType, + 'pusher_type': instance.pusherType, + 'repository': instance.repository, + 'sender': instance.sender, + }; diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index bd1c1b8c..03e42ae9 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.0.15 from annotations +// Mocks generated by Mockito 5.1.0 from annotations // in github/test/src/mocks.dart. // Do not manually edit this file. @@ -8,15 +8,15 @@ import 'package:github/src/common.dart' as _i3; import 'package:http/http.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +// ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters -// ignore_for_file: camel_case_types // ignore_for_file: comment_references // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors -// ignore_for_file: unnecessary_overrides // ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types class _FakeClient_0 extends _i1.Fake implements _i2.Client {} @@ -259,6 +259,4 @@ class MockGitHub extends _i1.Mock implements _i3.GitHub { @override void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), returnValueForMissingStub: null); - @override - String toString() => super.toString(); } From 3fd3fe5816c6156d6e6850f569fc5974513d59de Mon Sep 17 00:00:00 2001 From: Xilai Zhang Date: Mon, 28 Mar 2022 11:37:40 -0700 Subject: [PATCH 027/139] Revert "create event from githhub webhook event" This reverts commit 55b7aef3c3c9e1609466596d24e6d6253614fae9. --- lib/src/server/hooks.dart | 21 --------------------- lib/src/server/hooks.g.dart | 21 --------------------- test/src/mocks.mocks.dart | 8 +++++--- 3 files changed, 5 insertions(+), 45 deletions(-) diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index b33a5b8e..8c8ac396 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -214,24 +214,3 @@ class PullRequestEvent extends HookEvent { _$PullRequestEventFromJson(input); Map toJson() => _$PullRequestEventToJson(this); } - -@JsonSerializable(fieldRename: FieldRename.snake) -class CreateEvent extends HookEvent { - CreateEvent({ - this.ref, - this.refType, - this.pusherType, - this.repository, - this.sender, - }); - - factory CreateEvent.fromJson(Map input) => _$CreateEventFromJson(input); - String? ref; - String? refType; - String? pusherType; - Repository? repository; - User? sender; - - Map toJson() => _$CreateEventToJson(this); -} - diff --git a/lib/src/server/hooks.g.dart b/lib/src/server/hooks.g.dart index 3babd5cf..108b0e7a 100644 --- a/lib/src/server/hooks.g.dart +++ b/lib/src/server/hooks.g.dart @@ -152,24 +152,3 @@ Map _$PullRequestEventToJson(PullRequestEvent instance) => 'sender': instance.sender, 'repository': instance.repository, }; - -CreateEvent _$CreateEventFromJson(Map json) => CreateEvent( - ref: json['ref'] as String?, - refType: json['ref_type'] as String?, - pusherType: json['pusher_type'] as String?, - repository: json['repository'] == null - ? null - : Repository.fromJson(json['repository'] as Map), - sender: json['sender'] == null - ? null - : User.fromJson(json['sender'] as Map), - ); - -Map _$CreateEventToJson(CreateEvent instance) => - { - 'ref': instance.ref, - 'ref_type': instance.refType, - 'pusher_type': instance.pusherType, - 'repository': instance.repository, - 'sender': instance.sender, - }; diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index 03e42ae9..bd1c1b8c 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.1.0 from annotations +// Mocks generated by Mockito 5.0.15 from annotations // in github/test/src/mocks.dart. // Do not manually edit this file. @@ -8,15 +8,15 @@ import 'package:github/src/common.dart' as _i3; import 'package:http/http.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; -// ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters +// ignore_for_file: camel_case_types // ignore_for_file: comment_references // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_overrides // ignore_for_file: unnecessary_parenthesis -// ignore_for_file: camel_case_types class _FakeClient_0 extends _i1.Fake implements _i2.Client {} @@ -259,4 +259,6 @@ class MockGitHub extends _i1.Mock implements _i3.GitHub { @override void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), returnValueForMissingStub: null); + @override + String toString() => super.toString(); } From 3e6410e99ceaaab4052bc3463fce067f56c7e83c Mon Sep 17 00:00:00 2001 From: Xilai Zhang Date: Mon, 28 Mar 2022 11:39:18 -0700 Subject: [PATCH 028/139] create webhook event, without edit to mocks.mocks --- lib/src/server/hooks.dart | 20 ++++++++++++++++++++ lib/src/server/hooks.g.dart | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index 8c8ac396..93bf330b 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -214,3 +214,23 @@ class PullRequestEvent extends HookEvent { _$PullRequestEventFromJson(input); Map toJson() => _$PullRequestEventToJson(this); } + +@JsonSerializable(fieldRename: FieldRename.snake) +class CreateEvent extends HookEvent { + CreateEvent({ + this.ref, + this.refType, + this.pusherType, + this.repository, + this.sender, + }); + + factory CreateEvent.fromJson(Map input) => _$CreateEventFromJson(input); + String? ref; + String? refType; + String? pusherType; + Repository? repository; + User? sender; + + Map toJson() => _$CreateEventToJson(this); +} diff --git a/lib/src/server/hooks.g.dart b/lib/src/server/hooks.g.dart index 108b0e7a..3babd5cf 100644 --- a/lib/src/server/hooks.g.dart +++ b/lib/src/server/hooks.g.dart @@ -152,3 +152,24 @@ Map _$PullRequestEventToJson(PullRequestEvent instance) => 'sender': instance.sender, 'repository': instance.repository, }; + +CreateEvent _$CreateEventFromJson(Map json) => CreateEvent( + ref: json['ref'] as String?, + refType: json['ref_type'] as String?, + pusherType: json['pusher_type'] as String?, + repository: json['repository'] == null + ? null + : Repository.fromJson(json['repository'] as Map), + sender: json['sender'] == null + ? null + : User.fromJson(json['sender'] as Map), + ); + +Map _$CreateEventToJson(CreateEvent instance) => + { + 'ref': instance.ref, + 'ref_type': instance.refType, + 'pusher_type': instance.pusherType, + 'repository': instance.repository, + 'sender': instance.sender, + }; From 696559aafc6abbeea678da84af2960e977283223 Mon Sep 17 00:00:00 2001 From: Xilai Zhang Date: Mon, 28 Mar 2022 17:33:29 -0700 Subject: [PATCH 029/139] add test --- test/server/hooks_test.dart | 18 +++++ test/server/hooks_test_data.dart | 124 +++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) diff --git a/test/server/hooks_test.dart b/test/server/hooks_test.dart index b9d87e65..09deae27 100644 --- a/test/server/hooks_test.dart +++ b/test/server/hooks_test.dart @@ -39,4 +39,22 @@ void main() { expect(checkRun.status, CheckRunStatus.queued); }); }); + + group('CreateEvent', () { + test('deserialize', () async { + final createEvent = CreateEvent.fromJson( + json.decode(createString) as Map); + expect(createEvent.ref, 'simple-branch'); + expect(createEvent.refType, 'branch'); + expect(createEvent.pusherType, 'user'); + + final repo = createEvent.repository!; + expect(repo.slug().fullName, 'Codertocat/Hello-World'); + expect(repo.id, 186853002); + + final sender = createEvent.sender!; + expect(sender.login, "Codertocat"); + expect(sender.htmlUrl, "https://github.com/Codertocat"); + }); + }); } diff --git a/test/server/hooks_test_data.dart b/test/server/hooks_test_data.dart index 6d780d51..c6f12f84 100644 --- a/test/server/hooks_test_data.dart +++ b/test/server/hooks_test_data.dart @@ -548,3 +548,127 @@ const String checkRunString = ''' } } '''; + +const String createString = ''' +{ + "ref": "simple-branch", + "ref_type": "branch", + "master_branch": "master", + "description": null, + "pusher_type": "user", + "repository": { + "id": 186853002, + "node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "private": false, + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2019-05-15T15:19:25Z", + "updated_at": "2019-05-15T15:20:41Z", + "pushed_at": "2019-05-15T15:20:56Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Ruby", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": null, + "forks": 1, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + } +} +'''; From 4d2a485f21e6d54e986315e0880d5ec3587a83dd Mon Sep 17 00:00:00 2001 From: Xilai Zhang Date: Tue, 29 Mar 2022 10:02:48 -0700 Subject: [PATCH 030/139] format files --- lib/src/server/hooks.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index 93bf330b..ea250c48 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -225,7 +225,8 @@ class CreateEvent extends HookEvent { this.sender, }); - factory CreateEvent.fromJson(Map input) => _$CreateEventFromJson(input); + factory CreateEvent.fromJson(Map input) => + _$CreateEventFromJson(input); String? ref; String? refType; String? pusherType; From 781e8beb889162f7f3b4f662b1f66dccb4dc25f0 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 29 Mar 2022 16:36:21 -0600 Subject: [PATCH 031/139] prep 9.1.0 --- CHANGELOG.md | 9 +++++++++ pubspec.yaml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7813d830..a8a57b4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 9.1.0 + +* add 'create' github webhook event to hooks.dart by @XilaiZhang in https://github.com/SpinlockLabs/github.dart/pull/304 + +## New Contributors +* @XilaiZhang made their first contribution in https://github.com/SpinlockLabs/github.dart/pull/304 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.0.3...9.1.0 + ## 9.0.3 * Update Language Colors March 13th 2022 by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/302 diff --git a/pubspec.yaml b/pubspec.yaml index 7065b6fa..01e5fbde 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.0.3 +version: 9.1.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 28446163b310d1df756232240486609ad7660f48 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 7 Apr 2022 05:23:48 -0400 Subject: [PATCH 032/139] add beta dependabot --- .github/dependabot.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 00000000..39bd9ac1 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,7 @@ +version: 2 +enable-beta-ecosystems: true +updates: + - package-ecosystem: "pub" + directory: "/" + schedule: + interval: "weekly" \ No newline at end of file From 70db48001c85c454e5d258617626f82acce56669 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 11 Apr 2022 12:45:46 -0600 Subject: [PATCH 033/139] prep 9.1.1 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8a57b4e..f1de1051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.1.1 + +* Don't add state query param twice by @passsy in https://github.com/SpinlockLabs/github.dart/pull/264 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.1.0...9.1.1 + ## 9.1.0 * add 'create' github webhook event to hooks.dart by @XilaiZhang in https://github.com/SpinlockLabs/github.dart/pull/304 diff --git a/pubspec.yaml b/pubspec.yaml index 01e5fbde..3d088c7b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.1.0 +version: 9.1.1 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From e679667362176cb22c3f5af7efc4087cc8566ec2 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 11 Apr 2022 15:44:34 -0600 Subject: [PATCH 034/139] dart format --- lib/src/common/pulls_service.dart | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index 4a49521b..38f659c9 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -29,12 +29,9 @@ class PullRequestsService extends Service { putValue('sort', sort, params); putValue('state', state, params); - return PaginationHelper(github).objects( - 'GET', - '/repos/${slug.fullName}/pulls', - (dynamic i) => PullRequest.fromJson(i), - pages: pages, - params: params); + return PaginationHelper(github).objects('GET', + '/repos/${slug.fullName}/pulls', (dynamic i) => PullRequest.fromJson(i), + pages: pages, params: params); } /// Fetches a single pull request. From 76887704d6b6ad60879c8f049ddaf9c315a138a5 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:31:48 -0600 Subject: [PATCH 035/139] fixes for error handling and createComment --- lib/src/common/github.dart | 25 +++-- lib/src/common/pulls_service.dart | 4 +- pubspec.yaml | 5 +- tool/auto_release_on_merge.dart | 112 -------------------- tool/release_unreleased_prs.dart | 170 ++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+), 125 deletions(-) delete mode 100644 tool/auto_release_on_merge.dart create mode 100644 tool/release_unreleased_prs.dart diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index 31605c91..e715c2a9 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -419,19 +419,24 @@ class GitHub { /// @alwaysThrows void handleStatusCode(http.Response response) { - String? message; + print(response.body); + String? message = ''; List>? errors; if (response.headers['content-type']!.contains('application/json')) { - final json = jsonDecode(response.body); - message = json['message']; - if (json['errors'] != null) { - try { - errors = List>.from(json['errors']); - } catch (_) { - errors = [ - {'code': json['errors'].toString()} - ]; + try { + final json = jsonDecode(response.body); + message = json['message']; + if (json['errors'] != null) { + try { + errors = List>.from(json['errors']); + } catch (_) { + errors = [ + {'code': json['errors'].toString()} + ]; + } } + } catch (ex) { + print(ex); } } switch (response.statusCode) { diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index 8c1d3633..7c05a010 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -164,12 +164,12 @@ class PullRequestsService extends Service { /// Creates a new pull request comment. /// /// API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment - Future createComment( + Future createComment( RepositorySlug slug, int number, CreatePullRequestComment comment) { return github.postJSON('/repos/${slug.fullName}/pulls/$number/comments', body: GitHubJson.encode(comment.toJson()), convert: (dynamic i) => PullRequestComment.fromJson(i), - statusCode: 201) as Future; + statusCode: 201); } // TODO: Implement editComment: https://developer.github.com/v3/pulls/comments/#edit-a-comment diff --git a/pubspec.yaml b/pubspec.yaml index 01e5fbde..8a31d767 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,6 @@ environment: sdk: '>=2.14.0 <3.0.0' dependencies: - collection: ^1.15.0 http: ^0.13.0 http_parser: ^4.0.0 json_annotation: ^4.3.0 @@ -17,8 +16,12 @@ dev_dependencies: build_runner: any build_test: any build_web_compilers: any + collection: ^1.15.0 + dependency_validator: json_serializable: ^6.0.0 lints: ^1.0.0 mockito: ^5.0.0 + pub_semver: test: ^1.16.0 yaml: ^3.0.0 + yaml_edit: diff --git a/tool/auto_release_on_merge.dart b/tool/auto_release_on_merge.dart deleted file mode 100644 index 2b762bd0..00000000 --- a/tool/auto_release_on_merge.dart +++ /dev/null @@ -1,112 +0,0 @@ -import 'dart:io'; -import 'package:github/github.dart'; -import 'package:yaml/yaml.dart'; - -const semvers = ['major', 'minor', 'patch']; - -/// Meant to be run from the github workflow. -/// Expected arguments of: -/// [repo] the full repo owner/name format -/// [pr number] PR number of which to release -/// the semver label is expected to be on the PR -void main(List args) async { - if (args.length < 2) { - print('Usage: dart tool/auto_release_on_merge owner_and_repo pull_number'); - exit(1); - } - - final fullrepo = args[0]; - final pullnumber = int.parse(args[1]); - final currentVersion = getVersion(); - var slug = RepositorySlug.full(fullrepo); - var gh = GitHub(auth: findAuthenticationFromEnvironment()); - - print('Loading PR $pullnumber from $slug'); - var pr = await gh.pullRequests.get(slug, pullnumber); - if (!(pr.merged ?? false)) { - print('PR not merged. skipping.'); - exit(0); - } - print('PR $pullnumber loaded'); - - var labels = pr.labels ?? []; - var semverLabel = labels - .map((e) => e.name) - .firstWhere((label) => label.startsWith('semver'), orElse: () => ''); - if (semverLabel.isEmpty) { - print('No semver label found'); - exit(2); - } - semverLabel = semverLabel.toLowerCase().replaceAll('semver:', '').trim(); - // ensure the semver label is valid - if (!semvers.contains(semverLabel)) { - print('semver label [$semverLabel] is not one of $semvers'); - exit(3); - } - print('Semver label: $semverLabel'); - - run('cider bump $semverLabel'); - var newVersion = getVersion(); - print('Current Version: $currentVersion'); - print('New Version : $newVersion'); - - var rn = await gh.repositories.generateReleaseNotes(CreateReleaseNotes( - slug.owner, slug.name, newVersion, - previousTagName: currentVersion)); - - var releaseNotes = rn.body.replaceFirst('## What\'s Changed', ''); - releaseNotes = '## $newVersion\n$releaseNotes'; - - print(releaseNotes); - - var log = File('CHANGELOG.md'); - var logdata = log.existsSync() ? log.readAsStringSync() : ''; - log.writeAsStringSync('${releaseNotes}\n\n$logdata'); - - run('git add pubspec.yaml CHANGELOG.md'); - run('git', rest: ['commit', '-m', 'prep $newVersion']); - run('git push'); - // var commit = run('git rev-parse HEAD'); - // print('autoprep commit: $commit'); - - var release = await gh.repositories.createRelease( - slug, - CreateRelease.from( - tagName: newVersion, - name: newVersion, - generateReleaseNotes: true, - targetCommitish: 'master', - isDraft: false, - isPrerelease: false)); - - print('$newVersion release created at ${release.createdAt}'); - exit(0); -} - -String getVersion() { - var y = loadYaml(File('pubspec.yaml').readAsStringSync()); - var newVersion = y['version'].toString(); - return newVersion; -} - -String run(String cmd, {List? rest}) { - var args = []; - if (rest != null) { - args = rest; - } else { - args = cmd.split(' '); - if (args.isEmpty) return ''; - cmd = args.removeAt(0); - } - var result = Process.runSync(cmd, args); - if (result.exitCode != 0) { - print('Command failed'); - } - if (result.stdout != null) print(result.stdout); - if (result.stderr != null) print(result.stderr); - if (result.exitCode != 0) { - exit(6); - } - - return result.stdout; -} diff --git a/tool/release_unreleased_prs.dart b/tool/release_unreleased_prs.dart new file mode 100644 index 00000000..3bec7a3d --- /dev/null +++ b/tool/release_unreleased_prs.dart @@ -0,0 +1,170 @@ +import 'dart:io'; +import 'package:github/github.dart'; +import 'package:pub_semver/pub_semver.dart'; +import 'package:yaml_edit/yaml_edit.dart'; + +/////////////////////////////////////////////////////////// +const mainBranchName = 'main'; +const semverMajor = 'semver:major'; +const semverMinor = 'semver:minor'; +const semverPatch = 'semver:patch'; +const semvers = [semverMajor, semverMinor, semverPatch]; +const fullrepo = 'SpinlockLabs/github.dart'; +/////////////////////////////////////////////////////////// + +var _gh = GitHub(auth: findAuthenticationFromEnvironment()); +var _slug = RepositorySlug.full(fullrepo); + +Future main(List args) async { + // get the latest released version + var latestVersion = await getLatestVersion(_slug); + + // get all PRs (issues) that are merged but unreleased + var unreleased = await getUnreleasedPRs(); + + if (unreleased.isEmpty) { + print('No unreleased PRs found'); + return; + } + + // Calculate the next version + var nextVersion = getNextVersion(latestVersion, unreleased); + + // Use the new version to generate release notes + var notes = await generateReleaseNotes(latestVersion.toString(), nextVersion); + + // update the changelog with the new release notes + updateChangeLog(notes, nextVersion); + + // update the version in the pubspec + updatePubspec(nextVersion); + + // commit those changes and push them + commitUpdates(nextVersion); + + // create a new release in github at main + await createRelease(nextVersion, mainBranchName); + + // remove the unreleased labels + for (final i in unreleased) { + await _gh.issues.removeLabelForIssue(_slug, i.number, 'unreleased'); + await _gh.issues.addLabelsToIssue(_slug, i.number, ['released']); + await _gh.issues.createComment(_slug, i.number, 'Released in version $nextVersion https://github.com/$fullrepo/releases/tag/$nextVersion'); + } + + exit(0); +} + +String run(String cmd, {List? rest}) { + var args = []; + if (rest != null) { + args = rest; + } else { + args = cmd.split(' '); + if (args.isEmpty) { + return ''; + } + cmd = args.removeAt(0); + } + var result = Process.runSync(cmd, args); + if (result.exitCode != 0) { + print('Command failed'); + } + if (result.stdout != null) { + print(result.stdout); + } + if (result.stderr != null) { + print(result.stderr); + } + // if (result.exitCode != 0) { + // exit(6); + // } + + return result.stdout; +} + +Future getLatestVersion(RepositorySlug slug) async { + var latestRelease = await _gh.repositories.getLatestRelease(slug); + var latestTag = latestRelease.tagName!; + print('Latest Tag: $latestTag'); + return Version.parse(latestTag); +} + +Future> getUnreleasedPRs() async { + print('Loading unreleased PRs...'); + var prs = await _gh.search.issues('repo:${_slug.fullName} is:pull-request label:unreleased state:closed', sort: 'desc').toList(); + print('${prs.length} loaded'); + return prs; +} + +String getNextVersion(Version currentVersion, List unreleased) { + var semvers = Set(); + for (final pr in unreleased){ + var prlabels = pr.labels.where((element) => element.name.startsWith('semver:')).toList(); + for (final l in prlabels) { + semvers.add(l.name); + } + } + print('Calculating next version based on $semvers'); + var newVersion = ''; + if (semvers.contains('semver:major')) { + newVersion = currentVersion.nextMajor.toString(); + } else if (semvers.contains('semver:minor')) { + newVersion = currentVersion.nextMinor.toString(); + } else if (semvers.contains('semver:patch')) { + newVersion = currentVersion.nextPatch.toString(); + } + print('Next Version: $newVersion'); + return newVersion; +} + +Future generateReleaseNotes(String fromVersion, String newVersion) async { + var notes = await _gh.repositories.generateReleaseNotes(CreateReleaseNotes( + _slug.owner, _slug.name, newVersion, + previousTagName: fromVersion)); + + var releaseNotes = notes.body.replaceFirst('## What\'s Changed', ''); + + var r = '## $newVersion\n$releaseNotes'; + print(r); + return r; +} + +void updateChangeLog(String notes, String version) { + var log = File('CHANGELOG.md'); + var logdata = log.existsSync() ? log.readAsStringSync() : ''; + if (logdata.contains('## $version')) { + return; + } + log.writeAsStringSync('$notes\n\n$logdata'); +} + +void updatePubspec(String newVersion) { + var f = File('pubspec.yaml'); + var editor = YamlEditor(f.readAsStringSync()); + editor.update(['version'], newVersion); + f.writeAsStringSync(editor.toString()); +} + +Future createRelease(String version, String target) async { + print('Creating release ...'); + var release = await _gh.repositories.createRelease( + _slug, + CreateRelease.from( + tagName: version, + name: version, + generateReleaseNotes: true, + targetCommitish: target, + isDraft: false, + isPrerelease: false)); + + print('Release ${release.name} created ${release.createdAt}'); + print(release.body); + return release; +} + +void commitUpdates(String version) { + run('git add pubspec.yaml CHANGELOG.md'); + run('git', rest: ['commit', '-m', 'prep $version']); + run('git push'); +} \ No newline at end of file From 52fe66c45db103c534b576096bdf0841b7039a1b Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:33:14 -0600 Subject: [PATCH 036/139] fix getIfExists when creating a release --- lib/src/common/repos_service.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/common/repos_service.dart b/lib/src/common/repos_service.dart index 04163260..45904bc2 100644 --- a/lib/src/common/repos_service.dart +++ b/lib/src/common/repos_service.dart @@ -1003,7 +1003,11 @@ class RepositoriesService extends Service { if (alreadyExistsErrorCode != null) { final field = alreadyExistsErrorCode['field']; if (field == 'tag_name') { - return getReleaseByTagName(slug, createRelease.tagName); + if (getIfExists) { + return getReleaseByTagName(slug, createRelease.tagName); + } else { + throw Exception('Tag / Release already exists ${createRelease.tagName}'); + } } } else { print( From 08327e50e5da6263b1d42f2f4f1823564dc86895 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:33:59 -0600 Subject: [PATCH 037/139] update github workflows --- ..._on_merge.yml => release_unreleased_prs.yml} | 17 ++++++++--------- .github/workflows/require_semver_label.yml | 9 +++++++-- .github/workflows/tests.yml | 4 ---- .github/workflows/triage.yml | 2 +- .pubignore | 3 +++ 5 files changed, 19 insertions(+), 16 deletions(-) rename .github/workflows/{auto_release_on_merge.yml => release_unreleased_prs.yml} (60%) create mode 100644 .pubignore diff --git a/.github/workflows/auto_release_on_merge.yml b/.github/workflows/release_unreleased_prs.yml similarity index 60% rename from .github/workflows/auto_release_on_merge.yml rename to .github/workflows/release_unreleased_prs.yml index 21a6f293..2999ef34 100644 --- a/.github/workflows/auto_release_on_merge.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -1,6 +1,7 @@ -name: Auto-Release on PR Merge +name: Release unreleased PR -# Runs when a PR merges. See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges +# Runs when a PR merges. +# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges on: pull_request: types: @@ -9,25 +10,23 @@ on: jobs: release: if: github.event.pull_request.merged == true - permissions: - contents: write runs-on: ubuntu-latest container: dart:2.14.4 + permissions: + contents: write steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 2 - ref: master + ref: main - name: Release run: | git config --global user.name ${{ secrets.USER_NAME }} git config --global user.email ${{ secrets.USER_EMAIL }} export PATH="$PATH":"$HOME/.pub-cache/bin" - export GITHUB_TOKEN=${{secrets.GITHUB_TOKEN}} + export GITHUB_TOKEN=${{secrets.MACHINE_GITHUB_API_TOKEN}} export MACHINE_GITHUB_API_TOKEN=${{secrets.MACHINE_GITHUB_API_TOKEN}} pub get - pub global activate cider - dart tool/auto_release_on_merge.dart ${{github.repository}} ${{github.event.pull_request.number}} - \ No newline at end of file + dart tool/release_unreleased_prs.dart \ No newline at end of file diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml index 5de414a6..a1b0bbe8 100644 --- a/.github/workflows/require_semver_label.yml +++ b/.github/workflows/require_semver_label.yml @@ -1,4 +1,4 @@ -name: Require Semver Pull Request Label +name: Require semver:* and unreleased Label on: pull_request: types: [opened, labeled, unlabeled, synchronize] @@ -10,4 +10,9 @@ jobs: with: mode: exactly count: 1 - labels: "semver:patch, semver:minor, semver:major" \ No newline at end of file + labels: "semver:patch, semver:minor, semver:major" + - uses: mheap/github-action-required-labels@v1 + with: + mode: exactly + count: 1 + labels: "unreleased" \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7fc5a1d6..b0ca36a3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,10 +12,6 @@ jobs: - uses: dart-lang/setup-dart@v1 - name: Install dependencies run: dart pub get - - name: Format - run: dart format --output=none --set-exit-if-changed . - - name: Analyze - run: dart analyze # - name: Unit tests # run: dart test test # - name: Integration tests diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 7c89b22c..c4893c72 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -18,7 +18,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - labels: ['untriaged'] + labels: ['untriaged','unreleased'] }) - name: Comment On New Issues uses: actions/github-script@v3 diff --git a/.pubignore b/.pubignore new file mode 100644 index 00000000..09134047 --- /dev/null +++ b/.pubignore @@ -0,0 +1,3 @@ +tool +test +integration_test \ No newline at end of file From 9186462c1fb3b9d6e87996a24e469e8405b67984 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:34:54 -0600 Subject: [PATCH 038/139] temp: disable publish on release for testing --- .github/workflows/publish_release.yml | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 3d6f125f..63d8c65b 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -1,21 +1,21 @@ -name: Publish to pub +# name: Publish to pub -on: - release: - types: [published] +# on: +# release: +# types: [published] -jobs: - publish: +# jobs: +# publish: - runs-on: ubuntu-latest +# runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: Publish - uses: sakebook/actions-flutter-pub-publisher@v1.3.1 - with: - credential: ${{ secrets.CREDENTIAL_JSON }} - flutter_package: false - skip_test: true - dry_run: false \ No newline at end of file +# steps: +# - name: Checkout +# uses: actions/checkout@v1 +# - name: Publish +# uses: sakebook/actions-flutter-pub-publisher@v1.3.1 +# with: +# credential: ${{ secrets.CREDENTIAL_JSON }} +# flutter_package: false +# skip_test: true +# dry_run: false \ No newline at end of file From 230e17946b8283fdbaf6752f51b805e0ad7b4e57 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:41:52 -0600 Subject: [PATCH 039/139] Create label_prs.yml --- .github/workflows/label_prs.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/label_prs.yml diff --git a/.github/workflows/label_prs.yml b/.github/workflows/label_prs.yml new file mode 100644 index 00000000..066e47b6 --- /dev/null +++ b/.github/workflows/label_prs.yml @@ -0,0 +1,22 @@ +name: Add PR labels on open +on: + pull_request: + types: [opened] + +jobs: + assignUnreleased: + name: Unreleased + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Apply unreleased label + uses: actions/github-script@v3 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + github.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['unreleased'] + }) From 21e26d213573796054c920b6f058d1bb8f8231aa Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:42:47 -0600 Subject: [PATCH 040/139] test auto-release for testing --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ccdb9ab2..c64d3727 100644 --- a/README.md +++ b/README.md @@ -32,3 +32,4 @@ See the examples in the example directory to learn how to use some of the featur ## Contacting Us Post a question or idea: https://github.com/SpinlockLabs/github.dart/discussions + From 164b7452debbef86f1ff8114bf54abae304290f5 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:49:52 -0600 Subject: [PATCH 041/139] main branch name change --- .github/workflows/release_unreleased_prs.yml | 2 +- tool/release_unreleased_prs.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml index 2999ef34..87cec9be 100644 --- a/.github/workflows/release_unreleased_prs.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 2 - ref: main + ref: master - name: Release run: | git config --global user.name ${{ secrets.USER_NAME }} diff --git a/tool/release_unreleased_prs.dart b/tool/release_unreleased_prs.dart index 3bec7a3d..72be1284 100644 --- a/tool/release_unreleased_prs.dart +++ b/tool/release_unreleased_prs.dart @@ -4,7 +4,7 @@ import 'package:pub_semver/pub_semver.dart'; import 'package:yaml_edit/yaml_edit.dart'; /////////////////////////////////////////////////////////// -const mainBranchName = 'main'; +const mainBranchName = 'master'; const semverMajor = 'semver:major'; const semverMinor = 'semver:minor'; const semverPatch = 'semver:patch'; From 01a23cf846d9ea911e3c63070ea5fe11fc2671a7 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:50:40 -0600 Subject: [PATCH 042/139] test PR for auto-release test --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index c64d3727..ccdb9ab2 100644 --- a/README.md +++ b/README.md @@ -32,4 +32,3 @@ See the examples in the example directory to learn how to use some of the featur ## Contacting Us Post a question or idea: https://github.com/SpinlockLabs/github.dart/discussions - From 9639ea73a678d1b92cf53f01281e606cc102f87f Mon Sep 17 00:00:00 2001 From: robrbecker Date: Sun, 17 Apr 2022 03:52:09 +0000 Subject: [PATCH 043/139] prep 9.1.2 --- CHANGELOG.md | 8 ++++++++ pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1de1051..4b8b6259 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 9.1.2 + +* test auto-release by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/307 +* test PR for auto-release by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/308 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.1.1...9.1.2 + ## 9.1.1 * Don't add state query param twice by @passsy in https://github.com/SpinlockLabs/github.dart/pull/264 diff --git a/pubspec.yaml b/pubspec.yaml index 138fa9ae..f6c4afde 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.1.1 +version: 9.1.2 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 950983a6d35080a0f0a79255c5cc94459b9db7a5 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 21:56:09 -0600 Subject: [PATCH 044/139] remove 9.1.2 and enable re-enable publish --- .github/workflows/publish_release.yml | 34 +++++++++++++-------------- CHANGELOG.md | 8 ------- pubspec.yaml | 2 +- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 63d8c65b..3d6f125f 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -1,21 +1,21 @@ -# name: Publish to pub +name: Publish to pub -# on: -# release: -# types: [published] +on: + release: + types: [published] -# jobs: -# publish: +jobs: + publish: -# runs-on: ubuntu-latest + runs-on: ubuntu-latest -# steps: -# - name: Checkout -# uses: actions/checkout@v1 -# - name: Publish -# uses: sakebook/actions-flutter-pub-publisher@v1.3.1 -# with: -# credential: ${{ secrets.CREDENTIAL_JSON }} -# flutter_package: false -# skip_test: true -# dry_run: false \ No newline at end of file + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Publish + uses: sakebook/actions-flutter-pub-publisher@v1.3.1 + with: + credential: ${{ secrets.CREDENTIAL_JSON }} + flutter_package: false + skip_test: true + dry_run: false \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b8b6259..f1de1051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,3 @@ -## 9.1.2 - -* test auto-release by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/307 -* test PR for auto-release by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/308 - - -**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.1.1...9.1.2 - ## 9.1.1 * Don't add state query param twice by @passsy in https://github.com/SpinlockLabs/github.dart/pull/264 diff --git a/pubspec.yaml b/pubspec.yaml index f6c4afde..138fa9ae 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.1.2 +version: 9.1.1 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 7846d4cbba15b161bee272e5ac6c3ad0b293a088 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 22:12:05 -0600 Subject: [PATCH 045/139] prep 9.2.0 --- CHANGELOG.md | 11 +++++++++++ pubspec.yaml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1de1051..bd3c6417 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 9.2.0 + +* test auto-release by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/307 +* test PR for auto-release by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/308 +* Added assignees to Issue model for #289 by @sjhorn in https://github.com/SpinlockLabs/github.dart/pull/290 + +## New Contributors +* @sjhorn made their first contribution in https://github.com/SpinlockLabs/github.dart/pull/290 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.1.1...9.2.0 + ## 9.1.1 * Don't add state query param twice by @passsy in https://github.com/SpinlockLabs/github.dart/pull/264 diff --git a/pubspec.yaml b/pubspec.yaml index b746b7bd..3bb66e40 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.1.1 +version: 9.2.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 66e5a9e8c726ea8e0b7b94f0cebb80810e667006 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 16 Apr 2022 23:04:26 -0600 Subject: [PATCH 046/139] dart format --- example/gist.dart | 7 ++++ example/gist.html | 36 +++++++++++++++++++ example/release_notes.dart | 59 +++++++++++++++++++++++++++++++ example/release_notes.html | 21 +++++++++++ lib/src/common/repos_service.dart | 3 +- 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100755 example/gist.dart create mode 100755 example/gist.html create mode 100644 example/release_notes.dart create mode 100644 example/release_notes.html diff --git a/example/gist.dart b/example/gist.dart new file mode 100755 index 00000000..0541ba58 --- /dev/null +++ b/example/gist.dart @@ -0,0 +1,7 @@ +import 'package:github/github.dart'; + +Future main() async { + final github = GitHub(auth: findAuthenticationFromEnvironment()); + var g = await github.gists.getGist('c14da36c866b9fe6f84f5d774b76570b'); + print(g.files); +} diff --git a/example/gist.html b/example/gist.html new file mode 100755 index 00000000..e25fd0bb --- /dev/null +++ b/example/gist.html @@ -0,0 +1,36 @@ + + + + + + + + Gist + + + + +

Gist

+ + +

+ +
+

+
+
+ + + + + + \ No newline at end of file diff --git a/example/release_notes.dart b/example/release_notes.dart new file mode 100644 index 00000000..867474ee --- /dev/null +++ b/example/release_notes.dart @@ -0,0 +1,59 @@ +import 'dart:html'; + +import 'common.dart'; +import 'package:pub_semver/pub_semver.dart'; + +late DivElement releasesDiv; + +Future main() async { + await initViewSourceButton('release_notes.dart'); + releasesDiv = querySelector('#release_notes')! as DivElement; + releasesDiv.innerText = await loadReleaseNotes(); +} + +Future loadReleaseNotes() async { + var slug = RepositorySlug.full('robrbecker/experiment'); + // var slug = RepositorySlug.full('SpinlockLabs/github.dart'); + + var latestRelease = await github.repositories.getLatestRelease(slug); + var latestTag = latestRelease.tagName!; + var latestVersion = Version.parse(latestTag); + + var unreleasedPRs = await github.search + .issues( + 'repo:${slug.fullName} is:pull-request label:unreleased state:closed', + sort: 'desc') + .toList(); + if (unreleasedPRs.isEmpty) { + print('No unreleased PRs'); + return ''; + } + var semvers = Set(); + for (var pr in unreleasedPRs) { + var prlabels = pr.labels + .where((element) => element.name.startsWith('semver:')) + .toList(); + for (var l in prlabels) { + semvers.add(l.name); + } + } + print(latestTag); + print(unreleasedPRs.first.toJson()); + print(semvers); + + var newVersion = ''; + if (semvers.contains('semver:major')) { + newVersion = latestVersion.nextMajor.toString(); + } else if (semvers.contains('semver:minor')) { + newVersion = latestVersion.nextMinor.toString(); + } else if (semvers.contains('semver:patch')) { + newVersion = latestVersion.nextPatch.toString(); + } + print(newVersion); + if (newVersion.isEmpty) return ''; + + var notes = await github.repositories.generateReleaseNotes(CreateReleaseNotes( + slug.owner, slug.name, newVersion, + previousTagName: latestTag)); + return '${notes.name}\n${notes.body}'; +} diff --git a/example/release_notes.html b/example/release_notes.html new file mode 100644 index 00000000..9544974f --- /dev/null +++ b/example/release_notes.html @@ -0,0 +1,21 @@ + + + + + GitHub Release Notes + + + +
+

GitHub Release Notes

+ +

+
+ +
+ + + + + + \ No newline at end of file diff --git a/lib/src/common/repos_service.dart b/lib/src/common/repos_service.dart index 45904bc2..a3a73531 100644 --- a/lib/src/common/repos_service.dart +++ b/lib/src/common/repos_service.dart @@ -1006,7 +1006,8 @@ class RepositoriesService extends Service { if (getIfExists) { return getReleaseByTagName(slug, createRelease.tagName); } else { - throw Exception('Tag / Release already exists ${createRelease.tagName}'); + throw Exception( + 'Tag / Release already exists ${createRelease.tagName}'); } } } else { From 09a76ba74c72ff9a72442bd117e256d9590b23a4 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 18 Apr 2022 08:05:34 -0600 Subject: [PATCH 047/139] Skip label no_release_on_merge when autoreleasing --- tool/release_unreleased_prs.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/release_unreleased_prs.dart b/tool/release_unreleased_prs.dart index 72be1284..372eefc4 100644 --- a/tool/release_unreleased_prs.dart +++ b/tool/release_unreleased_prs.dart @@ -92,7 +92,7 @@ Future getLatestVersion(RepositorySlug slug) async { Future> getUnreleasedPRs() async { print('Loading unreleased PRs...'); - var prs = await _gh.search.issues('repo:${_slug.fullName} is:pull-request label:unreleased state:closed', sort: 'desc').toList(); + var prs = await _gh.search.issues('repo:${_slug.fullName} is:pull-request label:unreleased -label:no_release_on_merge state:closed', sort: 'desc').toList(); print('${prs.length} loaded'); return prs; } From 921269ba8f803ba47470c624460c23c289b3291b Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 18 Apr 2022 08:33:07 -0600 Subject: [PATCH 048/139] add manual release action & more release docs --- .github/workflows/release_unreleased_prs.yml | 5 +++-- CONTRIBUTING.md | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml index 87cec9be..e3b196cd 100644 --- a/.github/workflows/release_unreleased_prs.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -1,15 +1,16 @@ -name: Release unreleased PR +name: Release unreleased PRs # Runs when a PR merges. # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges on: + workflow_dispatch: pull_request: types: - closed jobs: release: - if: github.event.pull_request.merged == true + if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest container: dart:2.14.4 permissions: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9a74cae..ac480095 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,7 +43,18 @@ If you get on IRC and ask us, we can review your work and add you as a committer This repo is now configured to release after every PR merge. This means a couple things for PRs that are put up: -1. A semver label is required. A github check will remind you that you need one. Reviewers should check that it is correct. +1. A semver label is required. A github check will remind you that you need one. Reviewers should check that it is correct. See https://semver.org/ to understand more. 2. There is no need to modify the version in the pubspec.yaml in your PRs. The tooling will update the version according to the semver label applied to your PR. 3. Same thing for the CHANGELOG.md. Tooling will update it automatically after merge. -4. A github release will be created and published ot pub.dev for you. \ No newline at end of file +4. A github release will be created and published to pub.dev for you. + +For example if your PR has `semver:minor` label applied and the latest version is 1.2.3, once merged, the tooling will: +- update the pubspec.yaml to 1.3.0 +- Add the github auto-generated release notes with 1.3.0 to the top of the CHANGELOG.md +- Create a release in github for 1.3.0 (which creates a git tag of 1.3.0) +- Remove the `unreleased` label from the PR and add the `released` label +- Comment on the PR stating the version that it was released in and link to the release +- When the release is created, it will automatically be published to pub.dev + +NOTE: If you want the ability to merge a PR **WITHOUT** automatically releasing and publishing, simply add the `no_release_on_merge` label before merging. Do note that the PR has been merged though and whatever the next PR is that triggers a release will release and publish everything that has been merged. So if you want to batch a few PRs into 1 release, label them all `no_release_on_merge`. Then whichever is the last to be merged, remove that label before merging to trigger the release. +You may also manually trigger the action to release unreleased PRs from the Actions tab in Github. From 328fa4197c6bab8333ebf940550ecda4ff8f3ec3 Mon Sep 17 00:00:00 2001 From: Ricardo Amador Date: Wed, 22 Jun 2022 16:42:47 -0700 Subject: [PATCH 049/139] Added a new conclusion state. --- lib/src/common/model/checks.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index 8d497540..0bb26e29 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -45,6 +45,7 @@ class CheckRunConclusion extends EnumWithValue { static const neutral = CheckRunConclusion._('neutral'); static const cancelled = CheckRunConclusion._('cancelled'); static const timedOut = CheckRunConclusion._('timed_out'); + static const skipped = CheckRunConclusion._('skipped'); static const actionRequired = CheckRunConclusion._('action_required'); static const empty = CheckRunConclusion._(null); From 9f55646b25f566d5b1bbd130c783a82eeb304a28 Mon Sep 17 00:00:00 2001 From: Ricardo Amador Date: Wed, 22 Jun 2022 17:58:29 -0700 Subject: [PATCH 050/139] Add a test for the new conclusion state. --- lib/src/common/model/checks.dart | 1 + test/unit/checks_test.dart | 101 +++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index 0bb26e29..ccde4502 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -61,6 +61,7 @@ class CheckRunConclusion extends EnumWithValue { neutral, cancelled, timedOut, + skipped, actionRequired ]) { if (level.value == value) { diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart index 15c8f9d8..bc08f7b3 100644 --- a/test/unit/checks_test.dart +++ b/test/unit/checks_test.dart @@ -105,5 +105,106 @@ void main() { expect(checkRun.name, 'mighty_readme'); expect(checkRun.conclusion, CheckRunConclusion.neutral); }); + + test('CheckRun fromJson for skipped conclusion', () { + /// The checkRun Json is the official Github values + /// + /// Github api url: https://docs.github.com/en/rest/reference/checks#get-a-check-run + const checkRunJson = '''{ + "id": 10, + "head_sha": "ce587453ced02b1526dfb4cb910479d431683101", + "node_id": "MDg6Q2hlY2tSdW40", + "external_id": "", + "url": "https://api.github.com/repos/github/hello-world/check-runs/4", + "html_url": "https://github.com/github/hello-world/runs/4", + "details_url": "https://example.com", + "status": "completed", + "conclusion": "skipped", + "started_at": "2018-05-04T01:14:52Z", + "completed_at": "2018-05-04T01:14:52Z", + "output": { + "title": "Mighty Readme report", + "summary": "There are 0 failures, 2 warnings, and 1 notice.", + "text": "You may have some misspelled words on lines 2 and 4. You also may want to add a section in your README about how to install your app.", + "annotations_count": 2, + "annotations_url": "https://api.github.com/repos/github/hello-world/check-runs/4/annotations" + }, + "name": "mighty_readme", + "check_suite": { + "id": 5 + }, + "app": { + "id": 1, + "slug": "octoapp", + "node_id": "MDExOkludGVncmF0aW9uMQ==", + "owner": { + "login": "github", + "id": 1, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", + "url": "https://api.github.com/orgs/github", + "repos_url": "https://api.github.com/orgs/github/repos", + "events_url": "https://api.github.com/orgs/github/events", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": true + }, + "name": "Octocat App", + "description": "", + "external_url": "https://example.com", + "html_url": "https://github.com/apps/octoapp", + "created_at": "2017-07-08T16:18:44-04:00", + "updated_at": "2017-07-08T16:18:44-04:00", + "permissions": { + "metadata": "read", + "contents": "read", + "issues": "write", + "single_file": "write" + }, + "events": [ + "push", + "pull_request" + ] + }, + "pull_requests": [ + { + "url": "https://api.github.com/repos/github/hello-world/pulls/1", + "id": 1934, + "number": 3956, + "head": { + "ref": "say-hello", + "sha": "3dca65fa3e8d4b3da3f3d056c59aee1c50f41390", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + }, + "base": { + "ref": "master", + "sha": "e7fdf7640066d71ad16a86fbcbb9c6a10a18af4f", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + } + } + ] + }'''; + final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); + + expect(checkRun.id, 10); + expect(checkRun.name, 'mighty_readme'); + expect(checkRun.conclusion, CheckRunConclusion.skipped); + }); }); } From fc7329f65e4ca652beade93b448488fa573fff6d Mon Sep 17 00:00:00 2001 From: robrbecker Date: Thu, 23 Jun 2022 20:15:11 +0000 Subject: [PATCH 051/139] prep 9.3.0 --- CHANGELOG.md | 9 +++++++++ pubspec.yaml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3c6417..87fdac9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 9.3.0 + +* Added a new conclusion state to support flutter autosubmit bot by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/315 + +## New Contributors +* @ricardoamador made their first contribution in https://github.com/SpinlockLabs/github.dart/pull/315 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.2.0...9.3.0 + ## 9.2.0 * test auto-release by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/307 diff --git a/pubspec.yaml b/pubspec.yaml index 3bb66e40..92173dcf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.2.0 +version: 9.3.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 4a0bb47072be7bc59760b841ad336b4a8ea581c5 Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Thu, 23 Jun 2022 14:39:09 -0700 Subject: [PATCH 052/139] Fix publish release workflow --- .github/workflows/publish_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 3d6f125f..0299a486 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -13,9 +13,9 @@ jobs: - name: Checkout uses: actions/checkout@v1 - name: Publish - uses: sakebook/actions-flutter-pub-publisher@v1.3.1 + uses: caseyhillers/actions-flutter-pub-publisher@v1.5.1 with: credential: ${{ secrets.CREDENTIAL_JSON }} flutter_package: false skip_test: true - dry_run: false \ No newline at end of file + dry_run: false From 1847b8a651f70562022e9eb458d07f6264f1a60e Mon Sep 17 00:00:00 2001 From: Ricardo Amador Date: Fri, 1 Jul 2022 16:29:40 -0700 Subject: [PATCH 053/139] Implemented toString in checkrun --- lib/src/common/model/checks.dart | 7 ++ test/unit/checks_test.dart | 200 +++++++++++++++++-------------- 2 files changed, 114 insertions(+), 93 deletions(-) diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index 8d497540..2db62f7b 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:github/src/common/model/pulls.dart'; import 'package:github/src/common/util/utils.dart'; import 'package:meta/meta.dart'; @@ -148,6 +150,11 @@ class CheckRun { 'conclusion': conclusion, }; } + + @override + String toString() { + return jsonEncode(toJson()); + } } @immutable diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart index 15c8f9d8..c7eefb05 100644 --- a/test/unit/checks_test.dart +++ b/test/unit/checks_test.dart @@ -3,107 +3,121 @@ import 'dart:convert'; import 'package:github/src/common/model/checks.dart'; import 'package:test/test.dart'; +/// The checkRun Json is the official Github values +/// +/// Github api url: https://docs.github.com/en/rest/reference/checks#get-a-check-run +const checkRunJson = '''{ + "id": 4, + "head_sha": "ce587453ced02b1526dfb4cb910479d431683101", + "node_id": "MDg6Q2hlY2tSdW40", + "external_id": "", + "url": "https://api.github.com/repos/github/hello-world/check-runs/4", + "html_url": "https://github.com/github/hello-world/runs/4", + "details_url": "https://example.com", + "status": "completed", + "conclusion": "neutral", + "started_at": "2018-05-04T01:14:52Z", + "completed_at": "2018-05-04T01:14:52Z", + "output": { + "title": "Mighty Readme report", + "summary": "There are 0 failures, 2 warnings, and 1 notice.", + "text": "You may have some misspelled words on lines 2 and 4. You also may want to add a section in your README about how to install your app.", + "annotations_count": 2, + "annotations_url": "https://api.github.com/repos/github/hello-world/check-runs/4/annotations" + }, + "name": "mighty_readme", + "check_suite": { + "id": 5 + }, + "app": { + "id": 1, + "slug": "octoapp", + "node_id": "MDExOkludGVncmF0aW9uMQ==", + "owner": { + "login": "github", + "id": 1, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", + "url": "https://api.github.com/orgs/github", + "repos_url": "https://api.github.com/orgs/github/repos", + "events_url": "https://api.github.com/orgs/github/events", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": true + }, + "name": "Octocat App", + "description": "", + "external_url": "https://example.com", + "html_url": "https://github.com/apps/octoapp", + "created_at": "2017-07-08T16:18:44-04:00", + "updated_at": "2017-07-08T16:18:44-04:00", + "permissions": { + "metadata": "read", + "contents": "read", + "issues": "write", + "single_file": "write" + }, + "events": [ + "push", + "pull_request" + ] + }, + "pull_requests": [ + { + "url": "https://api.github.com/repos/github/hello-world/pulls/1", + "id": 1934, + "number": 3956, + "head": { + "ref": "say-hello", + "sha": "3dca65fa3e8d4b3da3f3d056c59aee1c50f41390", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + }, + "base": { + "ref": "master", + "sha": "e7fdf7640066d71ad16a86fbcbb9c6a10a18af4f", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + } + } + ] +}'''; + +const String expectedToString = '{"name":"mighty_readme","id":4,"external_id":"","status":"completed","head_sha":"","check_suite":{"id":5},"details_url":"https://example.com","started_at":"2018-05-04T01:14:52.000Z","conclusion":"neutral"}'; + void main() { group('Check run', () { test('CheckRun fromJson', () { - /// The checkRun Json is the official Github values - /// - /// Github api url: https://docs.github.com/en/rest/reference/checks#get-a-check-run - const checkRunJson = '''{ - "id": 4, - "head_sha": "ce587453ced02b1526dfb4cb910479d431683101", - "node_id": "MDg6Q2hlY2tSdW40", - "external_id": "", - "url": "https://api.github.com/repos/github/hello-world/check-runs/4", - "html_url": "https://github.com/github/hello-world/runs/4", - "details_url": "https://example.com", - "status": "completed", - "conclusion": "neutral", - "started_at": "2018-05-04T01:14:52Z", - "completed_at": "2018-05-04T01:14:52Z", - "output": { - "title": "Mighty Readme report", - "summary": "There are 0 failures, 2 warnings, and 1 notice.", - "text": "You may have some misspelled words on lines 2 and 4. You also may want to add a section in your README about how to install your app.", - "annotations_count": 2, - "annotations_url": "https://api.github.com/repos/github/hello-world/check-runs/4/annotations" - }, - "name": "mighty_readme", - "check_suite": { - "id": 5 - }, - "app": { - "id": 1, - "slug": "octoapp", - "node_id": "MDExOkludGVncmF0aW9uMQ==", - "owner": { - "login": "github", - "id": 1, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", - "url": "https://api.github.com/orgs/github", - "repos_url": "https://api.github.com/orgs/github/repos", - "events_url": "https://api.github.com/orgs/github/events", - "avatar_url": "https://github.com/images/error/octocat_happy.gif", - "gravatar_id": "", - "html_url": "https://github.com/octocat", - "followers_url": "https://api.github.com/users/octocat/followers", - "following_url": "https://api.github.com/users/octocat/following{/other_user}", - "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", - "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", - "organizations_url": "https://api.github.com/users/octocat/orgs", - "received_events_url": "https://api.github.com/users/octocat/received_events", - "type": "User", - "site_admin": true - }, - "name": "Octocat App", - "description": "", - "external_url": "https://example.com", - "html_url": "https://github.com/apps/octoapp", - "created_at": "2017-07-08T16:18:44-04:00", - "updated_at": "2017-07-08T16:18:44-04:00", - "permissions": { - "metadata": "read", - "contents": "read", - "issues": "write", - "single_file": "write" - }, - "events": [ - "push", - "pull_request" - ] - }, - "pull_requests": [ - { - "url": "https://api.github.com/repos/github/hello-world/pulls/1", - "id": 1934, - "number": 3956, - "head": { - "ref": "say-hello", - "sha": "3dca65fa3e8d4b3da3f3d056c59aee1c50f41390", - "repo": { - "id": 526, - "url": "https://api.github.com/repos/github/hello-world", - "name": "hello-world" - } - }, - "base": { - "ref": "master", - "sha": "e7fdf7640066d71ad16a86fbcbb9c6a10a18af4f", - "repo": { - "id": 526, - "url": "https://api.github.com/repos/github/hello-world", - "name": "hello-world" - } - } - } - ] - }'''; + final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); expect(checkRun.id, 4); expect(checkRun.name, 'mighty_readme'); expect(checkRun.conclusion, CheckRunConclusion.neutral); }); + + test('CheckRun toString', () { + // indirectly tests the toJson method as well. + final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); + expect(checkRun, isNotNull); + final checkRunString = checkRun.toString(); + expect(checkRunString, isNotNull); + print(checkRunString); + expect(checkRunString == expectedToString, isTrue); + }); }); } From 0f2422acbc8c7293d0f99882682a6cb8cc6c5f95 Mon Sep 17 00:00:00 2001 From: Ricardo Amador Date: Fri, 1 Jul 2022 16:32:03 -0700 Subject: [PATCH 054/139] Remove print statement --- test/unit/checks_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart index c7eefb05..87e11b33 100644 --- a/test/unit/checks_test.dart +++ b/test/unit/checks_test.dart @@ -116,7 +116,6 @@ void main() { expect(checkRun, isNotNull); final checkRunString = checkRun.toString(); expect(checkRunString, isNotNull); - print(checkRunString); expect(checkRunString == expectedToString, isTrue); }); }); From 2287c65695763a9a2a67ca3581b95705753488d7 Mon Sep 17 00:00:00 2001 From: robrbecker Date: Wed, 6 Jul 2022 17:51:52 +0000 Subject: [PATCH 055/139] prep 9.4.0 --- CHANGELOG.md | 8 ++++++++ pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87fdac9d..59375550 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 9.4.0 + +* Fix publish release workflow by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/316 +* Add support for toString to the Checkrun object. by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/318 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.3.0...9.4.0 + ## 9.3.0 * Added a new conclusion state to support flutter autosubmit bot by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/315 diff --git a/pubspec.yaml b/pubspec.yaml index 92173dcf..794e7a29 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.3.0 +version: 9.4.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 546abc295310072f9c6c4f2cfd4d4abb5c923a7e Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Wed, 6 Jul 2022 13:34:37 -0700 Subject: [PATCH 056/139] Simplify publish release action --- .github/workflows/publish_release.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 0299a486..c9c1df8f 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -12,10 +12,9 @@ jobs: steps: - name: Checkout uses: actions/checkout@v1 - - name: Publish - uses: caseyhillers/actions-flutter-pub-publisher@v1.5.1 - with: - credential: ${{ secrets.CREDENTIAL_JSON }} - flutter_package: false - skip_test: true - dry_run: false + - name: Setup credentials + run: | + mkdir -p ~/.pub-cache + echo ${{ secrets.CREDENTIAL_JSON }} > ~/.pub-cache/credentials.json + - name: Publish package + run: pub publish -f \ No newline at end of file From ce4a60676866bb9fa5d5fe852eeb19a414edf86f Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 22 Oct 2022 07:32:25 -0600 Subject: [PATCH 057/139] Add star chart to the readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ccdb9ab2..fc8aa669 100644 --- a/README.md +++ b/README.md @@ -32,3 +32,7 @@ See the examples in the example directory to learn how to use some of the featur ## Contacting Us Post a question or idea: https://github.com/SpinlockLabs/github.dart/discussions + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=SpinlockLabs/github.dart&type=Date)](https://star-history.com/#SpinlockLabs/github.dart&Date) \ No newline at end of file From d17192cea7b594d6f7126fc3dfff2fc46b1cf9ed Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 22 Oct 2022 08:53:25 -0600 Subject: [PATCH 058/139] Update to github-script 6 (#331) Try updating to github-script 6 Co-authored-by: Rob Becker --- .github/workflows/label_prs.yml | 4 ++-- .github/workflows/triage.yml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/label_prs.yml b/.github/workflows/label_prs.yml index 066e47b6..8f30b23d 100644 --- a/.github/workflows/label_prs.yml +++ b/.github/workflows/label_prs.yml @@ -10,11 +10,11 @@ jobs: steps: - uses: actions/checkout@master - name: Apply unreleased label - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | - github.issues.addLabels({ + github.rest.issues.addLabels({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index c4893c72..90dddd83 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -10,22 +10,22 @@ jobs: steps: - uses: actions/checkout@master - name: Apply untriaged label - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | - github.issues.addLabels({ + github.rest.issues.addLabels({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, labels: ['untriaged','unreleased'] }) - name: Comment On New Issues - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | - github.issues.createComment({ + github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, From ee05c4324622c40ab423c12fbd515c067faad600 Mon Sep 17 00:00:00 2001 From: robrbecker Date: Sat, 22 Oct 2022 14:53:55 +0000 Subject: [PATCH 059/139] prep 9.4.1 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59375550..d09d1b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.4.1 + +* Update to github-script 6 by @robbecker-wf in https://github.com/SpinlockLabs/github.dart/pull/331 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.4.0...9.4.1 + ## 9.4.0 * Fix publish release workflow by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/316 diff --git a/pubspec.yaml b/pubspec.yaml index 794e7a29..9aa43f84 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.4.0 +version: 9.4.1 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From af4a3c67c24f7a066acfd92152886cfa2b9d3332 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 22 Oct 2022 08:56:27 -0600 Subject: [PATCH 060/139] fix indentation in publish_release.yml --- .github/workflows/publish_release.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index c9c1df8f..3743cd63 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -12,9 +12,9 @@ jobs: steps: - name: Checkout uses: actions/checkout@v1 - - name: Setup credentials - run: | - mkdir -p ~/.pub-cache - echo ${{ secrets.CREDENTIAL_JSON }} > ~/.pub-cache/credentials.json - - name: Publish package - run: pub publish -f \ No newline at end of file + - name: Setup credentials + run: | + mkdir -p ~/.pub-cache + echo ${{ secrets.CREDENTIAL_JSON }} > ~/.pub-cache/credentials.json + - name: Publish package + run: pub publish -f \ No newline at end of file From 1311d42945eeee91e359908ef659fb094bf1c12b Mon Sep 17 00:00:00 2001 From: Jeff Ward Date: Sat, 22 Oct 2022 10:57:57 -0400 Subject: [PATCH 061/139] Add 'commits' member to GitHubComparison object (#330) Co-authored-by: Rob Becker --- lib/src/common/model/repos.dart | 3 +- lib/src/common/model/repos.g.dart | 4 + test/src/mocks.mocks.dart | 562 +++++++++++++++++++++--------- 3 files changed, 411 insertions(+), 158 deletions(-) diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index 739d6ca2..3612aa34 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -11,9 +11,10 @@ class GitHubComparison { final int? behindBy; final int? totalCommits; final List? files; + final List? commits; GitHubComparison(this.url, this.status, this.aheadBy, this.behindBy, - this.totalCommits, this.files); + this.totalCommits, this.files, this.commits); factory GitHubComparison.fromJson(Map json) => _$GitHubComparisonFromJson(json); diff --git a/lib/src/common/model/repos.g.dart b/lib/src/common/model/repos.g.dart index 78184d6f..b2e395bd 100644 --- a/lib/src/common/model/repos.g.dart +++ b/lib/src/common/model/repos.g.dart @@ -16,6 +16,9 @@ GitHubComparison _$GitHubComparisonFromJson(Map json) => (json['files'] as List?) ?.map((e) => CommitFile.fromJson(e as Map)) .toList(), + (json['commits'] as List?) + ?.map((e) => RepositoryCommit.fromJson(e as Map)) + .toList(), ); Map _$GitHubComparisonToJson(GitHubComparison instance) => @@ -26,6 +29,7 @@ Map _$GitHubComparisonToJson(GitHubComparison instance) => 'behind_by': instance.behindBy, 'total_commits': instance.totalCommits, 'files': instance.files, + 'commits': instance.commits, }; Repository _$RepositoryFromJson(Map json) => Repository( diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index 6b9c20c5..56e777d3 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -1,58 +1,180 @@ -// Mocks generated by Mockito 5.0.17 from annotations +// Mocks generated by Mockito 5.3.2 from annotations // in github/test/src/mocks.dart. // Do not manually edit this file. +// ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i4; import 'package:github/src/common.dart' as _i3; import 'package:http/http.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +// ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters -// ignore_for_file: camel_case_types // ignore_for_file: comment_references // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors -// ignore_for_file: unnecessary_overrides // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class -class _FakeClient_0 extends _i1.Fake implements _i2.Client {} +class _FakeClient_0 extends _i1.SmartFake implements _i2.Client { + _FakeClient_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeActivityService_1 extends _i1.Fake implements _i3.ActivityService {} +class _FakeActivityService_1 extends _i1.SmartFake + implements _i3.ActivityService { + _FakeActivityService_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeAuthorizationsService_2 extends _i1.Fake - implements _i3.AuthorizationsService {} +class _FakeAuthorizationsService_2 extends _i1.SmartFake + implements _i3.AuthorizationsService { + _FakeAuthorizationsService_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeGistsService_3 extends _i1.Fake implements _i3.GistsService {} +class _FakeGistsService_3 extends _i1.SmartFake implements _i3.GistsService { + _FakeGistsService_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeGitService_4 extends _i1.Fake implements _i3.GitService {} +class _FakeGitService_4 extends _i1.SmartFake implements _i3.GitService { + _FakeGitService_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeIssuesService_5 extends _i1.Fake implements _i3.IssuesService {} +class _FakeIssuesService_5 extends _i1.SmartFake implements _i3.IssuesService { + _FakeIssuesService_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeMiscService_6 extends _i1.Fake implements _i3.MiscService {} +class _FakeMiscService_6 extends _i1.SmartFake implements _i3.MiscService { + _FakeMiscService_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeOrganizationsService_7 extends _i1.Fake - implements _i3.OrganizationsService {} +class _FakeOrganizationsService_7 extends _i1.SmartFake + implements _i3.OrganizationsService { + _FakeOrganizationsService_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakePullRequestsService_8 extends _i1.Fake - implements _i3.PullRequestsService {} +class _FakePullRequestsService_8 extends _i1.SmartFake + implements _i3.PullRequestsService { + _FakePullRequestsService_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeRepositoriesService_9 extends _i1.Fake - implements _i3.RepositoriesService {} +class _FakeRepositoriesService_9 extends _i1.SmartFake + implements _i3.RepositoriesService { + _FakeRepositoriesService_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeSearchService_10 extends _i1.Fake implements _i3.SearchService {} +class _FakeSearchService_10 extends _i1.SmartFake implements _i3.SearchService { + _FakeSearchService_10( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeUrlShortenerService_11 extends _i1.Fake - implements _i3.UrlShortenerService {} +class _FakeUrlShortenerService_11 extends _i1.SmartFake + implements _i3.UrlShortenerService { + _FakeUrlShortenerService_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeUsersService_12 extends _i1.Fake implements _i3.UsersService {} +class _FakeUsersService_12 extends _i1.SmartFake implements _i3.UsersService { + _FakeUsersService_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeChecksService_13 extends _i1.Fake implements _i3.ChecksService {} +class _FakeChecksService_13 extends _i1.SmartFake implements _i3.ChecksService { + _FakeChecksService_13( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} -class _FakeResponse_14 extends _i1.Fake implements _i2.Response {} +class _FakeResponse_14 extends _i1.SmartFake implements _i2.Response { + _FakeResponse_14( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} /// A class which mocks [GitHub]. /// @@ -63,201 +185,327 @@ class MockGitHub extends _i1.Mock implements _i3.GitHub { } @override - set auth(_i3.Authentication? _auth) => - super.noSuchMethod(Invocation.setter(#auth, _auth), - returnValueForMissingStub: null); + set auth(_i3.Authentication? _auth) => super.noSuchMethod( + Invocation.setter( + #auth, + _auth, + ), + returnValueForMissingStub: null, + ); @override - String get endpoint => - (super.noSuchMethod(Invocation.getter(#endpoint), returnValue: '') - as String); + String get endpoint => (super.noSuchMethod( + Invocation.getter(#endpoint), + returnValue: '', + ) as String); @override - _i2.Client get client => (super.noSuchMethod(Invocation.getter(#client), - returnValue: _FakeClient_0()) as _i2.Client); + _i2.Client get client => (super.noSuchMethod( + Invocation.getter(#client), + returnValue: _FakeClient_0( + this, + Invocation.getter(#client), + ), + ) as _i2.Client); @override - _i3.ActivityService get activity => - (super.noSuchMethod(Invocation.getter(#activity), - returnValue: _FakeActivityService_1()) as _i3.ActivityService); + _i3.ActivityService get activity => (super.noSuchMethod( + Invocation.getter(#activity), + returnValue: _FakeActivityService_1( + this, + Invocation.getter(#activity), + ), + ) as _i3.ActivityService); @override - _i3.AuthorizationsService get authorizations => - (super.noSuchMethod(Invocation.getter(#authorizations), - returnValue: _FakeAuthorizationsService_2()) - as _i3.AuthorizationsService); + _i3.AuthorizationsService get authorizations => (super.noSuchMethod( + Invocation.getter(#authorizations), + returnValue: _FakeAuthorizationsService_2( + this, + Invocation.getter(#authorizations), + ), + ) as _i3.AuthorizationsService); @override - _i3.GistsService get gists => (super.noSuchMethod(Invocation.getter(#gists), - returnValue: _FakeGistsService_3()) as _i3.GistsService); + _i3.GistsService get gists => (super.noSuchMethod( + Invocation.getter(#gists), + returnValue: _FakeGistsService_3( + this, + Invocation.getter(#gists), + ), + ) as _i3.GistsService); @override - _i3.GitService get git => (super.noSuchMethod(Invocation.getter(#git), - returnValue: _FakeGitService_4()) as _i3.GitService); + _i3.GitService get git => (super.noSuchMethod( + Invocation.getter(#git), + returnValue: _FakeGitService_4( + this, + Invocation.getter(#git), + ), + ) as _i3.GitService); @override - _i3.IssuesService get issues => - (super.noSuchMethod(Invocation.getter(#issues), - returnValue: _FakeIssuesService_5()) as _i3.IssuesService); + _i3.IssuesService get issues => (super.noSuchMethod( + Invocation.getter(#issues), + returnValue: _FakeIssuesService_5( + this, + Invocation.getter(#issues), + ), + ) as _i3.IssuesService); @override - _i3.MiscService get misc => (super.noSuchMethod(Invocation.getter(#misc), - returnValue: _FakeMiscService_6()) as _i3.MiscService); + _i3.MiscService get misc => (super.noSuchMethod( + Invocation.getter(#misc), + returnValue: _FakeMiscService_6( + this, + Invocation.getter(#misc), + ), + ) as _i3.MiscService); @override _i3.OrganizationsService get organizations => (super.noSuchMethod( - Invocation.getter(#organizations), - returnValue: _FakeOrganizationsService_7()) as _i3.OrganizationsService); + Invocation.getter(#organizations), + returnValue: _FakeOrganizationsService_7( + this, + Invocation.getter(#organizations), + ), + ) as _i3.OrganizationsService); @override _i3.PullRequestsService get pullRequests => (super.noSuchMethod( - Invocation.getter(#pullRequests), - returnValue: _FakePullRequestsService_8()) as _i3.PullRequestsService); + Invocation.getter(#pullRequests), + returnValue: _FakePullRequestsService_8( + this, + Invocation.getter(#pullRequests), + ), + ) as _i3.PullRequestsService); @override _i3.RepositoriesService get repositories => (super.noSuchMethod( - Invocation.getter(#repositories), - returnValue: _FakeRepositoriesService_9()) as _i3.RepositoriesService); + Invocation.getter(#repositories), + returnValue: _FakeRepositoriesService_9( + this, + Invocation.getter(#repositories), + ), + ) as _i3.RepositoriesService); @override - _i3.SearchService get search => - (super.noSuchMethod(Invocation.getter(#search), - returnValue: _FakeSearchService_10()) as _i3.SearchService); + _i3.SearchService get search => (super.noSuchMethod( + Invocation.getter(#search), + returnValue: _FakeSearchService_10( + this, + Invocation.getter(#search), + ), + ) as _i3.SearchService); @override _i3.UrlShortenerService get urlShortener => (super.noSuchMethod( - Invocation.getter(#urlShortener), - returnValue: _FakeUrlShortenerService_11()) as _i3.UrlShortenerService); + Invocation.getter(#urlShortener), + returnValue: _FakeUrlShortenerService_11( + this, + Invocation.getter(#urlShortener), + ), + ) as _i3.UrlShortenerService); @override - _i3.UsersService get users => (super.noSuchMethod(Invocation.getter(#users), - returnValue: _FakeUsersService_12()) as _i3.UsersService); + _i3.UsersService get users => (super.noSuchMethod( + Invocation.getter(#users), + returnValue: _FakeUsersService_12( + this, + Invocation.getter(#users), + ), + ) as _i3.UsersService); @override - _i3.ChecksService get checks => - (super.noSuchMethod(Invocation.getter(#checks), - returnValue: _FakeChecksService_13()) as _i3.ChecksService); + _i3.ChecksService get checks => (super.noSuchMethod( + Invocation.getter(#checks), + returnValue: _FakeChecksService_13( + this, + Invocation.getter(#checks), + ), + ) as _i3.ChecksService); @override - _i4.Future getJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - String? preview}) => + _i4.Future getJSON( + String? path, { + int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + String? preview, + }) => (super.noSuchMethod( - Invocation.method(#getJSON, [ - path - ], { + Invocation.method( + #getJSON, + [path], + { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); + #preview: preview, + }, + ), + returnValue: _i4.Future.value(null), + ) as _i4.Future); @override - _i4.Future postJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => + _i4.Future postJSON( + String? path, { + int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview, + }) => (super.noSuchMethod( - Invocation.method(#postJSON, [ - path - ], { + Invocation.method( + #postJSON, + [path], + { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); + #preview: preview, + }, + ), + returnValue: _i4.Future.value(null), + ) as _i4.Future); @override - _i4.Future putJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => + _i4.Future putJSON( + String? path, { + int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview, + }) => (super.noSuchMethod( - Invocation.method(#putJSON, [ - path - ], { + Invocation.method( + #putJSON, + [path], + { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); + #preview: preview, + }, + ), + returnValue: _i4.Future.value(null), + ) as _i4.Future); @override - _i4.Future patchJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => + _i4.Future patchJSON( + String? path, { + int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview, + }) => (super.noSuchMethod( - Invocation.method(#patchJSON, [ - path - ], { + Invocation.method( + #patchJSON, + [path], + { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); + #preview: preview, + }, + ), + returnValue: _i4.Future.value(null), + ) as _i4.Future); @override - _i4.Future requestJson(String? method, String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => + _i4.Future requestJson( + String? method, + String? path, { + int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview, + }) => (super.noSuchMethod( - Invocation.method(#requestJson, [ + Invocation.method( + #requestJson, + [ method, - path - ], { + path, + ], + { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); + #preview: preview, + }, + ), + returnValue: _i4.Future.value(null), + ) as _i4.Future); @override - _i4.Future<_i2.Response> request(String? method, String? path, - {Map? headers, - Map? params, - dynamic body, - int? statusCode, - void Function(_i2.Response)? fail, - String? preview}) => + _i4.Future<_i2.Response> request( + String? method, + String? path, { + Map? headers, + Map? params, + dynamic body, + int? statusCode, + void Function(_i2.Response)? fail, + String? preview, + }) => (super.noSuchMethod( - Invocation.method(#request, [ - method, - path - ], { - #headers: headers, - #params: params, - #body: body, - #statusCode: statusCode, - #fail: fail, - #preview: preview - }), - returnValue: Future<_i2.Response>.value(_FakeResponse_14())) - as _i4.Future<_i2.Response>); + Invocation.method( + #request, + [ + method, + path, + ], + { + #headers: headers, + #params: params, + #body: body, + #statusCode: statusCode, + #fail: fail, + #preview: preview, + }, + ), + returnValue: _i4.Future<_i2.Response>.value(_FakeResponse_14( + this, + Invocation.method( + #request, + [ + method, + path, + ], + { + #headers: headers, + #params: params, + #body: body, + #statusCode: statusCode, + #fail: fail, + #preview: preview, + }, + ), + )), + ) as _i4.Future<_i2.Response>); @override - void handleStatusCode(_i2.Response? response) => - super.noSuchMethod(Invocation.method(#handleStatusCode, [response]), - returnValueForMissingStub: null); + void handleStatusCode(_i2.Response? response) => super.noSuchMethod( + Invocation.method( + #handleStatusCode, + [response], + ), + returnValueForMissingStub: null, + ); @override - void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), - returnValueForMissingStub: null); + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); } From 7056f9c2bf17c5f437e6cb32012a7d16f9ed3278 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 22 Oct 2022 09:11:07 -0600 Subject: [PATCH 062/139] regen mocks for Dart 2.14 and dart format --- test/src/mocks.mocks.dart | 559 +++++++++---------------------- test/unit/checks_test.dart | 4 +- tool/release_unreleased_prs.dart | 34 +- 3 files changed, 178 insertions(+), 419 deletions(-) diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart index 56e777d3..c381f58a 100644 --- a/test/src/mocks.mocks.dart +++ b/test/src/mocks.mocks.dart @@ -1,8 +1,7 @@ -// Mocks generated by Mockito 5.3.2 from annotations +// Mocks generated by Mockito 5.2.0 from annotations // in github/test/src/mocks.dart. // Do not manually edit this file. -// ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i4; import 'package:github/src/common.dart' as _i3; @@ -18,163 +17,41 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: prefer_const_constructors // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types -// ignore_for_file: subtype_of_sealed_class -class _FakeClient_0 extends _i1.SmartFake implements _i2.Client { - _FakeClient_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeClient_0 extends _i1.Fake implements _i2.Client {} -class _FakeActivityService_1 extends _i1.SmartFake - implements _i3.ActivityService { - _FakeActivityService_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeActivityService_1 extends _i1.Fake implements _i3.ActivityService {} -class _FakeAuthorizationsService_2 extends _i1.SmartFake - implements _i3.AuthorizationsService { - _FakeAuthorizationsService_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeAuthorizationsService_2 extends _i1.Fake + implements _i3.AuthorizationsService {} -class _FakeGistsService_3 extends _i1.SmartFake implements _i3.GistsService { - _FakeGistsService_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeGistsService_3 extends _i1.Fake implements _i3.GistsService {} -class _FakeGitService_4 extends _i1.SmartFake implements _i3.GitService { - _FakeGitService_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeGitService_4 extends _i1.Fake implements _i3.GitService {} -class _FakeIssuesService_5 extends _i1.SmartFake implements _i3.IssuesService { - _FakeIssuesService_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeIssuesService_5 extends _i1.Fake implements _i3.IssuesService {} -class _FakeMiscService_6 extends _i1.SmartFake implements _i3.MiscService { - _FakeMiscService_6( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeMiscService_6 extends _i1.Fake implements _i3.MiscService {} -class _FakeOrganizationsService_7 extends _i1.SmartFake - implements _i3.OrganizationsService { - _FakeOrganizationsService_7( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeOrganizationsService_7 extends _i1.Fake + implements _i3.OrganizationsService {} -class _FakePullRequestsService_8 extends _i1.SmartFake - implements _i3.PullRequestsService { - _FakePullRequestsService_8( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakePullRequestsService_8 extends _i1.Fake + implements _i3.PullRequestsService {} -class _FakeRepositoriesService_9 extends _i1.SmartFake - implements _i3.RepositoriesService { - _FakeRepositoriesService_9( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeRepositoriesService_9 extends _i1.Fake + implements _i3.RepositoriesService {} -class _FakeSearchService_10 extends _i1.SmartFake implements _i3.SearchService { - _FakeSearchService_10( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeSearchService_10 extends _i1.Fake implements _i3.SearchService {} -class _FakeUrlShortenerService_11 extends _i1.SmartFake - implements _i3.UrlShortenerService { - _FakeUrlShortenerService_11( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeUrlShortenerService_11 extends _i1.Fake + implements _i3.UrlShortenerService {} -class _FakeUsersService_12 extends _i1.SmartFake implements _i3.UsersService { - _FakeUsersService_12( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeUsersService_12 extends _i1.Fake implements _i3.UsersService {} -class _FakeChecksService_13 extends _i1.SmartFake implements _i3.ChecksService { - _FakeChecksService_13( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeChecksService_13 extends _i1.Fake implements _i3.ChecksService {} -class _FakeResponse_14 extends _i1.SmartFake implements _i2.Response { - _FakeResponse_14( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} +class _FakeResponse_14 extends _i1.Fake implements _i2.Response {} /// A class which mocks [GitHub]. /// @@ -185,327 +62,201 @@ class MockGitHub extends _i1.Mock implements _i3.GitHub { } @override - set auth(_i3.Authentication? _auth) => super.noSuchMethod( - Invocation.setter( - #auth, - _auth, - ), - returnValueForMissingStub: null, - ); + set auth(_i3.Authentication? _auth) => + super.noSuchMethod(Invocation.setter(#auth, _auth), + returnValueForMissingStub: null); @override - String get endpoint => (super.noSuchMethod( - Invocation.getter(#endpoint), - returnValue: '', - ) as String); + String get endpoint => + (super.noSuchMethod(Invocation.getter(#endpoint), returnValue: '') + as String); @override - _i2.Client get client => (super.noSuchMethod( - Invocation.getter(#client), - returnValue: _FakeClient_0( - this, - Invocation.getter(#client), - ), - ) as _i2.Client); + _i2.Client get client => (super.noSuchMethod(Invocation.getter(#client), + returnValue: _FakeClient_0()) as _i2.Client); @override - _i3.ActivityService get activity => (super.noSuchMethod( - Invocation.getter(#activity), - returnValue: _FakeActivityService_1( - this, - Invocation.getter(#activity), - ), - ) as _i3.ActivityService); + _i3.ActivityService get activity => + (super.noSuchMethod(Invocation.getter(#activity), + returnValue: _FakeActivityService_1()) as _i3.ActivityService); @override - _i3.AuthorizationsService get authorizations => (super.noSuchMethod( - Invocation.getter(#authorizations), - returnValue: _FakeAuthorizationsService_2( - this, - Invocation.getter(#authorizations), - ), - ) as _i3.AuthorizationsService); + _i3.AuthorizationsService get authorizations => + (super.noSuchMethod(Invocation.getter(#authorizations), + returnValue: _FakeAuthorizationsService_2()) + as _i3.AuthorizationsService); @override - _i3.GistsService get gists => (super.noSuchMethod( - Invocation.getter(#gists), - returnValue: _FakeGistsService_3( - this, - Invocation.getter(#gists), - ), - ) as _i3.GistsService); + _i3.GistsService get gists => (super.noSuchMethod(Invocation.getter(#gists), + returnValue: _FakeGistsService_3()) as _i3.GistsService); @override - _i3.GitService get git => (super.noSuchMethod( - Invocation.getter(#git), - returnValue: _FakeGitService_4( - this, - Invocation.getter(#git), - ), - ) as _i3.GitService); + _i3.GitService get git => (super.noSuchMethod(Invocation.getter(#git), + returnValue: _FakeGitService_4()) as _i3.GitService); @override - _i3.IssuesService get issues => (super.noSuchMethod( - Invocation.getter(#issues), - returnValue: _FakeIssuesService_5( - this, - Invocation.getter(#issues), - ), - ) as _i3.IssuesService); + _i3.IssuesService get issues => + (super.noSuchMethod(Invocation.getter(#issues), + returnValue: _FakeIssuesService_5()) as _i3.IssuesService); @override - _i3.MiscService get misc => (super.noSuchMethod( - Invocation.getter(#misc), - returnValue: _FakeMiscService_6( - this, - Invocation.getter(#misc), - ), - ) as _i3.MiscService); + _i3.MiscService get misc => (super.noSuchMethod(Invocation.getter(#misc), + returnValue: _FakeMiscService_6()) as _i3.MiscService); @override _i3.OrganizationsService get organizations => (super.noSuchMethod( - Invocation.getter(#organizations), - returnValue: _FakeOrganizationsService_7( - this, - Invocation.getter(#organizations), - ), - ) as _i3.OrganizationsService); + Invocation.getter(#organizations), + returnValue: _FakeOrganizationsService_7()) as _i3.OrganizationsService); @override _i3.PullRequestsService get pullRequests => (super.noSuchMethod( - Invocation.getter(#pullRequests), - returnValue: _FakePullRequestsService_8( - this, - Invocation.getter(#pullRequests), - ), - ) as _i3.PullRequestsService); + Invocation.getter(#pullRequests), + returnValue: _FakePullRequestsService_8()) as _i3.PullRequestsService); @override _i3.RepositoriesService get repositories => (super.noSuchMethod( - Invocation.getter(#repositories), - returnValue: _FakeRepositoriesService_9( - this, - Invocation.getter(#repositories), - ), - ) as _i3.RepositoriesService); + Invocation.getter(#repositories), + returnValue: _FakeRepositoriesService_9()) as _i3.RepositoriesService); @override - _i3.SearchService get search => (super.noSuchMethod( - Invocation.getter(#search), - returnValue: _FakeSearchService_10( - this, - Invocation.getter(#search), - ), - ) as _i3.SearchService); + _i3.SearchService get search => + (super.noSuchMethod(Invocation.getter(#search), + returnValue: _FakeSearchService_10()) as _i3.SearchService); @override _i3.UrlShortenerService get urlShortener => (super.noSuchMethod( - Invocation.getter(#urlShortener), - returnValue: _FakeUrlShortenerService_11( - this, - Invocation.getter(#urlShortener), - ), - ) as _i3.UrlShortenerService); + Invocation.getter(#urlShortener), + returnValue: _FakeUrlShortenerService_11()) as _i3.UrlShortenerService); @override - _i3.UsersService get users => (super.noSuchMethod( - Invocation.getter(#users), - returnValue: _FakeUsersService_12( - this, - Invocation.getter(#users), - ), - ) as _i3.UsersService); + _i3.UsersService get users => (super.noSuchMethod(Invocation.getter(#users), + returnValue: _FakeUsersService_12()) as _i3.UsersService); @override - _i3.ChecksService get checks => (super.noSuchMethod( - Invocation.getter(#checks), - returnValue: _FakeChecksService_13( - this, - Invocation.getter(#checks), - ), - ) as _i3.ChecksService); + _i3.ChecksService get checks => + (super.noSuchMethod(Invocation.getter(#checks), + returnValue: _FakeChecksService_13()) as _i3.ChecksService); @override - _i4.Future getJSON( - String? path, { - int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - String? preview, - }) => + _i4.Future getJSON(String? path, + {int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + String? preview}) => (super.noSuchMethod( - Invocation.method( - #getJSON, - [path], - { + Invocation.method(#getJSON, [ + path + ], { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, - #preview: preview, - }, - ), - returnValue: _i4.Future.value(null), - ) as _i4.Future); + #preview: preview + }), + returnValue: Future.value(null)) as _i4.Future); @override - _i4.Future postJSON( - String? path, { - int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview, - }) => + _i4.Future postJSON(String? path, + {int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview}) => (super.noSuchMethod( - Invocation.method( - #postJSON, - [path], - { + Invocation.method(#postJSON, [ + path + ], { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview, - }, - ), - returnValue: _i4.Future.value(null), - ) as _i4.Future); + #preview: preview + }), + returnValue: Future.value(null)) as _i4.Future); @override - _i4.Future putJSON( - String? path, { - int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview, - }) => + _i4.Future putJSON(String? path, + {int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview}) => (super.noSuchMethod( - Invocation.method( - #putJSON, - [path], - { + Invocation.method(#putJSON, [ + path + ], { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview, - }, - ), - returnValue: _i4.Future.value(null), - ) as _i4.Future); + #preview: preview + }), + returnValue: Future.value(null)) as _i4.Future); @override - _i4.Future patchJSON( - String? path, { - int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview, - }) => + _i4.Future patchJSON(String? path, + {int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview}) => (super.noSuchMethod( - Invocation.method( - #patchJSON, - [path], - { + Invocation.method(#patchJSON, [ + path + ], { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview, - }, - ), - returnValue: _i4.Future.value(null), - ) as _i4.Future); + #preview: preview + }), + returnValue: Future.value(null)) as _i4.Future); @override - _i4.Future requestJson( - String? method, - String? path, { - int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview, - }) => + _i4.Future requestJson(String? method, String? path, + {int? statusCode, + void Function(_i2.Response)? fail, + Map? headers, + Map? params, + _i3.JSONConverter? convert, + dynamic body, + String? preview}) => (super.noSuchMethod( - Invocation.method( - #requestJson, - [ + Invocation.method(#requestJson, [ method, - path, - ], - { + path + ], { #statusCode: statusCode, #fail: fail, #headers: headers, #params: params, #convert: convert, #body: body, - #preview: preview, - }, - ), - returnValue: _i4.Future.value(null), - ) as _i4.Future); + #preview: preview + }), + returnValue: Future.value(null)) as _i4.Future); @override - _i4.Future<_i2.Response> request( - String? method, - String? path, { - Map? headers, - Map? params, - dynamic body, - int? statusCode, - void Function(_i2.Response)? fail, - String? preview, - }) => + _i4.Future<_i2.Response> request(String? method, String? path, + {Map? headers, + Map? params, + dynamic body, + int? statusCode, + void Function(_i2.Response)? fail, + String? preview}) => (super.noSuchMethod( - Invocation.method( - #request, - [ - method, - path, - ], - { - #headers: headers, - #params: params, - #body: body, - #statusCode: statusCode, - #fail: fail, - #preview: preview, - }, - ), - returnValue: _i4.Future<_i2.Response>.value(_FakeResponse_14( - this, - Invocation.method( - #request, - [ - method, - path, - ], - { - #headers: headers, - #params: params, - #body: body, - #statusCode: statusCode, - #fail: fail, - #preview: preview, - }, - ), - )), - ) as _i4.Future<_i2.Response>); + Invocation.method(#request, [ + method, + path + ], { + #headers: headers, + #params: params, + #body: body, + #statusCode: statusCode, + #fail: fail, + #preview: preview + }), + returnValue: Future<_i2.Response>.value(_FakeResponse_14())) + as _i4.Future<_i2.Response>); @override - void handleStatusCode(_i2.Response? response) => super.noSuchMethod( - Invocation.method( - #handleStatusCode, - [response], - ), - returnValueForMissingStub: null, - ); + void handleStatusCode(_i2.Response? response) => + super.noSuchMethod(Invocation.method(#handleStatusCode, [response]), + returnValueForMissingStub: null); @override - void dispose() => super.noSuchMethod( - Invocation.method( - #dispose, - [], - ), - returnValueForMissingStub: null, - ); + void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), + returnValueForMissingStub: null); } diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart index 7d77662c..8af59043 100644 --- a/test/unit/checks_test.dart +++ b/test/unit/checks_test.dart @@ -97,12 +97,12 @@ const checkRunJson = '''{ ] }'''; -const String expectedToString = '{"name":"mighty_readme","id":4,"external_id":"","status":"completed","head_sha":"","check_suite":{"id":5},"details_url":"https://example.com","started_at":"2018-05-04T01:14:52.000Z","conclusion":"neutral"}'; +const String expectedToString = + '{"name":"mighty_readme","id":4,"external_id":"","status":"completed","head_sha":"","check_suite":{"id":5},"details_url":"https://example.com","started_at":"2018-05-04T01:14:52.000Z","conclusion":"neutral"}'; void main() { group('Check run', () { test('CheckRun fromJson', () { - final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); expect(checkRun.id, 4); diff --git a/tool/release_unreleased_prs.dart b/tool/release_unreleased_prs.dart index 372eefc4..aca8dae1 100644 --- a/tool/release_unreleased_prs.dart +++ b/tool/release_unreleased_prs.dart @@ -49,7 +49,8 @@ Future main(List args) async { for (final i in unreleased) { await _gh.issues.removeLabelForIssue(_slug, i.number, 'unreleased'); await _gh.issues.addLabelsToIssue(_slug, i.number, ['released']); - await _gh.issues.createComment(_slug, i.number, 'Released in version $nextVersion https://github.com/$fullrepo/releases/tag/$nextVersion'); + await _gh.issues.createComment(_slug, i.number, + 'Released in version $nextVersion https://github.com/$fullrepo/releases/tag/$nextVersion'); } exit(0); @@ -92,15 +93,21 @@ Future getLatestVersion(RepositorySlug slug) async { Future> getUnreleasedPRs() async { print('Loading unreleased PRs...'); - var prs = await _gh.search.issues('repo:${_slug.fullName} is:pull-request label:unreleased -label:no_release_on_merge state:closed', sort: 'desc').toList(); + var prs = await _gh.search + .issues( + 'repo:${_slug.fullName} is:pull-request label:unreleased -label:no_release_on_merge state:closed', + sort: 'desc') + .toList(); print('${prs.length} loaded'); return prs; } String getNextVersion(Version currentVersion, List unreleased) { var semvers = Set(); - for (final pr in unreleased){ - var prlabels = pr.labels.where((element) => element.name.startsWith('semver:')).toList(); + for (final pr in unreleased) { + var prlabels = pr.labels + .where((element) => element.name.startsWith('semver:')) + .toList(); for (final l in prlabels) { semvers.add(l.name); } @@ -118,13 +125,14 @@ String getNextVersion(Version currentVersion, List unreleased) { return newVersion; } -Future generateReleaseNotes(String fromVersion, String newVersion) async { +Future generateReleaseNotes( + String fromVersion, String newVersion) async { var notes = await _gh.repositories.generateReleaseNotes(CreateReleaseNotes( _slug.owner, _slug.name, newVersion, previousTagName: fromVersion)); - + var releaseNotes = notes.body.replaceFirst('## What\'s Changed', ''); - + var r = '## $newVersion\n$releaseNotes'; print(r); return r; @@ -147,8 +155,8 @@ void updatePubspec(String newVersion) { } Future createRelease(String version, String target) async { - print('Creating release ...'); - var release = await _gh.repositories.createRelease( + print('Creating release ...'); + var release = await _gh.repositories.createRelease( _slug, CreateRelease.from( tagName: version, @@ -158,13 +166,13 @@ Future createRelease(String version, String target) async { isDraft: false, isPrerelease: false)); - print('Release ${release.name} created ${release.createdAt}'); - print(release.body); - return release; + print('Release ${release.name} created ${release.createdAt}'); + print(release.body); + return release; } void commitUpdates(String version) { run('git add pubspec.yaml CHANGELOG.md'); run('git', rest: ['commit', '-m', 'prep $version']); run('git push'); -} \ No newline at end of file +} From f90446459e2723baecc16f8ac725b5147bd915ab Mon Sep 17 00:00:00 2001 From: robrbecker Date: Sat, 22 Oct 2022 15:15:48 +0000 Subject: [PATCH 063/139] prep 9.5.0 --- CHANGELOG.md | 9 +++++++++ pubspec.yaml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d09d1b76..5de4e987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 9.5.0 + +* Add 'commits' member to GitHubComparison object by @fuzzybinary in https://github.com/SpinlockLabs/github.dart/pull/330 + +## New Contributors +* @fuzzybinary made their first contribution in https://github.com/SpinlockLabs/github.dart/pull/330 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.4.1...9.5.0 + ## 9.4.1 * Update to github-script 6 by @robbecker-wf in https://github.com/SpinlockLabs/github.dart/pull/331 diff --git a/pubspec.yaml b/pubspec.yaml index 9aa43f84..77f1f627 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.4.1 +version: 9.5.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From eb66f129cd44be6fc97de3b449a51d3c645d0c05 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sat, 22 Oct 2022 09:19:21 -0600 Subject: [PATCH 064/139] use "dart pub" instead of just "pub" --- .github/workflows/dart.yml | 2 +- .github/workflows/publish_demos.yml | 6 +++--- .github/workflows/publish_release.yml | 2 +- .github/workflows/release_unreleased_prs.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 0a4012c0..798e95c2 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: Install dependencies - run: pub get + run: dart pub get - name: Dart Analyzer run: dart analyze - name: Check Dart Format diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index a92beb58..33f242d2 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -18,9 +18,9 @@ jobs: - name: Install and Build 🔧 run: | - pub global activate webdev - pub get - pub global run webdev build -o build -- --delete-conflicting-outputs + dart pub global activate webdev + dart pub get + dart pub global run webdev build -o build -- --delete-conflicting-outputs rm build/example/packages - name: Publish 🚀 diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 3743cd63..ca9789ba 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -17,4 +17,4 @@ jobs: mkdir -p ~/.pub-cache echo ${{ secrets.CREDENTIAL_JSON }} > ~/.pub-cache/credentials.json - name: Publish package - run: pub publish -f \ No newline at end of file + run: dart pub publish -f \ No newline at end of file diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml index e3b196cd..c3afb5dd 100644 --- a/.github/workflows/release_unreleased_prs.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -29,5 +29,5 @@ jobs: export PATH="$PATH":"$HOME/.pub-cache/bin" export GITHUB_TOKEN=${{secrets.MACHINE_GITHUB_API_TOKEN}} export MACHINE_GITHUB_API_TOKEN=${{secrets.MACHINE_GITHUB_API_TOKEN}} - pub get + dart pub get dart tool/release_unreleased_prs.dart \ No newline at end of file From b9f545a4cfa9c8acae996a7151f94ee49ba5cf65 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 31 Oct 2022 08:28:23 -0600 Subject: [PATCH 065/139] Fix up unit tests & run them in CI (#336) - remove mockito generated mocks, use nock instead - lots of test fixes - add testing matrix - added a makefile - added ocktokit scenarios - actually run tests in CI --- .github/workflows/dart.yml | 7 +- .github/workflows/release_unreleased_prs.yml | 2 +- .github/workflows/tests.yml | 24 +- Makefile | 20 + dart_test.yaml | 15 + lib/src/common/model/misc.dart | 12 +- lib/src/common/model/repos_releases.dart | 1 + lib/src/common/model/repos_releases.g.dart | 2 +- pubspec.yaml | 3 +- test/assets/responses/nocked_responses.dart | 1474 ++++++++++++++++++ test/code_search_test.dart | 21 - test/git_test.dart | 419 ++--- test/scenarios_test.dart | 140 ++ test/src/mocks.dart | 5 - test/src/mocks.mocks.dart | 262 ---- test/unit/common/model/misc_test.dart | 51 +- 16 files changed, 1870 insertions(+), 588 deletions(-) create mode 100644 Makefile create mode 100644 dart_test.yaml create mode 100644 test/assets/responses/nocked_responses.dart delete mode 100644 test/code_search_test.dart create mode 100644 test/scenarios_test.dart delete mode 100644 test/src/mocks.dart delete mode 100644 test/src/mocks.mocks.dart diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 798e95c2..119546e2 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -4,12 +4,9 @@ on: [push] jobs: build: - runs-on: ubuntu-latest - container: - image: dart:2.14 - + image: dart:2.17 steps: - uses: actions/checkout@v1 - name: Install dependencies @@ -17,6 +14,6 @@ jobs: - name: Dart Analyzer run: dart analyze - name: Check Dart Format - run: dart format --set-exit-if-changed -o none lib test tool example && echo Dart Format 👍 || echo Files needed Dart formatting 😢 + run: dart format --set-exit-if-changed -o none lib test tool example integration_test && echo Dart Format 👍 || echo Files needed Dart formatting 😢 - name: Check if Publishable run: dart pub publish --dry-run diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml index c3afb5dd..a087b032 100644 --- a/.github/workflows/release_unreleased_prs.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -12,7 +12,7 @@ jobs: release: if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest - container: dart:2.14.4 + container: dart:2.17.7 permissions: contents: write diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b0ca36a3..6e1cb6e5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,13 +6,19 @@ on: branches: [ master ] jobs: test: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + sdk: [2.14.4, 2.17.7, stable] # Test with at least the declared minimum Dart version steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1 - - name: Install dependencies - run: dart pub get - # - name: Unit tests - # run: dart test test - # - name: Integration tests - # run: dart test integration_test + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v1.3 + with: + sdk: ${{ matrix.sdk }} + - name: Install dependencies + run: dart pub get + - name: Unit tests + run: dart test + # - name: Integration tests + # run: dart test integration_test diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..c146167b --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +.DEFAULT_GOAL := help +SHELL=/bin/bash -o pipefail + +# Cite: https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html +.PHONY: help +help: ## Display this help page + @grep -E '^[a-zA-Z0-9/_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: fixtures +fixtures: ## Run octokit-fixtures-server for scenario tests + @npx octokit-fixtures-server & + +.PHONY: stop +stop: ## Stop the fixtures server + @killall node + +.PHONY: test +test: fixtures ## Run tests + @dart test -P all + make stop \ No newline at end of file diff --git a/dart_test.yaml b/dart_test.yaml new file mode 100644 index 00000000..04f3491b --- /dev/null +++ b/dart_test.yaml @@ -0,0 +1,15 @@ +tags: + scenarios: + skip: | + Not run by default when running dart test. To run: + npx octokit-fixtures-server + dart test -P scenarios + or run all tests with: + make test + +presets: + scenarios: + include_tags: scenarios + run_skipped: true + all: + run_skipped: true \ No newline at end of file diff --git a/lib/src/common/model/misc.dart b/lib/src/common/model/misc.dart index ad693d34..adf7b2be 100644 --- a/lib/src/common/model/misc.dart +++ b/lib/src/common/model/misc.dart @@ -44,10 +44,14 @@ class RateLimit { /// /// API docs: https://developer.github.com/v3/rate_limit/ factory RateLimit.fromRateLimitResponse(Map response) { - final rateJson = response['rate'] as Map; - final limit = rateJson['limit'] as int?; - final remaining = rateJson['remaining'] as int?; - final resets = DateTime.fromMillisecondsSinceEpoch(rateJson['reset']!); + final rateJson = response['rate'] == null + ? null + : response['rate'] as Map; + final limit = rateJson?['limit'] as int?; + final remaining = rateJson?['remaining'] as int?; + final resets = rateJson?['reset'] == null + ? null + : DateTime.fromMillisecondsSinceEpoch(rateJson?['reset']); return RateLimit(limit, remaining, resets); } diff --git a/lib/src/common/model/repos_releases.dart b/lib/src/common/model/repos_releases.dart index 4656dd1c..30a80172 100644 --- a/lib/src/common/model/repos_releases.dart +++ b/lib/src/common/model/repos_releases.dart @@ -175,6 +175,7 @@ class CreateRelease { String? discussionCategoryName; + @JsonKey(defaultValue: false) bool generateReleaseNotes = false; CreateRelease(this.tagName); diff --git a/lib/src/common/model/repos_releases.g.dart b/lib/src/common/model/repos_releases.g.dart index bcaec1ee..2e0998e7 100644 --- a/lib/src/common/model/repos_releases.g.dart +++ b/lib/src/common/model/repos_releases.g.dart @@ -101,7 +101,7 @@ CreateRelease _$CreateReleaseFromJson(Map json) => ..isDraft = json['draft'] as bool? ..isPrerelease = json['prerelease'] as bool? ..discussionCategoryName = json['discussion_category_name'] as String? - ..generateReleaseNotes = json['generate_release_notes'] as bool; + ..generateReleaseNotes = json['generate_release_notes'] as bool? ?? false; Map _$CreateReleaseToJson(CreateRelease instance) => { diff --git a/pubspec.yaml b/pubspec.yaml index 77f1f627..ed60fc15 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,7 +21,8 @@ dev_dependencies: json_serializable: ^6.0.0 lints: ^1.0.0 mockito: ^5.0.0 - pub_semver: + nock: ^1.0.0 + pub_semver: ^2.0.0 test: ^1.16.0 yaml: ^3.0.0 yaml_edit: diff --git a/test/assets/responses/nocked_responses.dart b/test/assets/responses/nocked_responses.dart new file mode 100644 index 00000000..6feb9465 --- /dev/null +++ b/test/assets/responses/nocked_responses.dart @@ -0,0 +1,1474 @@ +var getBlob = ''' +{ + "content": "Q29udGVudCBvZiB0aGUgYmxvYg==", + "encoding": "base64", + "url": "https://api.github.com/repos/octocat/example/git/blobs/3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15", + "sha": "3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15", + "size": 19, + "node_id": "Q29udGVudCBvZiB0aGUgYmxvYg==" +}'''; + +var createBlob = ''' +{ + "url": "https://api.github.com/repos/octocat/example/git/blobs/3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15", + "sha": "3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15", + "content": "bbb", + "encoding": "utf-8" +}'''; + +var getCommit = ''' +{ + "sha": "7638417db6d59f3c431d3e1f261cc637155684cd", + "node_id": "MDY6Q29tbWl0NmRjYjA5YjViNTc4NzVmMzM0ZjYxYWViZWQ2OTVlMmU0MTkzZGI1ZQ==", + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd", + "html_url": "https://github.com/octocat/Hello-World/commit/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "date": "2014-11-07T22:01:45Z", + "name": "Monalisa Octocat", + "email": "octocat@github.com" + }, + "committer": { + "date": "2014-11-07T22:01:45Z", + "name": "Monalisa Octocat", + "email": "octocat@github.com" + }, + "message": "added readme, because im a good github citizen", + "tree": { + "url": "https://api.github.com/repos/octocat/Hello-World/git/trees/691272480426f78a0138979dd3ce63b77f706feb", + "sha": "691272480426f78a0138979dd3ce63b77f706feb" + }, + "parents": [ + { + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/1acc419d4d6a9ce985db7be48c6349a0475975b5", + "sha": "1acc419d4d6a9ce985db7be48c6349a0475975b5", + "html_url": "https://github.com/octocat/Hello-World/commit/7638417db6d59f3c431d3e1f261cc637155684cd" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + } +}'''; + +var createCommit = ''' +{ + "sha": "7638417db6d59f3c431d3e1f261cc637155684cd", + "node_id": "MDY6Q29tbWl0NzYzODQxN2RiNmQ1OWYzYzQzMWQzZTFmMjYxY2M2MzcxNTU2ODRjZA==", + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "date": "2014-11-07T22:01:45Z", + "name": "Monalisa Octocat", + "email": "octocat@github.com" + }, + "committer": { + "date": "2014-11-07T22:01:45Z", + "name": "Monalisa Octocat", + "email": "octocat@github.com" + }, + "message": "aMessage", + "tree": { + "url": "https://api.github.com/repos/octocat/Hello-World/git/trees/827efc6d56897b048c772eb4087f854f46256132", + "sha": "aTreeSha" + }, + "parents": [ + { + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/7d1b31e74ee336d15cbd21741bc88a537ed063a0", + "sha": "7d1b31e74ee336d15cbd21741bc88a537ed063a0", + "html_url": "https://github.com/octocat/Hello-World/commit/7d1b31e74ee336d15cbd21741bc88a537ed063a0" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + }, + "html_url": "https://github.com/octocat/Hello-World/commit/7638417db6d59f3c431d3e1f261cc637155684cd" +}'''; + +var getReference = '''{ + "ref": "refs/heads/b", + "node_id": "MDM6UmVmcmVmcy9oZWFkcy9mZWF0dXJlQQ==", + "url": "https://api.github.com/repos/octocat/Hello-World/git/refs/heads/featureA", + "object": { + "type": "commit", + "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" + } +}'''; + +var createReference = '''{ + "ref": "refs/heads/b", + "node_id": "MDM6UmVmcmVmcy9oZWFkcy9mZWF0dXJlQQ==", + "url": "https://api.github.com/repos/octocat/Hello-World/git/refs/heads/featureA", + "object": { + "type": "commit", + "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" + } +}'''; + +var getTag = '''{ + "node_id": "MDM6VGFnOTQwYmQzMzYyNDhlZmFlMGY5ZWU1YmM3YjJkNWM5ODU4ODdiMTZhYw==", + "tag": "v0.0.1", + "sha": "940bd336248efae0f9ee5bc7b2d5c985887b16ac", + "url": "https://api.github.com/repos/octocat/Hello-World/git/tags/940bd336248efae0f9ee5bc7b2d5c985887b16ac", + "message": "initial version", + "tagger": { + "name": "Monalisa Octocat", + "email": "octocat@github.com", + "date": "2014-11-07T22:01:45Z" + }, + "object": { + "type": "commit", + "sha": "c3d0be41ecbe669545ee3e94d31ed9a4bc91ee3c", + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/c3d0be41ecbe669545ee3e94d31ed9a4bc91ee3c" + }, + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + } +}'''; + +var createTag = '''{ + "node_id": "MDM6VGFnOTQwYmQzMzYyNDhlZmFlMGY5ZWU1YmM3YjJkNWM5ODU4ODdiMTZhYw==", + "tag": "v0.0.1", + "sha": "940bd336248efae0f9ee5bc7b2d5c985887b16ac", + "url": "https://api.github.com/repos/octocat/Hello-World/git/tags/940bd336248efae0f9ee5bc7b2d5c985887b16ac", + "message": "initial version", + "tagger": { + "name": "Monalisa Octocat", + "email": "octocat@github.com", + "date": "2014-11-07T22:01:45Z" + }, + "object": { + "type": "commit", + "sha": "c3d0be41ecbe669545ee3e94d31ed9a4bc91ee3c", + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/c3d0be41ecbe669545ee3e94d31ed9a4bc91ee3c" + }, + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + } +}'''; + +var createTree = '''{ + "sha": "44b4fc6d56897b048c772eb4087f854f46256132", + "url": "https://api.github.com/repos/octocat/Hello-World/trees/44b4fc6d56897b048c772eb4087f854f46256132", + "tree": [ + { + "path": "file.rb", + "mode": "100644", + "type": "blob", + "size": 132, + "sha": "44b4fc6d56897b048c772eb4087f854f46256132", + "url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" + } + ], + "truncated": true +}'''; + +var searchResults = '''{ + "total_count": 17, + "incomplete_results": false, + "items": [ + { + "name": "search.dart", + "path": "lib/src/common/model/search.dart", + "sha": "c61f39e54eeef0b20d132d2c3ea48bcd3b0d34a9", + "url": "https://api.github.com/repositories/22344823/contents/lib/src/common/model/search.dart?ref=27929ddc731393422327dddee0aaa56d0164c775", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/c61f39e54eeef0b20d132d2c3ea48bcd3b0d34a9", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/27929ddc731393422327dddee0aaa56d0164c775/lib/src/common/model/search.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "search_service.dart", + "path": "lib/src/common/search_service.dart", + "sha": "e98344a6f07d4d9ba1d5b1045354c6a8d3a5323f", + "url": "https://api.github.com/repositories/22344823/contents/lib/src/common/search_service.dart?ref=11a83b4fc9558b7f8c47fdced01c7a8dac3c65b2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/e98344a6f07d4d9ba1d5b1045354c6a8d3a5323f", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/11a83b4fc9558b7f8c47fdced01c7a8dac3c65b2/lib/src/common/search_service.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "search.dart", + "path": "example/search.dart", + "sha": "9ca8b0ac2bfe0ce4afe2d49713ba639146f1ee1a", + "url": "https://api.github.com/repositories/22344823/contents/example/search.dart?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/9ca8b0ac2bfe0ce4afe2d49713ba639146f1ee1a", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/example/search.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "emoji.dart", + "path": "example/emoji.dart", + "sha": "7604d4619400b6b2a19ab11baa60dfa6fa08843e", + "url": "https://api.github.com/repositories/22344823/contents/example/emoji.dart?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/7604d4619400b6b2a19ab11baa60dfa6fa08843e", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/example/emoji.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "search.html", + "path": "example/search.html", + "sha": "16f41b72e4e6135c63aaf923be50a6c87ec80126", + "url": "https://api.github.com/repositories/22344823/contents/example/search.html?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/16f41b72e4e6135c63aaf923be50a6c87ec80126", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/example/search.html", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "mocks.mocks.dart", + "path": "test/src/mocks.mocks.dart", + "sha": "c381f58a8641b8814afd65b6b7a39384035e2ae3", + "url": "https://api.github.com/repositories/22344823/contents/test/src/mocks.mocks.dart?ref=7056f9c2bf17c5f437e6cb32012a7d16f9ed3278", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/c381f58a8641b8814afd65b6b7a39384035e2ae3", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/7056f9c2bf17c5f437e6cb32012a7d16f9ed3278/test/src/mocks.mocks.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "emoji.html", + "path": "example/emoji.html", + "sha": "bdafb143dd918a4872e982b3f876c32aaf9877b2", + "url": "https://api.github.com/repositories/22344823/contents/example/emoji.html?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/bdafb143dd918a4872e982b3f876c32aaf9877b2", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/example/emoji.html", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "index.html", + "path": "example/index.html", + "sha": "81e054e8a613cb2932f905e42c3dc2e294e551ac", + "url": "https://api.github.com/repositories/22344823/contents/example/index.html?ref=c72b46031fcd326820cbc5bb0c3b4b1c15e075e4", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/81e054e8a613cb2932f905e42c3dc2e294e551ac", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/c72b46031fcd326820cbc5bb0c3b4b1c15e075e4/example/index.html", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "readme.md", + "path": "example/readme.md", + "sha": "0781c2ba3898ee16123d9b63a7685d588f3f7511", + "url": "https://api.github.com/repositories/22344823/contents/example/readme.md?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/0781c2ba3898ee16123d9b63a7685d588f3f7511", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/example/readme.md", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "CHANGELOG.md", + "path": "CHANGELOG.md", + "sha": "5de4e987d591c1f71b8f94311671fa8edb38ca6b", + "url": "https://api.github.com/repositories/22344823/contents/CHANGELOG.md?ref=f90446459e2723baecc16f8ac725b5147bd915ab", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/5de4e987d591c1f71b8f94311671fa8edb38ca6b", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/f90446459e2723baecc16f8ac725b5147bd915ab/CHANGELOG.md", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "github.dart", + "path": "lib/src/common/github.dart", + "sha": "e715c2a9b4439c24f00b00071cc86db63c426f1e", + "url": "https://api.github.com/repositories/22344823/contents/lib/src/common/github.dart?ref=921269ba8f803ba47470c624460c23c289b3291b", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/e715c2a9b4439c24f00b00071cc86db63c426f1e", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/921269ba8f803ba47470c624460c23c289b3291b/lib/src/common/github.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "common.dart", + "path": "lib/src/common.dart", + "sha": "f8be345ced35b7320355e04663f7504cb0a502b6", + "url": "https://api.github.com/repositories/22344823/contents/lib/src/common.dart?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/f8be345ced35b7320355e04663f7504cb0a502b6", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/lib/src/common.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "search.dart", + "path": "test/experiment/search.dart", + "sha": "1fffe4dd40ca49cff3f96d248a1740ac67e6a602", + "url": "https://api.github.com/repositories/22344823/contents/test/experiment/search.dart?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/1fffe4dd40ca49cff3f96d248a1740ac67e6a602", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/test/experiment/search.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "code_search_test.dart", + "path": "test/code_search_test.dart", + "sha": "3d60cf6329a298d99d8b074009c2a8fd3c39a470", + "url": "https://api.github.com/repositories/22344823/contents/test/code_search_test.dart?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/3d60cf6329a298d99d8b074009c2a8fd3c39a470", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/test/code_search_test.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "xplat_browser.dart", + "path": "lib/src/browser/xplat_browser.dart", + "sha": "79aeeb174148ae38f6a26d2297356b160e504b6b", + "url": "https://api.github.com/repositories/22344823/contents/lib/src/browser/xplat_browser.dart?ref=4875e4b34ade7f5e36443cd5a2716fe83d9360a2", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/79aeeb174148ae38f6a26d2297356b160e504b6b", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/4875e4b34ade7f5e36443cd5a2716fe83d9360a2/lib/src/browser/xplat_browser.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "release_notes.dart", + "path": "example/release_notes.dart", + "sha": "867474ee071b0b026fcf64cd2409830279c8b2db", + "url": "https://api.github.com/repositories/22344823/contents/example/release_notes.dart?ref=921269ba8f803ba47470c624460c23c289b3291b", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/867474ee071b0b026fcf64cd2409830279c8b2db", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/921269ba8f803ba47470c624460c23c289b3291b/example/release_notes.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + }, + { + "name": "release_unreleased_prs.dart", + "path": "tool/release_unreleased_prs.dart", + "sha": "aca8dae11ec0a26804761ea302934829bf70b4c9", + "url": "https://api.github.com/repositories/22344823/contents/tool/release_unreleased_prs.dart?ref=7056f9c2bf17c5f437e6cb32012a7d16f9ed3278", + "git_url": "https://api.github.com/repositories/22344823/git/blobs/aca8dae11ec0a26804761ea302934829bf70b4c9", + "html_url": "https://github.com/SpinlockLabs/github.dart/blob/7056f9c2bf17c5f437e6cb32012a7d16f9ed3278/tool/release_unreleased_prs.dart", + "repository": { + "id": 22344823, + "node_id": "MDEwOlJlcG9zaXRvcnkyMjM0NDgyMw==", + "name": "github.dart", + "full_name": "SpinlockLabs/github.dart", + "private": false, + "owner": { + "login": "SpinlockLabs", + "id": 26679435, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjI2Njc5NDM1", + "avatar_url": "https://avatars.githubusercontent.com/u/26679435?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/SpinlockLabs", + "html_url": "https://github.com/SpinlockLabs", + "followers_url": "https://api.github.com/users/SpinlockLabs/followers", + "following_url": "https://api.github.com/users/SpinlockLabs/following{/other_user}", + "gists_url": "https://api.github.com/users/SpinlockLabs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/SpinlockLabs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/SpinlockLabs/subscriptions", + "organizations_url": "https://api.github.com/users/SpinlockLabs/orgs", + "repos_url": "https://api.github.com/users/SpinlockLabs/repos", + "events_url": "https://api.github.com/users/SpinlockLabs/events{/privacy}", + "received_events_url": "https://api.github.com/users/SpinlockLabs/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/SpinlockLabs/github.dart", + "description": "GitHub Client Library for Dart", + "fork": false, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart", + "forks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/forks", + "keys_url": "https://api.github.com/repos/SpinlockLabs/github.dart/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/SpinlockLabs/github.dart/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/SpinlockLabs/github.dart/teams", + "hooks_url": "https://api.github.com/repos/SpinlockLabs/github.dart/hooks", + "issue_events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/events{/number}", + "events_url": "https://api.github.com/repos/SpinlockLabs/github.dart/events", + "assignees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/assignees{/user}", + "branches_url": "https://api.github.com/repos/SpinlockLabs/github.dart/branches{/branch}", + "tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/tags", + "blobs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/SpinlockLabs/github.dart/statuses/{sha}", + "languages_url": "https://api.github.com/repos/SpinlockLabs/github.dart/languages", + "stargazers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/stargazers", + "contributors_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contributors", + "subscribers_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscribers", + "subscription_url": "https://api.github.com/repos/SpinlockLabs/github.dart/subscription", + "commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/SpinlockLabs/github.dart/contents/{+path}", + "compare_url": "https://api.github.com/repos/SpinlockLabs/github.dart/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/SpinlockLabs/github.dart/merges", + "archive_url": "https://api.github.com/repos/SpinlockLabs/github.dart/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/SpinlockLabs/github.dart/downloads", + "issues_url": "https://api.github.com/repos/SpinlockLabs/github.dart/issues{/number}", + "pulls_url": "https://api.github.com/repos/SpinlockLabs/github.dart/pulls{/number}", + "milestones_url": "https://api.github.com/repos/SpinlockLabs/github.dart/milestones{/number}", + "notifications_url": "https://api.github.com/repos/SpinlockLabs/github.dart/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/SpinlockLabs/github.dart/labels{/name}", + "releases_url": "https://api.github.com/repos/SpinlockLabs/github.dart/releases{/id}", + "deployments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/deployments" + }, + "score": 1.0 + } + ] +}'''; diff --git a/test/code_search_test.dart b/test/code_search_test.dart deleted file mode 100644 index 3d60cf63..00000000 --- a/test/code_search_test.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:io'; -import 'package:github/github.dart'; - -Future main() async { - print('Searching ...'); - final github = GitHub(); - - final resultsStream = github.search.code( - 'github', - repo: 'SpinlockLabs/github.dart', - perPage: 5, - pages: 1, - ); - final results = await resultsStream.first; - print('${results.totalCount} results'); - var k = 1; - for (final i in results.items!) { - print('${k++} ${i.path}'); - } - exit(0); -} diff --git a/test/git_test.dart b/test/git_test.dart index d6e19bdb..2eaff028 100644 --- a/test/git_test.dart +++ b/test/git_test.dart @@ -1,310 +1,191 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:github/src/common.dart'; -import 'package:http/http.dart' as http; -import 'package:mockito/mockito.dart'; +import 'dart:io'; +import 'package:github/github.dart'; +import 'package:nock/nock.dart'; import 'package:test/test.dart'; -import 'src/mocks.mocks.dart'; +import 'assets/responses/nocked_responses.dart' as nocked; + +const fakeApiUrl = 'http://fake.api.github.com'; +const date = '2014-10-02T15:21:29Z'; + +GitHub createGithub() { + return GitHub( + endpoint: fakeApiUrl, + auth: + Authentication.withToken('0000000000000000000000000000000000000001')); +} void main() { - late MockGitHub github; + late GitHub github; late GitService git; late RepositorySlug repo; const someSha = 'someSHA'; + setUpAll(nock.init); + setUp(() { - github = MockGitHub(); + nock.cleanAll(); + github = createGithub(); git = GitService(github); repo = RepositorySlug('o', 'n'); }); + tearDown(nock.cleanAll); - group('getBlob()', () { - test('constructs correct path', () { - git.getBlob(repo, 'sh'); - - verify(github.getJSON('/repos/o/n/git/blobs/sh', - convert: (dynamic i) => GitBlob.fromJson(i), - statusCode: StatusCodes.OK)); - }); + test('getBlob()', () async { + nock(fakeApiUrl).get('/repos/o/n/git/blobs/sh').reply(200, nocked.getBlob); + final blob = await git.getBlob(repo, 'sh'); + expect(blob.sha, '3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15'); + expect(nock.pendingMocks.isEmpty, true); }); - group('createBlob()', () { - test('constructs correct path', () { - var blob = CreateGitBlob('bbb', 'utf-8'); - git.createBlob(repo, blob); - - verify(github.postJSON( - '/repos/o/n/git/blobs', - convert: (dynamic i) => GitBlob.fromJson(i), - statusCode: StatusCodes.CREATED, - body: GitHubJson.encode(blob), - )); - }); - - test('creates valid JSON body', () { - var blob = CreateGitBlob('bbb', 'utf-8'); - - git.createBlob(repo, blob); - final body = captureSentBody(github)!; - expect(body['content'], equals('bbb')); - expect(body['encoding'], equals('utf-8')); - }); + test('createBlob()', () async { + nock(fakeApiUrl) + .post('/repos/o/n/git/blobs', '{"content":"bbb","encoding":"utf-8"}') + .reply(201, nocked.createBlob); + var blob = await git.createBlob(repo, CreateGitBlob('bbb', 'utf-8')); + expect(blob.content, 'bbb'); + expect(blob.encoding, 'utf-8'); }); - group('getCommit()', () { - test('constructs correct path', () { - git.getCommit(repo, 'sh'); - - verify(github.getJSON('/repos/o/n/git/commits/sh', - convert: (dynamic i) => GitCommit.fromJson(i), - statusCode: StatusCodes.OK)); - }); + test('getCommit()', () async { + nock(fakeApiUrl) + .get('/repos/o/n/git/commits/sh') + .reply(200, nocked.getCommit); + var commit = await git.getCommit(repo, 'sh'); + expect(commit.sha, '7638417db6d59f3c431d3e1f261cc637155684cd'); }); - group('createCommit()', () { - test('constructs correct path', () { - final commit = CreateGitCommit('aMessage', 'aTreeSha'); - git.createCommit(repo, commit); - - verify(github.postJSON( - '/repos/o/n/git/commits', - convert: (dynamic i) => GitCommit.fromJson(i), - statusCode: StatusCodes.CREATED, - body: GitHubJson.encode(commit), - )); - }); - - test('creates valid JSON body', () { - // given - const date = '2014-10-02T15:21:29Z'; - - final commit = CreateGitCommit('aMessage', 'aTreeSha') - ..parents = ['parentSha1', 'parentSha2'] - ..committer = GitCommitUser('cName', 'cEmail', DateTime.parse(date)) - ..author = GitCommitUser('aName', 'aEmail', DateTime.parse(date)); - - // when - git.createCommit(repo, commit); - - // then - final body = captureSentBody(github)!; - expect(body['message'], equals('aMessage')); - expect(body['tree'], equals('aTreeSha')); - expect(body['parents'], equals(['parentSha1', 'parentSha2'])); - expect(body['committer']['name'], equals('cName')); - expect(body['committer']['email'], equals('cEmail')); - expect(body['committer']['date'], equals(date)); - expect(body['author']['name'], equals('aName')); - expect(body['author']['email'], equals('aEmail')); - expect(body['author']['date'], equals(date)); - }); + test('createCommit()', () async { + nock(fakeApiUrl) + .post('/repos/o/n/git/commits', + '{"message":"aMessage","tree":"aTreeSha","parents":["parentSha1","parentSha2"],"committer":{"name":"cName","email":"cEmail","date":"2014-10-02T15:21:29Z"},"author":{"name":"aName","email":"aEmail","date":"2014-10-02T15:21:29Z"}}') + .reply(201, nocked.createCommit); + + var commit = await git.createCommit( + repo, + CreateGitCommit('aMessage', 'aTreeSha') + ..parents = ['parentSha1', 'parentSha2'] + ..committer = GitCommitUser('cName', 'cEmail', DateTime.parse(date)) + ..author = GitCommitUser('aName', 'aEmail', DateTime.parse(date))); + expect(commit.message, 'aMessage'); + expect(commit.tree!.sha, 'aTreeSha'); }); - group('getReference()', () { - test('constructs correct path', () { - git.getReference(repo, 'heads/b'); - - verify(github.getJSON('/repos/o/n/git/refs/heads/b', - convert: (dynamic i) => GitReference.fromJson(i), - statusCode: StatusCodes.OK)); - }); + test('getReference()', () async { + nock(fakeApiUrl) + .get('/repos/o/n/git/refs/heads/b') + .reply(200, nocked.getReference); + var ref = await git.getReference(repo, 'heads/b'); + expect(ref.ref, 'refs/heads/b'); }); - group('createReference()', () { + test('createReference()', () async { const someRef = 'refs/heads/b'; - test('constructs correct path', () { - git.createReference(repo, someRef, someSha); - - verify(github.postJSON('/repos/o/n/git/refs', - convert: (dynamic i) => GitReference.fromJson(i), - statusCode: StatusCodes.CREATED, - body: GitHubJson.encode({'ref': someRef, 'sha': someSha}))); - }); - - test('creates valid JSON body', () { - git.createReference(repo, someRef, someSha); - - final body = captureSentBody(github)!; - expect(body['ref'], equals(someRef)); - expect(body['sha'], equals(someSha)); - }); + nock(fakeApiUrl) + .post('/repos/o/n/git/refs', '{"ref":"refs/heads/b","sha":"someSHA"}') + .reply(201, nocked.createReference); + var ref = await git.createReference(repo, someRef, someSha); + expect(ref.ref, someRef); }); - group('editReference()', () { - test('constructs correct path', () { - // given - final expectedResponse = http.Response('{}', 200); - - when(github.request(any, any, body: any, headers: any)) - .thenReturn(Future.value(expectedResponse)); - - // when - git.editReference(repo, 'heads/b', someSha); - - // then - verify(github.request('PATCH', '/repos/o/n/git/refs/heads/b', - headers: any, body: any)); - }); - - test('creates valid JSON body', () { - // given - final expectedResponse = http.Response('{}', 200); - when(github.request(any, any, body: any, headers: any)) - .thenReturn(Future.value(expectedResponse)); - - // when - git.editReference(repo, 'heads/b', someSha, force: true); + test('editReference()', () async { + nock(fakeApiUrl) + .patch('/repos/o/n/git/refs/heads/b', '{"sha":"someSHA","force":true}') + .reply(200, '{}'); - // then - final captured = verify(github.request( - any, - any, - body: captureAny, - headers: captureAny, - )).captured; - - final body = jsonDecode(captured[0]); - final headers = captured[1]; - - expect(body['sha'], equals(someSha)); - expect(body['force'], equals(true)); - expect(headers['content-length'], equals('30')); - }); + await git.editReference(repo, 'heads/b', someSha, force: true); }); - group('deleteReference()', () { - test('constructs correct path', () { - // given - final expectedResponse = http.Response('{}', 200); - when(github.request(any, any)).thenReturn(Future.value(expectedResponse)); - - // when - git.deleteReference(repo, 'heads/b'); - - // then - verify(github.request('DELETE', '/repos/o/n/git/refs/heads/b')); - }); + test('deleteReference()', () async { + nock(fakeApiUrl).delete('/repos/o/n/git/refs/heads/b').reply(200, '{}'); + await git.deleteReference(repo, 'heads/b'); }); - group('getTag()', () { - test('constructs correct path', () { - git.getTag(repo, someSha); - - verify(github.getJSON('/repos/o/n/git/tags/someSHA', - convert: (dynamic i) => GitTag.fromJson(i), - statusCode: StatusCodes.OK)); - }); + test('getTag()', () async { + nock(fakeApiUrl) + .get('/repos/o/n/git/tags/someSHA') + .reply(200, nocked.getTag); + await git.getTag(repo, someSha); }); - group('createTag()', () { - final createGitTag = CreateGitTag('v0.0.1', 'a message', someSha, 'commit', - GitCommitUser('aName', 'aEmail', DateTime.now())); - - test('constructs correct path', () { - git.createTag(repo, createGitTag); - - verify(github.postJSON('/repos/o/n/git/tags', - convert: (dynamic i) => GitTag.fromJson(i), - statusCode: StatusCodes.CREATED, - body: GitHubJson.encode(createGitTag))); - }); - - test('creates valid JSON body', () { - git.createTag(repo, createGitTag); - - final body = captureSentBody(github)!; - expect(body['tag'], equals('v0.0.1')); - expect(body['message'], equals('a message')); - expect(body['object'], equals(someSha)); - expect(body['type'], equals('commit')); - expect(body['tagger']['name'], equals('aName')); - }); + test('createTag()', () async { + nock(fakeApiUrl) + .post('/repos/o/n/git/tags', + '{"tag":"v0.0.1","message":"initial version","object":"someSHA","type":"commit","tagger":{"name":"Monalisa Octocat","email":"octocat@github.com","date":"$date"}}') + .reply(201, nocked.createTag); + + final createGitTag = CreateGitTag( + 'v0.0.1', + 'initial version', + someSha, + 'commit', + GitCommitUser( + 'Monalisa Octocat', 'octocat@github.com', DateTime.parse(date))); + + var tag = await git.createTag(repo, createGitTag); + + expect(tag.tag, 'v0.0.1'); + expect(tag.message, 'initial version'); + expect(tag.tagger?.name, 'Monalisa Octocat'); }); - group('getTree()', () { - test('constructs correct path', () { - git.getTree(repo, 'sh'); - - verify(github.getJSON('/repos/o/n/git/trees/sh', - convert: (dynamic j) => GitTree.fromJson(j), - statusCode: StatusCodes.OK)); - }); + test('getTree()', () async { + nock(fakeApiUrl) + .get('/repos/o/n/git/trees/sh?recursive=1') + .reply(200, '{}'); + await git.getTree(repo, 'sh', recursive: true); }); - group('getTree(recursive: true)', () { - test('constructs correct path', () { - git.getTree(repo, 'sh', recursive: true); - - verify(github.getJSON('/repos/o/n/git/trees/sh?recursive=1', - convert: (dynamic j) => GitTree.fromJson(j), - statusCode: StatusCodes.OK)); - }); + test('createTree()', () async { + nock(fakeApiUrl) + .post('/repos/o/n/git/trees', + '{"tree":[{"path":"file.rb","mode":"100644","type":"blob","sha":"44b4fc6d56897b048c772eb4087f854f46256132"}]}') + .reply(201, nocked.createTree); + + var createTree = CreateGitTree([ + CreateGitTreeEntry('file.rb', '100644', 'blob', + sha: '44b4fc6d56897b048c772eb4087f854f46256132') + ]); + + var tree = await git.createTree(repo, createTree); + var entry = tree.entries?.first; + expect(entry?.path, 'file.rb'); + expect(entry?.mode, '100644'); + expect(entry?.type, 'blob'); + expect(entry?.sha, '44b4fc6d56897b048c772eb4087f854f46256132'); + + nock(fakeApiUrl) + .post('/repos/o/n/git/trees', + '{"tree":[{"path":"file.rb","mode":"100644","type":"blob","content":"content"}]}') + .reply(201, nocked.createTree); + + createTree = CreateGitTree( + [CreateGitTreeEntry('file.rb', '100644', 'blob', content: 'content')]); + + tree = await git.createTree(repo, createTree); + entry = tree.entries?.first; + expect(entry?.path, 'file.rb'); + expect(entry?.mode, '100644'); + expect(entry?.type, 'blob'); + expect(entry?.sha, '44b4fc6d56897b048c772eb4087f854f46256132'); }); - group('createTree()', () { - test('constructs correct path', () { - final createGitTree = CreateGitTree([]); - git.createTree(repo, createGitTree); - - verify(github.postJSON('/repos/o/n/git/trees', - convert: (dynamic j) => GitTree.fromJson(j), - statusCode: StatusCodes.CREATED, - body: GitHubJson.encode(createGitTree))); - }); - - test('with sha creates valid JSON body', () { - // given - var treeEntry = CreateGitTreeEntry('file.rb', '100644', 'blob', - sha: '44b4fc6d56897b048c772eb4087f854f46256132'); - - final tree = CreateGitTree([treeEntry]); - - // when - git.createTree(repo, tree); - - // then - final body = captureSentBody(github)!; - expect(body['tree'], isNotNull); - expect(body['tree'][0]['path'], equals('file.rb')); - expect(body['tree'][0]['mode'], equals('100644')); - expect(body['tree'][0]['type'], equals('blob')); - expect(body['tree'][0]['sha'], - equals('44b4fc6d56897b048c772eb4087f854f46256132')); - expect(body['tree'][0]['content'], isNull); - }); - - test('with content creates valid JSON body', () { - // given - var treeEntry = CreateGitTreeEntry('file.rb', '100644', 'blob', - content: 'some file content'); - - final tree = CreateGitTree([treeEntry]); - - // when - git.createTree(repo, tree); - - // then - final body = captureSentBody(github)!; - expect(body['tree'], isNotNull); - expect(body['tree'][0]['path'], equals('file.rb')); - expect(body['tree'][0]['mode'], equals('100644')); - expect(body['tree'][0]['type'], equals('blob')); - expect(body['tree'][0]['sha'], isNull); - expect(body['tree'][0]['content'], equals('some file content')); - }); + test('code search', () async { + nock(fakeApiUrl) + .get( + '/search/code?q=search%20repo%3ASpinlockLabs%2Fgithub.dart%20in%3Afile&per_page=20&page=1') + .reply(200, nocked.searchResults); + + final results = (await github.search + .code( + 'search', + repo: 'SpinlockLabs/github.dart', + perPage: 20, + pages: 1, + ) + .toList()) + .first; + expect(results.totalCount, 17); + expect(results.items?.length, 17); }); } - -Map? captureSentBody(MockGitHub github) { - final bodyString = verify(github.postJSON( - any, - convert: any, - statusCode: any, - body: captureAny, - )).captured.single; - - final body = jsonDecode(bodyString) as Map?; - return body; -} diff --git a/test/scenarios_test.dart b/test/scenarios_test.dart new file mode 100644 index 00000000..6486553d --- /dev/null +++ b/test/scenarios_test.dart @@ -0,0 +1,140 @@ +@Tags(['scenarios']) +@TestOn('vm') + +import 'dart:convert'; + +import 'package:github/github.dart'; +import 'package:http/http.dart' as http; +import 'package:test/test.dart'; + +final defaultFixtureServerUri = Uri.parse('http://localhost:3000/fixtures'); + +/// All folder names at @octokit/fixtures/scenarios/api.github.com +/// are valid values for [scenario]. +Future createGithubWithScenario(String scenario, + {Uri? fixtureServerUri}) async { + fixtureServerUri ??= defaultFixtureServerUri; + + // send a request to the fixtures server to get load a fixture + var resp = await http.post(fixtureServerUri, + headers: {'Content-Type': 'application/json'}, + body: '{"scenario": "$scenario"}'); + if (resp.statusCode < 200 || resp.statusCode >= 300) { + throw Exception( + 'Error loading scenario: $scenario\n${resp.statusCode}\n${resp.body}'); + } + var j = json.decode(resp.body); + return GitHub( + endpoint: j['url'], + auth: + Authentication.withToken('0000000000000000000000000000000000000001')); +} + +/// Run scenario tests against ockokits fixtures-server +/// https://github.com/octokit/fixtures-server +/// +/// These tests are a port of the rest.js ocktokit tests from +/// https://github.com/octokit/rest.js/tree/master/test/scenarios +/// +/// The fixture server must be running before running these tests +/// The easiest way is to install node and then run +/// npx octokit-fixtures-server +/// +/// TODO(robrbecker) Implement a fixture-server "light" in Dart +/// directly using nock so we can remove the dependency on node +/// and running a server in order to run tests +void main() { + test('add-and-remove-repository-collaborator', () async { + var gh = await createGithubWithScenario( + 'add-and-remove-repository-collaborator'); + // todo do test + }, skip: true); + test('add-labels-to-issue', () async { + var gh = await createGithubWithScenario('add-labels-to-issue'); + // todo do test + }, skip: true); + test('branch-protection', () async { + var gh = await createGithubWithScenario('branch-protection'); + // todo do test + }, skip: true); + test('create-file', () async { + var gh = await createGithubWithScenario('create-file'); + // todo do test + }, skip: true); + + test('create-status', () async { + var gh = await createGithubWithScenario('create-status'); + // todo do test + }, skip: true); + test('errors', () async { + var gh = await createGithubWithScenario('errors'); + // todo do test + }, skip: true); + test('get-archive', () async { + var gh = await createGithubWithScenario('get-archive'); + // todo do test + }, skip: true); + test('get-content', () async { + var gh = await createGithubWithScenario('get-content'); + // todo do test + }, skip: true); + + test('get-organization', () async { + var gh = await createGithubWithScenario('get-organization'); + var org = await gh.organizations.get('octokit-fixture-org'); + expect(org.login, 'octokit-fixture-org'); + }); + + test('get-repository', () async { + var gh = await createGithubWithScenario('get-repository'); + // todo do test + }, skip: true); + test('get-root', () async { + var gh = await createGithubWithScenario('get-root'); + // todo do test + }, skip: true); + test('git-refs', () async { + var gh = await createGithubWithScenario('git-refs'); + // todo do test + }, skip: true); + test('labels', () async { + var gh = await createGithubWithScenario('labels'); + // todo do test + }, skip: true); + test('lock-issue', () async { + var gh = await createGithubWithScenario('lock-issue'); + // todo do test + }, skip: true); + test('mark-notifications-as-read', () async { + var gh = await createGithubWithScenario('mark-notifications-as-read'); + // todo do test + }, skip: true); + test('markdown', () async { + var gh = await createGithubWithScenario('markdown'); + // todo do test + }, skip: true); + test('paginate-issues', () async { + var gh = await createGithubWithScenario('paginate-issues'); + // todo do test + }, skip: true); + test('project-cards', () async { + var gh = await createGithubWithScenario('project-cards'); + // todo do test + }, skip: true); + test('release-assets-conflict', () async { + var gh = await createGithubWithScenario('release-assets-conflict'); + // todo do test + }, skip: true); + test('release-assets', () async { + var gh = await createGithubWithScenario('release-assets'); + // todo do test + }, skip: true); + test('rename-repository', () async { + var gh = await createGithubWithScenario('rename-repository'); + // todo do test + }, skip: true); + test('search-issues', () async { + var gh = await createGithubWithScenario('search-issues'); + // todo do test + }, skip: true); +} diff --git a/test/src/mocks.dart b/test/src/mocks.dart deleted file mode 100644 index 8add5505..00000000 --- a/test/src/mocks.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:github/src/common.dart'; -import 'package:mockito/annotations.dart'; - -@GenerateMocks([GitHub]) -void main() {} diff --git a/test/src/mocks.mocks.dart b/test/src/mocks.mocks.dart deleted file mode 100644 index c381f58a..00000000 --- a/test/src/mocks.mocks.dart +++ /dev/null @@ -1,262 +0,0 @@ -// Mocks generated by Mockito 5.2.0 from annotations -// in github/test/src/mocks.dart. -// Do not manually edit this file. - -import 'dart:async' as _i4; - -import 'package:github/src/common.dart' as _i3; -import 'package:http/http.dart' as _i2; -import 'package:mockito/mockito.dart' as _i1; - -// ignore_for_file: type=lint -// ignore_for_file: avoid_redundant_argument_values -// ignore_for_file: avoid_setters_without_getters -// ignore_for_file: comment_references -// ignore_for_file: implementation_imports -// ignore_for_file: invalid_use_of_visible_for_testing_member -// ignore_for_file: prefer_const_constructors -// ignore_for_file: unnecessary_parenthesis -// ignore_for_file: camel_case_types - -class _FakeClient_0 extends _i1.Fake implements _i2.Client {} - -class _FakeActivityService_1 extends _i1.Fake implements _i3.ActivityService {} - -class _FakeAuthorizationsService_2 extends _i1.Fake - implements _i3.AuthorizationsService {} - -class _FakeGistsService_3 extends _i1.Fake implements _i3.GistsService {} - -class _FakeGitService_4 extends _i1.Fake implements _i3.GitService {} - -class _FakeIssuesService_5 extends _i1.Fake implements _i3.IssuesService {} - -class _FakeMiscService_6 extends _i1.Fake implements _i3.MiscService {} - -class _FakeOrganizationsService_7 extends _i1.Fake - implements _i3.OrganizationsService {} - -class _FakePullRequestsService_8 extends _i1.Fake - implements _i3.PullRequestsService {} - -class _FakeRepositoriesService_9 extends _i1.Fake - implements _i3.RepositoriesService {} - -class _FakeSearchService_10 extends _i1.Fake implements _i3.SearchService {} - -class _FakeUrlShortenerService_11 extends _i1.Fake - implements _i3.UrlShortenerService {} - -class _FakeUsersService_12 extends _i1.Fake implements _i3.UsersService {} - -class _FakeChecksService_13 extends _i1.Fake implements _i3.ChecksService {} - -class _FakeResponse_14 extends _i1.Fake implements _i2.Response {} - -/// A class which mocks [GitHub]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockGitHub extends _i1.Mock implements _i3.GitHub { - MockGitHub() { - _i1.throwOnMissingStub(this); - } - - @override - set auth(_i3.Authentication? _auth) => - super.noSuchMethod(Invocation.setter(#auth, _auth), - returnValueForMissingStub: null); - @override - String get endpoint => - (super.noSuchMethod(Invocation.getter(#endpoint), returnValue: '') - as String); - @override - _i2.Client get client => (super.noSuchMethod(Invocation.getter(#client), - returnValue: _FakeClient_0()) as _i2.Client); - @override - _i3.ActivityService get activity => - (super.noSuchMethod(Invocation.getter(#activity), - returnValue: _FakeActivityService_1()) as _i3.ActivityService); - @override - _i3.AuthorizationsService get authorizations => - (super.noSuchMethod(Invocation.getter(#authorizations), - returnValue: _FakeAuthorizationsService_2()) - as _i3.AuthorizationsService); - @override - _i3.GistsService get gists => (super.noSuchMethod(Invocation.getter(#gists), - returnValue: _FakeGistsService_3()) as _i3.GistsService); - @override - _i3.GitService get git => (super.noSuchMethod(Invocation.getter(#git), - returnValue: _FakeGitService_4()) as _i3.GitService); - @override - _i3.IssuesService get issues => - (super.noSuchMethod(Invocation.getter(#issues), - returnValue: _FakeIssuesService_5()) as _i3.IssuesService); - @override - _i3.MiscService get misc => (super.noSuchMethod(Invocation.getter(#misc), - returnValue: _FakeMiscService_6()) as _i3.MiscService); - @override - _i3.OrganizationsService get organizations => (super.noSuchMethod( - Invocation.getter(#organizations), - returnValue: _FakeOrganizationsService_7()) as _i3.OrganizationsService); - @override - _i3.PullRequestsService get pullRequests => (super.noSuchMethod( - Invocation.getter(#pullRequests), - returnValue: _FakePullRequestsService_8()) as _i3.PullRequestsService); - @override - _i3.RepositoriesService get repositories => (super.noSuchMethod( - Invocation.getter(#repositories), - returnValue: _FakeRepositoriesService_9()) as _i3.RepositoriesService); - @override - _i3.SearchService get search => - (super.noSuchMethod(Invocation.getter(#search), - returnValue: _FakeSearchService_10()) as _i3.SearchService); - @override - _i3.UrlShortenerService get urlShortener => (super.noSuchMethod( - Invocation.getter(#urlShortener), - returnValue: _FakeUrlShortenerService_11()) as _i3.UrlShortenerService); - @override - _i3.UsersService get users => (super.noSuchMethod(Invocation.getter(#users), - returnValue: _FakeUsersService_12()) as _i3.UsersService); - @override - _i3.ChecksService get checks => - (super.noSuchMethod(Invocation.getter(#checks), - returnValue: _FakeChecksService_13()) as _i3.ChecksService); - @override - _i4.Future getJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - String? preview}) => - (super.noSuchMethod( - Invocation.method(#getJSON, [ - path - ], { - #statusCode: statusCode, - #fail: fail, - #headers: headers, - #params: params, - #convert: convert, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); - @override - _i4.Future postJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => - (super.noSuchMethod( - Invocation.method(#postJSON, [ - path - ], { - #statusCode: statusCode, - #fail: fail, - #headers: headers, - #params: params, - #convert: convert, - #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); - @override - _i4.Future putJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => - (super.noSuchMethod( - Invocation.method(#putJSON, [ - path - ], { - #statusCode: statusCode, - #fail: fail, - #headers: headers, - #params: params, - #convert: convert, - #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); - @override - _i4.Future patchJSON(String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => - (super.noSuchMethod( - Invocation.method(#patchJSON, [ - path - ], { - #statusCode: statusCode, - #fail: fail, - #headers: headers, - #params: params, - #convert: convert, - #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); - @override - _i4.Future requestJson(String? method, String? path, - {int? statusCode, - void Function(_i2.Response)? fail, - Map? headers, - Map? params, - _i3.JSONConverter? convert, - dynamic body, - String? preview}) => - (super.noSuchMethod( - Invocation.method(#requestJson, [ - method, - path - ], { - #statusCode: statusCode, - #fail: fail, - #headers: headers, - #params: params, - #convert: convert, - #body: body, - #preview: preview - }), - returnValue: Future.value(null)) as _i4.Future); - @override - _i4.Future<_i2.Response> request(String? method, String? path, - {Map? headers, - Map? params, - dynamic body, - int? statusCode, - void Function(_i2.Response)? fail, - String? preview}) => - (super.noSuchMethod( - Invocation.method(#request, [ - method, - path - ], { - #headers: headers, - #params: params, - #body: body, - #statusCode: statusCode, - #fail: fail, - #preview: preview - }), - returnValue: Future<_i2.Response>.value(_FakeResponse_14())) - as _i4.Future<_i2.Response>); - @override - void handleStatusCode(_i2.Response? response) => - super.noSuchMethod(Invocation.method(#handleStatusCode, [response]), - returnValueForMissingStub: null); - @override - void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), - returnValueForMissingStub: null); -} diff --git a/test/unit/common/model/misc_test.dart b/test/unit/common/model/misc_test.dart index e5bb9a4d..a7cbf3c2 100644 --- a/test/unit/common/model/misc_test.dart +++ b/test/unit/common/model/misc_test.dart @@ -6,16 +6,47 @@ import 'package:test/test.dart'; void main() { group('RateLimit', () { test('fromRateLimitResponse', () { - // This is a truncated version of the response - const rateLimitJson = '''{ - "resources": { - "rate": { - "limit": 5000, - "remaining": 4999, - "reset": 1372700873, - "used": 1 - } - }'''; + const rateLimitJson = ''' +{ + "resources": { + "core": { + "limit": 5000, + "remaining": 4999, + "reset": 1372700873, + "used": 1 + }, + "search": { + "limit": 30, + "remaining": 18, + "reset": 1372697452, + "used": 12 + }, + "graphql": { + "limit": 5000, + "remaining": 4993, + "reset": 1372700389, + "used": 7 + }, + "integration_manifest": { + "limit": 5000, + "remaining": 4999, + "reset": 1551806725, + "used": 1 + }, + "code_scanning_upload": { + "limit": 500, + "remaining": 499, + "reset": 1551806725, + "used": 1 + } + }, + "rate": { + "limit": 5000, + "remaining": 4999, + "reset": 1372700873, + "used": 1 + } +}'''; final rateLimit = RateLimit.fromRateLimitResponse(jsonDecode(rateLimitJson)); From 5f7b2645007208522dc5d53b7bf48f206dafa73a Mon Sep 17 00:00:00 2001 From: robrbecker Date: Mon, 31 Oct 2022 14:28:57 +0000 Subject: [PATCH 066/139] prep 9.5.1 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5de4e987..fcbf764c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.5.1 + +* Fix up unit tests & run them in CI by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/336 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.5.0...9.5.1 + ## 9.5.0 * Add 'commits' member to GitHubComparison object by @fuzzybinary in https://github.com/SpinlockLabs/github.dart/pull/330 diff --git a/pubspec.yaml b/pubspec.yaml index ed60fc15..d7d20f57 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.5.0 +version: 9.5.1 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 203d1d5126009657a23a219b3052e3098269222d Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 31 Oct 2022 08:33:12 -0600 Subject: [PATCH 067/139] fix publish GHA --- .github/workflows/publish_release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index ca9789ba..320032df 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -8,7 +8,8 @@ jobs: publish: runs-on: ubuntu-latest - + container: + image: dart:2.17 steps: - name: Checkout uses: actions/checkout@v1 From 6854f404ca505bbc553db0ab0c72f6dcbcdfbcb7 Mon Sep 17 00:00:00 2001 From: Ricardo Amador <32242716+ricardoamador@users.noreply.github.com> Date: Mon, 31 Oct 2022 07:35:47 -0700 Subject: [PATCH 068/139] Update to allow different merge methods in pulls_service (#333) * Updated to allow different merge methods in pulls_service. * Adding tests for pulls service merge changes. --- lib/src/common/pulls_service.dart | 18 ++++ test/pulls_test.dart | 143 ++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 test/pulls_test.dart diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index 9c611cf9..bbf45a51 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -121,15 +121,27 @@ class PullRequestsService extends Service { RepositorySlug slug, int number, { String? message, + MergeMethod mergeMethod = MergeMethod.merge, + String? requestSha, }) { final json = {}; if (message != null) { json['commit_message'] = message; } + if (requestSha != null) { + json['sha'] = requestSha; + } + + json['merge_method'] = mergeMethod.name; + + // Recommended Accept header when making a merge request. + Map? headers = {}; + headers['Accept'] = 'application/vnd.github+json'; return github .request('PUT', '/repos/${slug.fullName}/pulls/$number/merge', + headers: headers, body: GitHubJson.encode(json)) .then((response) { return PullRequestMerge.fromJson( @@ -184,3 +196,9 @@ class PullRequestsService extends Service { ); } } + +enum MergeMethod { + merge, + squash, + rebase, +} \ No newline at end of file diff --git a/test/pulls_test.dart b/test/pulls_test.dart new file mode 100644 index 00000000..ae711b2c --- /dev/null +++ b/test/pulls_test.dart @@ -0,0 +1,143 @@ +import 'dart:async'; + +import 'package:github/src/common.dart'; +import 'package:http/http.dart' as http; +import 'package:mockito/mockito.dart'; +import 'package:test/test.dart'; + +import 'src/mocks.mocks.dart'; + +void main() { + late MockGitHub github; + late PullRequestsService pulls; + late RepositorySlug repo; + const someSha = 'someSHA'; + + setUp(() { + github = MockGitHub(); + pulls = PullRequestsService(github); + repo = RepositorySlug('o', 'n'); + }); + + group('Merge', () { + test('Merge() normal', () async { + const expectedMessage = 'Pull Request successfully merged'; + const expectedMerge = true; + + when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) + .thenAnswer((_) => Future.value( + http.Response('''{ + "sha": "$someSha", + "merged": $expectedMerge, + "message": "$expectedMessage" + }''', 200) + )); + + var pullRequestMerge = await pulls.merge(repo, 1); + + verify(github.request('PUT', '/repos/o/n/pulls/1/merge', + headers: anyNamed("headers"), body: '''{"merge_method":"merge"}''')); + + expect(pullRequestMerge.merged, isTrue); + expect(pullRequestMerge.message, expectedMessage); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with squash', () async { + const expectedMessage = 'Pull Request successfully merged'; + const expectedMerge = true; + + when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) + .thenAnswer((_) => Future.value( + http.Response('''{ + "sha": "$someSha", + "merged": $expectedMerge, + "message": "$expectedMessage" + }''', 200) + )); + + var pullRequestMerge = await pulls.merge(repo, 1, mergeMethod: MergeMethod.squash); + + verify(github.request('PUT', '/repos/o/n/pulls/1/merge', + headers: anyNamed("headers"), body: '''{"merge_method":"squash"}''')); + + expect(pullRequestMerge.merged, isTrue); + expect(pullRequestMerge.message, expectedMessage); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with rebase', () async { + const expectedMessage = 'Pull Request successfully merged'; + const expectedMerge = true; + + when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) + .thenAnswer((_) => Future.value( + http.Response('''{ + "sha": "$someSha", + "merged": $expectedMerge, + "message": "$expectedMessage" + }''', 200) + )); + + var pullRequestMerge = await pulls.merge(repo, 1, mergeMethod: MergeMethod.rebase); + + verify(github.request('PUT', '/repos/o/n/pulls/1/merge', + headers: anyNamed("headers"), body: '''{"merge_method":"rebase"}''')); + + expect(pullRequestMerge.merged, isTrue); + expect(pullRequestMerge.message, expectedMessage); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with commitMessage', () async { + const expectedMessage = 'Pull Request successfully merged'; + const expectedMerge = true; + const commitMessage = 'Some message'; + + when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) + .thenAnswer((_) => Future.value( + http.Response('''{ + "sha": "$someSha", + "merged": $expectedMerge, + "message": "$expectedMessage" + }''', 200) + )); + + var pullRequestMerge = await pulls.merge(repo, 1, message: commitMessage, mergeMethod: MergeMethod.squash); + + verify(github.request('PUT', '/repos/o/n/pulls/1/merge', + headers: anyNamed("headers"), body: '''{"commit_message":"$commitMessage","merge_method":"squash"}''')); + + expect(pullRequestMerge.merged, isTrue); + expect(pullRequestMerge.message, expectedMessage); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with commitMessage, with sha', () async { + const expectedMessage = 'Pull Request successfully merged'; + const expectedMerge = true; + const commitMessage = 'Some message'; + const commitSha = 'commitSha'; + + when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) + .thenAnswer((_) => Future.value( + http.Response('''{ + "sha": "$someSha", + "merged": $expectedMerge, + "message": "$expectedMessage" + }''', 200) + )); + + var pullRequestMerge = await pulls.merge(repo, 1, message: commitMessage, + mergeMethod: MergeMethod.squash, requestSha: commitSha); + + verify(github.request('PUT', '/repos/o/n/pulls/1/merge', + headers: anyNamed("headers"), + body: '''{"commit_message":"$commitMessage","sha":"$commitSha","merge_method":"squash"}''')); + + expect(pullRequestMerge.merged, isTrue); + expect(pullRequestMerge.message, expectedMessage); + expect(pullRequestMerge.sha, someSha); + }); + }); +} \ No newline at end of file From 450cdb5af0ad87e33a514d34a00c1ae52896690d Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 31 Oct 2022 17:44:01 -0600 Subject: [PATCH 069/139] fix up merged PR, tests failing --- lib/src/common/pulls_service.dart | 5 +- test/assets/responses/nocked_responses.dart | 6 + test/git_test.dart | 73 ++++++++++ test/pulls_test.dart | 143 -------------------- 4 files changed, 81 insertions(+), 146 deletions(-) delete mode 100644 test/pulls_test.dart diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index bbf45a51..f0ec3dcc 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -141,8 +141,7 @@ class PullRequestsService extends Service { return github .request('PUT', '/repos/${slug.fullName}/pulls/$number/merge', - headers: headers, - body: GitHubJson.encode(json)) + headers: headers, body: GitHubJson.encode(json)) .then((response) { return PullRequestMerge.fromJson( jsonDecode(response.body) as Map); @@ -201,4 +200,4 @@ enum MergeMethod { merge, squash, rebase, -} \ No newline at end of file +} diff --git a/test/assets/responses/nocked_responses.dart b/test/assets/responses/nocked_responses.dart index 6feb9465..3a1b9b5b 100644 --- a/test/assets/responses/nocked_responses.dart +++ b/test/assets/responses/nocked_responses.dart @@ -1472,3 +1472,9 @@ var searchResults = '''{ } ] }'''; + +var mergedPR1 = '''{ + "sha": "someSHA", + "merged": true, + "message": "Pull Request successfully merged" +}'''; diff --git a/test/git_test.dart b/test/git_test.dart index 2eaff028..f769571b 100644 --- a/test/git_test.dart +++ b/test/git_test.dart @@ -188,4 +188,77 @@ void main() { expect(results.totalCount, 17); expect(results.items?.length, 17); }); + + group('Merge', () { + test('Merge() normal', () async { + nock(fakeApiUrl) + .put('/repos/o/n/pulls/1/merge', '{"merge_method":"merge"}') + .reply(201, nocked.mergedPR1); + + var pullRequestMerge = await github.pullRequests.merge(repo, 1); + + expect(pullRequestMerge.merged, true); + expect(pullRequestMerge.message, 'Pull Request successfully merged'); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with squash', () async { + nock(fakeApiUrl) + .put('/repos/o/n/pulls/1/merge', '{"merge_method":"squash"}') + .reply(201, nocked.mergedPR1); + + var pullRequestMerge = await github.pullRequests + .merge(repo, 1, mergeMethod: MergeMethod.squash); + + expect(pullRequestMerge.merged, true); + expect(pullRequestMerge.message, 'Pull Request successfully merged'); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with rebase', () async { + nock(fakeApiUrl) + .put('/repos/o/n/pulls/1/merge', '{"merge_method":"rebase"}') + .reply(201, nocked.mergedPR1); + + var pullRequestMerge = await github.pullRequests + .merge(repo, 1, mergeMethod: MergeMethod.rebase); + + expect(pullRequestMerge.merged, true); + expect(pullRequestMerge.message, 'Pull Request successfully merged'); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with commitMessage', () async { + const commitMessage = 'Some message'; + nock(fakeApiUrl) + .put('/repos/o/n/pulls/1/merge', + '{"commit_message":"$commitMessage","merge_method":"squash"}') + .reply(201, nocked.mergedPR1); + + var pullRequestMerge = await github.pullRequests.merge(repo, 1, + message: commitMessage, mergeMethod: MergeMethod.squash); + + expect(pullRequestMerge.merged, true); + expect(pullRequestMerge.message, 'Pull Request successfully merged'); + expect(pullRequestMerge.sha, someSha); + }); + + test('Merge() with commitMessage, with sha', () async { + const commitMessage = 'Some message'; + const commitSha = 'commitSha'; + nock(fakeApiUrl) + .put('/repos/o/n/pulls/1/merge', + '{"commit_message":"$commitMessage","sha":"$commitSha","merge_method":"squash"}') + .reply(201, nocked.mergedPR1); + + var pullRequestMerge = await github.pullRequests.merge(repo, 1, + message: commitMessage, + mergeMethod: MergeMethod.squash, + requestSha: commitSha); + + expect(pullRequestMerge.merged, true); + expect(pullRequestMerge.message, 'Pull Request successfully merged'); + expect(pullRequestMerge.sha, someSha); + }); + }); } diff --git a/test/pulls_test.dart b/test/pulls_test.dart deleted file mode 100644 index ae711b2c..00000000 --- a/test/pulls_test.dart +++ /dev/null @@ -1,143 +0,0 @@ -import 'dart:async'; - -import 'package:github/src/common.dart'; -import 'package:http/http.dart' as http; -import 'package:mockito/mockito.dart'; -import 'package:test/test.dart'; - -import 'src/mocks.mocks.dart'; - -void main() { - late MockGitHub github; - late PullRequestsService pulls; - late RepositorySlug repo; - const someSha = 'someSHA'; - - setUp(() { - github = MockGitHub(); - pulls = PullRequestsService(github); - repo = RepositorySlug('o', 'n'); - }); - - group('Merge', () { - test('Merge() normal', () async { - const expectedMessage = 'Pull Request successfully merged'; - const expectedMerge = true; - - when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) - .thenAnswer((_) => Future.value( - http.Response('''{ - "sha": "$someSha", - "merged": $expectedMerge, - "message": "$expectedMessage" - }''', 200) - )); - - var pullRequestMerge = await pulls.merge(repo, 1); - - verify(github.request('PUT', '/repos/o/n/pulls/1/merge', - headers: anyNamed("headers"), body: '''{"merge_method":"merge"}''')); - - expect(pullRequestMerge.merged, isTrue); - expect(pullRequestMerge.message, expectedMessage); - expect(pullRequestMerge.sha, someSha); - }); - - test('Merge() with squash', () async { - const expectedMessage = 'Pull Request successfully merged'; - const expectedMerge = true; - - when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) - .thenAnswer((_) => Future.value( - http.Response('''{ - "sha": "$someSha", - "merged": $expectedMerge, - "message": "$expectedMessage" - }''', 200) - )); - - var pullRequestMerge = await pulls.merge(repo, 1, mergeMethod: MergeMethod.squash); - - verify(github.request('PUT', '/repos/o/n/pulls/1/merge', - headers: anyNamed("headers"), body: '''{"merge_method":"squash"}''')); - - expect(pullRequestMerge.merged, isTrue); - expect(pullRequestMerge.message, expectedMessage); - expect(pullRequestMerge.sha, someSha); - }); - - test('Merge() with rebase', () async { - const expectedMessage = 'Pull Request successfully merged'; - const expectedMerge = true; - - when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) - .thenAnswer((_) => Future.value( - http.Response('''{ - "sha": "$someSha", - "merged": $expectedMerge, - "message": "$expectedMessage" - }''', 200) - )); - - var pullRequestMerge = await pulls.merge(repo, 1, mergeMethod: MergeMethod.rebase); - - verify(github.request('PUT', '/repos/o/n/pulls/1/merge', - headers: anyNamed("headers"), body: '''{"merge_method":"rebase"}''')); - - expect(pullRequestMerge.merged, isTrue); - expect(pullRequestMerge.message, expectedMessage); - expect(pullRequestMerge.sha, someSha); - }); - - test('Merge() with commitMessage', () async { - const expectedMessage = 'Pull Request successfully merged'; - const expectedMerge = true; - const commitMessage = 'Some message'; - - when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) - .thenAnswer((_) => Future.value( - http.Response('''{ - "sha": "$someSha", - "merged": $expectedMerge, - "message": "$expectedMessage" - }''', 200) - )); - - var pullRequestMerge = await pulls.merge(repo, 1, message: commitMessage, mergeMethod: MergeMethod.squash); - - verify(github.request('PUT', '/repos/o/n/pulls/1/merge', - headers: anyNamed("headers"), body: '''{"commit_message":"$commitMessage","merge_method":"squash"}''')); - - expect(pullRequestMerge.merged, isTrue); - expect(pullRequestMerge.message, expectedMessage); - expect(pullRequestMerge.sha, someSha); - }); - - test('Merge() with commitMessage, with sha', () async { - const expectedMessage = 'Pull Request successfully merged'; - const expectedMerge = true; - const commitMessage = 'Some message'; - const commitSha = 'commitSha'; - - when(github.request(any, any, headers: anyNamed("headers"), body: anyNamed("body"))) - .thenAnswer((_) => Future.value( - http.Response('''{ - "sha": "$someSha", - "merged": $expectedMerge, - "message": "$expectedMessage" - }''', 200) - )); - - var pullRequestMerge = await pulls.merge(repo, 1, message: commitMessage, - mergeMethod: MergeMethod.squash, requestSha: commitSha); - - verify(github.request('PUT', '/repos/o/n/pulls/1/merge', - headers: anyNamed("headers"), - body: '''{"commit_message":"$commitMessage","sha":"$commitSha","merge_method":"squash"}''')); - - expect(pullRequestMerge.merged, isTrue); - expect(pullRequestMerge.message, expectedMessage); - expect(pullRequestMerge.sha, someSha); - }); - }); -} \ No newline at end of file From 8423ee6036ec68165c3196e6d609e559a0288f2c Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 31 Oct 2022 17:51:24 -0600 Subject: [PATCH 070/139] require Dart 2.17 --- .github/workflows/tests.yml | 2 +- CHANGELOG.md | 2 +- pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6e1cb6e5..225f514f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - sdk: [2.14.4, 2.17.7, stable] # Test with at least the declared minimum Dart version + sdk: [2.17.7, stable] # Test with at least the declared minimum Dart version steps: - uses: actions/checkout@v2 - uses: dart-lang/setup-dart@v1.3 diff --git a/CHANGELOG.md b/CHANGELOG.md index fcbf764c..fd49b5ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ ## 9.5.1 +* Require Dart 2.17 * Fix up unit tests & run them in CI by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/336 - **Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.5.0...9.5.1 ## 9.5.0 diff --git a/pubspec.yaml b/pubspec.yaml index d7d20f57..1ba3138f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart environment: - sdk: '>=2.14.0 <3.0.0' + sdk: '>=2.17.0 <3.0.0' dependencies: http: ^0.13.0 From 9287a0ecf16522209d2aa8bfc70ab9be1e8edd92 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 31 Oct 2022 17:59:37 -0600 Subject: [PATCH 071/139] use latest dart in github actions workflows --- .github/workflows/dart.yml | 2 +- .github/workflows/publish_demos.yml | 2 +- .github/workflows/publish_release.yml | 2 +- .github/workflows/release_unreleased_prs.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 119546e2..bb1838d7 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -6,7 +6,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: dart:2.17 + image: dart steps: - uses: actions/checkout@v1 - name: Install dependencies diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 33f242d2..25a2bb12 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -7,7 +7,7 @@ jobs: build-and-deploy: runs-on: ubuntu-latest container: - image: google/dart:latest + image: dart steps: - name: Checkout 🛎️ uses: actions/checkout@v2.3.1 diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 320032df..0287d22a 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest container: - image: dart:2.17 + image: dart steps: - name: Checkout uses: actions/checkout@v1 diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml index a087b032..9b33737d 100644 --- a/.github/workflows/release_unreleased_prs.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -12,7 +12,7 @@ jobs: release: if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest - container: dart:2.17.7 + container: dart permissions: contents: write From d6347b2b7715f7039369f6af199b9489a0574019 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 1 Nov 2022 08:12:13 -0600 Subject: [PATCH 072/139] prep 9.6.0 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd49b5ee..1e7a870d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.6.0 + +* Update to allow different merge methods in pulls_service by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/333 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.5.1...9.6.0 + ## 9.5.1 * Require Dart 2.17 diff --git a/pubspec.yaml b/pubspec.yaml index 1ba3138f..76b54847 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.5.1 +version: 9.6.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 11544fcf69c4268d6faa6b36745ec96957b89a75 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 1 Nov 2022 08:16:55 -0600 Subject: [PATCH 073/139] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e7a870d..f77d669a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 9.6.0 +* Require Dart 2.17 * Update to allow different merge methods in pulls_service by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/333 @@ -7,7 +8,6 @@ ## 9.5.1 -* Require Dart 2.17 * Fix up unit tests & run them in CI by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/336 **Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.5.0...9.5.1 From e9230e6a1314f727d4030b1aa9090c2e0b8659ad Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Tue, 29 Nov 2022 18:50:21 -0800 Subject: [PATCH 074/139] Add calendar versioning (#338) Add calendar version --- lib/src/common/github.dart | 14 ++++++++++++++ test/common/github_test.dart | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 test/common/github_test.dart diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index e715c2a9..77864725 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -21,6 +21,7 @@ class GitHub { GitHub({ Authentication? auth, this.endpoint = 'https://api.github.com', + this.version = '2022-11-28', http.Client? client, }) : auth = auth ?? Authentication.anonymous(), client = client ?? http.Client(); @@ -29,12 +30,24 @@ class GitHub { static const _ratelimitResetHeader = 'x-ratelimit-reset'; static const _ratelimitRemainingHeader = 'x-ratelimit-remaining'; + @visibleForTesting + static const versionHeader = 'X-GitHub-Api-Version'; + /// Authentication Information Authentication? auth; /// API Endpoint final String endpoint; + /// Calendar version of the GitHub API to use. + /// + /// Changing this value is unsupported. However, it may unblock you if there's + /// hotfix versions. + /// + /// See also: + /// * https://docs.github.com/en/rest/overview/api-versions?apiVersion=2022-11-28 + final String version; + /// HTTP Client final http.Client client; @@ -306,6 +319,7 @@ class GitHub { } headers.putIfAbsent('Accept', () => v3ApiMimeType); + headers.putIfAbsent(versionHeader, () => version); final response = await request( method, diff --git a/test/common/github_test.dart b/test/common/github_test.dart new file mode 100644 index 00000000..45c3b68f --- /dev/null +++ b/test/common/github_test.dart @@ -0,0 +1,26 @@ +import 'dart:io'; + +import 'package:github/src/common/github.dart'; +import 'package:http/http.dart'; +import 'package:http/testing.dart'; +import 'package:test/test.dart'; + +void main() { + group(GitHub, () { + test('passes calendar version header', () async { + Request? request; + final client = MockClient((r) async { + request = r; + return Response('{}', HttpStatus.ok); + }); + + final github = GitHub(client: client); + await github.getJSON(''); // Make HTTP request + + expect(request, isNotNull); + expect(request!.headers.containsKey(GitHub.versionHeader), isTrue); + final version = request!.headers[GitHub.versionHeader]; + expect(version, github.version); + }); + }); +} From a983dd2ef7c80524e0e96721b52bc4ef4fbbeeeb Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Wed, 30 Nov 2022 11:23:43 -0700 Subject: [PATCH 075/139] prep 9.7.0 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f77d669a..2ec0527e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 9.7.0 +* Add calendar versioning by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/338 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.6.0...9.7.0 ## 9.6.0 * Require Dart 2.17 diff --git a/pubspec.yaml b/pubspec.yaml index 76b54847..f45153a6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.6.0 +version: 9.7.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 067d7d3b3b359eecf32343443c1c715546714c67 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Wed, 30 Nov 2022 11:33:51 -0700 Subject: [PATCH 076/139] fail if a git command fails --- tool/release_unreleased_prs.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tool/release_unreleased_prs.dart b/tool/release_unreleased_prs.dart index aca8dae1..2eb1d273 100644 --- a/tool/release_unreleased_prs.dart +++ b/tool/release_unreleased_prs.dart @@ -77,9 +77,9 @@ String run(String cmd, {List? rest}) { if (result.stderr != null) { print(result.stderr); } - // if (result.exitCode != 0) { - // exit(6); - // } + if (result.exitCode != 0) { + exit(6); + } return result.stdout; } From 4f6553791f3daa6ab217c14505525f567007bb18 Mon Sep 17 00:00:00 2001 From: Nehal Patel Date: Thu, 26 Jan 2023 12:35:01 -0800 Subject: [PATCH 077/139] Add "head_branch" field to CheckSuite object (#347) * Add "head_branch" field to CheckSuite object * Add CheckSuite test * Add forked repository test to validate behavior when "head_branch" is null * Update CHANGELOG and pubspec --- CHANGELOG.md | 9 +++ lib/src/common/model/checks.dart | 3 + pubspec.yaml | 2 +- test/unit/checksuite_test.dart | 121 +++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 test/unit/checksuite_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ec0527e..f48c4621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 9.8.0 + +* Add "head_branch" field to CheckSuite object by @nehalvpatel in https://github.com/SpinlockLabs/github.dart/pull/347 + +## New Contributors +* @nehalvpatel made their first contribution in https://github.com/SpinlockLabs/github.dart/pull/347 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.7.0...9.8.0 + ## 9.7.0 * Add calendar versioning by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/338 diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index 43b49769..9d7d6e21 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -362,12 +362,14 @@ class CheckRunAction { @immutable class CheckSuite { final int? id; + final String? headBranch; final String? headSha; final CheckRunConclusion conclusion; final List pullRequests; const CheckSuite({ required this.conclusion, + required this.headBranch, required this.headSha, required this.id, required this.pullRequests, @@ -381,6 +383,7 @@ class CheckSuite { .toList(); return CheckSuite( conclusion: CheckRunConclusion._fromValue(input['conclusion']), + headBranch: input['head_branch'], headSha: input['head_sha'], id: input['id'], pullRequests: pullRequests, diff --git a/pubspec.yaml b/pubspec.yaml index f45153a6..81066cc1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.7.0 +version: 9.8.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart diff --git a/test/unit/checksuite_test.dart b/test/unit/checksuite_test.dart new file mode 100644 index 00000000..d9571bc9 --- /dev/null +++ b/test/unit/checksuite_test.dart @@ -0,0 +1,121 @@ +import 'dart:convert'; + +import 'package:github/src/common/model/checks.dart'; +import 'package:test/test.dart'; + +/// The checkSuite Json is composed from multiple GitHub examples +/// +/// See https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28 +/// See https://docs.github.com/en/rest/checks/suites?apiVersion=2022-11-28 +const checkSuiteJson = '''{ + "id": 5, + "head_branch": "main", + "head_sha": "d6fde92930d4715a2b49857d24b940956b26d2d3", + "conclusion": "neutral", + "pull_requests": [ + { + "url": "https://api.github.com/repos/github/hello-world/pulls/1", + "id": 1934, + "number": 3956, + "head": { + "ref": "say-hello", + "sha": "3dca65fa3e8d4b3da3f3d056c59aee1c50f41390", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + }, + "base": { + "ref": "master", + "sha": "e7fdf7640066d71ad16a86fbcbb9c6a10a18af4f", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + } + } + ] +}'''; + +const String expectedToString = + '{"name":"mighty_readme","id":4,"external_id":"","status":"completed","head_sha":"","check_suite":{"id":5},"details_url":"https://example.com","started_at":"2018-05-04T01:14:52.000Z","conclusion":"neutral"}'; + +void main() { + group('Check suite', () { + test('CheckSuite fromJson', () { + final checkSuite = CheckSuite.fromJson(jsonDecode(checkSuiteJson)); + + expect(checkSuite.id, 5); + expect(checkSuite.headBranch, 'main'); + expect(checkSuite.headSha, 'd6fde92930d4715a2b49857d24b940956b26d2d3'); + expect(checkSuite.conclusion, CheckRunConclusion.neutral); + expect(checkSuite.pullRequests.isNotEmpty, true); + }); + + test('CheckSuite fromJson for skipped conclusion', () { + /// The checkSuite Json is composed from multiple GitHub examples + /// + /// See https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28 + /// See https://docs.github.com/en/rest/checks/suites?apiVersion=2022-11-28 + const checkSuiteJson = '''{ + "id": 10, + "head_branch": "master", + "head_sha": "ce587453ced02b1526dfb4cb910479d431683101", + "conclusion": "skipped", + "pull_requests": [ + { + "url": "https://api.github.com/repos/github/hello-world/pulls/1", + "id": 1934, + "number": 3956, + "head": { + "ref": "say-hello", + "sha": "3dca65fa3e8d4b3da3f3d056c59aee1c50f41390", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + }, + "base": { + "ref": "master", + "sha": "e7fdf7640066d71ad16a86fbcbb9c6a10a18af4f", + "repo": { + "id": 526, + "url": "https://api.github.com/repos/github/hello-world", + "name": "hello-world" + } + } + } + ] + }'''; + final checkSuite = CheckSuite.fromJson(jsonDecode(checkSuiteJson)); + + expect(checkSuite.id, 10); + expect(checkSuite.headBranch, 'master'); + expect(checkSuite.headSha, 'ce587453ced02b1526dfb4cb910479d431683101'); + expect(checkSuite.conclusion, CheckRunConclusion.skipped); + expect(checkSuite.pullRequests.isNotEmpty, true); + }); + + test('CheckSuite fromJson for forked repository', () { + /// The checkSuite Json is composed from multiple GitHub examples + /// + /// See https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28 + /// See https://docs.github.com/en/rest/checks/suites?apiVersion=2022-11-28 + const checkSuiteJson = '''{ + "id": 10, + "head_branch": null, + "head_sha": "ce587453ced02b1526dfb4cb910479d431683101", + "conclusion": "skipped", + "pull_requests": [] + }'''; + final checkSuite = CheckSuite.fromJson(jsonDecode(checkSuiteJson)); + + expect(checkSuite.id, 10); + expect(checkSuite.headBranch, null); + expect(checkSuite.pullRequests.isEmpty, true); + }); + }); +} From 4f5e7559e7fcef4b41efb70039103096343399ad Mon Sep 17 00:00:00 2001 From: Ricardo Amador <32242716+ricardoamador@users.noreply.github.com> Date: Thu, 2 Feb 2023 10:21:56 -0800 Subject: [PATCH 078/139] Add author_association to the IssueComment object for access. (#348) * Add author_association to the IssueComment object for access. * Update changelog.md * Add new line before EOF --------- Co-authored-by: Casey Hillers --- CHANGELOG.md | 6 +++ lib/src/common/model/issues.dart | 2 + lib/src/common/model/issues.g.dart | 2 + test/unit/issues_test.dart | 63 ++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 test/unit/issues_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index f48c4621..9fd43ae6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 9.9.0 + +* Add "author_association" field to the IssueComment object by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/348 + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.8.0...9.9.0 + ## 9.8.0 * Add "head_branch" field to CheckSuite object by @nehalvpatel in https://github.com/SpinlockLabs/github.dart/pull/347 diff --git a/lib/src/common/model/issues.dart b/lib/src/common/model/issues.dart index 4a86f62b..4534892e 100644 --- a/lib/src/common/model/issues.dart +++ b/lib/src/common/model/issues.dart @@ -149,6 +149,7 @@ class IssueComment { this.url, this.htmlUrl, this.issueUrl, + this.authorAssociation, }); int? id; String? body; @@ -158,6 +159,7 @@ class IssueComment { String? url; String? htmlUrl; String? issueUrl; + String? authorAssociation; factory IssueComment.fromJson(Map input) => _$IssueCommentFromJson(input); diff --git a/lib/src/common/model/issues.g.dart b/lib/src/common/model/issues.g.dart index 0b6b8a3f..12e03103 100644 --- a/lib/src/common/model/issues.g.dart +++ b/lib/src/common/model/issues.g.dart @@ -123,6 +123,7 @@ IssueComment _$IssueCommentFromJson(Map json) => IssueComment( url: json['url'] as String?, htmlUrl: json['html_url'] as String?, issueUrl: json['issue_url'] as String?, + authorAssociation: json['author_association'] as String?, ); Map _$IssueCommentToJson(IssueComment instance) => @@ -135,6 +136,7 @@ Map _$IssueCommentToJson(IssueComment instance) => 'url': instance.url, 'html_url': instance.htmlUrl, 'issue_url': instance.issueUrl, + 'author_association': instance.authorAssociation, }; IssueLabel _$IssueLabelFromJson(Map json) => IssueLabel( diff --git a/test/unit/issues_test.dart b/test/unit/issues_test.dart new file mode 100644 index 00000000..88b06086 --- /dev/null +++ b/test/unit/issues_test.dart @@ -0,0 +1,63 @@ +import 'dart:convert'; +import 'package:github/src/common/model/issues.dart'; + +import 'package:test/test.dart'; + + +const String testIssueCommentJson = ''' + { + "url": "https://api.github.com/repos/flutter/cocoon/issues/comments/1352355796", + "html_url": "https://github.com/flutter/cocoon/pull/2356#issuecomment-1352355796", + "issue_url": "https://api.github.com/repos/flutter/cocoon/issues/2356", + "id": 1352355796, + "node_id": "IC_kwDOA8VHis5Qm0_U", + "user": { + "login": "CaseyHillers", + "id": 2148558, + "node_id": "MDQ6VXNlcjIxNDg1NTg=", + "avatar_url": "https://avatars.githubusercontent.com/u/2148558?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/CaseyHillers", + "html_url": "https://github.com/CaseyHillers", + "followers_url": "https://api.github.com/users/CaseyHillers/followers", + "following_url": "https://api.github.com/users/CaseyHillers/following{/other_user}", + "gists_url": "https://api.github.com/users/CaseyHillers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/CaseyHillers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/CaseyHillers/subscriptions", + "organizations_url": "https://api.github.com/users/CaseyHillers/orgs", + "repos_url": "https://api.github.com/users/CaseyHillers/repos", + "events_url": "https://api.github.com/users/CaseyHillers/events{/privacy}", + "received_events_url": "https://api.github.com/users/CaseyHillers/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2022-12-14T23:26:32Z", + "updated_at": "2022-12-14T23:26:32Z", + "author_association": "MEMBER", + "body": "FYI you need to run https://github.com/flutter/cocoon/blob/main/format.sh for formatting Cocoon code", + "reactions": { + "url": "https://api.github.com/repos/flutter/cocoon/issues/comments/1352355796/reactions", + "total_count": 0, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + }, + "performed_via_github_app": null + } +'''; + +void main() { + group('Issue Comments', () { + test('IssueComment from Json', () { + final issueComment = IssueComment.fromJson(jsonDecode(testIssueCommentJson)); + expect(1352355796, issueComment.id); + expect('MEMBER', issueComment.authorAssociation); + expect('CaseyHillers', issueComment.user!.login); + }); + }); +} From ed73adf7b4663d19bf2031b9411db2cc09f11b0e Mon Sep 17 00:00:00 2001 From: Ricardo Amador <32242716+ricardoamador@users.noreply.github.com> Date: Thu, 2 Feb 2023 11:38:55 -0800 Subject: [PATCH 079/139] Update package version (#350) --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 81066cc1..bdc75ce3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.8.0 +version: 9.9.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 5e64d599b8baee4eec4973af50acf44c9d825dc8 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 2 Feb 2023 23:55:32 -0800 Subject: [PATCH 080/139] Expose CheckSuitesService and ChuckRunsService classes (#351) Require Dart 2.18 Also a bunch of other cleanup, enabled latest lints removed duplicate lints sorted lints etc --- .github/workflows/tests.yml | 2 +- CHANGELOG.md | 5 + analysis_options.yaml | 342 +------------------- example/release_notes.dart | 13 +- example/stars.dart | 2 +- lib/src/common/activity_service.dart | 64 ++-- lib/src/common/authorizations_service.dart | 6 +- lib/src/common/checks_service.dart | 37 +-- lib/src/common/gists_service.dart | 24 +- lib/src/common/git_service.dart | 28 +- lib/src/common/github.dart | 7 +- lib/src/common/issues_service.dart | 55 ++-- lib/src/common/misc_service.dart | 5 +- lib/src/common/model/users.dart | 2 +- lib/src/common/orgs_service.dart | 34 +- lib/src/common/pulls_service.dart | 27 +- lib/src/common/repos_service.dart | 108 ++++--- lib/src/common/search_service.dart | 29 +- lib/src/common/users_service.dart | 37 +-- lib/src/common/util/oauth2.dart | 6 +- pubspec.yaml | 10 +- test/assets/responses/nocked_responses.dart | 22 +- test/common/github_test.dart | 2 +- test/experiment/error_handling.dart | 4 - test/git_test.dart | 1 - test/scenarios_test.dart | 2 + test/unit/issues_test.dart | 4 +- tool/release_unreleased_prs.dart | 2 +- 28 files changed, 258 insertions(+), 622 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 225f514f..b5a0c40d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - sdk: [2.17.7, stable] # Test with at least the declared minimum Dart version + sdk: [2.18.7, stable] # Test with at least the declared minimum Dart version steps: - uses: actions/checkout@v2 - uses: dart-lang/setup-dart@v1.3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fd43ae6..eae3873b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.10.0-dev + +* Require Dart 2.18 +* Expose `CheckSuitesService` and `ChuckRunsService` classes. + ## 9.9.0 * Add "author_association" field to the IssueComment object by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/348 diff --git a/analysis_options.yaml b/analysis_options.yaml index 1b107aa5..f7a9ff49 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,397 +1,61 @@ include: package:lints/recommended.yaml analyzer: - strong-mode: - implicit-casts: true - implicit-dynamic: true + language: + #strict-casts: true linter: rules: - - # Separate the control structure expression from its statement. - # http://dart-lang.github.io/linter/lints/always_put_control_body_on_new_line.html - always_put_control_body_on_new_line - - # Put @required named parameters first. - # http://dart-lang.github.io/linter/lints/always_put_required_named_parameters_first.html - always_put_required_named_parameters_first - - # Avoid bool literals in conditional expressions. - # http://dart-lang.github.io/linter/lints/avoid_bool_literals_in_conditional_expressions.html - # - avoid_bool_literals_in_conditional_expressions - - # Don't explicitly catch Error or types that implement it. - # http://dart-lang.github.io/linter/lints/avoid_catching_errors.html - avoid_catching_errors - - # Avoid defining a class that contains only static members. - # http://dart-lang.github.io/linter/lints/avoid_classes_with_only_static_members.html - avoid_classes_with_only_static_members - - # Avoid double and int checks. - # http://dart-lang.github.io/linter/lints/avoid_double_and_int_checks.html - avoid_double_and_int_checks - - # Avoid field initializers in const classes. - # http://dart-lang.github.io/linter/lints/avoid_field_initializers_in_const_classes.html - avoid_field_initializers_in_const_classes - - # Avoid using `forEach` with a function literal. - # http://dart-lang.github.io/linter/lints/avoid_function_literals_in_foreach_calls.html - # reason: Use for (x in y) or forEach(someFunc) instead - # - avoid_function_literals_in_foreach_calls - - # Don't implement classes that override `==`. - # http://dart-lang.github.io/linter/lints/avoid_implementing_value_types.html - avoid_implementing_value_types - - # Avoid JavaScript rounded ints. - # http://dart-lang.github.io/linter/lints/avoid_js_rounded_ints.html - avoid_js_rounded_ints - - # Avoid positional boolean parameters. - # http://dart-lang.github.io/linter/lints/avoid_positional_boolean_parameters.html - # - avoid_positional_boolean_parameters - - # Avoid `print` calls in production code. - # http://dart-lang.github.io/linter/lints/avoid_print.html - # - avoid_print - - # Avoid private typedef functions. - # http://dart-lang.github.io/linter/lints/avoid_private_typedef_functions.html - avoid_private_typedef_functions - - # Don't rename parameters of overridden methods. - # http://dart-lang.github.io/linter/lints/avoid_renaming_method_parameters.html - # - avoid_renaming_method_parameters - - # Avoid returning null from members whose return type is bool, double, int, or num. - # http://dart-lang.github.io/linter/lints/avoid_returning_null.html - avoid_returning_null - - # Avoid returning null for Future. - # http://dart-lang.github.io/linter/lints/avoid_returning_null_for_future.html - avoid_returning_null_for_future - - # Avoid returning null for void. - # http://dart-lang.github.io/linter/lints/avoid_returning_null_for_void.html - - avoid_returning_null_for_void - - # Avoid returning this from methods just to enable a fluent interface. - # http://dart-lang.github.io/linter/lints/avoid_returning_this.html - avoid_returning_this - - # Avoid setters without getters. - # http://dart-lang.github.io/linter/lints/avoid_setters_without_getters.html - avoid_setters_without_getters - - # Avoid single cascade in expression statements. - # http://dart-lang.github.io/linter/lints/avoid_single_cascade_in_expression_statements.html - - avoid_single_cascade_in_expression_statements - - # Avoid slow async `dart:io` methods. - # http://dart-lang.github.io/linter/lints/avoid_slow_async_io.html - avoid_slow_async_io - - # Avoid defining unused parameters in constructors. - # http://dart-lang.github.io/linter/lints/avoid_unused_constructor_parameters.html - avoid_unused_constructor_parameters - - # Avoid async functions that return void. - # http://dart-lang.github.io/linter/lints/avoid_void_async.html - avoid_void_async - - # Await only futures. - # http://dart-lang.github.io/linter/lints/await_only_futures.html - - await_only_futures - - # Name types using UpperCamelCase. - # http://dart-lang.github.io/linter/lints/camel_case_types.html - - camel_case_types - - # Cancel instances of dart.async.StreamSubscription. - # http://dart-lang.github.io/linter/lints/cancel_subscriptions.html - cancel_subscriptions - - # Cascade consecutive method invocations on the same reference. - # http://dart-lang.github.io/linter/lints/cascade_invocations.html - # - cascade_invocations - - # Close instances of `dart.core.Sink`. - # http://dart-lang.github.io/linter/lints/close_sinks.html - close_sinks - - # Only reference in scope identifiers in doc comments. - # http://dart-lang.github.io/linter/lints/comment_references.html - comment_references - - # Avoid control flow in finally blocks. - # http://dart-lang.github.io/linter/lints/control_flow_in_finally.html - - control_flow_in_finally - - # DO reference all public properties in debug methods. - # http://dart-lang.github.io/linter/lints/diagnostic_describe_all_properties.html - diagnostic_describe_all_properties - - # Adhere to Effective Dart Guide directives sorting conventions. - # http://dart-lang.github.io/linter/lints/directives_ordering.html - directives_ordering - - # Avoid empty statements. - # http://dart-lang.github.io/linter/lints/empty_statements.html - - empty_statements - - # Name source files using `lowercase_with_underscores`. - # http://dart-lang.github.io/linter/lints/file_names.html - - file_names - - # Use Flutter TODO format: // TODO(username): message, https://URL-to-issue. - # http://dart-lang.github.io/linter/lints/flutter_style_todos.html - # - flutter_style_todos - - # Always override `hashCode` if overriding `==`. - # http://dart-lang.github.io/linter/lints/hash_and_equals.html - - hash_and_equals - - # Don't import implementation files from another package. - # http://dart-lang.github.io/linter/lints/implementation_imports.html - - implementation_imports - - # Conditions should not unconditionally evaluate to `true` or to `false`. - # http://dart-lang.github.io/linter/lints/invariant_booleans.html - # reason: There are several outstanding bugs with this lint that cause a good deal of noise - - invariant_booleans - - # Invocation of Iterable.contains with references of unrelated types. - # http://dart-lang.github.io/linter/lints/iterable_contains_unrelated_type.html - - iterable_contains_unrelated_type - - # Join return statement with assignment when possible. - # http://dart-lang.github.io/linter/lints/join_return_with_assignment.html - join_return_with_assignment - - - # AVOID lines longer than 80 characters. - # http://dart-lang.github.io/linter/lints/lines_longer_than_80_chars.html - # - lines_longer_than_80_chars - - # Invocation of `remove` with references of unrelated types. - # http://dart-lang.github.io/linter/lints/list_remove_unrelated_type.html - - list_remove_unrelated_type - - # Boolean expression composed only with literals. - # http://dart-lang.github.io/linter/lints/literal_only_boolean_expressions.html - literal_only_boolean_expressions - - # Don't use adjacent strings in list. - # http://dart-lang.github.io/linter/lints/no_adjacent_strings_in_list.html - no_adjacent_strings_in_list - - - # Name non-constant identifiers using lowerCamelCase. - # http://dart-lang.github.io/linter/lints/non_constant_identifier_names.html - - non_constant_identifier_names - - # Avoid defining a one-member abstract class when a simple function will do. - # http://dart-lang.github.io/linter/lints/one_member_abstracts.html + - omit_local_variable_types - one_member_abstracts - - # Only throw instances of classes extending either Exception or Error. - # http://dart-lang.github.io/linter/lints/only_throw_errors.html - only_throw_errors - - # Don't override fields. - # http://dart-lang.github.io/linter/lints/overridden_fields.html - - overridden_fields - - # Provide doc comments for all public APIs. - # http://dart-lang.github.io/linter/lints/package_api_docs.html - package_api_docs - - # Use `lowercase_with_underscores` for package names. - # http://dart-lang.github.io/linter/lints/package_names.html - - package_names - - # Prefix library names with the package name and a dot-separated path. - # http://dart-lang.github.io/linter/lints/package_prefixed_library_names.html - - package_prefixed_library_names - - # Don't reassign references to parameters of functions or methods. - # http://dart-lang.github.io/linter/lints/parameter_assignments.html - # - parameter_assignments - - # Prefer putting asserts in initializer list. - # http://dart-lang.github.io/linter/lints/prefer_asserts_in_initializer_lists.html - prefer_asserts_in_initializer_lists - - # Prefer asserts with message. - # http://dart-lang.github.io/linter/lints/prefer_asserts_with_message.html - # - prefer_asserts_with_message - - # Prefer using a boolean as the assert condition. - # http://dart-lang.github.io/linter/lints/prefer_bool_in_asserts.html - # reason: This lint rule has been deprecated - # - prefer_bool_in_asserts - - # Prefer using `??=` over testing for null. - # http://dart-lang.github.io/linter/lints/prefer_conditional_assignment.html - # - prefer_conditional_assignment - - # Prefer const with constant constructors. - # http://dart-lang.github.io/linter/lints/prefer_const_constructors.html - prefer_const_constructors - - # Prefer declare const constructors on `@immutable` classes. - # http://dart-lang.github.io/linter/lints/prefer_const_constructors_in_immutables.html - prefer_const_constructors_in_immutables - - # Prefer const over final for declarations. - # http://dart-lang.github.io/linter/lints/prefer_const_declarations.html - prefer_const_declarations - - # Prefer const literals as parameters of constructors on @immutable classes. - # http://dart-lang.github.io/linter/lints/prefer_const_literals_to_create_immutables.html - prefer_const_literals_to_create_immutables - - # Prefer defining constructors instead of static methods to create instances. - # http://dart-lang.github.io/linter/lints/prefer_constructors_over_static_methods.html - prefer_constructors_over_static_methods - - # Prefer final in for-each loop variable if reference is not reassigned. - # http://dart-lang.github.io/linter/lints/prefer_final_in_for_each.html - prefer_final_in_for_each - - # Use `forEach` to only apply a function to all the elements. - # http://dart-lang.github.io/linter/lints/prefer_foreach.html - prefer_foreach - - # Use a function declaration to bind a function to a name. - # http://dart-lang.github.io/linter/lints/prefer_function_declarations_over_variables.html - - prefer_function_declarations_over_variables - - # Prefer if elements to conditional expressions where possible. - # http://dart-lang.github.io/linter/lints/prefer_if_elements_to_conditional_expressions.html - prefer_if_elements_to_conditional_expressions - - # Use initializing formals when possible. - # http://dart-lang.github.io/linter/lints/prefer_initializing_formals.html - - prefer_initializing_formals - - # Inline list item declarations where possible. - # http://dart-lang.github.io/linter/lints/prefer_inlined_adds.html - - prefer_inlined_adds - - # Prefer int literals over double literals. - # http://dart-lang.github.io/linter/lints/prefer_int_literals.html - prefer_int_literals - - # Prefer using mixins. - # http://dart-lang.github.io/linter/lints/prefer_mixin.html - prefer_mixin - - # Prefer typing uninitialized variables and fields. - # http://dart-lang.github.io/linter/lints/prefer_typing_uninitialized_variables.html - - prefer_typing_uninitialized_variables - - # Don't use the Null type, unless you are positive that you don't want void. - # http://dart-lang.github.io/linter/lints/prefer_void_to_null.html - - prefer_void_to_null - - # Provide a deprecation message, via @Deprecated("message"). - # http://dart-lang.github.io/linter/lints/provide_deprecation_message.html - - provide_deprecation_message - - # Document all public members. - # http://dart-lang.github.io/linter/lints/public_member_api_docs.html - # reason: Can get annoying for React component lifecycle methods, constructors. - # - public_member_api_docs - - # Sort child properties last in widget instance creations. - # http://dart-lang.github.io/linter/lints/sort_child_properties_last.html - sort_child_properties_last - - # Sort constructor declarations before other members. - # http://dart-lang.github.io/linter/lints/sort_constructors_first.html - # - sort_constructors_first - - # Sort pub dependencies. - # http://dart-lang.github.io/linter/lints/sort_pub_dependencies.html - sort_pub_dependencies - - # Sort unnamed constructor declarations first. - # http://dart-lang.github.io/linter/lints/sort_unnamed_constructors_first.html - sort_unnamed_constructors_first - - # Test type arguments in operator ==(Object other). - # http://dart-lang.github.io/linter/lints/test_types_in_equals.html - test_types_in_equals - - # Avoid `throw` in finally block. - # http://dart-lang.github.io/linter/lints/throw_in_finally.html - throw_in_finally - - # Type annotate public APIs. - # http://dart-lang.github.io/linter/lints/type_annotate_public_apis.html - # reason: React component render() method can return either ReactElement or false. Use overrides. - type_annotate_public_apis - - # Unnecessary await keyword in return. - # http://dart-lang.github.io/linter/lints/unnecessary_await_in_return.html - unnecessary_await_in_return - - # Avoid using braces in interpolation when not needed. - # http://dart-lang.github.io/linter/lints/unnecessary_brace_in_string_interps.html - - unnecessary_brace_in_string_interps - - # Avoid wrapping fields in getters and setters just to be "safe". - # http://dart-lang.github.io/linter/lints/unnecessary_getters_setters.html - - unnecessary_getters_setters - - # Don't create a lambda when a tear-off will do. - # http://dart-lang.github.io/linter/lints/unnecessary_lambdas.html - unnecessary_lambdas - - # Avoid null in null-aware assignment. - # http://dart-lang.github.io/linter/lints/unnecessary_null_aware_assignments.html - - unnecessary_null_aware_assignments - - # Don't override a method to do a super method invocation with the same parameters. - # http://dart-lang.github.io/linter/lints/unnecessary_overrides.html - - unnecessary_overrides - - # Unnecessary parenthesis can be removed. - # http://dart-lang.github.io/linter/lints/unnecessary_parenthesis.html - unnecessary_parenthesis - - # Avoid using unnecessary statements. - # http://dart-lang.github.io/linter/lints/unnecessary_statements.html - unnecessary_statements - - # Avoid unsafe HTML APIs. - # http://dart-lang.github.io/linter/lints/unsafe_html.html - # - unsafe_html - - # Prefer an 8-digit hexadecimal integer(0xFFFFFFFF) to instantiate Color. - # http://dart-lang.github.io/linter/lints/use_full_hex_values_for_flutter_colors.html - use_full_hex_values_for_flutter_colors - - # Use a setter for operations that conceptually change a property. - # http://dart-lang.github.io/linter/lints/use_setters_to_change_properties.html - use_setters_to_change_properties - - # Use string buffers to compose strings. - # http://dart-lang.github.io/linter/lints/use_string_buffers.html - use_string_buffers - - # Start the name of the method with to/_to or as/_as if applicable. - # http://dart-lang.github.io/linter/lints/use_to_and_as_if_applicable.html - use_to_and_as_if_applicable - - # Don't assign to void. - # http://dart-lang.github.io/linter/lints/void_checks.html - # reason: Trying to assigning a value to void is an error. - - void_checks - - - omit_local_variable_types - - prefer_final_fields - - use_function_type_syntax_for_parameters diff --git a/example/release_notes.dart b/example/release_notes.dart index 867474ee..be929744 100644 --- a/example/release_notes.dart +++ b/example/release_notes.dart @@ -1,8 +1,9 @@ import 'dart:html'; -import 'common.dart'; import 'package:pub_semver/pub_semver.dart'; +import 'common.dart'; + late DivElement releasesDiv; Future main() async { @@ -28,12 +29,12 @@ Future loadReleaseNotes() async { print('No unreleased PRs'); return ''; } - var semvers = Set(); - for (var pr in unreleasedPRs) { + var semvers = {}; + for (final pr in unreleasedPRs) { var prlabels = pr.labels .where((element) => element.name.startsWith('semver:')) .toList(); - for (var l in prlabels) { + for (final l in prlabels) { semvers.add(l.name); } } @@ -50,7 +51,9 @@ Future loadReleaseNotes() async { newVersion = latestVersion.nextPatch.toString(); } print(newVersion); - if (newVersion.isEmpty) return ''; + if (newVersion.isEmpty) { + return ''; + } var notes = await github.repositories.generateReleaseNotes(CreateReleaseNotes( slug.owner, slug.name, newVersion, diff --git a/example/stars.dart b/example/stars.dart index a7c96bc4..52a95e54 100644 --- a/example/stars.dart +++ b/example/stars.dart @@ -30,6 +30,6 @@ void loadStars() { $stars!.append(h); }).onDone(() { querySelector('#total')! - .appendText(querySelectorAll('.user').length.toString() + ' stars'); + .appendText('${querySelectorAll('.user').length} stars'); }); } diff --git a/lib/src/common/activity_service.dart b/lib/src/common/activity_service.dart index 16b7b84a..0001fcdc 100644 --- a/lib/src/common/activity_service.dart +++ b/lib/src/common/activity_service.dart @@ -15,9 +15,8 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/events/#list-public-events Stream listPublicEvents({int pages = 2}) { - return PaginationHelper(github).objects( - 'GET', '/events', (dynamic i) => Event.fromJson(i), - pages: pages); + return PaginationHelper(github) + .objects('GET', '/events', Event.fromJson, pages: pages); } /// Lists public events for a network of repositories. @@ -25,8 +24,8 @@ class ActivityService extends Service { /// API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories Stream listRepositoryNetworkEvents(RepositorySlug slug, {int pages = 2}) { - return PaginationHelper(github).objects('GET', - '/networks/${slug.fullName}/events', (dynamic i) => Event.fromJson(i), + return PaginationHelper(github).objects( + 'GET', '/networks/${slug.fullName}/events', Event.fromJson, pages: pages); } @@ -47,9 +46,7 @@ class ActivityService extends Service { /// API docs: https://developer.github.com/v3/activity/events/#list-repository-events Stream listRepositoryIssueEvents(RepositorySlug slug, {int? pages}) { return PaginationHelper(github).objects( - 'GET', - '/repos/${slug.fullName}/issues/events', - (dynamic i) => Event.fromJson(i), + 'GET', '/repos/${slug.fullName}/issues/events', Event.fromJson, pages: pages); } @@ -62,8 +59,8 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/events/#list-repository-events Stream listRepositoryEvents(RepositorySlug slug, {int? pages}) { - return PaginationHelper(github).objects('GET', - '/repos/${slug.fullName}/events', (dynamic i) => Event.fromJson(i), + return PaginationHelper(github).objects( + 'GET', '/repos/${slug.fullName}/events', Event.fromJson, pages: pages); } @@ -77,9 +74,8 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization Stream listEventsForOrganization(String name, {int? pages}) { - return PaginationHelper(github).objects( - 'GET', '/orgs/$name/events', (dynamic i) => Event.fromJson(i), - pages: pages); + return PaginationHelper(github) + .objects('GET', '/orgs/$name/events', Event.fromJson, pages: pages); } /// Returns an [EventPoller] for public events for an organization. @@ -105,7 +101,7 @@ class ActivityService extends Service { /// API docs: https://developer.github.com/v3/activity/events/#list-events-performed-by-a-user Stream listEventsPerformedByUser(String username, {int? pages}) { return PaginationHelper(github).objects( - 'GET', '/users/$username/events', (dynamic i) => Event.fromJson(i), + 'GET', '/users/$username/events', Event.fromJson, pages: pages); } @@ -113,8 +109,8 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/events/#list-public-events-performed-by-a-user Stream listPublicEventsPerformedByUser(String username, {int? pages}) { - return PaginationHelper(github).objects('GET', - '/users/$username/events/public', (dynamic i) => Event.fromJson(i), + return PaginationHelper(github).objects( + 'GET', '/users/$username/events/public', Event.fromJson, pages: pages); } @@ -132,7 +128,7 @@ class ActivityService extends Service { Stream listNotifications( {bool all = false, bool participating = false}) { return PaginationHelper(github).objects( - 'GET', '/notifications', (dynamic i) => Notification.fromJson(i), + 'GET', '/notifications', Notification.fromJson, params: {'all': all, 'participating': participating}); } @@ -141,10 +137,8 @@ class ActivityService extends Service { /// API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository Stream listRepositoryNotifications(RepositorySlug repository, {bool all = false, bool participating = false}) { - return PaginationHelper(github).objects( - 'GET', - '/repos/${repository.fullName}/notifications', - (dynamic i) => Notification.fromJson(i), + return PaginationHelper(github).objects('GET', + '/repos/${repository.fullName}/notifications', Notification.fromJson, params: {'all': all, 'participating': participating}); } @@ -192,8 +186,7 @@ class ActivityService extends Service { /// API docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread Future getThread(String threadId) => github.getJSON('/notification/threads/$threadId', - statusCode: StatusCodes.OK, - convert: (dynamic i) => Notification.fromJson(i)); + statusCode: StatusCodes.OK, convert: Notification.fromJson); /// Mark the specified notification thread as read. /// @@ -214,8 +207,8 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/starring/#list-stargazers Stream listStargazers(RepositorySlug slug, {int perPage = 30}) { - return PaginationHelper(github).objects('GET', - '/repos/${slug.fullName}/stargazers', (dynamic i) => User.fromJson(i), + return PaginationHelper(github).objects( + 'GET', '/repos/${slug.fullName}/stargazers', User.fromJson, params: {'per_page': perPage}); } @@ -224,7 +217,7 @@ class ActivityService extends Service { /// API docs: https://developer.github.com/v3/activity/starring/#list-repositories-being-starred Stream listStarredByUser(String user, {int perPage = 30}) { return PaginationHelper(github).objects( - 'GET', '/users/$user/starred', (dynamic i) => Repository.fromJson(i), + 'GET', '/users/$user/starred', Repository.fromJson, params: {'per_page': perPage}); } @@ -233,7 +226,7 @@ class ActivityService extends Service { /// API docs: https://developer.github.com/v3/activity/starring/#list-repositories-being-starred Stream listStarred({int perPage = 30}) { return PaginationHelper(github).objects( - 'GET', '/user/starred', (dynamic i) => Repository.fromJson(i), + 'GET', '/user/starred', Repository.fromJson, params: {'per_page': perPage}); } @@ -272,24 +265,24 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/watching/#list-watchers Stream listWatchers(RepositorySlug slug) { - return PaginationHelper(github).objects('GET', - '/repos/${slug.fullName}/subscribers', (dynamic i) => User.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/repos/${slug.fullName}/subscribers', User.fromJson); } /// Lists the repositories the specified user is watching. /// /// API docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched Stream listWatchedByUser(String user) { - return PaginationHelper(github).objects('GET', '/users/$user/subscriptions', - (dynamic i) => Repository.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/users/$user/subscriptions', Repository.fromJson); } /// Lists the repositories the current user is watching. /// /// API docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched Stream listWatched() { - return PaginationHelper(github).objects( - 'GET', '/user/subscriptions', (dynamic i) => Repository.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/user/subscriptions', Repository.fromJson); } /// Fetches repository subscription information. @@ -298,8 +291,7 @@ class ActivityService extends Service { Future getRepositorySubscription( RepositorySlug slug) => github.getJSON('/repos/${slug.fullName}/subscription', - statusCode: StatusCodes.OK, - convert: (dynamic i) => RepositorySubscription.fromJson(i)); + statusCode: StatusCodes.OK, convert: RepositorySubscription.fromJson); /// Sets the Repository Subscription Status /// @@ -315,7 +307,7 @@ class ActivityService extends Service { return github.putJSON( '/repos/${slug.fullName}/subscription', statusCode: StatusCodes.OK, - convert: (dynamic i) => RepositorySubscription.fromJson(i), + convert: RepositorySubscription.fromJson, body: GitHubJson.encode(map), ); } diff --git a/lib/src/common/authorizations_service.dart b/lib/src/common/authorizations_service.dart index 7e714afb..3cbe6ef0 100644 --- a/lib/src/common/authorizations_service.dart +++ b/lib/src/common/authorizations_service.dart @@ -16,8 +16,8 @@ class AuthorizationsService extends Service { /// /// API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-authorizations Stream listAuthorizations() { - return PaginationHelper(github).objects( - 'GET', '/authorizations', (dynamic i) => Authorization.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/authorizations', Authorization.fromJson); } /// Fetches an authorization specified by [id]. @@ -25,7 +25,7 @@ class AuthorizationsService extends Service { /// API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-authorization Future getAuthorization(int id) => github.getJSON('/authorizations/$id', - statusCode: 200, convert: (dynamic i) => Authorization.fromJson(i)); + statusCode: 200, convert: Authorization.fromJson); // TODO: Implement remaining API methods of authorizations: // See https://developer.github.com/v3/oauth_authorizations/ diff --git a/lib/src/common/checks_service.dart b/lib/src/common/checks_service.dart index d3b63f77..0e87f4d2 100644 --- a/lib/src/common/checks_service.dart +++ b/lib/src/common/checks_service.dart @@ -11,21 +11,21 @@ class ChecksService extends Service { /// Methods to interact with Check Runs. /// /// API docs: https://developer.github.com/v3/checks/runs/ - final _CheckRunsService checkRuns; + final CheckRunsService checkRuns; /// Methods to interact with Check Suites. /// /// API docs: https://developer.github.com/v3/checks/suites/ - final _CheckSuitesService checkSuites; + final CheckSuitesService checkSuites; ChecksService(GitHub github) - : checkRuns = _CheckRunsService._(github), - checkSuites = _CheckSuitesService._(github), + : checkRuns = CheckRunsService._(github), + checkSuites = CheckSuitesService._(github), super(github); } -class _CheckRunsService extends Service { - _CheckRunsService._(GitHub github) : super(github); +class CheckRunsService extends Service { + CheckRunsService._(GitHub github) : super(github); /// Creates a new check run for a specific commit in a repository. /// Your GitHub App must have the `checks:write` permission to create check runs. @@ -78,7 +78,7 @@ class _CheckRunsService extends Service { 'output': output, 'actions': actions, })), - convert: (i) => CheckRun.fromJson(i), + convert: CheckRun.fromJson, ); } @@ -129,7 +129,7 @@ class _CheckRunsService extends Service { 'output': output, 'actions': actions, })), - convert: (i) => CheckRun.fromJson(i), + convert: CheckRun.fromJson, ); } @@ -153,7 +153,7 @@ class _CheckRunsService extends Service { return PaginationHelper(github).objects, CheckRun>( 'GET', 'repos/$slug/commits/$ref/check-runs', - (input) => CheckRun.fromJson(input), + CheckRun.fromJson, statusCode: StatusCodes.OK, preview: _previewHeader, params: createNonNullMap({ @@ -184,7 +184,7 @@ class _CheckRunsService extends Service { return PaginationHelper(github).objects, CheckRun>( 'GET', 'repos/$slug/check-suites/$checkSuiteId/check-runs', - (input) => CheckRun.fromJson(input), + CheckRun.fromJson, statusCode: StatusCodes.OK, preview: _previewHeader, params: createNonNullMap({ @@ -210,7 +210,7 @@ class _CheckRunsService extends Service { 'repos/${slug.fullName}/check-runs/$checkRunId', preview: _previewHeader, statusCode: StatusCodes.OK, - convert: (i) => CheckRun.fromJson(i), + convert: CheckRun.fromJson, ); } @@ -227,15 +227,15 @@ class _CheckRunsService extends Service { .objects, CheckRunAnnotation>( 'GET', '/repos/${slug.fullName}/check-runs/${checkRun.id}/annotations', - (i) => CheckRunAnnotation.fromJSON(i), + CheckRunAnnotation.fromJSON, statusCode: StatusCodes.OK, preview: _previewHeader, ); } } -class _CheckSuitesService extends Service { - _CheckSuitesService._(GitHub github) : super(github); +class CheckSuitesService extends Service { + CheckSuitesService._(GitHub github) : super(github); /// Gets a single check suite using its `id`. /// GitHub Apps must have the `checks:read` permission on a private repository or pull access to a public repository to get check suites. @@ -250,7 +250,7 @@ class _CheckSuitesService extends Service { return github.requestJson( 'GET', 'repos/$slug/check-suites/$checkSuiteId', - convert: (dynamic input) => CheckSuite.fromJson(input), + convert: CheckSuite.fromJson, preview: _previewHeader, statusCode: StatusCodes.OK, ); @@ -274,7 +274,7 @@ class _CheckSuitesService extends Service { return PaginationHelper(github).objects, CheckSuite>( 'GET', 'repos/$slug/commits/$ref/check-suites', - (input) => CheckSuite.fromJson(input), + CheckSuite.fromJson, preview: _previewHeader, params: createNonNullMap({ 'app_id': appId, @@ -304,7 +304,8 @@ class _CheckSuitesService extends Service { preview: _previewHeader, body: {'auto_trigger_checks': autoTriggerChecks}, convert: (input) => (input['preferences']['auto_trigger_checks'] as List) - .map((e) => AutoTriggerChecks.fromJson(e)) + .cast>() + .map(AutoTriggerChecks.fromJson) .toList(), ); } @@ -326,7 +327,7 @@ class _CheckSuitesService extends Service { statusCode: StatusCodes.CREATED, preview: _previewHeader, params: {'head_sha': headSha}, - convert: (input) => CheckSuite.fromJson(input), + convert: CheckSuite.fromJson, ); } diff --git a/lib/src/common/gists_service.dart b/lib/src/common/gists_service.dart index 9f64717e..9078e03d 100644 --- a/lib/src/common/gists_service.dart +++ b/lib/src/common/gists_service.dart @@ -14,8 +14,8 @@ class GistsService extends Service { /// /// API docs: https://developer.github.com/v3/gists/#list-gists Stream listUserGists(String username) { - return PaginationHelper(github).objects( - 'GET', '/users/$username/gists', (dynamic i) => Gist.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/users/$username/gists', Gist.fromJson); } /// Fetches the gists for the currently authenticated user. @@ -23,8 +23,7 @@ class GistsService extends Service { /// /// API docs: https://developer.github.com/v3/gists/#list-gists Stream listCurrentUserGists() { - return PaginationHelper(github) - .objects('GET', '/gists', (dynamic i) => Gist.fromJson(i)); + return PaginationHelper(github).objects('GET', '/gists', Gist.fromJson); } /// Fetches the currently authenticated user's public gists. @@ -32,7 +31,7 @@ class GistsService extends Service { /// API docs: https://developer.github.com/v3/gists/#list-gists Stream listCurrentUserPublicGists() { return PaginationHelper(github) - .objects('GET', '/gists/public', (dynamic i) => Gist.fromJson(i)); + .objects('GET', '/gists/public', Gist.fromJson); } /// Fetches the currently authenticated user's starred gists. @@ -40,14 +39,14 @@ class GistsService extends Service { /// API docs: https://developer.github.com/v3/gists/#list-gists Stream listCurrentUserStarredGists() { return PaginationHelper(github) - .objects('GET', '/gists/starred', (dynamic i) => Gist.fromJson(i)); + .objects('GET', '/gists/starred', Gist.fromJson); } /// Fetches a Gist by the specified [id]. /// /// API docs: https://developer.github.com/v3/gists/#get-a-single-gist Future getGist(String id) => github.getJSON('/gists/$id', - statusCode: StatusCodes.OK, convert: (dynamic i) => Gist.fromJson(i)); + statusCode: StatusCodes.OK, convert: Gist.fromJson); /// Creates a Gist /// @@ -77,7 +76,7 @@ class GistsService extends Service { '/gists', statusCode: 201, body: GitHubJson.encode(map), - convert: (dynamic i) => Gist.fromJson(i), + convert: Gist.fromJson, ); } @@ -116,7 +115,7 @@ class GistsService extends Service { '/gists/$id', statusCode: 200, body: GitHubJson.encode(map), - convert: (dynamic i) => Gist.fromJson(i), + convert: Gist.fromJson, ); } @@ -166,8 +165,8 @@ class GistsService extends Service { /// /// API docs: https://developer.github.com/v3/gists/comments/#list-comments-on-a-gist Stream listComments(String gistId) { - return PaginationHelper(github).objects('GET', '/gists/$gistId/comments', - (dynamic i) => GistComment.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/gists/$gistId/comments', GistComment.fromJson); } // TODO: Implement getComment: https://developer.github.com/v3/gists/comments/#get-a-single-comment @@ -177,8 +176,7 @@ class GistsService extends Service { /// API docs: https://developer.github.com/v3/gists/comments/#create-a-comment Future createComment(String gistId, CreateGistComment request) { return github.postJSON('/gists/$gistId/comments', - body: GitHubJson.encode(request), - convert: (dynamic i) => GistComment.fromJson(i)); + body: GitHubJson.encode(request), convert: GistComment.fromJson); } // TODO: Implement editComment: https://developer.github.com/v3/gists/comments/#edit-a-comment diff --git a/lib/src/common/git_service.dart b/lib/src/common/git_service.dart index 1165eeb0..7052e4f6 100644 --- a/lib/src/common/git_service.dart +++ b/lib/src/common/git_service.dart @@ -15,15 +15,14 @@ class GitService extends Service { /// API docs: https://developer.github.com/v3/git/blobs/#get-a-blob Future getBlob(RepositorySlug slug, String? sha) => github.getJSON('/repos/${slug.fullName}/git/blobs/$sha', - convert: (dynamic i) => GitBlob.fromJson(i), - statusCode: StatusCodes.OK); + convert: GitBlob.fromJson, statusCode: StatusCodes.OK); /// Creates a blob with specified [blob] content. /// /// API docs: https://developer.github.com/v3/git/blobs/#create-a-blob Future createBlob(RepositorySlug slug, CreateGitBlob blob) { return github.postJSON('/repos/${slug.fullName}/git/blobs', - convert: (dynamic i) => GitBlob.fromJson(i), + convert: GitBlob.fromJson, statusCode: StatusCodes.CREATED, body: GitHubJson.encode(blob)); } @@ -33,15 +32,14 @@ class GitService extends Service { /// API docs: https://developer.github.com/v3/git/commits/#get-a-commit Future getCommit(RepositorySlug slug, String? sha) => github.getJSON('/repos/${slug.fullName}/git/commits/$sha', - convert: (dynamic i) => GitCommit.fromJson(i), - statusCode: StatusCodes.OK); + convert: GitCommit.fromJson, statusCode: StatusCodes.OK); /// Creates a new commit in a repository. /// /// API docs: https://developer.github.com/v3/git/commits/#create-a-commit Future createCommit(RepositorySlug slug, CreateGitCommit commit) { return github.postJSON('/repos/${slug.fullName}/git/commits', - convert: (dynamic i) => GitCommit.fromJson(i), + convert: GitCommit.fromJson, statusCode: StatusCodes.CREATED, body: GitHubJson.encode(commit)); } @@ -53,8 +51,7 @@ class GitService extends Service { /// API docs: https://developer.github.com/v3/git/refs/#get-a-reference Future getReference(RepositorySlug slug, String ref) => github.getJSON('/repos/${slug.fullName}/git/refs/$ref', - convert: (dynamic i) => GitReference.fromJson(i), - statusCode: StatusCodes.OK); + convert: GitReference.fromJson, statusCode: StatusCodes.OK); /// Lists the references in a repository. /// @@ -69,8 +66,7 @@ class GitService extends Service { path += '/$type'; } - return PaginationHelper(github) - .objects('GET', path, (dynamic i) => GitReference.fromJson(i)); + return PaginationHelper(github).objects('GET', path, GitReference.fromJson); } /// Creates a new reference in a repository. @@ -82,7 +78,7 @@ class GitService extends Service { Future createReference( RepositorySlug slug, String ref, String? sha) { return github.postJSON('/repos/${slug.fullName}/git/refs', - convert: (dynamic i) => GitReference.fromJson(i), + convert: GitReference.fromJson, statusCode: StatusCodes.CREATED, body: GitHubJson.encode({'ref': ref, 'sha': sha})); } @@ -123,15 +119,14 @@ class GitService extends Service { /// API docs: https://developer.github.com/v3/git/tags/#get-a-tag Future getTag(RepositorySlug slug, String? sha) => github.getJSON('/repos/${slug.fullName}/git/tags/$sha', - convert: (dynamic i) => GitTag.fromJson(i), - statusCode: StatusCodes.OK); + convert: GitTag.fromJson, statusCode: StatusCodes.OK); /// Creates a new tag in a repository. /// /// API docs: https://developer.github.com/v3/git/tags/#create-a-tag-object Future createTag(RepositorySlug slug, CreateGitTag tag) => github.postJSON('/repos/${slug.fullName}/git/tags', - convert: (dynamic i) => GitTag.fromJson(i), + convert: GitTag.fromJson, statusCode: StatusCodes.CREATED, body: GitHubJson.encode(tag)); @@ -149,8 +144,7 @@ class GitService extends Service { } return github.getJSON(path, - convert: (dynamic j) => GitTree.fromJson(j), - statusCode: StatusCodes.OK); + convert: GitTree.fromJson, statusCode: StatusCodes.OK); } /// Creates a new tree in a repository. @@ -158,7 +152,7 @@ class GitService extends Service { /// API docs: https://developer.github.com/v3/git/trees/#create-a-tree Future createTree(RepositorySlug slug, CreateGitTree tree) { return github.postJSON('/repos/${slug.fullName}/git/trees', - convert: (dynamic j) => GitTree.fromJson(j), + convert: GitTree.fromJson, statusCode: StatusCodes.CREATED, body: GitHubJson.encode(tree)); } diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index 77864725..fdfbdc1c 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -333,7 +333,7 @@ class GitHub { final json = jsonDecode(response.body); - final T returnValue = convert(json)!; + final returnValue = convert(json) as T; _applyExpandos(returnValue, response); return returnValue; } @@ -424,15 +424,12 @@ class GitHub { } else { return response; } - - throw UnknownError(this); } /// /// Internal method to handle status codes /// - @alwaysThrows - void handleStatusCode(http.Response response) { + Never handleStatusCode(http.Response response) { print(response.body); String? message = ''; List>? errors; diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index b20d809a..490396fb 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -123,7 +123,7 @@ class IssuesService extends Service { return PaginationHelper(github).objects( 'GET', pathSegment, - (dynamic i) => Issue.fromJson(i), + Issue.fromJson, params: params, ); } @@ -144,7 +144,7 @@ class IssuesService extends Service { return PaginationHelper(github).objects( 'GET', '/repos/${slug.owner}/${slug.name}/issues/$issueNumber/reactions$query', - (dynamic i) => Reaction.fromJson(i), + Reaction.fromJson, headers: { 'Accept': 'application/vnd.github.squirrel-girl-preview+json', }, @@ -169,7 +169,7 @@ class IssuesService extends Service { /// API docs: https://developer.github.com/v3/issues/#get-a-single-issue Future get(RepositorySlug slug, int issueNumber) => github.getJSON('/repos/${slug.fullName}/issues/$issueNumber', - convert: (dynamic i) => Issue.fromJson(i)); + convert: Issue.fromJson); /// Create an issue. /// @@ -194,8 +194,8 @@ class IssuesService extends Service { /// /// API docs: https://developer.github.com/v3/issues/assignees/#list-assignees Stream listAssignees(RepositorySlug slug) { - return PaginationHelper(github).objects('GET', - '/repos/${slug.fullName}/assignees', (dynamic i) => User.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/repos/${slug.fullName}/assignees', User.fromJson); } /// Checks if a user is an assignee for the specified repository. @@ -215,17 +215,15 @@ class IssuesService extends Service { return PaginationHelper(github).objects( 'GET', '/repos/${slug.fullName}/issues/$issueNumber/comments', - (dynamic i) => IssueComment.fromJson(i)); + IssueComment.fromJson); } /// Lists all comments in a repository. /// /// API docs: https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue Stream listCommentsByRepo(RepositorySlug slug) { - return PaginationHelper(github).objects( - 'GET', - '/repos/${slug.fullName}/issues/comments', - (dynamic i) => IssueComment.fromJson(i)); + return PaginationHelper(github).objects('GET', + '/repos/${slug.fullName}/issues/comments', IssueComment.fromJson); } /// Fetches the specified issue comment. @@ -233,7 +231,7 @@ class IssuesService extends Service { /// API docs: https://developer.github.com/v3/issues/comments/#get-a-single-comment Future getComment(RepositorySlug slug, int id) => github.getJSON('/repos/${slug.fullName}/issues/comments/$id', - convert: (dynamic i) => IssueComment.fromJson(i)); + convert: IssueComment.fromJson); /// Creates a new comment on the specified issue /// @@ -244,7 +242,7 @@ class IssuesService extends Service { return github.postJSON( '/repos/${slug.fullName}/issues/$issueNumber/comments', body: it, - convert: (dynamic i) => IssueComment.fromJson(i), + convert: IssueComment.fromJson, statusCode: StatusCodes.CREATED, ); } @@ -257,7 +255,7 @@ class IssuesService extends Service { return github.postJSON( '/repos/${slug.fullName}/issues/comments/$id', body: it, - convert: (dynamic i) => IssueComment.fromJson(i), + convert: IssueComment.fromJson, statusCode: StatusCodes.OK, ); } @@ -277,10 +275,8 @@ class IssuesService extends Service { /// /// API docs: https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository Stream listLabels(RepositorySlug slug) { - return PaginationHelper(github).objects( - 'GET', - '/repos/${slug.fullName}/labels', - (dynamic i) => IssueLabel.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/repos/${slug.fullName}/labels', IssueLabel.fromJson); } /// Fetches a single label. @@ -288,8 +284,7 @@ class IssuesService extends Service { /// API docs: https://developer.github.com/v3/issues/labels/#get-a-single-label Future getLabel(RepositorySlug slug, String name) => github.getJSON('/repos/${slug.fullName}/labels/$name', - convert: (dynamic i) => IssueLabel.fromJson(i), - statusCode: StatusCodes.OK); + convert: IssueLabel.fromJson, statusCode: StatusCodes.OK); /// Creates a new label on the specified repository. /// @@ -298,7 +293,7 @@ class IssuesService extends Service { RepositorySlug slug, String name, String color) { return github.postJSON('/repos/${slug.fullName}/labels', body: GitHubJson.encode({'name': name, 'color': color}), - convert: (dynamic i) => IssueLabel.fromJson(i)); + convert: IssueLabel.fromJson); } /// Edits a label. @@ -307,7 +302,7 @@ class IssuesService extends Service { Future editLabel(RepositorySlug slug, String name, String color) { return github.postJSON('/repos/${slug.fullName}/labels/$name', body: GitHubJson.encode({'name': name, 'color': color}), - convert: (dynamic i) => IssueLabel.fromJson(i)); + convert: IssueLabel.fromJson); } /// Deletes a label. @@ -327,7 +322,7 @@ class IssuesService extends Service { return PaginationHelper(github).objects( 'GET', '/repos/${slug.fullName}/issues/$issueNumber/labels', - (dynamic i) => IssueLabel.fromJson(i)); + IssueLabel.fromJson); } /// Adds labels to an issue. @@ -338,10 +333,8 @@ class IssuesService extends Service { return github.postJSON, List>( '/repos/${slug.fullName}/issues/$issueNumber/labels', body: GitHubJson.encode(labels), - convert: (input) => input - .cast>() - .map((i) => IssueLabel.fromJson(i)) - .toList(), + convert: (input) => + input.cast>().map(IssueLabel.fromJson).toList(), ); } @@ -354,8 +347,7 @@ class IssuesService extends Service { .request('PUT', '/repos/${slug.fullName}/issues/$issueNumber/labels', body: GitHubJson.encode(labels)) .then((response) { - return jsonDecode(response.body) - .map((Map it) => IssueLabel.fromJson(it)); + return jsonDecode(response.body).map(IssueLabel.fromJson); }); } @@ -386,9 +378,7 @@ class IssuesService extends Service { /// API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository Stream listMilestones(RepositorySlug slug) { return PaginationHelper(github).objects( - 'GET', - '/repos/${slug.fullName}/milestones', - (dynamic i) => Milestone.fromJson(i)); + 'GET', '/repos/${slug.fullName}/milestones', Milestone.fromJson); } // TODO: Implement getMilestone: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone @@ -399,8 +389,7 @@ class IssuesService extends Service { Future createMilestone( RepositorySlug slug, CreateMilestone request) { return github.postJSON('/repos/${slug.fullName}/milestones', - body: GitHubJson.encode(request), - convert: (dynamic i) => Milestone.fromJson(i)); + body: GitHubJson.encode(request), convert: Milestone.fromJson); } // TODO: Implement editMilestone: https://developer.github.com/v3/issues/milestones/#update-a-milestone diff --git a/lib/src/common/misc_service.dart b/lib/src/common/misc_service.dart index f34a7964..4951848f 100644 --- a/lib/src/common/misc_service.dart +++ b/lib/src/common/misc_service.dart @@ -35,7 +35,7 @@ class MiscService extends Service { /// API docs: https://developer.github.com/v3/gitignore/#get-a-single-template Future getGitignoreTemplate(String name) => github.getJSON('/gitignore/templates/$name', - convert: (dynamic i) => GitignoreTemplate.fromJson(i)); + convert: GitignoreTemplate.fromJson); /// Renders Markdown from the [input]. /// @@ -70,8 +70,7 @@ class MiscService extends Service { /// Gets the GitHub API Status. Future getApiStatus() => github.getJSON('https://status.github.com/api/status.json', - statusCode: StatusCodes.OK, - convert: (dynamic i) => APIStatus.fromJson(i)); + statusCode: StatusCodes.OK, convert: APIStatus.fromJson); /// Returns an ASCII Octocat with the specified [text]. Future getOctocat([String? text]) { diff --git a/lib/src/common/model/users.dart b/lib/src/common/model/users.dart index 766f6185..8044983a 100644 --- a/lib/src/common/model/users.dart +++ b/lib/src/common/model/users.dart @@ -26,7 +26,7 @@ class User { this.updatedAt, }); - @JsonKey(ignore: true) + @JsonKey(includeToJson: false, includeFromJson: false) Map? json; // TODO remove /// User's Username diff --git a/lib/src/common/orgs_service.dart b/lib/src/common/orgs_service.dart index f72f93b1..c0774bda 100644 --- a/lib/src/common/orgs_service.dart +++ b/lib/src/common/orgs_service.dart @@ -22,16 +22,15 @@ class OrganizationsService extends Service { requestPath = '/user/orgs'; } return PaginationHelper(github) - .objects('GET', requestPath, (dynamic i) => Organization.fromJson(i)); + .objects('GET', requestPath, Organization.fromJson); } /// Fetches the organization specified by [name]. /// /// API docs: https://developer.github.com/v3/orgs/#get-an-organization Future get(String? name) => github.getJSON('/orgs/$name', - convert: (dynamic i) => Organization.fromJson(i), - statusCode: StatusCodes.OK, - fail: (http.Response response) { + convert: Organization.fromJson, + statusCode: StatusCodes.OK, fail: (http.Response response) { if (response.statusCode == 404) { throw OrganizationNotFound(github, name); } @@ -66,7 +65,7 @@ class OrganizationsService extends Service { return github.postJSON('/orgs/$org', statusCode: 200, - convert: (dynamic i) => Organization.fromJson(i), + convert: Organization.fromJson, body: GitHubJson.encode(map)); } @@ -74,8 +73,8 @@ class OrganizationsService extends Service { /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-teams Stream listTeams(String orgName) { - return PaginationHelper(github).objects( - 'GET', '/orgs/$orgName/teams', (dynamic i) => Team.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/orgs/$orgName/teams', Team.fromJson); } /// Gets the team specified by the [teamId]. @@ -83,8 +82,7 @@ class OrganizationsService extends Service { /// API docs: https://developer.github.com/v3/orgs/teams/#get-team Future getTeam(int teamId) { return github.getJSON('/teams/$teamId', - convert: (dynamic i) => Organization.fromJson(i), - statusCode: 200) as Future; + convert: Organization.fromJson, statusCode: 200) as Future; } /// Creates a Team. @@ -100,9 +98,7 @@ class OrganizationsService extends Service { }); return github.postJSON('/orgs/$org/teams', - statusCode: 201, - convert: (dynamic i) => Team.fromJson(i), - body: GitHubJson.encode(map)); + statusCode: 201, convert: Team.fromJson, body: GitHubJson.encode(map)); } /// Edits a Team. @@ -119,7 +115,7 @@ class OrganizationsService extends Service { return github.postJSON( '/teams/$teamId', statusCode: 200, - convert: (dynamic i) => Team.fromJson(i), + convert: Team.fromJson, body: GitHubJson.encode(map), ); } @@ -137,8 +133,8 @@ class OrganizationsService extends Service { /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-team-members Stream listTeamMembers(int teamId) { - return PaginationHelper(github).objects( - 'GET', '/teams/$teamId/members', (dynamic i) => TeamMember.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/teams/$teamId/members', TeamMember.fromJson); } Future getTeamMemberStatus(int teamId, String user) { @@ -192,8 +188,8 @@ class OrganizationsService extends Service { /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-team-repos Stream listTeamRepositories(int teamId) { - return PaginationHelper(github).objects( - 'GET', '/teams/$teamId/repos', (dynamic i) => Repository.fromJson(i)); + return PaginationHelper(github) + .objects('GET', '/teams/$teamId/repos', Repository.fromJson); } /// Checks if a team manages the specified repository. @@ -234,7 +230,7 @@ class OrganizationsService extends Service { /// API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams Stream listUserTeams() { return PaginationHelper(github) - .objects('GET', '/user/teams', (dynamic i) => Team.fromJson(i)); + .objects('GET', '/user/teams', Team.fromJson); } /// Lists all of the users in an organization @@ -242,7 +238,7 @@ class OrganizationsService extends Service { /// API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams Stream listUsers(String org) { return PaginationHelper(github) - .objects('GET', '/orgs/$org/members', (dynamic i) => User.fromJson(i)); + .objects('GET', '/orgs/$org/members', User.fromJson); } /// Lists the hooks for the specified organization. diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index f0ec3dcc..5242f0e3 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -29,8 +29,8 @@ class PullRequestsService extends Service { putValue('sort', sort, params); putValue('state', state, params); - return PaginationHelper(github).objects('GET', - '/repos/${slug.fullName}/pulls', (dynamic i) => PullRequest.fromJson(i), + return PaginationHelper(github).objects( + 'GET', '/repos/${slug.fullName}/pulls', PullRequest.fromJson, pages: pages, params: params); } @@ -39,8 +39,7 @@ class PullRequestsService extends Service { /// API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request Future get(RepositorySlug slug, int number) => github.getJSON('/repos/${slug.fullName}/pulls/$number', - convert: (dynamic i) => PullRequest.fromJson(i), - statusCode: StatusCodes.OK); + convert: PullRequest.fromJson, statusCode: StatusCodes.OK); /// Creates a Pull Request based on the given [request]. /// @@ -48,7 +47,7 @@ class PullRequestsService extends Service { Future create(RepositorySlug slug, CreatePullRequest request) { return github.postJSON( '/repos/${slug.fullName}/pulls', - convert: (dynamic i) => PullRequest.fromJson(i), + convert: PullRequest.fromJson, body: GitHubJson.encode(request), preview: request.draft! ? 'application/vnd.github.shadow-cat-preview+json' @@ -83,7 +82,7 @@ class PullRequestsService extends Service { return PaginationHelper(github).objects( 'GET', '/repos/${slug.fullName}/pulls/$number/commits', - (dynamic i) => RepositoryCommit.fromJson(i)); + RepositoryCommit.fromJson); } /// Lists the files in a pull request. @@ -93,7 +92,7 @@ class PullRequestsService extends Service { return PaginationHelper(github).objects( 'GET', '/repos/${slug.fullName}/pulls/$number/files', - (dynamic i) => PullRequestFile.fromJson(i)); + PullRequestFile.fromJson); } /// Lists the reviews for a pull request. @@ -103,7 +102,7 @@ class PullRequestsService extends Service { return PaginationHelper(github).objects( 'GET', '/repos/${slug.fullName}/pulls/$number/reviews', - (dynamic i) => PullRequestReview.fromJson(i)); + PullRequestReview.fromJson); } Future isMerged(RepositorySlug slug, int number) { @@ -156,17 +155,15 @@ class PullRequestsService extends Service { return PaginationHelper(github).objects( 'GET', '/repos/${slug.fullName}/pulls/$number/comments', - (dynamic i) => PullRequestComment.fromJson(i)); + PullRequestComment.fromJson); } /// Lists all comments on all pull requests for the repository. /// /// API docs: https://developer.github.com/v3/pulls/comments/#list-comments-in-a-repository Stream listComments(RepositorySlug slug) { - return PaginationHelper(github).objects( - 'GET', - '/repos/${slug.fullName}/pulls/comments', - (dynamic i) => PullRequestComment.fromJson(i)); + return PaginationHelper(github).objects('GET', + '/repos/${slug.fullName}/pulls/comments', PullRequestComment.fromJson); } /// Creates a new pull request comment. @@ -176,7 +173,7 @@ class PullRequestsService extends Service { RepositorySlug slug, int number, CreatePullRequestComment comment) { return github.postJSON('/repos/${slug.fullName}/pulls/$number/comments', body: GitHubJson.encode(comment.toJson()), - convert: (dynamic i) => PullRequestComment.fromJson(i), + convert: PullRequestComment.fromJson, statusCode: 201); } @@ -191,7 +188,7 @@ class PullRequestsService extends Service { return github.postJSON( '/repos/${slug.fullName}/pulls/${review.pullNumber}/reviews', body: GitHubJson.encode(review), - convert: (dynamic i) => PullRequestReview.fromJson(i), + convert: PullRequestReview.fromJson, ); } } diff --git a/lib/src/common/repos_service.dart b/lib/src/common/repos_service.dart index a3a73531..535e1060 100644 --- a/lib/src/common/repos_service.dart +++ b/lib/src/common/repos_service.dart @@ -27,7 +27,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Repository>( 'GET', '/user/repos', - (i) => Repository.fromJson(i), + Repository.fromJson, params: params, ); } @@ -49,7 +49,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Repository>( 'GET', '/users/$user/repos', - (i) => Repository.fromJson(i), + Repository.fromJson, params: params, ); } @@ -65,7 +65,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Repository>( 'GET', '/orgs/$org/repos', - (i) => Repository.fromJson(i), + Repository.fromJson, params: params, ); } @@ -91,7 +91,7 @@ class RepositoriesService extends Service { .expand((http.Response response) { final list = jsonDecode(response.body) as List>; - return list.map((Map it) => Repository.fromJson(it)); + return list.map(Repository.fromJson); }); } @@ -107,13 +107,13 @@ class RepositoriesService extends Service { return github.postJSON, Repository>( '/orgs/$org/repos', body: GitHubJson.encode(repository), - convert: (i) => Repository.fromJson(i), + convert: Repository.fromJson, ); } else { return github.postJSON, Repository>( '/user/repos', body: GitHubJson.encode(repository), - convert: (i) => Repository.fromJson(i), + convert: Repository.fromJson, ); } } @@ -122,7 +122,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(slug); return github.getJSON, LicenseDetails>( '/repos/${slug.owner}/${slug.name}/license', - convert: (json) => LicenseDetails.fromJson(json), + convert: LicenseDetails.fromJson, ); } @@ -133,7 +133,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(slug); return github.getJSON, Repository>( '/repos/${slug.owner}/${slug.name}', - convert: (i) => Repository.fromJson(i), + convert: Repository.fromJson, statusCode: StatusCodes.OK, fail: (http.Response response) { if (response.statusCode == 404) { @@ -206,7 +206,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Contributor>( 'GET', '/repos/${slug.fullName}/contributors', - (i) => Contributor.fromJson(i), + Contributor.fromJson, params: {'anon': anon.toString()}, ); } @@ -219,7 +219,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Team>( 'GET', '/repos/${slug.fullName}/teams', - (i) => Team.fromJson(i), + Team.fromJson, ); } @@ -242,7 +242,7 @@ class RepositoriesService extends Service { {int page = 1, int? pages, int perPage = 30}) { ArgumentError.checkNotNull(slug); return PaginationHelper(github).objects, Tag>( - 'GET', '/repos/${slug.fullName}/tags', (i) => Tag.fromJson(i), + 'GET', '/repos/${slug.fullName}/tags', Tag.fromJson, pages: pages, params: {'page': page, 'per_page': perPage}); } @@ -254,7 +254,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Branch>( 'GET', '/repos/${slug.fullName}/branches', - (i) => Branch.fromJson(i), + Branch.fromJson, ); } @@ -266,7 +266,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(branch); return github.getJSON, Branch>( '/repos/${slug.fullName}/branches/$branch', - convert: (i) => Branch.fromJson(i), + convert: Branch.fromJson, ); } @@ -278,7 +278,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Collaborator>( 'GET', '/repos/${slug.fullName}/collaborators', - (json) => Collaborator.fromJson(json), + Collaborator.fromJson, ); } @@ -346,7 +346,7 @@ class RepositoriesService extends Service { .objects, CommitComment>( 'GET', '/repos/${slug.fullName}/commits/${commit.sha}/comments', - (i) => CommitComment.fromJson(i), + CommitComment.fromJson, statusCode: StatusCodes.OK, ); } @@ -360,7 +360,7 @@ class RepositoriesService extends Service { .objects, CommitComment>( 'GET', 'repos/${slug.fullName}/comments', - (i) => CommitComment.fromJson(i), + CommitComment.fromJson, statusCode: StatusCodes.OK, ); } @@ -392,7 +392,7 @@ class RepositoriesService extends Service { '/repos/${slug.fullName}/commits/${commit.sha}/comments', body: GitHubJson.encode(data), statusCode: StatusCodes.CREATED, - convert: (i) => CommitComment.fromJson(i), + convert: CommitComment.fromJson, ); } @@ -406,7 +406,7 @@ class RepositoriesService extends Service { return github.getJSON, CommitComment>( '/repos/${slug.fullName}/comments/$id', statusCode: StatusCodes.OK, - convert: (i) => CommitComment.fromJson(i), + convert: CommitComment.fromJson, ); } @@ -426,7 +426,7 @@ class RepositoriesService extends Service { '/repos/${slug.fullName}/comments/$id', body: GitHubJson.encode(createNonNullMap({'body': body})), statusCode: StatusCodes.OK, - convert: (i) => CommitComment.fromJson(i), + convert: CommitComment.fromJson, ); } @@ -455,7 +455,7 @@ class RepositoriesService extends Service { .objects, RepositoryCommit>( 'GET', '/repos/${slug.fullName}/commits', - (i) => RepositoryCommit.fromJson(i), + RepositoryCommit.fromJson, ); } @@ -467,7 +467,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(sha); return github.getJSON, RepositoryCommit>( '/repos/${slug.fullName}/commits/$sha', - convert: (i) => RepositoryCommit.fromJson(i), + convert: RepositoryCommit.fromJson, statusCode: StatusCodes.OK, ); } @@ -501,7 +501,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(refHead); return github.getJSON, GitHubComparison>( '/repos/${slug.fullName}/compare/$refBase...$refHead', - convert: (j) => GitHubComparison.fromJson(j), + convert: GitHubComparison.fromJson, ); } @@ -572,8 +572,10 @@ class RepositoriesService extends Service { } contents.file = GitHubFile.fromJson(input as Map); } else { - contents.tree = - (input as List).map((it) => GitHubFile.fromJson(it)).toList(); + contents.tree = (input as List) + .cast>() + .map(GitHubFile.fromJson) + .toList(); } return contents; }, @@ -662,7 +664,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Repository>( 'GET', '/repos/${slug.fullName}/forks', - (i) => Repository.fromJson(i), + Repository.fromJson, ); } @@ -675,7 +677,7 @@ class RepositoriesService extends Service { return github.postJSON, Repository>( '/repos/${slug.fullName}/forks', body: GitHubJson.encode(fork), - convert: (i) => Repository.fromJson(i), + convert: Repository.fromJson, ); } @@ -820,7 +822,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, PublicKey>( 'GET', '/repos/${slug.fullName}/keys', - (i) => PublicKey.fromJson(i), + PublicKey.fromJson, ); } @@ -834,7 +836,7 @@ class RepositoriesService extends Service { return github.getJSON, PublicKey>( '/repos/${slug.fullName}/keys/$id', statusCode: StatusCodes.OK, - convert: (i) => PublicKey.fromJson(i), + convert: PublicKey.fromJson, ); } @@ -849,7 +851,7 @@ class RepositoriesService extends Service { '/repos/${slug.fullName}/keys', body: GitHubJson.encode(key), statusCode: StatusCodes.CREATED, - convert: (i) => PublicKey.fromJson(i), + convert: PublicKey.fromJson, ); } @@ -878,7 +880,7 @@ class RepositoriesService extends Service { return github.postJSON, RepositoryCommit>( '/repos/${slug.fullName}/merges', body: GitHubJson.encode(merge), - convert: (i) => RepositoryCommit.fromJson(i), + convert: RepositoryCommit.fromJson, statusCode: StatusCodes.CREATED, ); } @@ -891,7 +893,7 @@ class RepositoriesService extends Service { return github.getJSON, RepositoryPages>( '/repos/${slug.fullName}/pages', statusCode: StatusCodes.OK, - convert: (i) => RepositoryPages.fromJson(i), + convert: RepositoryPages.fromJson, ); } @@ -903,7 +905,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, PageBuild>( 'GET', '/repos/${slug.fullName}/pages/builds', - (i) => PageBuild.fromJson(i), + PageBuild.fromJson, statusCode: StatusCodes.OK, ); } @@ -915,7 +917,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(slug); return github.getJSON( '/repos/${slug.fullName}/pages/builds/latest', - convert: (dynamic i) => PageBuild.fromJson(i), + convert: PageBuild.fromJson, statusCode: StatusCodes.OK, ); } @@ -930,7 +932,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, Release>( 'GET', '/repos/${slug.fullName}/releases', - (i) => Release.fromJson(i), + Release.fromJson, ); } @@ -941,7 +943,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(slug); return github.getJSON, Release>( '/repos/${slug.fullName}/releases/latest', - convert: (i) => Release.fromJson(i), + convert: Release.fromJson, statusCode: StatusCodes.OK, ); } @@ -954,7 +956,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(id); return github.getJSON, Release>( '/repos/${slug.fullName}/releases/$id', - convert: (i) => Release.fromJson(i), + convert: Release.fromJson, ); } @@ -968,7 +970,7 @@ class RepositoriesService extends Service { RepositorySlug slug, String? tagName) async { return github.getJSON( '/repos/${slug.fullName}/releases/tags/$tagName', - convert: (dynamic i) => Release.fromJson(i), + convert: Release.fromJson, statusCode: StatusCodes.OK, fail: (http.Response response) { if (response.statusCode == 404) { @@ -992,7 +994,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(createRelease); final release = await github.postJSON, Release>( '/repos/${slug.fullName}/releases', - convert: (i) => Release.fromJson(i), + convert: Release.fromJson, body: GitHubJson.encode(createRelease.toJson()), statusCode: StatusCodes.CREATED); if (release.hasErrors) { @@ -1052,7 +1054,7 @@ class RepositoriesService extends Service { 'prerelease': preRelease ?? releaseToEdit.isPrerelease, })), statusCode: StatusCodes.OK, - convert: (i) => Release.fromJson(i), + convert: Release.fromJson, ); } @@ -1080,7 +1082,7 @@ class RepositoriesService extends Service { return PaginationHelper(github).objects, ReleaseAsset>( 'GET', '/repos/${slug.fullName}/releases/${release.id}/assets', - (i) => ReleaseAsset.fromJson(i), + ReleaseAsset.fromJson, statusCode: StatusCodes.OK, ); } @@ -1096,7 +1098,7 @@ class RepositoriesService extends Service { return github.postJSON, ReleaseAsset>( '/repos/${slug.fullName}/releases/assets/$assetId', statusCode: StatusCodes.OK, - convert: (i) => ReleaseAsset.fromJson(i), + convert: ReleaseAsset.fromJson, ); } @@ -1114,7 +1116,7 @@ class RepositoriesService extends Service { return github.postJSON, ReleaseAsset>( '/repos/${slug.fullName}/releases/assets/${assetToEdit.id}', statusCode: StatusCodes.OK, - convert: (i) => ReleaseAsset.fromJson(i), + convert: ReleaseAsset.fromJson, body: GitHubJson.encode(createNonNullMap({ 'name': name ?? assetToEdit.name, 'label': label ?? assetToEdit.label, @@ -1152,7 +1154,7 @@ class RepositoriesService extends Service { ), headers: headers, body: createReleaseAsset.assetData, - convert: (dynamic i) => ReleaseAsset.fromJson(i)); + convert: ReleaseAsset.fromJson); releaseAssets.add(releaseAsset); } return releaseAssets; @@ -1174,13 +1176,13 @@ class RepositoriesService extends Service { if (response.statusCode == StatusCodes.OK) { return (jsonDecode(response.body) as List) - .map((e) => ContributorStatistics.fromJson(e)) + .cast>() + .map(ContributorStatistics.fromJson) .toList(); } else if (response.statusCode == StatusCodes.ACCEPTED) { throw NotReady(github, path); } github.handleStatusCode(response); - throw UnknownError(github); } /// Fetches commit counts for the past year. @@ -1192,7 +1194,7 @@ class RepositoriesService extends Service { .objects, YearCommitCountWeek>( 'GET', '/repos/${slug.fullName}/stats/commit_activity', - (i) => YearCommitCountWeek.fromJson(i), + YearCommitCountWeek.fromJson, ); } @@ -1205,7 +1207,7 @@ class RepositoriesService extends Service { .objects, WeeklyChangesCount>( 'GET', '/repos/${slug.fullName}/stats/code_frequency', - (i) => WeeklyChangesCount.fromJson(i), + WeeklyChangesCount.fromJson, ); } @@ -1217,7 +1219,7 @@ class RepositoriesService extends Service { return github.getJSON( '/repos/${slug.fullName}/stats/participation', statusCode: StatusCodes.OK, - convert: (dynamic i) => ContributorParticipation.fromJson(i), + convert: ContributorParticipation.fromJson, ); } @@ -1230,7 +1232,7 @@ class RepositoriesService extends Service { .objects, PunchcardEntry>( 'GET', '/repos/${slug.fullName}/stats/punchcard', - (i) => PunchcardEntry.fromJson(i), + PunchcardEntry.fromJson, ); } @@ -1245,7 +1247,7 @@ class RepositoriesService extends Service { .objects, RepositoryStatus>( 'GET', '/repos/${slug.fullName}/commits/$ref/statuses', - (i) => RepositoryStatus.fromJson(i), + RepositoryStatus.fromJson, ); } @@ -1261,7 +1263,7 @@ class RepositoriesService extends Service { return github.postJSON, RepositoryStatus>( '/repos/${slug.fullName}/statuses/$ref', body: GitHubJson.encode(request), - convert: (i) => RepositoryStatus.fromJson(i), + convert: RepositoryStatus.fromJson, ); } @@ -1274,7 +1276,7 @@ class RepositoriesService extends Service { ArgumentError.checkNotNull(ref); return github.getJSON, CombinedRepositoryStatus>( '/repos/${slug.fullName}/commits/$ref/status', - convert: (i) => CombinedRepositoryStatus.fromJson(i), + convert: CombinedRepositoryStatus.fromJson, statusCode: StatusCodes.OK, ); } @@ -1291,7 +1293,7 @@ class RepositoriesService extends Service { '/repos/${crn.owner}/${crn.repo}/releases/generate-notes', body: GitHubJson.encode(crn), statusCode: StatusCodes.OK, - convert: (i) => ReleaseNotes.fromJson(i), + convert: ReleaseNotes.fromJson, ); } } diff --git a/lib/src/common/search_service.dart b/lib/src/common/search_service.dart index e98344a6..bf2b41ec 100644 --- a/lib/src/common/search_service.dart +++ b/lib/src/common/search_service.dart @@ -44,7 +44,10 @@ class SearchService extends Service { final items = input['items'] as List; - items.map((item) => Repository.fromJson(item)).forEach(controller.add); + items + .cast>() + .map(Repository.fromJson) + .forEach(controller.add); }).onDone(controller.close); return controller.stream; @@ -94,19 +97,19 @@ class SearchService extends Service { query += _searchQualifier('size', size); // build up the in: qualifier based on the 2 booleans - var _in = ''; + var inValue = ''; if (inFile) { - _in = 'file'; + inValue = 'file'; } if (inPath) { - if (_in.isEmpty) { - _in = 'path'; + if (inValue.isEmpty) { + inValue = 'path'; } else { - _in = 'file,path'; + inValue = 'file,path'; } } - if (_in.isNotEmpty) { - query += ' in:$_in'; + if (inValue.isNotEmpty) { + query += ' in:$inValue'; } final params = {}; @@ -159,7 +162,10 @@ class SearchService extends Service { final items = input['items'] as List; - items.map((item) => Issue.fromJson(item)).forEach(controller.add); + items + .cast>() + .map(Issue.fromJson) + .forEach(controller.add); }).onDone(controller.close); return controller.stream; @@ -206,7 +212,10 @@ class SearchService extends Service { final items = input['items'] as List; - items.map((item) => User.fromJson(item)).forEach(controller.add); + items + .cast>() + .map(User.fromJson) + .forEach(controller.add); }).onDone(controller.close); return controller.stream; diff --git a/lib/src/common/users_service.dart b/lib/src/common/users_service.dart index 3a469401..bb27ff6d 100644 --- a/lib/src/common/users_service.dart +++ b/lib/src/common/users_service.dart @@ -14,7 +14,7 @@ class UsersService extends Service { /// /// API docs: https://developer.github.com/v3/users/#get-a-single-user Future getUser(String? name) => - github.getJSON('/users/$name', convert: (dynamic i) => User.fromJson(i)); + github.getJSON('/users/$name', convert: User.fromJson); /// Updates the Current User. /// @@ -41,7 +41,7 @@ class UsersService extends Service { '/user', body: GitHubJson.encode(map), statusCode: 200, - convert: (dynamic i) => CurrentUser.fromJson(i), + convert: CurrentUser.fromJson, ); } @@ -58,14 +58,13 @@ class UsersService extends Service { /// Throws [AccessForbidden] if we are not authenticated. /// /// API docs: https://developer.github.com/v3/users/#get-the-authenticated-user - Future getCurrentUser() => github.getJSON('/user', - statusCode: StatusCodes.OK, - fail: (http.Response response) { + Future getCurrentUser() => + github.getJSON('/user', statusCode: StatusCodes.OK, + fail: (http.Response response) { if (response.statusCode == StatusCodes.FORBIDDEN) { throw AccessForbidden(github); } - }, - convert: (dynamic i) => CurrentUser.fromJson(i)); + }, convert: CurrentUser.fromJson); /// Checks if a user exists. Future isUser(String name) => github @@ -77,21 +76,21 @@ class UsersService extends Service { /// Lists all users. /// /// API docs: https://developer.github.com/v3/users/#get-all-users - Stream listUsers({int? pages, int? since}) => PaginationHelper(github) - .objects('GET', '/users', (dynamic i) => User.fromJson(i), + Stream listUsers({int? pages, int? since}) => + PaginationHelper(github).objects('GET', '/users', User.fromJson, pages: pages, params: {'since': since}); /// Lists all email addresses for the currently authenticated user. /// /// API docs: https://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user Stream listEmails() => PaginationHelper(github) - .objects('GET', '/user/emails', (dynamic i) => UserEmail.fromJson(i)); + .objects('GET', '/user/emails', UserEmail.fromJson); /// Add Emails /// /// API docs: https://developer.github.com/v3/users/emails/#add-email-addresses Stream addEmails(List emails) => PaginationHelper(github) - .objects('POST', '/user/emails', (dynamic i) => UserEmail.fromJson(i), + .objects('POST', '/user/emails', UserEmail.fromJson, statusCode: 201, body: GitHubJson.encode(emails)); /// Delete Emails @@ -106,8 +105,7 @@ class UsersService extends Service { /// /// API docs: https://developer.github.com/v3/users/followers/#list-followers-of-a-user Stream listUserFollowers(String user) => PaginationHelper(github) - .objects('GET', '/users/$user/followers', (dynamic i) => User.fromJson(i), - statusCode: 200); + .objects('GET', '/users/$user/followers', User.fromJson, statusCode: 200); /// Check if the current user is following the specified user. Future isFollowingUser(String user) => @@ -144,16 +142,14 @@ class UsersService extends Service { /// List current user followers. /// /// API docs: https://developer.github.com/v3/users/followers/#list-followers-of-a-user - Stream listCurrentUserFollowers() => PaginationHelper(github).objects( - 'GET', '/user/followers', (dynamic i) => User.fromJson(i), - statusCode: 200); + Stream listCurrentUserFollowers() => PaginationHelper(github) + .objects('GET', '/user/followers', User.fromJson, statusCode: 200); /// List current user following /// /// API docs: https://developer.github.com/v3/users/followers/#list-users-followed-by-the-authenticated-user - Stream listCurrentUserFollowing() => PaginationHelper(github).objects( - 'GET', '/user/following', (dynamic i) => User.fromJson(i), - statusCode: 200); + Stream listCurrentUserFollowing() => PaginationHelper(github) + .objects('GET', '/user/following', User.fromJson, statusCode: 200); /// Lists the verified public keys for a [userLogin]. If no [userLogin] is specified, /// the public keys for the authenticated user are fetched. @@ -162,8 +158,7 @@ class UsersService extends Service { /// and https://developer.github.com/v3/users/keys/#list-your-public-keys Stream listPublicKeys([String? userLogin]) { final path = userLogin == null ? '/user/keys' : '/users/$userLogin/keys'; - return PaginationHelper(github) - .objects('GET', path, (dynamic i) => PublicKey.fromJson(i)); + return PaginationHelper(github).objects('GET', path, PublicKey.fromJson); } // TODO: Implement getPublicKey: https://developer.github.com/v3/users/keys/#get-a-single-public-key diff --git a/lib/src/common/util/oauth2.dart b/lib/src/common/util/oauth2.dart index 5d3c9e59..9333d606 100644 --- a/lib/src/common/util/oauth2.dart +++ b/lib/src/common/util/oauth2.dart @@ -54,14 +54,12 @@ class OAuth2Flow { /// /// This should be displayed to the user. String createAuthorizeUrl() { - return baseUrl + - '/authorize' + - buildQueryString({ + return '$baseUrl/authorize${buildQueryString({ 'client_id': clientId, 'scope': scopes.join(','), 'redirect_uri': redirectUri, 'state': state - }); + })}'; } /// Exchanges the given [code] for a token. diff --git a/pubspec.yaml b/pubspec.yaml index bdc75ce3..188c93ec 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,15 +1,15 @@ name: github -version: 9.9.0 +version: 9.10.0-dev description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart environment: - sdk: '>=2.17.0 <3.0.0' + sdk: '>=2.18.0 <3.0.0' dependencies: http: ^0.13.0 http_parser: ^4.0.0 - json_annotation: ^4.4.0 + json_annotation: ^4.8.0 meta: ^1.3.0 dev_dependencies: @@ -18,8 +18,8 @@ dev_dependencies: build_web_compilers: any collection: ^1.15.0 dependency_validator: - json_serializable: ^6.0.0 - lints: ^1.0.0 + json_serializable: ^6.6.1 + lints: ^2.0.0 mockito: ^5.0.0 nock: ^1.0.0 pub_semver: ^2.0.0 diff --git a/test/assets/responses/nocked_responses.dart b/test/assets/responses/nocked_responses.dart index 3a1b9b5b..bf0e50f4 100644 --- a/test/assets/responses/nocked_responses.dart +++ b/test/assets/responses/nocked_responses.dart @@ -1,4 +1,4 @@ -var getBlob = ''' +String getBlob = ''' { "content": "Q29udGVudCBvZiB0aGUgYmxvYg==", "encoding": "base64", @@ -8,7 +8,7 @@ var getBlob = ''' "node_id": "Q29udGVudCBvZiB0aGUgYmxvYg==" }'''; -var createBlob = ''' +String createBlob = ''' { "url": "https://api.github.com/repos/octocat/example/git/blobs/3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15", "sha": "3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15", @@ -16,7 +16,7 @@ var createBlob = ''' "encoding": "utf-8" }'''; -var getCommit = ''' +String getCommit = ''' { "sha": "7638417db6d59f3c431d3e1f261cc637155684cd", "node_id": "MDY6Q29tbWl0NmRjYjA5YjViNTc4NzVmMzM0ZjYxYWViZWQ2OTVlMmU0MTkzZGI1ZQ==", @@ -52,7 +52,7 @@ var getCommit = ''' } }'''; -var createCommit = ''' +String createCommit = ''' { "sha": "7638417db6d59f3c431d3e1f261cc637155684cd", "node_id": "MDY6Q29tbWl0NzYzODQxN2RiNmQ1OWYzYzQzMWQzZTFmMjYxY2M2MzcxNTU2ODRjZA==", @@ -88,7 +88,7 @@ var createCommit = ''' "html_url": "https://github.com/octocat/Hello-World/commit/7638417db6d59f3c431d3e1f261cc637155684cd" }'''; -var getReference = '''{ +String getReference = '''{ "ref": "refs/heads/b", "node_id": "MDM6UmVmcmVmcy9oZWFkcy9mZWF0dXJlQQ==", "url": "https://api.github.com/repos/octocat/Hello-World/git/refs/heads/featureA", @@ -99,7 +99,7 @@ var getReference = '''{ } }'''; -var createReference = '''{ +String createReference = '''{ "ref": "refs/heads/b", "node_id": "MDM6UmVmcmVmcy9oZWFkcy9mZWF0dXJlQQ==", "url": "https://api.github.com/repos/octocat/Hello-World/git/refs/heads/featureA", @@ -110,7 +110,7 @@ var createReference = '''{ } }'''; -var getTag = '''{ +String getTag = '''{ "node_id": "MDM6VGFnOTQwYmQzMzYyNDhlZmFlMGY5ZWU1YmM3YjJkNWM5ODU4ODdiMTZhYw==", "tag": "v0.0.1", "sha": "940bd336248efae0f9ee5bc7b2d5c985887b16ac", @@ -134,7 +134,7 @@ var getTag = '''{ } }'''; -var createTag = '''{ +String createTag = '''{ "node_id": "MDM6VGFnOTQwYmQzMzYyNDhlZmFlMGY5ZWU1YmM3YjJkNWM5ODU4ODdiMTZhYw==", "tag": "v0.0.1", "sha": "940bd336248efae0f9ee5bc7b2d5c985887b16ac", @@ -158,7 +158,7 @@ var createTag = '''{ } }'''; -var createTree = '''{ +String createTree = '''{ "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/octocat/Hello-World/trees/44b4fc6d56897b048c772eb4087f854f46256132", "tree": [ @@ -174,7 +174,7 @@ var createTree = '''{ "truncated": true }'''; -var searchResults = '''{ +String searchResults = '''{ "total_count": 17, "incomplete_results": false, "items": [ @@ -1473,7 +1473,7 @@ var searchResults = '''{ ] }'''; -var mergedPR1 = '''{ +String mergedPR1 = '''{ "sha": "someSHA", "merged": true, "message": "Pull Request successfully merged" diff --git a/test/common/github_test.dart b/test/common/github_test.dart index 45c3b68f..7b50ef54 100644 --- a/test/common/github_test.dart +++ b/test/common/github_test.dart @@ -6,7 +6,7 @@ import 'package:http/testing.dart'; import 'package:test/test.dart'; void main() { - group(GitHub, () { + group(GitHub, () { test('passes calendar version header', () async { Request? request; final client = MockClient((r) async { diff --git a/test/experiment/error_handling.dart b/test/experiment/error_handling.dart index 5456b237..e76b7e9d 100644 --- a/test/experiment/error_handling.dart +++ b/test/experiment/error_handling.dart @@ -27,8 +27,4 @@ void main() { print(e); exit(0); } - - print('Invalid Entity Error Handling Failed'); - - exit(1); } diff --git a/test/git_test.dart b/test/git_test.dart index f769571b..34487b95 100644 --- a/test/git_test.dart +++ b/test/git_test.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'package:github/github.dart'; import 'package:nock/nock.dart'; import 'package:test/test.dart'; diff --git a/test/scenarios_test.dart b/test/scenarios_test.dart index 6486553d..c39ceb53 100644 --- a/test/scenarios_test.dart +++ b/test/scenarios_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: unused_local_variable + @Tags(['scenarios']) @TestOn('vm') diff --git a/test/unit/issues_test.dart b/test/unit/issues_test.dart index 88b06086..512d83a3 100644 --- a/test/unit/issues_test.dart +++ b/test/unit/issues_test.dart @@ -3,7 +3,6 @@ import 'package:github/src/common/model/issues.dart'; import 'package:test/test.dart'; - const String testIssueCommentJson = ''' { "url": "https://api.github.com/repos/flutter/cocoon/issues/comments/1352355796", @@ -54,7 +53,8 @@ const String testIssueCommentJson = ''' void main() { group('Issue Comments', () { test('IssueComment from Json', () { - final issueComment = IssueComment.fromJson(jsonDecode(testIssueCommentJson)); + final issueComment = + IssueComment.fromJson(jsonDecode(testIssueCommentJson)); expect(1352355796, issueComment.id); expect('MEMBER', issueComment.authorAssociation); expect('CaseyHillers', issueComment.user!.login); diff --git a/tool/release_unreleased_prs.dart b/tool/release_unreleased_prs.dart index 2eb1d273..b8cf8b17 100644 --- a/tool/release_unreleased_prs.dart +++ b/tool/release_unreleased_prs.dart @@ -103,7 +103,7 @@ Future> getUnreleasedPRs() async { } String getNextVersion(Version currentVersion, List unreleased) { - var semvers = Set(); + var semvers = {}; for (final pr in unreleased) { var prlabels = pr.labels .where((element) => element.name.startsWith('semver:')) From 2c4dfa0456e0fb894d9f4761216a40c01aeb9139 Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Thu, 23 Feb 2023 14:00:09 -0800 Subject: [PATCH 081/139] Add required UserAgent HTTP header (#352) * Add required UserAgent header * Prep 9.10.1 --- CHANGELOG.md | 6 ++++++ lib/src/common/github.dart | 3 +++ pubspec.yaml | 2 +- test/common/github_test.dart | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eae3873b..4f36eb35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 9.10.1 + +* Pass required User-Agent HTTP header on all requests + * If `Authentication.basic` is used, it will be your GitHub username/application + * Otherwise, it will default to `github.dart` + ## 9.10.0-dev * Require Dart 2.18 diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index fdfbdc1c..0aead228 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -377,6 +377,9 @@ class GitHub { headers.putIfAbsent('Authorization', () => 'basic $userAndPass'); } + // See https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#user-agent-required + headers.putIfAbsent('User-Agent', () => auth?.username ?? 'github.dart'); + if (method == 'PUT' && body == null) { headers.putIfAbsent('Content-Length', () => '0'); } diff --git a/pubspec.yaml b/pubspec.yaml index 188c93ec..afd47919 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.10.0-dev +version: 9.10.1 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart diff --git a/test/common/github_test.dart b/test/common/github_test.dart index 7b50ef54..4f7d6727 100644 --- a/test/common/github_test.dart +++ b/test/common/github_test.dart @@ -22,5 +22,21 @@ void main() { final version = request!.headers[GitHub.versionHeader]; expect(version, github.version); }); + + test('passes required user-agent header', () async { + Request? request; + final client = MockClient((r) async { + request = r; + return Response('{}', HttpStatus.ok); + }); + + final github = GitHub(client: client); + await github.getJSON(''); // Make HTTP request + + expect(request, isNotNull); + expect(request!.headers.containsKey('User-Agent'), isTrue); + final userAgent = request!.headers['User-Agent']; + expect(userAgent, 'github.dart'); + }); }); } From 0b8f3fe984cd2f95056c8cf698390495e3018aac Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Thu, 23 Feb 2023 15:00:07 -0800 Subject: [PATCH 082/139] [actions] Use pub.dev release process (#354) --- .github/workflows/publish_release.yml | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 0287d22a..658e690d 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -1,21 +1,10 @@ -name: Publish to pub +name: Publish to pub.dev on: - release: - types: [published] + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+*' jobs: publish: - - runs-on: ubuntu-latest - container: - image: dart - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: Setup credentials - run: | - mkdir -p ~/.pub-cache - echo ${{ secrets.CREDENTIAL_JSON }} > ~/.pub-cache/credentials.json - - name: Publish package - run: dart pub publish -f \ No newline at end of file + uses: dart-lang/setup-dart/.github/workflows/publish.yml From cc3ef8fa288a193bc2ea3e5efcdad6f581f796e6 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Fri, 24 Feb 2023 11:15:25 -0700 Subject: [PATCH 083/139] use machine github token for unreleased labels --- .github/workflows/label_prs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label_prs.yml b/.github/workflows/label_prs.yml index 8f30b23d..c631e84c 100644 --- a/.github/workflows/label_prs.yml +++ b/.github/workflows/label_prs.yml @@ -12,7 +12,7 @@ jobs: - name: Apply unreleased label uses: actions/github-script@v6 with: - github-token: ${{secrets.GITHUB_TOKEN}} + github-token: ${{secrets.MACHINE_GITHUB_API_TOKEN}} script: | github.rest.issues.addLabels({ issue_number: context.issue.number, From 3206fbe1f9965faf89c921217cf5f09d58f8bab2 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 13 Mar 2023 07:36:26 -0700 Subject: [PATCH 084/139] update dart CI; update action versions (#358) --- .github/dependabot.yaml | 10 ++++-- .github/workflows/dart.yml | 42 ++++++++++++++-------- .github/workflows/label_prs.yml | 2 +- .github/workflows/publish_demos.yml | 2 +- .github/workflows/publish_release.yml | 2 +- .github/workflows/require_semver_label.yml | 4 +-- .github/workflows/tests.yml | 24 ------------- .github/workflows/triage.yml | 2 +- README.md | 4 +-- 9 files changed, 44 insertions(+), 48 deletions(-) delete mode 100644 .github/workflows/tests.yml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 39bd9ac1..ad6ef734 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -1,7 +1,13 @@ +# Dependabot configuration file. version: 2 -enable-beta-ecosystems: true + updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + - package-ecosystem: "pub" directory: "/" schedule: - interval: "weekly" \ No newline at end of file + interval: "monthly" diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index bb1838d7..151d23f4 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -1,19 +1,33 @@ -name: Dart Checks (analyze,format,publishable) +name: Dart Checks -on: [push] +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] jobs: build: - runs-on: ubuntu-latest - container: - image: dart + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + # Test with at least the declared minimum Dart version + sdk: [2.18.7, stable] steps: - - uses: actions/checkout@v1 - - name: Install dependencies - run: dart pub get - - name: Dart Analyzer - run: dart analyze - - name: Check Dart Format - run: dart format --set-exit-if-changed -o none lib test tool example integration_test && echo Dart Format 👍 || echo Files needed Dart formatting 😢 - - name: Check if Publishable - run: dart pub publish --dry-run + - uses: actions/checkout@v3 + - uses: dart-lang/setup-dart@v1 + with: + sdk: ${{ matrix.sdk }} + + - name: Install dependencies + run: dart pub get + - name: Dart Analyzer + run: dart analyze + - name: Check Dart Format + if: ${{ matrix.sdk == 'stable' }} + run: dart format --set-exit-if-changed -onone . + - name: Unit tests + run: dart test + - name: Check if Publishable + run: dart pub publish --dry-run diff --git a/.github/workflows/label_prs.yml b/.github/workflows/label_prs.yml index c631e84c..d0285052 100644 --- a/.github/workflows/label_prs.yml +++ b/.github/workflows/label_prs.yml @@ -8,7 +8,7 @@ jobs: name: Unreleased runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v3 - name: Apply unreleased label uses: actions/github-script@v6 with: diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 25a2bb12..1066357a 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -10,7 +10,7 @@ jobs: image: dart steps: - name: Checkout 🛎️ - uses: actions/checkout@v2.3.1 + uses: actions/checkout@v3 - name: Install rsync 📚 run: | diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 658e690d..bdc52863 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -7,4 +7,4 @@ on: jobs: publish: - uses: dart-lang/setup-dart/.github/workflows/publish.yml + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml index a1b0bbe8..b764baaf 100644 --- a/.github/workflows/require_semver_label.yml +++ b/.github/workflows/require_semver_label.yml @@ -6,12 +6,12 @@ jobs: label: runs-on: ubuntu-latest steps: - - uses: mheap/github-action-required-labels@v1 + - uses: mheap/github-action-required-labels@v3 with: mode: exactly count: 1 labels: "semver:patch, semver:minor, semver:major" - - uses: mheap/github-action-required-labels@v1 + - uses: mheap/github-action-required-labels@v3 with: mode: exactly count: 1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index b5a0c40d..00000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Tests -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest] - sdk: [2.18.7, stable] # Test with at least the declared minimum Dart version - steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.3 - with: - sdk: ${{ matrix.sdk }} - - name: Install dependencies - run: dart pub get - - name: Unit tests - run: dart test - # - name: Integration tests - # run: dart test integration_test diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 90dddd83..224ea1ca 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -8,7 +8,7 @@ jobs: name: Assign Rob runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v3 - name: Apply untriaged label uses: actions/github-script@v6 with: diff --git a/README.md b/README.md index fc8aa669..24be2836 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # GitHub for Dart -![](https://github.com/SpinlockLabs/github.dart/workflows/Dart%20CI/badge.svg) +[![Dart Checks](https://github.com/SpinlockLabs/github.dart/actions/workflows/dart.yml/badge.svg)](https://github.com/SpinlockLabs/github.dart/actions/workflows/dart.yml) [![Pub](https://img.shields.io/pub/v/github.svg)](https://pub.dartlang.org/packages/github) This is a library for interacting with GitHub in Dart. It works on all platforms including web, server, and Flutter. @@ -35,4 +35,4 @@ Post a question or idea: https://github.com/SpinlockLabs/github.dart/discussions ## Star History -[![Star History Chart](https://api.star-history.com/svg?repos=SpinlockLabs/github.dart&type=Date)](https://star-history.com/#SpinlockLabs/github.dart&Date) \ No newline at end of file +[![Star History Chart](https://api.star-history.com/svg?repos=SpinlockLabs/github.dart&type=Date)](https://star-history.com/#SpinlockLabs/github.dart&Date) From 0a0ab4509eb9f92d3f49745ef990448228792acf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 11:33:46 -0600 Subject: [PATCH 085/139] Bump JamesIves/github-pages-deploy-action from 4.0.0 to 4.4.1 (#359) Bumps [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) from 4.0.0 to 4.4.1. - [Release notes](https://github.com/JamesIves/github-pages-deploy-action/releases) - [Commits](https://github.com/JamesIves/github-pages-deploy-action/compare/4.0.0...v4.4.1) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish_demos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 1066357a..dec1be49 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -24,7 +24,7 @@ jobs: rm build/example/packages - name: Publish 🚀 - uses: JamesIves/github-pages-deploy-action@4.0.0 + uses: JamesIves/github-pages-deploy-action@v4.4.1 with: branch: gh-pages # The branch the action should deploy to. folder: build/example # The folder the action should deploy. From 158673874dab67d11e225f75299d1068e69725d1 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 14 Mar 2023 18:31:46 -0700 Subject: [PATCH 086/139] expose IssueLabel.description; update labels REST APIs (#355) * expose IssueLabel.description; update labels REST APIs * add a deprecated forwarding method * Update issues_service.dart --------- Co-authored-by: Rob Becker --- lib/src/common/issues_service.dart | 44 +++++++++++++++++++++++++----- lib/src/common/model/issues.dart | 3 ++ lib/src/common/model/issues.g.dart | 2 ++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index 490396fb..9d8eb4ab 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -290,19 +290,49 @@ class IssuesService extends Service { /// /// API docs: https://developer.github.com/v3/issues/labels/#create-a-label Future createLabel( - RepositorySlug slug, String name, String color) { - return github.postJSON('/repos/${slug.fullName}/labels', - body: GitHubJson.encode({'name': name, 'color': color}), - convert: IssueLabel.fromJson); + RepositorySlug slug, + String name, { + String? color, + String? description, + }) { + return github.postJSON( + '/repos/${slug.fullName}/labels', + body: GitHubJson.encode({ + 'name': name, + if (color != null) 'color': color, + if (description != null) 'description': description, + }), + convert: IssueLabel.fromJson, + ); } /// Edits a label. /// /// API docs: https://developer.github.com/v3/issues/labels/#update-a-label + @Deprecated('See updateLabel instead.') Future editLabel(RepositorySlug slug, String name, String color) { - return github.postJSON('/repos/${slug.fullName}/labels/$name', - body: GitHubJson.encode({'name': name, 'color': color}), - convert: IssueLabel.fromJson); + return updateLabel(slug, name, color: color); + } + + /// Update a label. + /// + /// API docs: https://developer.github.com/v3/issues/labels/#update-a-label + Future updateLabel( + RepositorySlug slug, + String name, { + String? newName, + String? color, + String? description, + }) { + return github.patchJSON( + '/repos/${slug.fullName}/labels/$name', + body: GitHubJson.encode({ + if (newName != null) 'new_name': newName, + if (color != null) 'color': color, + if (description != null) 'description': description, + }), + convert: IssueLabel.fromJson, + ); } /// Deletes a label. diff --git a/lib/src/common/model/issues.dart b/lib/src/common/model/issues.dart index 4534892e..6746a305 100644 --- a/lib/src/common/model/issues.dart +++ b/lib/src/common/model/issues.dart @@ -172,12 +172,15 @@ class IssueLabel { IssueLabel({ this.name = '', this.color = '', + this.description = '', }); String name; String color; + String description; + factory IssueLabel.fromJson(Map input) => _$IssueLabelFromJson(input); Map toJson() => _$IssueLabelToJson(this); diff --git a/lib/src/common/model/issues.g.dart b/lib/src/common/model/issues.g.dart index 12e03103..0a027f67 100644 --- a/lib/src/common/model/issues.g.dart +++ b/lib/src/common/model/issues.g.dart @@ -142,12 +142,14 @@ Map _$IssueCommentToJson(IssueComment instance) => IssueLabel _$IssueLabelFromJson(Map json) => IssueLabel( name: json['name'] as String? ?? '', color: json['color'] as String? ?? '', + description: json['description'] as String? ?? '', ); Map _$IssueLabelToJson(IssueLabel instance) => { 'name': instance.name, 'color': instance.color, + 'description': instance.description, }; Milestone _$MilestoneFromJson(Map json) => Milestone( From 885e5bb9dd65fabc94aaccc878a517e54402a8d9 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Mar 2023 19:36:27 -0600 Subject: [PATCH 087/139] prep 9.8.0 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index afd47919..fe8a734f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.10.1 +version: 9.8.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From ea130cefce3eed826acac83a6a56e8b662af4945 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Mar 2023 19:52:11 -0600 Subject: [PATCH 088/139] prep 9.11.0 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f36eb35..7456f7d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 9.11.0 + +* expose IssueLabel.description; update labels REST APIs by @devoncarew in https://github.com/SpinlockLabs/github.dart/pull/355 + ## 9.10.1 * Pass required User-Agent HTTP header on all requests diff --git a/pubspec.yaml b/pubspec.yaml index fe8a734f..62d162e6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.8.0 +version: 9.11.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 0d65d6032a4927d9f14a48edd3ef5733bdddf340 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Mar 2023 20:30:56 -0600 Subject: [PATCH 089/139] update label workflows --- .github/workflows/label_prs.yml | 17 +++++------------ .github/workflows/require_semver_label.yml | 10 +++++++++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/label_prs.yml b/.github/workflows/label_prs.yml index d0285052..7de111ba 100644 --- a/.github/workflows/label_prs.yml +++ b/.github/workflows/label_prs.yml @@ -5,18 +5,11 @@ on: jobs: assignUnreleased: - name: Unreleased + name: Add Unreleased Label runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Apply unreleased label - uses: actions/github-script@v6 + - uses: buildsville/add-remove-label@v2.0.0 with: - github-token: ${{secrets.MACHINE_GITHUB_API_TOKEN}} - script: | - github.rest.issues.addLabels({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - labels: ['unreleased'] - }) + token: ${{secrets.GITHUB_TOKEN}} + labels: Unreleased + type: add diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml index b764baaf..7cb0feb9 100644 --- a/.github/workflows/require_semver_label.yml +++ b/.github/workflows/require_semver_label.yml @@ -11,8 +11,16 @@ jobs: mode: exactly count: 1 labels: "semver:patch, semver:minor, semver:major" + token: ${{secrets.MACHINE_GITHUB_API_TOKEN}} + add_comment: | + Add a semantic version label + semver:patch - non-breaking bug fixes or internal changes + semver:minor - non-breaking changes (additions, deprecations) + semver:major - contains changes that may break consumers - uses: mheap/github-action-required-labels@v3 with: mode: exactly count: 1 - labels: "unreleased" \ No newline at end of file + labels: "unreleased" + token: ${{secrets.MACHINE_GITHUB_API_TOKEN}} + add_comment: The unrelease label is required to track which PRs have yet to be released. \ No newline at end of file From fc6e0881edc70c49fb1f4e1b0dd6606f9f1f19fa Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Mar 2023 20:42:06 -0600 Subject: [PATCH 090/139] tweak label workflow again --- .github/workflows/label_prs.yml | 15 --------------- .github/workflows/require_semver_label.yml | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 16 deletions(-) delete mode 100644 .github/workflows/label_prs.yml diff --git a/.github/workflows/label_prs.yml b/.github/workflows/label_prs.yml deleted file mode 100644 index 7de111ba..00000000 --- a/.github/workflows/label_prs.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Add PR labels on open -on: - pull_request: - types: [opened] - -jobs: - assignUnreleased: - name: Add Unreleased Label - runs-on: ubuntu-latest - steps: - - uses: buildsville/add-remove-label@v2.0.0 - with: - token: ${{secrets.GITHUB_TOKEN}} - labels: Unreleased - type: add diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml index 7cb0feb9..9f00798a 100644 --- a/.github/workflows/require_semver_label.yml +++ b/.github/workflows/require_semver_label.yml @@ -2,8 +2,22 @@ name: Require semver:* and unreleased Label on: pull_request: types: [opened, labeled, unlabeled, synchronize] + +jobs: + assignUnreleased: + name: Add Unreleased Label + runs-on: ubuntu-latest + if: github.event.action == 'opened' + steps: + - uses: buildsville/add-remove-label@v2.0.0 + with: + token: ${{secrets.GITHUB_TOKEN}} + labels: Unreleased + type: add + jobs: label: + needs: assignUnreleased runs-on: ubuntu-latest steps: - uses: mheap/github-action-required-labels@v3 @@ -23,4 +37,4 @@ jobs: count: 1 labels: "unreleased" token: ${{secrets.MACHINE_GITHUB_API_TOKEN}} - add_comment: The unrelease label is required to track which PRs have yet to be released. \ No newline at end of file + add_comment: The unrelease label is required to track which PRs have yet to be released. From fef45b8aafb2928bd2ca60547f5edf6302647fc6 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Mar 2023 20:45:43 -0600 Subject: [PATCH 091/139] tweak 2 --- .github/workflows/require_semver_label.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml index 9f00798a..87d919fa 100644 --- a/.github/workflows/require_semver_label.yml +++ b/.github/workflows/require_semver_label.yml @@ -4,22 +4,15 @@ on: types: [opened, labeled, unlabeled, synchronize] jobs: - assignUnreleased: - name: Add Unreleased Label + label: runs-on: ubuntu-latest - if: github.event.action == 'opened' steps: - uses: buildsville/add-remove-label@v2.0.0 + if: github.event.action == 'opened' with: token: ${{secrets.GITHUB_TOKEN}} labels: Unreleased type: add - -jobs: - label: - needs: assignUnreleased - runs-on: ubuntu-latest - steps: - uses: mheap/github-action-required-labels@v3 with: mode: exactly From 728e119046d82405bede2a918de165bafbf5a1ec Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Mar 2023 20:52:21 -0600 Subject: [PATCH 092/139] tweak 3 --- .github/workflows/require_semver_label.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml index 87d919fa..0a6c2afd 100644 --- a/.github/workflows/require_semver_label.yml +++ b/.github/workflows/require_semver_label.yml @@ -18,16 +18,12 @@ jobs: mode: exactly count: 1 labels: "semver:patch, semver:minor, semver:major" - token: ${{secrets.MACHINE_GITHUB_API_TOKEN}} - add_comment: | - Add a semantic version label - semver:patch - non-breaking bug fixes or internal changes - semver:minor - non-breaking changes (additions, deprecations) - semver:major - contains changes that may break consumers + token: ${{secrets.GITHUB_TOKEN}} + add_comment: Add a semantic version label (semver:patch semver:minor semver:major) - uses: mheap/github-action-required-labels@v3 with: mode: exactly count: 1 labels: "unreleased" - token: ${{secrets.MACHINE_GITHUB_API_TOKEN}} + token: ${{secrets.GITHUB_TOKEN}} add_comment: The unrelease label is required to track which PRs have yet to be released. From d11724e8ec14d7d592175e11e5cd5fe3025be91b Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Mar 2023 21:11:03 -0600 Subject: [PATCH 093/139] comment out required semver label for now --- .github/workflows/require_semver_label.yml | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml index 0a6c2afd..0ac40231 100644 --- a/.github/workflows/require_semver_label.yml +++ b/.github/workflows/require_semver_label.yml @@ -13,17 +13,17 @@ jobs: token: ${{secrets.GITHUB_TOKEN}} labels: Unreleased type: add - - uses: mheap/github-action-required-labels@v3 - with: - mode: exactly - count: 1 - labels: "semver:patch, semver:minor, semver:major" - token: ${{secrets.GITHUB_TOKEN}} - add_comment: Add a semantic version label (semver:patch semver:minor semver:major) - - uses: mheap/github-action-required-labels@v3 - with: - mode: exactly - count: 1 - labels: "unreleased" - token: ${{secrets.GITHUB_TOKEN}} - add_comment: The unrelease label is required to track which PRs have yet to be released. + # - uses: mheap/github-action-required-labels@v3 + # with: + # mode: exactly + # count: 1 + # labels: "semver:patch, semver:minor, semver:major" + # token: ${{secrets.GITHUB_TOKEN}} + # add_comment: Add a semantic version label (semver:patch semver:minor semver:major) + # - uses: mheap/github-action-required-labels@v3 + # with: + # mode: exactly + # count: 1 + # labels: "unreleased" + # token: ${{secrets.GITHUB_TOKEN}} + # add_comment: The unrelease label is required to track which PRs have yet to be released. From 7b4563a0a5468aecdf3e0004a714f767a9b1d596 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Wed, 15 Mar 2023 08:27:02 -0600 Subject: [PATCH 094/139] only do manual release action --- .github/workflows/release_unreleased_prs.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml index 9b33737d..97f16aa3 100644 --- a/.github/workflows/release_unreleased_prs.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -4,9 +4,12 @@ name: Release unreleased PRs # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges on: workflow_dispatch: - pull_request: - types: - - closed + + # Comment out for now and just use manual kickoff of the action + # until we can figure our permissions + # pull_request: + # types: + # - closed jobs: release: From 44cc3580172f4b8b5711c852ae1d877e8cc359bf Mon Sep 17 00:00:00 2001 From: Ricardo Amador <32242716+ricardoamador@users.noreply.github.com> Date: Tue, 21 Mar 2023 14:56:14 -0700 Subject: [PATCH 095/139] Add updated methods to get teams and team membership for a user (#362) * Add updated methods to get teams and team membership for a user. * Fix formatting * Add tests and cleanup the orgs service. * Formatting. * Update formatting. * Cleanup error codes. * Formatting. --- lib/src/common/orgs_service.dart | 244 ++++++++++++++++++++++--------- test/unit/orgs_service_test.dart | 175 ++++++++++++++++++++++ 2 files changed, 349 insertions(+), 70 deletions(-) create mode 100644 test/unit/orgs_service_test.dart diff --git a/lib/src/common/orgs_service.dart b/lib/src/common/orgs_service.dart index c0774bda..d793a8b9 100644 --- a/lib/src/common/orgs_service.dart +++ b/lib/src/common/orgs_service.dart @@ -21,8 +21,11 @@ class OrganizationsService extends Service { if (userName == null) { requestPath = '/user/orgs'; } - return PaginationHelper(github) - .objects('GET', requestPath, Organization.fromJson); + return PaginationHelper(github).objects( + 'GET', + requestPath, + Organization.fromJson, + ); } /// Fetches the organization specified by [name]. @@ -31,7 +34,7 @@ class OrganizationsService extends Service { Future get(String? name) => github.getJSON('/orgs/$name', convert: Organization.fromJson, statusCode: StatusCodes.OK, fail: (http.Response response) { - if (response.statusCode == 404) { + if (response.statusCode == StatusCodes.NOT_FOUND) { throw OrganizationNotFound(github, name); } }); @@ -47,13 +50,15 @@ class OrganizationsService extends Service { /// Edits an Organization /// /// API docs: https://developer.github.com/v3/orgs/#edit-an-organization - Future edit(String org, - {String? billingEmail, - String? company, - String? email, - String? location, - String? name, - String? description}) { + Future edit( + String org, { + String? billingEmail, + String? company, + String? email, + String? location, + String? name, + String? description, + }) { final map = createNonNullMap({ 'billing_email': billingEmail, 'company': company, @@ -64,7 +69,7 @@ class OrganizationsService extends Service { }); return github.postJSON('/orgs/$org', - statusCode: 200, + statusCode: StatusCodes.OK, convert: Organization.fromJson, body: GitHubJson.encode(map)); } @@ -73,8 +78,11 @@ class OrganizationsService extends Service { /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-teams Stream listTeams(String orgName) { - return PaginationHelper(github) - .objects('GET', '/orgs/$orgName/teams', Team.fromJson); + return PaginationHelper(github).objects( + 'GET', + '/orgs/$orgName/teams', + Team.fromJson, + ); } /// Gets the team specified by the [teamId]. @@ -82,14 +90,34 @@ class OrganizationsService extends Service { /// API docs: https://developer.github.com/v3/orgs/teams/#get-team Future getTeam(int teamId) { return github.getJSON('/teams/$teamId', - convert: Organization.fromJson, statusCode: 200) as Future; + convert: Organization.fromJson, + statusCode: StatusCodes.OK) as Future; + } + + /// Gets the team specified by its [teamName]. + /// + /// https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#get-a-team-by-name + Future getTeamByName( + String orgName, + String teamName, + ) { + return github.getJSON( + 'orgs/$orgName/teams/$teamName', + convert: Team.fromJson, + statusCode: StatusCodes.OK, + ); } /// Creates a Team. /// /// API docs: https://developer.github.com/v3/orgs/teams/#create-team - Future createTeam(String org, String name, - {String? description, List? repos, String? permission}) { + Future createTeam( + String org, + String name, { + String? description, + List? repos, + String? permission, + }) { final map = createNonNullMap({ 'name': name, 'description': description, @@ -98,14 +126,20 @@ class OrganizationsService extends Service { }); return github.postJSON('/orgs/$org/teams', - statusCode: 201, convert: Team.fromJson, body: GitHubJson.encode(map)); + statusCode: StatusCodes.CREATED, + convert: Team.fromJson, + body: GitHubJson.encode(map)); } /// Edits a Team. /// /// API docs: https://developer.github.com/v3/orgs/teams/#edit-team - Future editTeam(int teamId, String name, - {String? description, String? permission}) { + Future editTeam( + int teamId, + String name, { + String? description, + String? permission, + }) { final map = createNonNullMap({ 'name': name, 'description': description, @@ -114,7 +148,7 @@ class OrganizationsService extends Service { return github.postJSON( '/teams/$teamId', - statusCode: 200, + statusCode: StatusCodes.OK, convert: Team.fromJson, body: GitHubJson.encode(map), ); @@ -125,7 +159,7 @@ class OrganizationsService extends Service { /// API docs: https://developer.github.com/v3/orgs/teams/#delete-team Future deleteTeam(int teamId) { return github.request('DELETE', '/teams/$teamId').then((response) { - return response.statusCode == 204; + return response.statusCode == StatusCodes.NO_CONTENT; }); } @@ -133,8 +167,11 @@ class OrganizationsService extends Service { /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-team-members Stream listTeamMembers(int teamId) { - return PaginationHelper(github) - .objects('GET', '/teams/$teamId/members', TeamMember.fromJson); + return PaginationHelper(github).objects( + 'GET', + '/teams/$teamId/members', + TeamMember.fromJson, + ); } Future getTeamMemberStatus(int teamId, String user) { @@ -143,85 +180,129 @@ class OrganizationsService extends Service { }); } - /// Returns the membership status for a user in a team. + /// Returns the membership status for a [user] in a team with [teamId]. /// /// API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership - Future getTeamMembership(int teamId, String user) { - final completer = Completer(); - - github - .getJSON( - '/teams/$teamId/memberships/$user', - statusCode: 200, - fail: (http.Response response) { - if (response.statusCode == 404) { - completer.complete(TeamMembershipState(null)); - } else { - github.handleStatusCode(response); - } - }, - convert: (dynamic json) => TeamMembershipState(json['state']), - ) - .then(completer.complete); + Future getTeamMembership( + int teamId, + String user, + ) { + return github.getJSON( + '/teams/$teamId/memberships/$user', + statusCode: StatusCodes.OK, + convert: (dynamic json) => TeamMembershipState( + json['state'], + ), + ); + } - return completer.future; + /// Returns the membership status for [user] in [teamName] given the [orgName]. + /// + /// Note that this will throw on NotFound if the user is not a member of the + /// team. Adding a fail function to set the value does not help unless you + /// throw out of the fail function. + Future getTeamMembershipByName( + String orgName, + String teamName, + String user, + ) { + return github.getJSON( + '/orgs/$orgName/teams/$teamName/memberships/$user', + statusCode: StatusCodes.OK, + convert: (dynamic json) => TeamMembershipState( + json['state'], + ), + ); } /// Invites a user to the specified team. /// /// API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership - Future addTeamMembership(int teamId, String user) async { - final response = await github - .request('PUT', '/teams/$teamId/memberships/$user', statusCode: 200); + Future addTeamMembership( + int teamId, + String user, + ) async { + final response = await github.request( + 'PUT', + '/teams/$teamId/memberships/$user', + statusCode: StatusCodes.OK, + ); return TeamMembershipState(jsonDecode(response.body)['state']); } /// Removes a user from the specified team. /// /// API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership - Future removeTeamMembership(int teamId, String user) { - return github.request('DELETE', '/teams/$teamId/memberships/$user', - statusCode: 204); + Future removeTeamMembership( + int teamId, + String user, + ) { + return github.request( + 'DELETE', + '/teams/$teamId/memberships/$user', + statusCode: StatusCodes.NO_CONTENT, + ); } /// Lists the repositories that the specified team has access to. /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-team-repos Stream listTeamRepositories(int teamId) { - return PaginationHelper(github) - .objects('GET', '/teams/$teamId/repos', Repository.fromJson); + return PaginationHelper(github).objects( + 'GET', + '/teams/$teamId/repos', + Repository.fromJson, + ); } /// Checks if a team manages the specified repository. /// /// API docs: https://developer.github.com/v3/orgs/teams/#get-team-repo - Future isTeamRepository(int teamId, RepositorySlug slug) { + Future isTeamRepository( + int teamId, + RepositorySlug slug, + ) { return github - .request('GET', '/teams/$teamId/repos/${slug.fullName}') + .request( + 'GET', + '/teams/$teamId/repos/${slug.fullName}', + ) .then((response) { - return response.statusCode == 204; + return response.statusCode == StatusCodes.NO_CONTENT; }); } /// Adds a repository to be managed by the specified team. /// /// API docs: https://developer.github.com/v3/orgs/teams/#add-team-repo - Future addTeamRepository(int teamId, RepositorySlug slug) { + Future addTeamRepository( + int teamId, + RepositorySlug slug, + ) { return github - .request('PUT', '/teams/$teamId/repos/${slug.fullName}') + .request( + 'PUT', + '/teams/$teamId/repos/${slug.fullName}', + ) .then((response) { - return response.statusCode == 204; + return response.statusCode == StatusCodes.NO_CONTENT; }); } /// Removes a repository from being managed by the specified team. /// /// API docs: https://developer.github.com/v3/orgs/teams/#remove-team-repo - Future removeTeamRepository(int teamId, RepositorySlug slug) { + Future removeTeamRepository( + int teamId, + RepositorySlug slug, + ) { return github - .request('DELETE', '/teams/$teamId/repos/${slug.fullName}') + .request( + 'DELETE', + '/teams/$teamId/repos/${slug.fullName}', + ) .then((response) { - return response.statusCode == 204; + return response.statusCode == StatusCodes.NO_CONTENT; }); } @@ -229,16 +310,22 @@ class OrganizationsService extends Service { /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams Stream listUserTeams() { - return PaginationHelper(github) - .objects('GET', '/user/teams', Team.fromJson); + return PaginationHelper(github).objects( + 'GET', + '/user/teams', + Team.fromJson, + ); } /// Lists all of the users in an organization /// /// API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams Stream listUsers(String org) { - return PaginationHelper(github) - .objects('GET', '/orgs/$org/members', User.fromJson); + return PaginationHelper(github).objects( + 'GET', + '/orgs/$org/members', + User.fromJson, + ); } /// Lists the hooks for the specified organization. @@ -252,14 +339,20 @@ class OrganizationsService extends Service { /// Fetches a single hook by [id]. /// /// API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook - Future getHook(String org, int id) => + Future getHook( + String org, + int id, + ) => github.getJSON('/orgs/$org/hooks/$id', convert: (dynamic i) => Hook.fromJson(i)..repoName = org); /// Creates an organization hook based on the specified [hook]. /// /// API docs: https://developer.github.com/v3/orgs/hooks/#create-a-hook - Future createHook(String org, CreateHook hook) { + Future createHook( + String org, + CreateHook hook, + ) { return github.postJSON('/orgs/$org/hooks', convert: (Map i) => Hook.fromJson(i)..repoName = org, body: GitHubJson.encode(hook)); @@ -270,16 +363,27 @@ class OrganizationsService extends Service { /// Pings the organization hook. /// /// API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook - Future pingHook(String org, int id) { + Future pingHook( + String org, + int id, + ) { return github - .request('POST', '/orgs/$org/hooks/$id/pings') - .then((response) => response.statusCode == 204); + .request( + 'POST', + '/orgs/$org/hooks/$id/pings', + ) + .then((response) => response.statusCode == StatusCodes.NO_CONTENT); } /// Deletes the specified hook. Future deleteHook(String org, int id) { - return github.request('DELETE', '/orgs/$org/hooks/$id').then((response) { - return response.statusCode == 204; + return github + .request( + 'DELETE', + '/orgs/$org/hooks/$id', + ) + .then((response) { + return response.statusCode == StatusCodes.NO_CONTENT; }); } } diff --git a/test/unit/orgs_service_test.dart b/test/unit/orgs_service_test.dart new file mode 100644 index 00000000..04fff9e1 --- /dev/null +++ b/test/unit/orgs_service_test.dart @@ -0,0 +1,175 @@ +import 'dart:io'; + +import 'package:github/github.dart'; +import 'package:http/http.dart'; +import 'package:http/testing.dart'; +import 'package:test/test.dart'; + +void main() { + const teamResponse = ''' + { + "name": "flutter-hackers", + "id": 1753404, + "slug": "flutter-hackers", + "permission": "pull", + "members_count": 255, + "repos_count": 34, + "organization": { + "login": "flutter", + "id": 14101776, + "url": "https://api.github.com/orgs/flutter", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "name": "Flutter", + "company": null, + "blog": "https://flutter.dev", + "location": null, + "email": null, + "public_repos": 30, + "public_gists": 0, + "followers": 6642, + "following": 0, + "html_url": "https://github.com/flutter", + "created_at": "2015-09-03T00:37:37Z", + "updated_at": "2022-03-17T17:35:40Z" + } + } +'''; + + const teamNotFoundResponse = ''' + { + "message": "Not Found", + "documentation_url": "https://docs.github.com/rest/reference/teams#list-teams" + } + '''; + + const activeMemberResponse = ''' + { + "state": "active", + "role": "member", + "url": "https://api.github.com/organizations/14101776/team/1753404/memberships/ricardoamador" + } + '''; + + const pendingMemberResponse = ''' + { + "state": "pending", + "role": "member", + "url": "https://api.github.com/organizations/14101776/team/1753404/memberships/ricardoamador" + } + '''; + + group(GitHub, () { + test('getTeamByName is successful', () async { + Request? request; + + final client = MockClient((r) async { + request = r; + return Response(teamResponse, HttpStatus.ok); + }); + + final github = GitHub(client: client); + final organizationsService = OrganizationsService(github); + + final team = await organizationsService.getTeamByName( + 'flutter', 'flutter-hackers'); + expect(team.name, 'flutter-hackers'); + expect(team.id, 1753404); + expect(team.organization!.login, 'flutter'); + expect(request, isNotNull); + }); + + test('getTeamByName not found', () async { + Request? request; + + final headers = {}; + headers['content-type'] = 'application/json'; + + final client = MockClient((r) async { + request = r; + return Response(teamNotFoundResponse, HttpStatus.notFound, + headers: headers); + }); + + final github = GitHub(client: client); + final organizationsService = OrganizationsService(github); + + // ignore: omit_local_variable_types + expect( + () async => organizationsService.getTeamByName( + 'flutter', 'flutter-programmers'), + throwsException); + expect(request, isNull); + }); + + test('getTeamMembership using string name, active', () async { + Request? request; + + final client = MockClient((r) async { + request = r; + return Response(activeMemberResponse, HttpStatus.ok); + }); + + final github = GitHub(client: client); + final organizationsService = OrganizationsService(github); + + final teamMembershipState = + await organizationsService.getTeamMembershipByName( + 'flutter', + 'flutter-hackers', + 'ricardoamador', + ); + expect(teamMembershipState.isActive, isTrue); + expect(request, isNotNull); + }); + + test('getTeamMembership using string name, pending', () async { + Request? request; + + final client = MockClient((r) async { + request = r; + return Response(pendingMemberResponse, HttpStatus.ok); + }); + + final github = GitHub(client: client); + final organizationsService = OrganizationsService(github); + + final teamMembershipState = + await organizationsService.getTeamMembershipByName( + 'flutter', + 'flutter-hackers', + 'ricardoamador', + ); + expect(teamMembershipState.isActive, isFalse); + expect(teamMembershipState.isPending, isTrue); + expect(request, isNotNull); + }); + + test('getTeamMembership using string name, null', () async { + Request? request; + + final headers = {}; + headers['content-type'] = 'application/json'; + + final client = MockClient((r) async { + request = r; + return Response( + teamNotFoundResponse, + HttpStatus.notFound, + headers: headers, + ); + }); + + final github = GitHub(client: client); + final organizationsService = OrganizationsService(github); + + expect( + () async => organizationsService.getTeamMembershipByName( + 'flutter', + 'flutter-hackers', + 'garfield', + ), + throwsException); + expect(request, isNull); + }); + }); +} From 043e0edcd65e9a608ac30e5d1646baa2d512383b Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Fri, 31 Mar 2023 10:26:05 -0700 Subject: [PATCH 096/139] Avoid printing messages to the console. (#365) --- CONTRIBUTING.md | 12 ++++++++++++ lib/src/common/github.dart | 3 +-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac480095..15f2d03b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,18 @@ GitHub.dart is committed to efficiency as much as possible. If your code is not Pull Request rejections are not a bad thing. It just means you need to fix something. Perhaps it is important to define 'rejection' as it is used in this case. A rejection is when a GitHub.dart committer comments on a Pull Request with a comment like 'rejected due to incorrect formatting'. +## Tests + +To run the complete test suite you will need to install +`octokit/fixtures-server`. + +``` +npm install --global @octokit/fixtures-server +``` + +Tests can be run using `make test`, which will start up a local mock +GitHub and execute tests against it using your localhost port 3000. + ## Contacting Us - IRC: `#directcode on irc.esper.net and irc.freenode.net` diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index 0aead228..62358bd8 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -433,7 +433,6 @@ class GitHub { /// Internal method to handle status codes /// Never handleStatusCode(http.Response response) { - print(response.body); String? message = ''; List>? errors; if (response.headers['content-type']!.contains('application/json')) { @@ -450,7 +449,7 @@ class GitHub { } } } catch (ex) { - print(ex); + throw UnknownError(this, ex.toString()); } } switch (response.statusCode) { From a3081681da68383d9a5f18ef3502f47f7144e7d8 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Mon, 17 Apr 2023 07:50:18 -0700 Subject: [PATCH 097/139] Add support for Timeline events (#366) This is primarily based on the timeline API response schema (using code generated from the schema by the script in `tool/process_github_schema.dart`). Where I could find existing model classes compatible with bits of that schema I tried to re-use them, extending them as necessary. I took some liberties where the GitHub API documentation was vague, contradictory, or otherwise dubious. The comments on the new code are based on the comments in the response schema. They're not super helpful, if I'm honest. I found that some of the model classes were inconsistent in various ways and tried to clean up the code near what I touched to be more consistent. For example, I made a bunch of fields on a bunch of model classes mutable where previously they were `final`, to be more consistent with other model classes. I also moved some constructors to be above their corresponding fields to be more consistent with other code that already did that. --- CHANGELOG.md | 4 + CONTRIBUTING.md | 8 + lib/src/common.dart | 2 + lib/src/common/issues_service.dart | 11 + lib/src/common/model/issues.dart | 82 ++- lib/src/common/model/issues.g.dart | 51 ++ lib/src/common/model/orgs.dart | 173 +++-- lib/src/common/model/orgs.g.dart | 55 +- lib/src/common/model/pulls.dart | 211 +++++- lib/src/common/model/pulls.g.dart | 83 +++ lib/src/common/model/reaction.dart | 49 +- lib/src/common/model/reaction.g.dart | 28 + lib/src/common/model/repos.dart | 557 +++++++++++---- lib/src/common/model/repos.g.dart | 138 ++++ lib/src/common/model/repos_commits.dart | 39 +- lib/src/common/model/repos_commits.g.dart | 12 + lib/src/common/model/timeline.dart | 582 ++++++++++++++++ lib/src/common/model/timeline.g.dart | 671 +++++++++++++++++++ lib/src/common/model/timeline_support.dart | 562 ++++++++++++++++ lib/src/common/model/timeline_support.g.dart | 409 +++++++++++ lib/src/common/model/users.dart | 73 +- lib/src/common/model/users.g.dart | 60 ++ tool/process_github_schema.dart | 621 +++++++++++++++++ 23 files changed, 4264 insertions(+), 217 deletions(-) create mode 100644 lib/src/common/model/timeline.dart create mode 100644 lib/src/common/model/timeline.g.dart create mode 100644 lib/src/common/model/timeline_support.dart create mode 100644 lib/src/common/model/timeline_support.g.dart create mode 100644 tool/process_github_schema.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 7456f7d4..df8472a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 9.12.0 + +* Add support for issue and PR timeline events via `Issue.listTimeline`. + ## 9.11.0 * expose IssueLabel.description; update labels REST APIs by @devoncarew in https://github.com/SpinlockLabs/github.dart/pull/355 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15f2d03b..47a2036f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,14 @@ GitHub.dart is committed to efficiency as much as possible. If your code is not Pull Request rejections are not a bad thing. It just means you need to fix something. Perhaps it is important to define 'rejection' as it is used in this case. A rejection is when a GitHub.dart committer comments on a Pull Request with a comment like 'rejected due to incorrect formatting'. +## Generated code + +To regenerate the JSON logic for the models, run: + +``` +dart run build_runner build -d +``` + ## Tests To run the complete test suite you will need to install diff --git a/lib/src/common.dart b/lib/src/common.dart index f8be345c..8ec0f7ae 100644 --- a/lib/src/common.dart +++ b/lib/src/common.dart @@ -31,6 +31,8 @@ export 'package:github/src/common/model/repos_releases.dart'; export 'package:github/src/common/model/repos_stats.dart'; export 'package:github/src/common/model/repos_statuses.dart'; export 'package:github/src/common/model/search.dart'; +export 'package:github/src/common/model/timeline.dart'; +export 'package:github/src/common/model/timeline_support.dart'; export 'package:github/src/common/model/users.dart'; export 'package:github/src/common/orgs_service.dart'; export 'package:github/src/common/pulls_service.dart'; diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index 9d8eb4ab..3b5e013f 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -432,4 +432,15 @@ class IssuesService extends Service { .request('DELETE', '/repos/${slug.fullName}/milestones/$number') .then((response) => response.statusCode == StatusCodes.NO_CONTENT); } + + /// Lists all timeline events for an issue. + /// + /// API docs: https://docs.github.com/en/rest/issues/timeline?apiVersion=2022-11-28 + Stream listTimeline(RepositorySlug slug, int issueNumber) { + return PaginationHelper(github).objects( + 'GET', + '/repos/${slug.fullName}/issues/$issueNumber/timeline', + TimelineEvent.fromJson, + ); + } } diff --git a/lib/src/common/model/issues.dart b/lib/src/common/model/issues.dart index 6746a305..12b40172 100644 --- a/lib/src/common/model/issues.dart +++ b/lib/src/common/model/issues.dart @@ -1,5 +1,4 @@ import 'package:github/src/common.dart'; -import 'package:github/src/common/model/users.dart'; import 'package:json_annotation/json_annotation.dart'; part 'issues.g.dart'; @@ -26,6 +25,24 @@ class Issue { this.updatedAt, this.body = '', this.closedBy, + + // Properties from the Timeline API + this.activeLockReason, + this.authorAssociation, + this.bodyHtml, + this.bodyText, + this.commentsUrl, + this.draft, + this.eventsUrl, + this.labelsUrl, + this.locked, + this.nodeId, + this.performedViaGithubApp, + this.reactions, + this.repository, + this.repositoryUrl, + this.stateReason, + this.timelineUrl, }) { if (labels != null) { this.labels = labels; @@ -89,6 +106,46 @@ class Issue { bool get isOpen => state == 'open'; bool get isClosed => state == 'closed'; + // The following properties were added to support the Timeline API. + + String? activeLockReason; + + /// How the author is associated with the repository. + /// + /// Example: `OWNER` + String? authorAssociation; + + String? bodyHtml; + + String? bodyText; + + String? commentsUrl; + + bool? draft; + + String? eventsUrl; + + String? labelsUrl; + + bool? locked; + + String? nodeId; + + GitHubApp? performedViaGithubApp; + + ReactionRollup? reactions; + + Repository? repository; + + String? repositoryUrl; + + /// The reason for the current state + /// + /// Example: `not_planned` + String? stateReason; + + String? timelineUrl; + factory Issue.fromJson(Map input) => _$IssueFromJson(input); Map toJson() => _$IssueToJson(this); } @@ -204,6 +261,13 @@ class Milestone { this.createdAt, this.updatedAt, this.dueOn, + + // Properties from the Timeline API + this.closedAt, + this.htmlUrl, + this.labelsUrl, + this.nodeId, + this.url, }); /// Unique Identifier for Milestone @@ -241,6 +305,22 @@ class Milestone { /// The due date for this milestone DateTime? dueOn; + // The following properties were added to support the Timeline API. + + DateTime? closedAt; + + /// Example: `https://github.com/octocat/Hello-World/milestones/v1.0` + String? htmlUrl; + + /// Example: `https://api.github.com/repos/octocat/Hello-World/milestones/1/labels` + String? labelsUrl; + + /// Example: `MDk6TWlsZXN0b25lMTAwMjYwNA==` + String? nodeId; + + /// Example: `https://api.github.com/repos/octocat/Hello-World/milestones/1` + String? url; + factory Milestone.fromJson(Map input) => _$MilestoneFromJson(input); Map toJson() => _$MilestoneToJson(this); diff --git a/lib/src/common/model/issues.g.dart b/lib/src/common/model/issues.g.dart index 0a027f67..40bbfa94 100644 --- a/lib/src/common/model/issues.g.dart +++ b/lib/src/common/model/issues.g.dart @@ -47,6 +47,29 @@ Issue _$IssueFromJson(Map json) => Issue( closedBy: json['closed_by'] == null ? null : User.fromJson(json['closed_by'] as Map), + activeLockReason: json['active_lock_reason'] as String?, + authorAssociation: json['author_association'] as String?, + bodyHtml: json['body_html'] as String?, + bodyText: json['body_text'] as String?, + commentsUrl: json['comments_url'] as String?, + draft: json['draft'] as bool?, + eventsUrl: json['events_url'] as String?, + labelsUrl: json['labels_url'] as String?, + locked: json['locked'] as bool?, + nodeId: json['node_id'] as String?, + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + reactions: json['reactions'] == null + ? null + : ReactionRollup.fromJson(json['reactions'] as Map), + repository: json['repository'] == null + ? null + : Repository.fromJson(json['repository'] as Map), + repositoryUrl: json['repository_url'] as String?, + stateReason: json['state_reason'] as String?, + timelineUrl: json['timeline_url'] as String?, ); Map _$IssueToJson(Issue instance) => { @@ -68,6 +91,22 @@ Map _$IssueToJson(Issue instance) => { 'updated_at': instance.updatedAt?.toIso8601String(), 'body': instance.body, 'closed_by': instance.closedBy, + 'active_lock_reason': instance.activeLockReason, + 'author_association': instance.authorAssociation, + 'body_html': instance.bodyHtml, + 'body_text': instance.bodyText, + 'comments_url': instance.commentsUrl, + 'draft': instance.draft, + 'events_url': instance.eventsUrl, + 'labels_url': instance.labelsUrl, + 'locked': instance.locked, + 'node_id': instance.nodeId, + 'performed_via_github_app': instance.performedViaGithubApp, + 'reactions': instance.reactions, + 'repository': instance.repository, + 'repository_url': instance.repositoryUrl, + 'state_reason': instance.stateReason, + 'timeline_url': instance.timelineUrl, }; IssueRequest _$IssueRequestFromJson(Map json) => IssueRequest( @@ -172,6 +211,13 @@ Milestone _$MilestoneFromJson(Map json) => Milestone( dueOn: json['due_on'] == null ? null : DateTime.parse(json['due_on'] as String), + closedAt: json['closed_at'] == null + ? null + : DateTime.parse(json['closed_at'] as String), + htmlUrl: json['html_url'] as String?, + labelsUrl: json['labels_url'] as String?, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, ); Map _$MilestoneToJson(Milestone instance) => { @@ -186,6 +232,11 @@ Map _$MilestoneToJson(Milestone instance) => { 'created_at': instance.createdAt?.toIso8601String(), 'updated_at': instance.updatedAt?.toIso8601String(), 'due_on': instance.dueOn?.toIso8601String(), + 'closed_at': instance.closedAt?.toIso8601String(), + 'html_url': instance.htmlUrl, + 'labels_url': instance.labelsUrl, + 'node_id': instance.nodeId, + 'url': instance.url, }; CreateMilestone _$CreateMilestoneFromJson(Map json) => diff --git a/lib/src/common/model/orgs.dart b/lib/src/common/model/orgs.dart index 21f7b417..5a26bb2c 100644 --- a/lib/src/common/model/orgs.dart +++ b/lib/src/common/model/orgs.dart @@ -24,57 +24,57 @@ class Organization { }); /// Organization Login - final String? login; + String? login; /// Organization ID - final int? id; + int? id; /// Url to Organization Profile @JsonKey(name: 'html_url') - final String? htmlUrl; + String? htmlUrl; /// Url to the Organization Avatar @JsonKey(name: 'avatar_url') - final String? avatarUrl; + String? avatarUrl; /// Organization Name - final String? name; + String? name; /// Organization Company - final String? company; + String? company; /// Organization Blog - final String? blog; + String? blog; /// Organization Location - final String? location; + String? location; /// Organization Email - final String? email; + String? email; /// Number of Public Repositories @JsonKey(name: 'public_repos') - final int? publicReposCount; + int? publicReposCount; /// Number of Public Gists @JsonKey(name: 'public_gists') - final int? publicGistsCount; + int? publicGistsCount; /// Number of Followers @JsonKey(name: 'followers') - final int? followersCount; + int? followersCount; /// Number of People this Organization is Following @JsonKey(name: 'following') - final int? followingCount; + int? followingCount; /// Time this organization was created @JsonKey(name: 'created_at') - final DateTime? createdAt; + DateTime? createdAt; /// Time this organization was updated @JsonKey(name: 'updated_at') - final DateTime? updatedAt; + DateTime? updatedAt; factory Organization.fromJson(Map input) => _$OrganizationFromJson(input); @@ -88,8 +88,9 @@ class OrganizationMembership { this.state, this.organization, }); - final String? state; - final Organization? organization; + + String? state; + Organization? organization; factory OrganizationMembership.fromJson(Map input) { return _$OrganizationMembershipFromJson(input); @@ -98,49 +99,139 @@ class OrganizationMembership { } /// Model class for a GitHub team. +/// +/// Different end-points populate different sets of properties. +/// +/// Groups of organization members that gives permissions on specified repositories. @JsonSerializable() class Team { Team({ - this.name, + this.description, + this.htmlUrl, this.id, - this.permission, + this.ldapDn, this.membersCount, - this.reposCount, + this.membersUrl, + this.name, + this.nodeId, this.organization, + this.parent, + this.permission, + this.permissions, + this.privacy, + this.reposCount, + this.repositoriesUrl, + this.slug, + this.url, }); - /// Team Name - final String? name; + /// Description of the team + /// + /// Example: `A great team.` + String? description; - /// Team ID - final int? id; + /// Format: uri + /// + /// Example: `https://github.com/orgs/rails/teams/core` + String? htmlUrl; - /// Team Permission - final String? permission; + /// Unique identifier of the team + /// + /// Example: `1` + int? id; + + /// Distinguished Name (DN) that team maps to within LDAP environment + /// + /// Example: `uid=example,ou=users,dc=github,dc=com` + String? ldapDn; /// Number of Members @JsonKey(name: 'members_count') - final int? membersCount; + int? membersCount; + + /// Example: `https://api.github.com/organizations/1/team/1/members{/member}` + String? membersUrl; + + /// Name of the team + /// + /// Example: `Justice League` + String? name; + + /// Example: `MDQ6VGVhbTE=` + String? nodeId; + + /// Organization + Organization? organization; + + /// Team Simple + /// + /// Groups of organization members that gives permissions on specified repositories. + Team? parent; + + /// Permission that the team will have for its repositories + /// + /// Example: `admin` + String? permission; + + Permissions? permissions; + + /// The level of privacy this team should have + /// + /// Example: `closed` + String? privacy; /// Number of Repositories @JsonKey(name: 'repos_count') - final int? reposCount; + int? reposCount; - /// Organization - final Organization? organization; + /// Format: uri + /// + /// Example: `https://api.github.com/organizations/1/team/1/repos` + String? repositoriesUrl; + + /// Example: `justice-league` + String? slug; + + /// URL for the team + /// + /// Format: uri + /// + /// Example: `https://api.github.com/organizations/1/team/1` + String? url; - factory Team.fromJson(Map input) { - return _$TeamFromJson(input); - } Map toJson() => _$TeamToJson(this); + + factory Team.fromJson(Map input) => _$TeamFromJson(input); +} + +@JsonSerializable() +class Permissions { + Permissions({ + this.admin, + this.maintain, + this.pull, + this.push, + this.triage, + }); + + bool? admin; + bool? maintain; + bool? pull; + bool? push; + bool? triage; + + Map toJson() => _$PermissionsToJson(this); + + factory Permissions.fromJson(Map input) => + _$PermissionsFromJson(input); } /// Model class for the team membership state. class TeamMembershipState { - final String? name; - TeamMembershipState(this.name); + String? name; + bool get isPending => name == 'pending'; bool get isActive => name == 'active'; bool get isInactive => name == null; @@ -158,25 +249,25 @@ class TeamMember { this.htmlUrl}); /// Member Username - final String? login; + String? login; /// Member ID - final int? id; + int? id; /// Url to Member Avatar @JsonKey(name: 'avatar_url') - final String? avatarUrl; + String? avatarUrl; /// Member Type - final String? type; + String? type; /// If the member is a site administrator @JsonKey(name: 'site_admin') - final bool? siteAdmin; + bool? siteAdmin; /// Profile of the Member @JsonKey(name: 'html_url') - final String? htmlUrl; + String? htmlUrl; factory TeamMember.fromJson(Map input) { return _$TeamMemberFromJson(input); diff --git a/lib/src/common/model/orgs.g.dart b/lib/src/common/model/orgs.g.dart index 0e19f2cf..c32f6702 100644 --- a/lib/src/common/model/orgs.g.dart +++ b/lib/src/common/model/orgs.g.dart @@ -64,23 +64,66 @@ Map _$OrganizationMembershipToJson( }; Team _$TeamFromJson(Map json) => Team( - name: json['name'] as String?, + description: json['description'] as String?, + htmlUrl: json['html_url'] as String?, id: json['id'] as int?, - permission: json['permission'] as String?, + ldapDn: json['ldap_dn'] as String?, membersCount: json['members_count'] as int?, - reposCount: json['repos_count'] as int?, + membersUrl: json['members_url'] as String?, + name: json['name'] as String?, + nodeId: json['node_id'] as String?, organization: json['organization'] == null ? null : Organization.fromJson(json['organization'] as Map), + parent: json['parent'] == null + ? null + : Team.fromJson(json['parent'] as Map), + permission: json['permission'] as String?, + permissions: json['permissions'] == null + ? null + : Permissions.fromJson(json['permissions'] as Map), + privacy: json['privacy'] as String?, + reposCount: json['repos_count'] as int?, + repositoriesUrl: json['repositories_url'] as String?, + slug: json['slug'] as String?, + url: json['url'] as String?, ); Map _$TeamToJson(Team instance) => { - 'name': instance.name, + 'description': instance.description, + 'html_url': instance.htmlUrl, 'id': instance.id, - 'permission': instance.permission, + 'ldap_dn': instance.ldapDn, 'members_count': instance.membersCount, - 'repos_count': instance.reposCount, + 'members_url': instance.membersUrl, + 'name': instance.name, + 'node_id': instance.nodeId, 'organization': instance.organization, + 'parent': instance.parent, + 'permission': instance.permission, + 'permissions': instance.permissions, + 'privacy': instance.privacy, + 'repos_count': instance.reposCount, + 'repositories_url': instance.repositoriesUrl, + 'slug': instance.slug, + 'url': instance.url, + }; + +Permissions _$PermissionsFromJson(Map json) => Permissions( + admin: json['admin'] as bool?, + maintain: json['maintain'] as bool?, + pull: json['pull'] as bool?, + push: json['push'] as bool?, + triage: json['triage'] as bool?, + ); + +Map _$PermissionsToJson(Permissions instance) => + { + 'admin': instance.admin, + 'maintain': instance.maintain, + 'pull': instance.pull, + 'push': instance.push, + 'triage': instance.triage, }; TeamMember _$TeamMemberFromJson(Map json) => TeamMember( diff --git a/lib/src/common/model/pulls.dart b/lib/src/common/model/pulls.dart index fd6e8d70..b6f20e55 100644 --- a/lib/src/common/model/pulls.dart +++ b/lib/src/common/model/pulls.dart @@ -90,6 +90,7 @@ class PullRequest { /// Whether or not the pull request is a draft bool? draft; + String? mergeCommitSha; /// If the pull request was merged @@ -157,6 +158,7 @@ class PullRequestMerge { this.sha, this.message, }); + bool? merged; String? sha; String? message; @@ -194,16 +196,16 @@ class CreatePullRequest { CreatePullRequest(this.title, this.head, this.base, {this.draft = false, this.body}); - final String? title; - final String? head; - final String? base; + String? title; + String? head; + String? base; /// Whether a draft PR should be created. /// /// This is currently experimental functionality since the way draft PRs are /// created through Github's REST API is in developer preview only - and could change at any time. @experimental - final bool? draft; + bool? draft; String? body; @@ -231,6 +233,7 @@ class PullRequestComment { this.pullRequestUrl, this.links, }); + int? id; String? diffHunk; String? path; @@ -280,6 +283,7 @@ class PullRequestFile { this.contentsUrl, this.patch, }); + String? sha; String? filename; String? status; @@ -308,6 +312,7 @@ class PullRequestReview { this.state, this.htmlUrl, this.pullRequestUrl}); + int id; User user; String? body; @@ -326,17 +331,209 @@ class PullRequestReview { @JsonSerializable() class CreatePullRequestReview { CreatePullRequestReview(this.owner, this.repo, this.pullNumber, this.event, - {this.body}); + {this.body, this.comments}); String owner; String repo; String event; String? body; int pullNumber; - // TODO List comments; + List? comments; factory CreatePullRequestReview.fromJson(Map input) => _$CreatePullRequestReviewFromJson(input); Map toJson() => _$CreatePullRequestReviewToJson(this); } -// TODO PullRequestReviewComment https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request + +/// Pull Request Review Comment +/// +/// Pull Request Review Comments are comments on a portion of the Pull Request's +/// diff. +@JsonSerializable() +class PullRequestReviewComment { + PullRequestReviewComment({ + this.authorAssociation, + this.body, + this.bodyHtml, + this.bodyText, + this.commitId, + this.createdAt, + this.diffHunk, + this.htmlUrl, + this.id, + this.inReplyToId, + this.line, + this.links, + this.nodeId, + this.originalCommitId, + this.originalLine, + this.originalPosition, + this.originalStartLine, + this.path, + this.position, + this.pullRequestReviewId, + this.pullRequestUrl, + this.reactions, + this.side, + this.startLine, + this.startSide, + this.subjectType, + this.updatedAt, + this.url, + this.user, + }); + + /// How the author is associated with the repository. + /// + /// Example: `OWNER` + String? authorAssociation; + + /// The text of the comment. + /// + /// Example: `We should probably include a check for null values here.` + String? body; + + /// Example: `"

comment body

"` + String? bodyHtml; + + /// Example: `"comment body"` + String? bodyText; + + /// The SHA of the commit to which the comment applies. + /// + /// Example: `6dcb09b5b57875f334f61aebed695e2e4193db5e` + String? commitId; + + DateTime? createdAt; + + /// The diff of the line that the comment refers to. + /// + /// Example: `@@ -16,33 +16,40 @@ public class Connection : IConnection...` + String? diffHunk; + + /// HTML URL for the pull request review comment. + /// + /// Example: `https://github.com/octocat/Hello-World/pull/1#discussion-diff-1` + String? htmlUrl; + + /// The ID of the pull request review comment. + int? id; + + /// The comment ID to reply to. + int? inReplyToId; + + /// The line of the blob to which the comment applies. The last line of the range + /// for a multi-line comment + int? line; + + @JsonKey(name: '_links') + ReviewLinks? links; + + /// The node ID of the pull request review comment. + /// + /// Example: `MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDEw` + String? nodeId; + + /// The SHA of the original commit to which the comment applies. + /// + /// Example: `9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840` + String? originalCommitId; + + /// The line of the blob to which the comment applies. The last line of the range + /// for a multi-line comment + int? originalLine; + + /// The index of the original line in the diff to which the comment applies. This + /// field is deprecated; use `original_line` instead. + int? originalPosition; + + /// The first line of the range for a multi-line comment. + int? originalStartLine; + + /// The relative path of the file to which the comment applies. + /// + /// Example: `config/database.yaml` + String? path; + + /// The line index in the diff to which the comment applies. This field is deprecated; + /// use `line` instead. + int? position; + + /// The ID of the pull request review to which the comment belongs. + int? pullRequestReviewId; + + /// URL for the pull request that the review comment belongs to. + /// + /// Example: `https://api.github.com/repos/octocat/Hello-World/pulls/1` + String? pullRequestUrl; + + /// Reaction Rollup + ReactionRollup? reactions; + + /// The side of the diff to which the comment applies. The side of the last line + /// of the range for a multi-line comment + String? side; + + /// The first line of the range for a multi-line comment. + int? startLine; + + /// The side of the first line of the range for a multi-line comment. + String? startSide; + + /// The level at which the comment is targeted, can be a diff line or a file. + String? subjectType; + + DateTime? updatedAt; + + /// URL for the pull request review comment + /// + /// Example: `https://api.github.com/repos/octocat/Hello-World/pulls/comments/1` + String? url; + + User? user; + + Map toJson() => _$PullRequestReviewCommentToJson(this); + + factory PullRequestReviewComment.fromJson(Map input) => + _$PullRequestReviewCommentFromJson(input); +} + +/// This is similar to [Links] but represents a different serialization +/// in the GitHub API. +/// +/// It is used for [PullRequestReviewComment.links] and +/// [ReviewEvent.links]. +class ReviewLinks { + ReviewLinks({ + this.html, + this.pullRequest, + this.self, + }); + + Uri? html; + Uri? pullRequest; + Uri? self; + + Map toJson() { + return { + 'html': {'href': html?.toString()}, + 'pullRequest': {'href': pullRequest?.toString()}, + 'self': {'href': self?.toString()}, + }; + } + + static Uri? _parseBlock(Map input, String key) { + if (input[key] is Map && input[key]['href'] is String) { + return Uri.parse(input[key]['href']! as String); + } + return null; + } + + factory ReviewLinks.fromJson(Map input) { + return ReviewLinks( + html: _parseBlock(input, 'html'), + pullRequest: _parseBlock(input, 'pull_request'), + self: _parseBlock(input, 'self'), + ); + } +} diff --git a/lib/src/common/model/pulls.g.dart b/lib/src/common/model/pulls.g.dart index 62d2bba6..3608260c 100644 --- a/lib/src/common/model/pulls.g.dart +++ b/lib/src/common/model/pulls.g.dart @@ -284,6 +284,10 @@ CreatePullRequestReview _$CreatePullRequestReviewFromJson( json['pull_number'] as int, json['event'] as String, body: json['body'] as String?, + comments: (json['comments'] as List?) + ?.map((e) => + PullRequestReviewComment.fromJson(e as Map)) + .toList(), ); Map _$CreatePullRequestReviewToJson( @@ -294,4 +298,83 @@ Map _$CreatePullRequestReviewToJson( 'event': instance.event, 'body': instance.body, 'pull_number': instance.pullNumber, + 'comments': instance.comments, + }; + +PullRequestReviewComment _$PullRequestReviewCommentFromJson( + Map json) => + PullRequestReviewComment( + authorAssociation: json['author_association'] as String?, + body: json['body'] as String?, + bodyHtml: json['body_html'] as String?, + bodyText: json['body_text'] as String?, + commitId: json['commit_id'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + diffHunk: json['diff_hunk'] as String?, + htmlUrl: json['html_url'] as String?, + id: json['id'] as int?, + inReplyToId: json['in_reply_to_id'] as int?, + line: json['line'] as int?, + links: json['_links'] == null + ? null + : ReviewLinks.fromJson(json['_links'] as Map), + nodeId: json['node_id'] as String?, + originalCommitId: json['original_commit_id'] as String?, + originalLine: json['original_line'] as int?, + originalPosition: json['original_position'] as int?, + originalStartLine: json['original_start_line'] as int?, + path: json['path'] as String?, + position: json['position'] as int?, + pullRequestReviewId: json['pull_request_review_id'] as int?, + pullRequestUrl: json['pull_request_url'] as String?, + reactions: json['reactions'] == null + ? null + : ReactionRollup.fromJson(json['reactions'] as Map), + side: json['side'] as String?, + startLine: json['start_line'] as int?, + startSide: json['start_side'] as String?, + subjectType: json['subject_type'] as String?, + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), + url: json['url'] as String?, + user: json['user'] == null + ? null + : User.fromJson(json['user'] as Map), + ); + +Map _$PullRequestReviewCommentToJson( + PullRequestReviewComment instance) => + { + 'author_association': instance.authorAssociation, + 'body': instance.body, + 'body_html': instance.bodyHtml, + 'body_text': instance.bodyText, + 'commit_id': instance.commitId, + 'created_at': instance.createdAt?.toIso8601String(), + 'diff_hunk': instance.diffHunk, + 'html_url': instance.htmlUrl, + 'id': instance.id, + 'in_reply_to_id': instance.inReplyToId, + 'line': instance.line, + '_links': instance.links, + 'node_id': instance.nodeId, + 'original_commit_id': instance.originalCommitId, + 'original_line': instance.originalLine, + 'original_position': instance.originalPosition, + 'original_start_line': instance.originalStartLine, + 'path': instance.path, + 'position': instance.position, + 'pull_request_review_id': instance.pullRequestReviewId, + 'pull_request_url': instance.pullRequestUrl, + 'reactions': instance.reactions, + 'side': instance.side, + 'start_line': instance.startLine, + 'start_side': instance.startSide, + 'subject_type': instance.subjectType, + 'updated_at': instance.updatedAt?.toIso8601String(), + 'url': instance.url, + 'user': instance.user, }; diff --git a/lib/src/common/model/reaction.dart b/lib/src/common/model/reaction.dart index 00b8e4ac..a9b73d7f 100644 --- a/lib/src/common/model/reaction.dart +++ b/lib/src/common/model/reaction.dart @@ -10,12 +10,6 @@ part 'reaction.g.dart'; /// See https://developer.github.com/v3/reactions/ @JsonSerializable() class Reaction { - final int? id; - final String? nodeId; - final User? user; - final String? content; - final DateTime? createdAt; - Reaction({ this.id, this.nodeId, @@ -24,6 +18,12 @@ class Reaction { this.createdAt, }); + int? id; + String? nodeId; + User? user; + String? content; + DateTime? createdAt; + ReactionType? get type => ReactionType.fromString(content); factory Reaction.fromJson(Map json) => @@ -34,9 +34,10 @@ class Reaction { @immutable class ReactionType { + const ReactionType._(this.content, this.emoji); + final String content; final String emoji; - const ReactionType._(this.content, this.emoji); @override String toString() => content; @@ -71,3 +72,37 @@ class ReactionType { static ReactionType? fromString(String? content) => _types[content!]; } + +@JsonSerializable() +class ReactionRollup { + ReactionRollup({ + this.plusOne, + this.minusOne, + this.confused, + this.eyes, + this.heart, + this.hooray, + this.laugh, + this.rocket, + this.totalCount, + this.url, + }); + + @JsonKey(name: '+1') + int? plusOne; + @JsonKey(name: '-1') + int? minusOne; + int? confused; + int? eyes; + int? heart; + int? hooray; + int? laugh; + int? rocket; + int? totalCount; + String? url; + + Map toJson() => _$ReactionRollupToJson(this); + + factory ReactionRollup.fromJson(Map input) => + _$ReactionRollupFromJson(input); +} diff --git a/lib/src/common/model/reaction.g.dart b/lib/src/common/model/reaction.g.dart index dc2ff705..d94eede4 100644 --- a/lib/src/common/model/reaction.g.dart +++ b/lib/src/common/model/reaction.g.dart @@ -25,3 +25,31 @@ Map _$ReactionToJson(Reaction instance) => { 'content': instance.content, 'created_at': instance.createdAt?.toIso8601String(), }; + +ReactionRollup _$ReactionRollupFromJson(Map json) => + ReactionRollup( + plusOne: json['+1'] as int?, + minusOne: json['-1'] as int?, + confused: json['confused'] as int?, + eyes: json['eyes'] as int?, + heart: json['heart'] as int?, + hooray: json['hooray'] as int?, + laugh: json['laugh'] as int?, + rocket: json['rocket'] as int?, + totalCount: json['total_count'] as int?, + url: json['url'] as String?, + ); + +Map _$ReactionRollupToJson(ReactionRollup instance) => + { + '+1': instance.plusOne, + '-1': instance.minusOne, + 'confused': instance.confused, + 'eyes': instance.eyes, + 'heart': instance.heart, + 'hooray': instance.hooray, + 'laugh': instance.laugh, + 'rocket': instance.rocket, + 'total_count': instance.totalCount, + 'url': instance.url, + }; diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index 3612aa34..d09c1a7e 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -5,17 +5,17 @@ part 'repos.g.dart'; @JsonSerializable() class GitHubComparison { - final String? url; - final String? status; - final int? aheadBy; - final int? behindBy; - final int? totalCommits; - final List? files; - final List? commits; - GitHubComparison(this.url, this.status, this.aheadBy, this.behindBy, this.totalCommits, this.files, this.commits); + String? url; + String? status; + int? aheadBy; + int? behindBy; + int? totalCommits; + List? files; + List? commits; + factory GitHubComparison.fromJson(Map json) => _$GitHubComparisonFromJson(json); Map toJson() => _$GitHubComparisonToJson(this); @@ -40,135 +40,416 @@ class GitHubComparison { /// Model class for a repository. @JsonSerializable() class Repository { - Repository( - {this.name = '', - this.id = 0, - this.fullName = '', - this.owner, - this.htmlUrl = '', - this.description = '', - this.cloneUrl = '', - this.gitUrl = '', - this.sshUrl = '', - this.svnUrl = '', - this.defaultBranch = '', - this.createdAt, - this.isPrivate = false, - this.isFork = false, - this.stargazersCount = 0, - this.watchersCount = 0, - this.language = '', - this.hasWiki = false, - this.hasDownloads = false, - this.forksCount = 0, - this.openIssuesCount = 0, - this.subscribersCount = 0, - this.networkCount = 0, - this.hasIssues = false, - this.size = 0, - this.archived = false, - this.disabled = false, - this.homepage = '', - this.updatedAt, - this.pushedAt, - this.license, - this.hasPages = false, - this.permissions}); + Repository({ + this.name = '', + this.id = 0, + this.fullName = '', + this.owner, + this.htmlUrl = '', + this.description = '', + this.cloneUrl = '', + this.gitUrl = '', + this.sshUrl = '', + this.svnUrl = '', + this.defaultBranch = '', + this.createdAt, + this.isPrivate = false, + this.isFork = false, + this.stargazersCount = 0, + this.watchersCount = 0, + this.language = '', + this.hasWiki = false, + this.hasDownloads = false, + this.forksCount = 0, + this.openIssuesCount = 0, + this.subscribersCount = 0, + this.networkCount = 0, + this.hasIssues = false, + this.size = 0, + this.archived = false, + this.disabled = false, + this.homepage = '', + this.updatedAt, + this.pushedAt, + this.license, + this.hasPages = false, + this.permissions, + + // Properties from the Timeline API + this.allowAutoMerge, + this.allowForking, + this.allowMergeCommit, + this.allowRebaseMerge, + this.allowSquashMerge, + this.allowUpdateBranch, + this.anonymousAccessEnabled, + this.archiveUrl, + this.assigneesUrl, + this.blobsUrl, + this.branchesUrl, + this.collaboratorsUrl, + this.commentsUrl, + this.commitsUrl, + this.compareUrl, + this.contentsUrl, + this.contributorsUrl, + this.deleteBranchOnMerge, + this.deploymentsUrl, + this.downloadsUrl, + this.eventsUrl, + this.forks, + this.forksUrl, + this.gitCommitsUrl, + this.gitRefsUrl, + this.gitTagsUrl, + this.hasDiscussions, + this.hasProjects, + this.hooksUrl, + this.isTemplate, + this.issueCommentUrl, + this.issueEventsUrl, + this.issuesUrl, + this.keysUrl, + this.labelsUrl, + this.languagesUrl, + this.masterBranch, + this.mergeCommitMessage, + this.mergeCommitTitle, + this.mergesUrl, + this.milestonesUrl, + this.mirrorUrl, + this.nodeId, + this.notificationsUrl, + this.openIssues, + this.organization, + this.pullsUrl, + this.releasesUrl, + this.squashMergeCommitMessage, + this.squashMergeCommitTitle, + this.stargazersUrl, + this.starredAt, + this.statusesUrl, + this.subscribersUrl, + this.subscriptionUrl, + this.tagsUrl, + this.teamsUrl, + this.tempCloneToken, + this.templateRepository, + this.topics, + this.treesUrl, + this.url, + this.visibility, + this.watchers, + this.webCommitSignoffRequired, + }); /// Repository Name - final String name; + String name; /// Repository ID - final int id; + int id; /// Full Repository Name - final String fullName; + String fullName; /// Repository Owner @JsonKey(defaultValue: null) - final UserInformation? owner; + UserInformation? owner; /// If the Repository is Private @JsonKey(name: 'private') - final bool isPrivate; + bool isPrivate; /// If the Repository is a fork @JsonKey(name: 'fork') - final bool isFork; + bool isFork; /// Url to the GitHub Repository Page - final String htmlUrl; + String htmlUrl; /// Repository Description - final String description; + String description; // https clone URL - final String cloneUrl; + String cloneUrl; - final String sshUrl; + String sshUrl; - final String svnUrl; + String svnUrl; - final String gitUrl; + String gitUrl; /// Url to the Repository Homepage - final String homepage; + String homepage; /// Repository Size - final int size; + // + /// The size of the repository. Size is calculated hourly. When a repository is + /// initially created, the size is 0. + int size; /// Repository Stars - final int stargazersCount; + int stargazersCount; /// Repository Watchers - final int watchersCount; + int watchersCount; /// Repository Language - final String language; + String language; /// If the Repository has Issues Enabled - final bool hasIssues; + bool hasIssues; /// If the Repository has the Wiki Enabled - final bool hasWiki; + bool hasWiki; /// If the Repository has any Downloads - final bool hasDownloads; + bool hasDownloads; /// If the Repository has any Github Pages - final bool hasPages; + bool hasPages; /// Number of Forks - final int forksCount; + int forksCount; /// Number of Open Issues - final int openIssuesCount; + int openIssuesCount; /// Repository Default Branch - final String defaultBranch; + String defaultBranch; /// Number of Subscribers - final int subscribersCount; + int subscribersCount; /// Number of users in the network - final int networkCount; + int networkCount; /// The time the repository was created at - final DateTime? createdAt; + DateTime? createdAt; /// The last time the repository was pushed at - final DateTime? pushedAt; + DateTime? pushedAt; - final DateTime? updatedAt; + DateTime? updatedAt; - final LicenseKind? license; + LicenseKind? license; - final bool archived; + bool archived; - final bool disabled; + bool disabled; RepositoryPermissions? permissions; + // The following properties were added to support the Timeline API. + + /// Whether to allow Auto-merge to be used on pull requests. + bool? allowAutoMerge; + + /// Whether to allow forking this repo + bool? allowForking; + + /// Whether to allow merge commits for pull requests. + bool? allowMergeCommit; + + /// Whether to allow rebase merges for pull requests. + bool? allowRebaseMerge; + + /// Whether to allow squash merges for pull requests. + bool? allowSquashMerge; + + /// Whether or not a pull request head branch that is behind its base branch can + /// always be updated even if it is not required to be up to date before merging. + bool? allowUpdateBranch; + + /// Whether anonymous git access is enabled for this repository + bool? anonymousAccessEnabled; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}` + String? archiveUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/assignees{/user}` + String? assigneesUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}` + String? blobsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/branches{/branch}` + String? branchesUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}` + String? collaboratorsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/comments{/number}` + String? commentsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/commits{/sha}` + String? commitsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}` + String? compareUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/contents/{+path}` + String? contentsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/contributors` + String? contributorsUrl; + + /// Whether to delete head branches when pull requests are merged + bool? deleteBranchOnMerge; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/deployments` + String? deploymentsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/downloads` + String? downloadsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/events` + String? eventsUrl; + + int? forks; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/forks` + String? forksUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}` + String? gitCommitsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}` + String? gitRefsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}` + String? gitTagsUrl; + + /// Whether discussions are enabled. + bool? hasDiscussions; + + /// Whether projects are enabled. + bool? hasProjects; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/hooks` + String? hooksUrl; + + /// Whether this repository acts as a template that can be used to generate new + /// repositories. + bool? isTemplate; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}` + String? issueCommentUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/issues/events{/number}` + String? issueEventsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/issues{/number}` + String? issuesUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/keys{/key_id}` + String? keysUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/labels{/name}` + String? labelsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/languages` + String? languagesUrl; + + String? masterBranch; + + /// The default value for a merge commit message. + /// + /// - `PR_TITLE` - default to the pull request's title. + /// - `PR_BODY` - default to the pull request's body. + /// - `BLANK` - default to a blank commit message. + String? mergeCommitMessage; + + /// The default value for a merge commit title. + /// + /// - `PR_TITLE` - default to the pull request's title. + /// - `MERGE_MESSAGE` - default to the classic title for a merge message (e.g., + /// Merge pull request #123 from branch-name). + String? mergeCommitTitle; + + /// Format: uri + /// + /// Example: `http://api.github.com/repos/octocat/Hello-World/merges` + String? mergesUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/milestones{/number}` + String? milestonesUrl; + + /// Format: uri + /// + /// Example: `git:git.example.com/octocat/Hello-World` + String? mirrorUrl; + + /// Example: `MDEwOlJlcG9zaXRvcnkxMjk2MjY5` + String? nodeId; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}` + String? notificationsUrl; + + int? openIssues; + + User? organization; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/pulls{/number}` + String? pullsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/releases{/id}` + String? releasesUrl; + + /// The default value for a squash merge commit message: + /// + /// - `PR_BODY` - default to the pull request's body. + /// - `COMMIT_MESSAGES` - default to the branch's commit messages. + /// - `BLANK` - default to a blank commit message. + String? squashMergeCommitMessage; + + /// The default value for a squash merge commit title: + /// + /// - `PR_TITLE` - default to the pull request's title. + /// - `COMMIT_OR_PR_TITLE` - default to the commit's title (if only one commit) + /// or the pull request's title (when more than one commit). + String? squashMergeCommitTitle; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/stargazers` + String? stargazersUrl; + + DateTime? starredAt; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/statuses/{sha}` + String? statusesUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/subscribers` + String? subscribersUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/subscription` + String? subscriptionUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/tags` + String? tagsUrl; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/teams` + String? teamsUrl; + + String? tempCloneToken; + + TemplateRepository? templateRepository; + + List? topics; + + /// Example: `http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}` + String? treesUrl; + + /// Example: `https://api.github.com/repos/octocat/Hello-World` + String? url; + + /// The repository visibility: public, private, or internal. + String? visibility; + + int? watchers; + + /// Whether to require contributors to sign off on web-based commits + bool? webCommitSignoffRequired; + factory Repository.fromJson(Map input) => _$RepositoryFromJson(input); Map toJson() => _$RepositoryToJson(this); @@ -187,13 +468,13 @@ class RepositoryPermissions { {this.admin = false, this.push = false, this.pull = false}); /// Administrative Access - final bool admin; + bool admin; /// Push Access - final bool push; + bool push; /// Pull Access - final bool pull; + bool pull; factory RepositoryPermissions.fromJson(Map json) => _$RepositoryPermissionsFromJson(json); @@ -203,14 +484,14 @@ class RepositoryPermissions { @JsonSerializable() class Tag { - final String name; - final CommitInfo commit; + Tag(this.name, this.commit, this.zipUrl, this.tarUrl); + + String name; + CommitInfo commit; @JsonKey(name: 'zipball_url') - final String zipUrl; + String zipUrl; @JsonKey(name: 'tarball_url') - final String tarUrl; - - Tag(this.name, this.commit, this.zipUrl, this.tarUrl); + String tarUrl; factory Tag.fromJson(Map input) => _$TagFromJson(input); Map toJson() => _$TagToJson(this); @@ -221,18 +502,18 @@ class Tag { @JsonSerializable() class CommitData { - final String? sha; - final GitCommit? commit; - final String? url; - final String? htmlUrl; - final String? commentsUrl; - - final CommitDataUser? author, committer; - final List>? parents; - CommitData(this.sha, this.commit, this.url, this.htmlUrl, this.commentsUrl, this.author, this.committer, this.parents); + String? sha; + GitCommit? commit; + String? url; + String? htmlUrl; + String? commentsUrl; + + CommitDataUser? author, committer; + List>? parents; + factory CommitData.fromJson(Map input) => _$CommitDataFromJson(input); Map toJson() => _$CommitDataToJson(this); @@ -240,11 +521,11 @@ class CommitData { @JsonSerializable() class CommitDataUser { - final String? login, type; + CommitDataUser(this.login, this.id, this.type); - final int? id; + String? login, type; - CommitDataUser(this.login, this.id, this.type); + int? id; factory CommitDataUser.fromJson(Map input) => _$CommitDataUserFromJson(input); @@ -253,11 +534,11 @@ class CommitDataUser { @JsonSerializable() class CommitInfo { - final String? sha; - final GitTree? tree; - CommitInfo(this.sha, this.tree); + String? sha; + GitTree? tree; + factory CommitInfo.fromJson(Map input) => _$CommitInfoFromJson(input); Map toJson() => _$CommitInfoToJson(this); @@ -266,19 +547,19 @@ class CommitInfo { /// User Information @JsonSerializable() class UserInformation { + UserInformation(this.login, this.id, this.avatarUrl, this.htmlUrl); + /// Owner Username - final String login; + String login; /// Owner ID - final int id; + int id; /// Avatar Url - final String avatarUrl; + String avatarUrl; /// Url to the user's GitHub Profile - final String htmlUrl; - - UserInformation(this.login, this.id, this.avatarUrl, this.htmlUrl); + String htmlUrl; factory UserInformation.fromJson(Map input) => _$UserInformationFromJson(input); @@ -288,14 +569,14 @@ class UserInformation { /// A Repository Slug @JsonSerializable() class RepositorySlug { + RepositorySlug(this.owner, this.name); + /// Repository Owner String owner; /// Repository Name String name; - RepositorySlug(this.owner, this.name); - /// Creates a Repository Slug from a full name. factory RepositorySlug.full(String f) { final split = f.split('/'); @@ -340,7 +621,7 @@ class CreateRepository { this.hasWiki}); /// Repository Name - final String? name; + String? name; /// Repository Description String? description; @@ -383,13 +664,13 @@ class CreateRepository { /// Model class for a branch. @JsonSerializable() class Branch { + Branch(this.name, this.commit); + /// The name of the branch. - final String? name; + String? name; /// Commit Information - final CommitData? commit; - - Branch(this.name, this.commit); + CommitData? commit; factory Branch.fromJson(Map json) => _$BranchFromJson(json); Map toJson() => _$BranchToJson(this); @@ -397,10 +678,10 @@ class Branch { /// A Breakdown of the Languages a repository uses. class LanguageBreakdown { - final Map _data; - LanguageBreakdown(Map data) : _data = data; + final Map _data; + /// The Primary Language String get primary { final list = mapToList(_data); @@ -439,25 +720,6 @@ class LanguageBreakdown { @JsonSerializable() class LicenseDetails { - final String? name; - final String? path; - final String? sha; - final int? size; - final Uri? url; - - final Uri? htmlUrl; - final Uri? gitUrl; - final Uri? downloadUrl; - - final String? type; - final String? content; - final String? encoding; - - @JsonKey(name: '_links') - final Links? links; - - final LicenseKind? license; - LicenseDetails( {this.name, this.path, @@ -473,6 +735,25 @@ class LicenseDetails { this.links, this.license}); + String? name; + String? path; + String? sha; + int? size; + Uri? url; + + Uri? htmlUrl; + Uri? gitUrl; + Uri? downloadUrl; + + String? type; + String? content; + String? encoding; + + @JsonKey(name: '_links') + Links? links; + + LicenseKind? license; + factory LicenseDetails.fromJson(Map json) => _$LicenseDetailsFromJson(json); @@ -481,14 +762,14 @@ class LicenseDetails { @JsonSerializable() class LicenseKind { - final String? key; - final String? name; - final String? spdxId; - final Uri? url; - final String? nodeId; - LicenseKind({this.key, this.name, this.spdxId, this.url, this.nodeId}); + String? key; + String? name; + String? spdxId; + Uri? url; + String? nodeId; + factory LicenseKind.fromJson(Map json) => _$LicenseKindFromJson(json); diff --git a/lib/src/common/model/repos.g.dart b/lib/src/common/model/repos.g.dart index b2e395bd..490b18b1 100644 --- a/lib/src/common/model/repos.g.dart +++ b/lib/src/common/model/repos.g.dart @@ -79,6 +79,79 @@ Repository _$RepositoryFromJson(Map json) => Repository( ? null : RepositoryPermissions.fromJson( json['permissions'] as Map), + allowAutoMerge: json['allow_auto_merge'] as bool?, + allowForking: json['allow_forking'] as bool?, + allowMergeCommit: json['allow_merge_commit'] as bool?, + allowRebaseMerge: json['allow_rebase_merge'] as bool?, + allowSquashMerge: json['allow_squash_merge'] as bool?, + allowUpdateBranch: json['allow_update_branch'] as bool?, + anonymousAccessEnabled: json['anonymous_access_enabled'] as bool?, + archiveUrl: json['archive_url'] as String?, + assigneesUrl: json['assignees_url'] as String?, + blobsUrl: json['blobs_url'] as String?, + branchesUrl: json['branches_url'] as String?, + collaboratorsUrl: json['collaborators_url'] as String?, + commentsUrl: json['comments_url'] as String?, + commitsUrl: json['commits_url'] as String?, + compareUrl: json['compare_url'] as String?, + contentsUrl: json['contents_url'] as String?, + contributorsUrl: json['contributors_url'] as String?, + deleteBranchOnMerge: json['delete_branch_on_merge'] as bool?, + deploymentsUrl: json['deployments_url'] as String?, + downloadsUrl: json['downloads_url'] as String?, + eventsUrl: json['events_url'] as String?, + forks: json['forks'] as int?, + forksUrl: json['forks_url'] as String?, + gitCommitsUrl: json['git_commits_url'] as String?, + gitRefsUrl: json['git_refs_url'] as String?, + gitTagsUrl: json['git_tags_url'] as String?, + hasDiscussions: json['has_discussions'] as bool?, + hasProjects: json['has_projects'] as bool?, + hooksUrl: json['hooks_url'] as String?, + isTemplate: json['is_template'] as bool?, + issueCommentUrl: json['issue_comment_url'] as String?, + issueEventsUrl: json['issue_events_url'] as String?, + issuesUrl: json['issues_url'] as String?, + keysUrl: json['keys_url'] as String?, + labelsUrl: json['labels_url'] as String?, + languagesUrl: json['languages_url'] as String?, + masterBranch: json['master_branch'] as String?, + mergeCommitMessage: json['merge_commit_message'] as String?, + mergeCommitTitle: json['merge_commit_title'] as String?, + mergesUrl: json['merges_url'] as String?, + milestonesUrl: json['milestones_url'] as String?, + mirrorUrl: json['mirror_url'] as String?, + nodeId: json['node_id'] as String?, + notificationsUrl: json['notifications_url'] as String?, + openIssues: json['open_issues'] as int?, + organization: json['organization'] == null + ? null + : User.fromJson(json['organization'] as Map), + pullsUrl: json['pulls_url'] as String?, + releasesUrl: json['releases_url'] as String?, + squashMergeCommitMessage: json['squash_merge_commit_message'] as String?, + squashMergeCommitTitle: json['squash_merge_commit_title'] as String?, + stargazersUrl: json['stargazers_url'] as String?, + starredAt: json['starred_at'] == null + ? null + : DateTime.parse(json['starred_at'] as String), + statusesUrl: json['statuses_url'] as String?, + subscribersUrl: json['subscribers_url'] as String?, + subscriptionUrl: json['subscription_url'] as String?, + tagsUrl: json['tags_url'] as String?, + teamsUrl: json['teams_url'] as String?, + tempCloneToken: json['temp_clone_token'] as String?, + templateRepository: json['template_repository'] == null + ? null + : TemplateRepository.fromJson( + json['template_repository'] as Map), + topics: + (json['topics'] as List?)?.map((e) => e as String).toList(), + treesUrl: json['trees_url'] as String?, + url: json['url'] as String?, + visibility: json['visibility'] as String?, + watchers: json['watchers'] as int?, + webCommitSignoffRequired: json['web_commit_signoff_required'] as bool?, ); Map _$RepositoryToJson(Repository instance) => @@ -116,6 +189,71 @@ Map _$RepositoryToJson(Repository instance) => 'archived': instance.archived, 'disabled': instance.disabled, 'permissions': instance.permissions, + 'allow_auto_merge': instance.allowAutoMerge, + 'allow_forking': instance.allowForking, + 'allow_merge_commit': instance.allowMergeCommit, + 'allow_rebase_merge': instance.allowRebaseMerge, + 'allow_squash_merge': instance.allowSquashMerge, + 'allow_update_branch': instance.allowUpdateBranch, + 'anonymous_access_enabled': instance.anonymousAccessEnabled, + 'archive_url': instance.archiveUrl, + 'assignees_url': instance.assigneesUrl, + 'blobs_url': instance.blobsUrl, + 'branches_url': instance.branchesUrl, + 'collaborators_url': instance.collaboratorsUrl, + 'comments_url': instance.commentsUrl, + 'commits_url': instance.commitsUrl, + 'compare_url': instance.compareUrl, + 'contents_url': instance.contentsUrl, + 'contributors_url': instance.contributorsUrl, + 'delete_branch_on_merge': instance.deleteBranchOnMerge, + 'deployments_url': instance.deploymentsUrl, + 'downloads_url': instance.downloadsUrl, + 'events_url': instance.eventsUrl, + 'forks': instance.forks, + 'forks_url': instance.forksUrl, + 'git_commits_url': instance.gitCommitsUrl, + 'git_refs_url': instance.gitRefsUrl, + 'git_tags_url': instance.gitTagsUrl, + 'has_discussions': instance.hasDiscussions, + 'has_projects': instance.hasProjects, + 'hooks_url': instance.hooksUrl, + 'is_template': instance.isTemplate, + 'issue_comment_url': instance.issueCommentUrl, + 'issue_events_url': instance.issueEventsUrl, + 'issues_url': instance.issuesUrl, + 'keys_url': instance.keysUrl, + 'labels_url': instance.labelsUrl, + 'languages_url': instance.languagesUrl, + 'master_branch': instance.masterBranch, + 'merge_commit_message': instance.mergeCommitMessage, + 'merge_commit_title': instance.mergeCommitTitle, + 'merges_url': instance.mergesUrl, + 'milestones_url': instance.milestonesUrl, + 'mirror_url': instance.mirrorUrl, + 'node_id': instance.nodeId, + 'notifications_url': instance.notificationsUrl, + 'open_issues': instance.openIssues, + 'organization': instance.organization, + 'pulls_url': instance.pullsUrl, + 'releases_url': instance.releasesUrl, + 'squash_merge_commit_message': instance.squashMergeCommitMessage, + 'squash_merge_commit_title': instance.squashMergeCommitTitle, + 'stargazers_url': instance.stargazersUrl, + 'starred_at': instance.starredAt?.toIso8601String(), + 'statuses_url': instance.statusesUrl, + 'subscribers_url': instance.subscribersUrl, + 'subscription_url': instance.subscriptionUrl, + 'tags_url': instance.tagsUrl, + 'teams_url': instance.teamsUrl, + 'temp_clone_token': instance.tempCloneToken, + 'template_repository': instance.templateRepository, + 'topics': instance.topics, + 'trees_url': instance.treesUrl, + 'url': instance.url, + 'visibility': instance.visibility, + 'watchers': instance.watchers, + 'web_commit_signoff_required': instance.webCommitSignoffRequired, }; RepositoryPermissions _$RepositoryPermissionsFromJson( diff --git a/lib/src/common/model/repos_commits.dart b/lib/src/common/model/repos_commits.dart index 940917ab..f79c774f 100644 --- a/lib/src/common/model/repos_commits.dart +++ b/lib/src/common/model/repos_commits.dart @@ -133,37 +133,56 @@ class CommitComment { this.htmlUrl, this.updatedAt, this.body, + + // Properties from the Timeline API + this.authorAssociation, + this.nodeId, + this.reactions, + this.user, }); /// Id of the comment - final int? id; + int? id; /// Relative path of the file on which the comment has been posted - final String? path; + String? path; /// Line on file - final int? line; + int? line; /// Position on the diff - final int? position; + int? position; /// SHA of the commit where the comment has been made - final String? commitId; + String? commitId; - final DateTime? createdAt; + DateTime? createdAt; /// Can be equals to [createdAt] - final DateTime? updatedAt; + DateTime? updatedAt; /// Ex: https://github.com/... - final String? htmlUrl; + String? htmlUrl; /// Ex: https://api.github.com/... @JsonKey(name: 'url') - final String? apiUrl; + String? apiUrl; /// Content of the comment - final String? body; + String? body; + + // The following properties were added to support the Timeline API. + + /// How the author is associated with the repository. + /// + /// Example: `OWNER` + String? authorAssociation; + + String? nodeId; + + ReactionRollup? reactions; + + User? user; factory CommitComment.fromJson(Map input) => _$CommitCommentFromJson(input); diff --git a/lib/src/common/model/repos_commits.g.dart b/lib/src/common/model/repos_commits.g.dart index c91901fc..5e74c999 100644 --- a/lib/src/common/model/repos_commits.g.dart +++ b/lib/src/common/model/repos_commits.g.dart @@ -98,6 +98,14 @@ CommitComment _$CommitCommentFromJson(Map json) => ? null : DateTime.parse(json['updated_at'] as String), body: json['body'] as String?, + authorAssociation: json['author_association'] as String?, + nodeId: json['node_id'] as String?, + reactions: json['reactions'] == null + ? null + : ReactionRollup.fromJson(json['reactions'] as Map), + user: json['user'] == null + ? null + : User.fromJson(json['user'] as Map), ); Map _$CommitCommentToJson(CommitComment instance) => @@ -112,4 +120,8 @@ Map _$CommitCommentToJson(CommitComment instance) => 'html_url': instance.htmlUrl, 'url': instance.apiUrl, 'body': instance.body, + 'author_association': instance.authorAssociation, + 'node_id': instance.nodeId, + 'reactions': instance.reactions, + 'user': instance.user, }; diff --git a/lib/src/common/model/timeline.dart b/lib/src/common/model/timeline.dart new file mode 100644 index 00000000..ae2c48ef --- /dev/null +++ b/lib/src/common/model/timeline.dart @@ -0,0 +1,582 @@ +import 'package:github/src/common.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'timeline.g.dart'; + +// Parts of this file were originally automatically generated from the response +// schema provided in the API documentation for GitHub's "List timeline events +// for an issue" API [1], using the `tool/process_github_schema.dart` script. +// +// Unfortunately, that schema contradicts the prose documentation [2] in a great +// variety of ways (for example none of the "common properties" are actually +// common to all the event types), so this code is an attempt to find the most +// pragmatic middleground between what is documented and what actually works. +// +// [1] https://docs.github.com/en/rest/issues/timeline?apiVersion=2022-11-28 +// [2] https://docs.github.com/en/webhooks-and-events/events/issue-event-types + +/// Model class for an issue or PR timeline event. +/// +/// This is a base class for the various event types. Events that only use the +/// default fields use this class; events that have additional fields use one +/// of the subclasses. +/// +/// The [TimelineEvent.fromJson] factory selects the right subclass based on +/// the [event] field. +/// +/// If the [event] type is not known, [TimelineEvent] is used. +/// +/// See also: https://docs.github.com/en/webhooks-and-events/events/issue-event-types +@JsonSerializable() +class TimelineEvent { + TimelineEvent({ + this.id = 0, + this.nodeId, + this.url, + this.actor, + this.event = '', + this.commitId, + this.commitUrl, + this.createdAt, + this.performedViaGithubApp, + }); + + int id; + String? nodeId; + String? url; + User? actor; + String event; + String? commitId; + String? commitUrl; + DateTime? createdAt; + GitHubApp? performedViaGithubApp; + + Map toJson() => _$TimelineEventToJson(this); + + factory TimelineEvent.fromJson(Map input) { + switch (input['event']) { + case 'added_to_project': + return ProjectEvent.fromJson(input); + case 'assigned': + return AssigneeEvent.fromJson(input); + case 'commented': + return CommentEvent.fromJson(input); + case 'committed': + return TimelineCommitEvent.fromJson(input); + case 'cross-referenced': + return CrossReferenceEvent.fromJson(input); + case 'demilestoned': + return MilestoneEvent.fromJson(input); + case 'labeled': + return LabelEvent.fromJson(input); + case 'locked': + return LockEvent.fromJson(input); + case 'milestoned': + return MilestoneEvent.fromJson(input); + case 'moved_columns_in_project': + return ProjectEvent.fromJson(input); + case 'removed_from_project': + return ProjectEvent.fromJson(input); + case 'renamed': + return RenameEvent.fromJson(input); + case 'review_dismissed': + return ReviewDismissedEvent.fromJson(input); + case 'review_requested': + return ReviewRequestEvent.fromJson(input); + case 'review_request_removed': + return ReviewRequestEvent.fromJson(input); + case 'reviewed': + return ReviewEvent.fromJson(input); + case 'unassigned': + return AssigneeEvent.fromJson(input); + case 'unlabeled': + return LabelEvent.fromJson(input); + default: + return _$TimelineEventFromJson(input); + } + } +} + +/// Labeled and Unlabeled Issue Events +@JsonSerializable() +class LabelEvent extends TimelineEvent { + LabelEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = '', // typically 'labeled' or 'unlabeled' + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.label, + }); + + IssueLabel? label; + + @override + Map toJson() => _$LabelEventToJson(this); + + factory LabelEvent.fromJson(Map input) => + _$LabelEventFromJson(input); +} + +/// Milestoned and Demilestoned Issue Event +@JsonSerializable() +class MilestoneEvent extends TimelineEvent { + MilestoneEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = '', // typically 'milestoned' or 'demilestoned' + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.milestone, + }); + + Milestone? milestone; + + @override + Map toJson() => _$MilestoneEventToJson(this); + + factory MilestoneEvent.fromJson(Map input) => + _$MilestoneEventFromJson(input); +} + +/// Renamed Issue Event +@JsonSerializable() +class RenameEvent extends TimelineEvent { + RenameEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = 'renamed', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.rename, + }); + + Rename? rename; + + @override + Map toJson() => _$RenameEventToJson(this); + + factory RenameEvent.fromJson(Map input) => + _$RenameEventFromJson(input); +} + +/// Review Requested and Review Request Removed Issue Events +@JsonSerializable() +class ReviewRequestEvent extends TimelineEvent { + ReviewRequestEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = + '', // typically 'review_requested' or 'review_request_removed' + super.commitId, + super.commitUrl, + super.createdAt, + this.requestedReviewer, + this.requestedTeam, + this.reviewRequester, + }); + + User? requestedReviewer; + + /// Team + /// + /// Groups of organization members that gives permissions on specified repositories. + Team? requestedTeam; + + User? reviewRequester; + + @override + Map toJson() => _$ReviewRequestEventToJson(this); + + factory ReviewRequestEvent.fromJson(Map input) => + _$ReviewRequestEventFromJson(input); +} + +/// Review Dismissed Issue Event +@JsonSerializable() +class ReviewDismissedEvent extends TimelineEvent { + ReviewDismissedEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = 'review_dismissed', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.dismissedReview, + }); + + DismissedReview? dismissedReview; + + @override + Map toJson() => _$ReviewDismissedEventToJson(this); + + factory ReviewDismissedEvent.fromJson(Map input) => + _$ReviewDismissedEventFromJson(input); +} + +/// Locked Issue Event +@JsonSerializable() +class LockEvent extends TimelineEvent { + LockEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = 'locked', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.lockReason, + }); + + /// Example: `"off-topic"` + String? lockReason; + + @override + Map toJson() => _$LockEventToJson(this); + + factory LockEvent.fromJson(Map input) => + _$LockEventFromJson(input); +} + +/// Added to Project, +/// Moved Columns in Project, +/// Removed from Project, and +/// Converted Note to Issue +/// Issue Events. +@JsonSerializable() +class ProjectEvent extends TimelineEvent { + ProjectEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event, // typically one of 'added_to_project', 'moved_columns_in_project', 'removed_from_project', 'converted_note_to_issue' + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.projectCard, + }); + + ProjectCard? projectCard; + + @override + Map toJson() => _$ProjectEventToJson(this); + + factory ProjectEvent.fromJson(Map input) => + _$ProjectEventFromJson(input); +} + +/// Timeline Comment Event +@JsonSerializable() +class CommentEvent extends TimelineEvent { + CommentEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = 'commented', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.authorAssociation, + this.body, + this.bodyHtml, + this.bodyText, + this.htmlUrl, + this.issueUrl, + this.reactions, + this.updatedAt, + this.user, + }); + + /// How the author is associated with the repository. + /// + /// Example: `OWNER` + String? authorAssociation; + + /// Contents of the issue comment + /// + /// Example: `What version of Safari were you using when you observed this bug?` + String? body; + + String? bodyHtml; + String? bodyText; + + String? htmlUrl; + + String? issueUrl; + + ReactionRollup? reactions; + + DateTime? updatedAt; + + User? user; + + @override + Map toJson() => _$CommentEventToJson(this); + + factory CommentEvent.fromJson(Map input) => + _$CommentEventFromJson(input); +} + +/// Timeline Cross Referenced Event +@JsonSerializable() +class CrossReferenceEvent extends TimelineEvent { + CrossReferenceEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = 'cross-referenced', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.source, + this.updatedAt, + }); + + Source? source; + + DateTime? updatedAt; + + @override + Map toJson() => _$CrossReferenceEventToJson(this); + + factory CrossReferenceEvent.fromJson(Map input) => + _$CrossReferenceEventFromJson(input); +} + +/// Timeline Committed Event +@JsonSerializable() +class TimelineCommitEvent extends TimelineEvent { + TimelineCommitEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = 'committed', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.author, + this.committer, + this.htmlUrl, + this.message, + this.parents, + this.sha, + this.tree, + this.verification, + }); + + User? author; + + /// Identifying information for the git-user + User? committer; + + /// Format: uri + String? htmlUrl; + + /// Message describing the purpose of the commit + String? message; + + List? parents; + + /// SHA for the commit + /// + /// Example: `7638417db6d59f3c431d3e1f261cc637155684cd` + String? sha; + + Tree? tree; + + Verification? verification; + + @override + Map toJson() => _$TimelineCommitEventToJson(this); + + factory TimelineCommitEvent.fromJson(Map input) => + _$TimelineCommitEventFromJson(input); +} + +/// Timeline Reviewed Event +@JsonSerializable() +class ReviewEvent extends TimelineEvent { + ReviewEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = 'reviewed', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.authorAssociation, + this.body, + this.bodyHtml, + this.bodyText, + this.htmlUrl, + this.links, + this.pullRequestUrl, + this.state, + this.submittedAt, + this.user, + }); + + /// How the author is associated with the repository. + /// + /// Example: `OWNER` + String? authorAssociation; + + /// The text of the review. + /// + /// Example: `This looks great.` + String? body; + + String? bodyHtml; + String? bodyText; + + /// Example: `https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80` + String? htmlUrl; + + @JsonKey(name: '_links') + ReviewLinks? links; + + /// Example: `https://api.github.com/repos/octocat/Hello-World/pulls/12` + String? pullRequestUrl; + + /// Example: `CHANGES_REQUESTED` + String? state; + + DateTime? submittedAt; + + User? user; + + @override + Map toJson() => _$ReviewEventToJson(this); + + factory ReviewEvent.fromJson(Map input) => + _$ReviewEventFromJson(input); +} + +/// Timeline Line Commented Event +@JsonSerializable() +class TimelineLineCommentedEvent extends TimelineEvent { + TimelineLineCommentedEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = '', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.comments, + }); + + List? comments; + + @override + Map toJson() => _$TimelineLineCommentedEventToJson(this); + + factory TimelineLineCommentedEvent.fromJson(Map input) => + _$TimelineLineCommentedEventFromJson(input); +} + +/// Timeline Commit Commented Event +@JsonSerializable() +class TimelineCommitCommentedEvent extends TimelineEvent { + TimelineCommitCommentedEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = '', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.comments, + }); + + List? comments; + + @override + Map toJson() => _$TimelineCommitCommentedEventToJson(this); + + factory TimelineCommitCommentedEvent.fromJson(Map input) => + _$TimelineCommitCommentedEventFromJson(input); +} + +/// Timeline Assigned and Timeline Unassigned Issue Events +@JsonSerializable() +class AssigneeEvent extends TimelineEvent { + AssigneeEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event, // typically 'assigned' or 'unassigned' + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.assignee, + }); + + User? assignee; + + @override + Map toJson() => _$AssigneeEventToJson(this); + + factory AssigneeEvent.fromJson(Map input) => + _$AssigneeEventFromJson(input); +} + +/// State Change Issue Event +@JsonSerializable() +class StateChangeIssueEvent extends TimelineEvent { + StateChangeIssueEvent({ + super.id = 0, + super.nodeId, + super.url, + super.actor, + super.event = '', + super.commitId, + super.commitUrl, + super.createdAt, + super.performedViaGithubApp, + this.stateReason, + }); + + String? stateReason; + + @override + Map toJson() => _$StateChangeIssueEventToJson(this); + + factory StateChangeIssueEvent.fromJson(Map input) => + _$StateChangeIssueEventFromJson(input); +} diff --git a/lib/src/common/model/timeline.g.dart b/lib/src/common/model/timeline.g.dart new file mode 100644 index 00000000..9d0bfc5a --- /dev/null +++ b/lib/src/common/model/timeline.g.dart @@ -0,0 +1,671 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'timeline.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TimelineEvent _$TimelineEventFromJson(Map json) => + TimelineEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + ); + +Map _$TimelineEventToJson(TimelineEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + }; + +LabelEvent _$LabelEventFromJson(Map json) => LabelEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + label: json['label'] == null + ? null + : IssueLabel.fromJson(json['label'] as Map), + ); + +Map _$LabelEventToJson(LabelEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'label': instance.label, + }; + +MilestoneEvent _$MilestoneEventFromJson(Map json) => + MilestoneEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + milestone: json['milestone'] == null + ? null + : Milestone.fromJson(json['milestone'] as Map), + ); + +Map _$MilestoneEventToJson(MilestoneEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'milestone': instance.milestone, + }; + +RenameEvent _$RenameEventFromJson(Map json) => RenameEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? 'renamed', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + rename: json['rename'] == null + ? null + : Rename.fromJson(json['rename'] as Map), + ); + +Map _$RenameEventToJson(RenameEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'rename': instance.rename, + }; + +ReviewRequestEvent _$ReviewRequestEventFromJson(Map json) => + ReviewRequestEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + requestedReviewer: json['requested_reviewer'] == null + ? null + : User.fromJson(json['requested_reviewer'] as Map), + requestedTeam: json['requested_team'] == null + ? null + : Team.fromJson(json['requested_team'] as Map), + reviewRequester: json['review_requester'] == null + ? null + : User.fromJson(json['review_requester'] as Map), + )..performedViaGithubApp = json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map); + +Map _$ReviewRequestEventToJson(ReviewRequestEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'requested_reviewer': instance.requestedReviewer, + 'requested_team': instance.requestedTeam, + 'review_requester': instance.reviewRequester, + }; + +ReviewDismissedEvent _$ReviewDismissedEventFromJson( + Map json) => + ReviewDismissedEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? 'review_dismissed', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + dismissedReview: json['dismissed_review'] == null + ? null + : DismissedReview.fromJson( + json['dismissed_review'] as Map), + ); + +Map _$ReviewDismissedEventToJson( + ReviewDismissedEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'dismissed_review': instance.dismissedReview, + }; + +LockEvent _$LockEventFromJson(Map json) => LockEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? 'locked', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + lockReason: json['lock_reason'] as String?, + ); + +Map _$LockEventToJson(LockEvent instance) => { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'lock_reason': instance.lockReason, + }; + +ProjectEvent _$ProjectEventFromJson(Map json) => ProjectEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + projectCard: json['project_card'] == null + ? null + : ProjectCard.fromJson(json['project_card'] as Map), + ); + +Map _$ProjectEventToJson(ProjectEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'project_card': instance.projectCard, + }; + +CommentEvent _$CommentEventFromJson(Map json) => CommentEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? 'commented', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + authorAssociation: json['author_association'] as String?, + body: json['body'] as String?, + bodyHtml: json['body_html'] as String?, + bodyText: json['body_text'] as String?, + htmlUrl: json['html_url'] as String?, + issueUrl: json['issue_url'] as String?, + reactions: json['reactions'] == null + ? null + : ReactionRollup.fromJson(json['reactions'] as Map), + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), + user: json['user'] == null + ? null + : User.fromJson(json['user'] as Map), + ); + +Map _$CommentEventToJson(CommentEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'author_association': instance.authorAssociation, + 'body': instance.body, + 'body_html': instance.bodyHtml, + 'body_text': instance.bodyText, + 'html_url': instance.htmlUrl, + 'issue_url': instance.issueUrl, + 'reactions': instance.reactions, + 'updated_at': instance.updatedAt?.toIso8601String(), + 'user': instance.user, + }; + +CrossReferenceEvent _$CrossReferenceEventFromJson(Map json) => + CrossReferenceEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? 'cross-referenced', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + source: json['source'] == null + ? null + : Source.fromJson(json['source'] as Map), + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), + ); + +Map _$CrossReferenceEventToJson( + CrossReferenceEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'source': instance.source, + 'updated_at': instance.updatedAt?.toIso8601String(), + }; + +TimelineCommitEvent _$TimelineCommitEventFromJson(Map json) => + TimelineCommitEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? 'committed', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + author: json['author'] == null + ? null + : User.fromJson(json['author'] as Map), + committer: json['committer'] == null + ? null + : User.fromJson(json['committer'] as Map), + htmlUrl: json['html_url'] as String?, + message: json['message'] as String?, + parents: (json['parents'] as List?) + ?.map((e) => Tree.fromJson(e as Map)) + .toList(), + sha: json['sha'] as String?, + tree: json['tree'] == null + ? null + : Tree.fromJson(json['tree'] as Map), + verification: json['verification'] == null + ? null + : Verification.fromJson(json['verification'] as Map), + ); + +Map _$TimelineCommitEventToJson( + TimelineCommitEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'author': instance.author, + 'committer': instance.committer, + 'html_url': instance.htmlUrl, + 'message': instance.message, + 'parents': instance.parents, + 'sha': instance.sha, + 'tree': instance.tree, + 'verification': instance.verification, + }; + +ReviewEvent _$ReviewEventFromJson(Map json) => ReviewEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? 'reviewed', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + authorAssociation: json['author_association'] as String?, + body: json['body'] as String?, + bodyHtml: json['body_html'] as String?, + bodyText: json['body_text'] as String?, + htmlUrl: json['html_url'] as String?, + links: json['_links'] == null + ? null + : ReviewLinks.fromJson(json['_links'] as Map), + pullRequestUrl: json['pull_request_url'] as String?, + state: json['state'] as String?, + submittedAt: json['submitted_at'] == null + ? null + : DateTime.parse(json['submitted_at'] as String), + user: json['user'] == null + ? null + : User.fromJson(json['user'] as Map), + ); + +Map _$ReviewEventToJson(ReviewEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'author_association': instance.authorAssociation, + 'body': instance.body, + 'body_html': instance.bodyHtml, + 'body_text': instance.bodyText, + 'html_url': instance.htmlUrl, + '_links': instance.links, + 'pull_request_url': instance.pullRequestUrl, + 'state': instance.state, + 'submitted_at': instance.submittedAt?.toIso8601String(), + 'user': instance.user, + }; + +TimelineLineCommentedEvent _$TimelineLineCommentedEventFromJson( + Map json) => + TimelineLineCommentedEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + comments: (json['comments'] as List?) + ?.map((e) => + PullRequestReviewComment.fromJson(e as Map)) + .toList(), + ); + +Map _$TimelineLineCommentedEventToJson( + TimelineLineCommentedEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'comments': instance.comments, + }; + +TimelineCommitCommentedEvent _$TimelineCommitCommentedEventFromJson( + Map json) => + TimelineCommitCommentedEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + comments: (json['comments'] as List?) + ?.map((e) => CommitComment.fromJson(e as Map)) + .toList(), + ); + +Map _$TimelineCommitCommentedEventToJson( + TimelineCommitCommentedEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'comments': instance.comments, + }; + +AssigneeEvent _$AssigneeEventFromJson(Map json) => + AssigneeEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + assignee: json['assignee'] == null + ? null + : User.fromJson(json['assignee'] as Map), + ); + +Map _$AssigneeEventToJson(AssigneeEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'assignee': instance.assignee, + }; + +StateChangeIssueEvent _$StateChangeIssueEventFromJson( + Map json) => + StateChangeIssueEvent( + id: json['id'] as int? ?? 0, + nodeId: json['node_id'] as String?, + url: json['url'] as String?, + actor: json['actor'] == null + ? null + : User.fromJson(json['actor'] as Map), + event: json['event'] as String? ?? '', + commitId: json['commit_id'] as String?, + commitUrl: json['commit_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + performedViaGithubApp: json['performed_via_github_app'] == null + ? null + : GitHubApp.fromJson( + json['performed_via_github_app'] as Map), + stateReason: json['state_reason'] as String?, + ); + +Map _$StateChangeIssueEventToJson( + StateChangeIssueEvent instance) => + { + 'id': instance.id, + 'node_id': instance.nodeId, + 'url': instance.url, + 'actor': instance.actor, + 'event': instance.event, + 'commit_id': instance.commitId, + 'commit_url': instance.commitUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'performed_via_github_app': instance.performedViaGithubApp, + 'state_reason': instance.stateReason, + }; diff --git a/lib/src/common/model/timeline_support.dart b/lib/src/common/model/timeline_support.dart new file mode 100644 index 00000000..f2b03c62 --- /dev/null +++ b/lib/src/common/model/timeline_support.dart @@ -0,0 +1,562 @@ +import 'package:github/src/common.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'timeline_support.g.dart'; + +/// GitHub app +/// +/// GitHub apps are a new way to extend GitHub. They can be installed directly +/// on organizations and user accounts and granted access to specific repositories. +/// They come with granular permissions and built-in webhooks. GitHub apps are +/// first class actors within GitHub. +@JsonSerializable() +class GitHubApp { + GitHubApp({ + this.clientId, + this.clientSecret, + this.createdAt, + this.description, + this.events, + this.externalUrl, + this.htmlUrl, + this.id, + this.installationsCount, + this.name, + this.nodeId, + this.owner, + this.pem, + this.permissions, + this.slug, + this.updatedAt, + this.webhookSecret, + }); + + /// Example: `"Iv1.25b5d1e65ffc4022"` + final String? clientId; + + /// Example: `"1d4b2097ac622ba702d19de498f005747a8b21d3"` + final String? clientSecret; + + final DateTime? createdAt; + + final String? description; + + /// The list of events for the GitHub app + /// + /// Example: `label` + /// + /// Example: `deployment` + final List? events; + + /// Example: `https://example.com` + final String? externalUrl; + + /// Example: `https://github.com/apps/super-ci` + final String? htmlUrl; + + /// Unique identifier of the GitHub app + final int? id; + + /// The number of installations associated with the GitHub app + final int? installationsCount; + + /// The name of the GitHub app + /// + /// Example: `Probot Owners` + final String? name; + + /// Example: `MDExOkludGVncmF0aW9uMQ==` + final String? nodeId; + + final User? owner; + + /// Example: + /// + /// ``` + /// -----BEGIN RSA PRIVATE KEY----- + /// MIIEogIBAAKCAQEArYxrNYD/iT5CZVpRJu4rBKmmze3PVmT/gCo2ATUvDvZTPTey + /// xcGJ3vvrJXazKk06pN05TN29o98jrYz4cengG3YGsXPNEpKsIrEl8NhbnxapEnM9 + /// JCMRe0P5JcPsfZlX6hmiT7136GRWiGOUba2X9+HKh8QJVLG5rM007TBER9/z9mWm + /// rJuNh+m5l320oBQY/Qq3A7wzdEfZw8qm/mIN0FCeoXH1L6B8xXWaAYBwhTEh6SSn + /// ZHlO1Xu1JWDmAvBCi0RO5aRSKM8q9QEkvvHP4yweAtK3N8+aAbZ7ovaDhyGz8r6r + /// zhU1b8Uo0Z2ysf503WqzQgIajr7Fry7/kUwpgQIDAQABAoIBADwJp80Ko1xHPZDy + /// fcCKBDfIuPvkmSW6KumbsLMaQv1aGdHDwwTGv3t0ixSay8CGlxMRtRDyZPib6SvQ + /// 6OH/lpfpbMdW2ErkksgtoIKBVrDilfrcAvrNZu7NxRNbhCSvN8q0s4ICecjbbVQh + /// nueSdlA6vGXbW58BHMq68uRbHkP+k+mM9U0mDJ1HMch67wlg5GbayVRt63H7R2+r + /// Vxcna7B80J/lCEjIYZznawgiTvp3MSanTglqAYi+m1EcSsP14bJIB9vgaxS79kTu + /// oiSo93leJbBvuGo8QEiUqTwMw4tDksmkLsoqNKQ1q9P7LZ9DGcujtPy4EZsamSJT + /// y8OJt0ECgYEA2lxOxJsQk2kI325JgKFjo92mQeUObIvPfSNWUIZQDTjniOI6Gv63 + /// GLWVFrZcvQBWjMEQraJA9xjPbblV8PtfO87MiJGLWCHFxmPz2dzoedN+2Coxom8m + /// V95CLz8QUShuao6u/RYcvUaZEoYs5bHcTmy5sBK80JyEmafJPtCQVxMCgYEAy3ar + /// Zr3yv4xRPEPMat4rseswmuMooSaK3SKub19WFI5IAtB/e7qR1Rj9JhOGcZz+OQrl + /// T78O2OFYlgOIkJPvRMrPpK5V9lslc7tz1FSh3BZMRGq5jSyD7ETSOQ0c8T2O/s7v + /// beEPbVbDe4mwvM24XByH0GnWveVxaDl51ABD65sCgYB3ZAspUkOA5egVCh8kNpnd + /// Sd6SnuQBE3ySRlT2WEnCwP9Ph6oPgn+oAfiPX4xbRqkL8q/k0BdHQ4h+zNwhk7+h + /// WtPYRAP1Xxnc/F+jGjb+DVaIaKGU18MWPg7f+FI6nampl3Q0KvfxwX0GdNhtio8T + /// Tj1E+SnFwh56SRQuxSh2gwKBgHKjlIO5NtNSflsUYFM+hyQiPiqnHzddfhSG+/3o + /// m5nNaSmczJesUYreH5San7/YEy2UxAugvP7aSY2MxB+iGsiJ9WD2kZzTUlDZJ7RV + /// UzWsoqBR+eZfVJ2FUWWvy8TpSG6trh4dFxImNtKejCR1TREpSiTV3Zb1dmahK9GV + /// rK9NAoGAbBxRLoC01xfxCTgt5BDiBcFVh4fp5yYKwavJPLzHSpuDOrrI9jDn1oKN + /// onq5sDU1i391zfQvdrbX4Ova48BN+B7p63FocP/MK5tyyBoT8zQEk2+vWDOw7H/Z + /// u5dTCPxTIsoIwUw1I+7yIxqJzLPFgR2gVBwY1ra/8iAqCj+zeBw= + /// -----END RSA PRIVATE KEY----- + /// ``` + final String? pem; + + /// The set of permissions for the GitHub app + final Permissions? permissions; + + /// The slug name of the GitHub app + /// + /// Example: `probot-owners` + final String? slug; + + final DateTime? updatedAt; + + /// Example: `"6fba8f2fc8a7e8f2cca5577eddd82ca7586b3b6b"` + final String? webhookSecret; + + Map toJson() => _$GitHubAppToJson(this); + + factory GitHubApp.fromJson(Map input) => + _$GitHubAppFromJson(input); +} + +@JsonSerializable() +class Rename { + Rename({ + this.from, + this.to, + }); + + final String? from; + final String? to; + + Map toJson() => _$RenameToJson(this); + + factory Rename.fromJson(Map input) => + _$RenameFromJson(input); +} + +@JsonSerializable() +class DismissedReview { + DismissedReview({ + this.dismissalCommitId, + this.dismissalMessage, + this.reviewId, + this.state, + }); + + final String? dismissalCommitId; + final String? dismissalMessage; + final int? reviewId; + final String? state; + + Map toJson() => _$DismissedReviewToJson(this); + + factory DismissedReview.fromJson(Map input) => + _$DismissedReviewFromJson(input); +} + +@JsonSerializable() +class ProjectCard { + ProjectCard({ + this.columnName, + this.id, + this.previousColumnName, + this.projectId, + this.projectUrl, + this.url, + }); + + final String? columnName; + final int? id; + final String? previousColumnName; + final int? projectId; + final String? projectUrl; + final String? url; + + Map toJson() => _$ProjectCardToJson(this); + + factory ProjectCard.fromJson(Map input) => + _$ProjectCardFromJson(input); +} + +@JsonSerializable() +class Source { + Source({ + this.issue, + this.type, + }); + + final Issue? issue; + final String? type; + + Map toJson() => _$SourceToJson(this); + + factory Source.fromJson(Map input) => + _$SourceFromJson(input); +} + +/// License +@JsonSerializable() +class License { + License({ + this.htmlUrl, + this.key, + this.name, + this.nodeId, + this.spdxId, + this.url, + }); + + final String? htmlUrl; + + /// Example: `mit` + final String? key; + + /// Example: `MIT License` + final String? name; + + /// Example: `MDc6TGljZW5zZW1pdA==` + final String? nodeId; + + /// Example: `MIT` + final String? spdxId; + + /// Example: `https://api.github.com/licenses/mit` + final String? url; + + Map toJson() => _$LicenseToJson(this); + + factory License.fromJson(Map input) => + _$LicenseFromJson(input); +} + +@JsonSerializable() +class TemplateRepository { + TemplateRepository({ + this.allowAutoMerge, + this.allowMergeCommit, + this.allowRebaseMerge, + this.allowSquashMerge, + this.allowUpdateBranch, + this.archiveUrl, + this.archived, + this.assigneesUrl, + this.blobsUrl, + this.branchesUrl, + this.cloneUrl, + this.collaboratorsUrl, + this.commentsUrl, + this.commitsUrl, + this.compareUrl, + this.contentsUrl, + this.contributorsUrl, + this.createdAt, + this.defaultBranch, + this.deleteBranchOnMerge, + this.deploymentsUrl, + this.description, + this.disabled, + this.downloadsUrl, + this.eventsUrl, + this.fork, + this.forksCount, + this.forksUrl, + this.fullName, + this.gitCommitsUrl, + this.gitRefsUrl, + this.gitTagsUrl, + this.gitUrl, + this.hasDownloads, + this.hasIssues, + this.hasPages, + this.hasProjects, + this.hasWiki, + this.homepage, + this.hooksUrl, + this.htmlUrl, + this.id, + this.isTemplate, + this.issueCommentUrl, + this.issueEventsUrl, + this.issuesUrl, + this.keysUrl, + this.labelsUrl, + this.language, + this.languagesUrl, + this.mergeCommitMessage, + this.mergeCommitTitle, + this.mergesUrl, + this.milestonesUrl, + this.mirrorUrl, + this.name, + this.networkCount, + this.nodeId, + this.notificationsUrl, + this.openIssuesCount, + this.owner, + this.permissions, + this.private, + this.pullsUrl, + this.pushedAt, + this.releasesUrl, + this.size, + this.squashMergeCommitMessage, + this.squashMergeCommitTitle, + this.sshUrl, + this.stargazersCount, + this.stargazersUrl, + this.statusesUrl, + this.subscribersCount, + this.subscribersUrl, + this.subscriptionUrl, + this.svnUrl, + this.tagsUrl, + this.teamsUrl, + this.tempCloneToken, + this.topics, + this.treesUrl, + this.updatedAt, + this.url, + this.visibility, + this.watchersCount, + }); + + final bool? allowAutoMerge; + final bool? allowMergeCommit; + final bool? allowRebaseMerge; + final bool? allowSquashMerge; + final bool? allowUpdateBranch; + final String? archiveUrl; + final bool? archived; + final String? assigneesUrl; + final String? blobsUrl; + final String? branchesUrl; + final String? cloneUrl; + final String? collaboratorsUrl; + final String? commentsUrl; + final String? commitsUrl; + final String? compareUrl; + final String? contentsUrl; + final String? contributorsUrl; + final DateTime? createdAt; + final String? defaultBranch; + final bool? deleteBranchOnMerge; + final String? deploymentsUrl; + final String? description; + final bool? disabled; + final String? downloadsUrl; + final String? eventsUrl; + final bool? fork; + final int? forksCount; + final String? forksUrl; + final String? fullName; + final String? gitCommitsUrl; + final String? gitRefsUrl; + final String? gitTagsUrl; + final String? gitUrl; + final bool? hasDownloads; + final bool? hasIssues; + final bool? hasPages; + final bool? hasProjects; + final bool? hasWiki; + final String? homepage; + final String? hooksUrl; + final String? htmlUrl; + final int? id; + final bool? isTemplate; + final String? issueCommentUrl; + final String? issueEventsUrl; + final String? issuesUrl; + final String? keysUrl; + final String? labelsUrl; + final String? language; + final String? languagesUrl; + + /// The default value for a merge commit message. + /// + /// - `PR_TITLE` - default to the pull request's title. + /// - `PR_BODY` - default to the pull request's body. + /// - `BLANK` - default to a blank commit message. + final String? mergeCommitMessage; + + /// The default value for a merge commit title. + /// + /// - `PR_TITLE` - default to the pull request's title. + /// - `MERGE_MESSAGE` - default to the classic title for a merge message (e.g., + /// Merge pull request #123 from branch-name). + final String? mergeCommitTitle; + + final String? mergesUrl; + final String? milestonesUrl; + final String? mirrorUrl; + final String? name; + final int? networkCount; + final String? nodeId; + final String? notificationsUrl; + final int? openIssuesCount; + final Owner? owner; + final Permissions? permissions; + final bool? private; + final String? pullsUrl; + final DateTime? pushedAt; + final String? releasesUrl; + final int? size; + + /// The default value for a squash merge commit message: + /// + /// - `PR_BODY` - default to the pull request's body. + /// - `COMMIT_MESSAGES` - default to the branch's commit messages. + /// - `BLANK` - default to a blank commit message. + final String? squashMergeCommitMessage; + + /// The default value for a squash merge commit title: + /// + /// - `PR_TITLE` - default to the pull request's title. + /// - `COMMIT_OR_PR_TITLE` - default to the commit's title (if only one commit) + /// or the pull request's title (when more than one commit). + final String? squashMergeCommitTitle; + + final String? sshUrl; + final int? stargazersCount; + final String? stargazersUrl; + final String? statusesUrl; + final int? subscribersCount; + final String? subscribersUrl; + final String? subscriptionUrl; + final String? svnUrl; + final String? tagsUrl; + final String? teamsUrl; + final String? tempCloneToken; + final List? topics; + final String? treesUrl; + final DateTime? updatedAt; + final String? url; + final String? visibility; + final int? watchersCount; + + Map toJson() => _$TemplateRepositoryToJson(this); + + factory TemplateRepository.fromJson(Map input) => + _$TemplateRepositoryFromJson(input); +} + +@JsonSerializable() +class Owner { + Owner({ + this.avatarUrl, + this.eventsUrl, + this.followersUrl, + this.followingUrl, + this.gistsUrl, + this.gravatarId, + this.htmlUrl, + this.id, + this.login, + this.nodeId, + this.organizationsUrl, + this.receivedEventsUrl, + this.reposUrl, + this.siteAdmin, + this.starredUrl, + this.subscriptionsUrl, + this.type, + this.url, + }); + + final String? avatarUrl; + final String? eventsUrl; + final String? followersUrl; + final String? followingUrl; + final String? gistsUrl; + final String? gravatarId; + final String? htmlUrl; + final int? id; + final String? login; + final String? nodeId; + final String? organizationsUrl; + final String? receivedEventsUrl; + final String? reposUrl; + final bool? siteAdmin; + final String? starredUrl; + final String? subscriptionsUrl; + final String? type; + final String? url; + + Map toJson() => _$OwnerToJson(this); + + factory Owner.fromJson(Map input) => _$OwnerFromJson(input); +} + +@JsonSerializable() +class Tree { + Tree({ + this.sha, + this.url, + this.htmlUrl, + }); + + /// SHA for the commit + /// + /// Example: `7638417db6d59f3c431d3e1f261cc637155684cd` + final String? sha; + + final String? url; + + final String? htmlUrl; + + Map toJson() => _$TreeToJson(this); + + factory Tree.fromJson(Map input) => _$TreeFromJson(input); +} + +@JsonSerializable() +class Verification { + Verification({ + this.payload, + this.reason, + this.signature, + this.verified, + }); + + final String? payload; + final String? reason; + final String? signature; + final bool? verified; + + Map toJson() => _$VerificationToJson(this); + + factory Verification.fromJson(Map input) => + _$VerificationFromJson(input); +} + +@JsonSerializable() +class HtmlLink { + HtmlLink({ + this.href, + }); + + final String? href; + + Map toJson() => _$HtmlLinkToJson(this); + + factory HtmlLink.fromJson(Map input) => + _$HtmlLinkFromJson(input); +} + +@JsonSerializable() +class PullRequestLink { + PullRequestLink({ + this.href, + }); + + /// Example: `https://api.github.com/repos/octocat/Hello-World/pulls/1` + final String? href; + + Map toJson() => _$PullRequestLinkToJson(this); + + factory PullRequestLink.fromJson(Map input) => + _$PullRequestLinkFromJson(input); +} diff --git a/lib/src/common/model/timeline_support.g.dart b/lib/src/common/model/timeline_support.g.dart new file mode 100644 index 00000000..c1e441f2 --- /dev/null +++ b/lib/src/common/model/timeline_support.g.dart @@ -0,0 +1,409 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'timeline_support.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +GitHubApp _$GitHubAppFromJson(Map json) => GitHubApp( + clientId: json['client_id'] as String?, + clientSecret: json['client_secret'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + description: json['description'] as String?, + events: + (json['events'] as List?)?.map((e) => e as String).toList(), + externalUrl: json['external_url'] as String?, + htmlUrl: json['html_url'] as String?, + id: json['id'] as int?, + installationsCount: json['installations_count'] as int?, + name: json['name'] as String?, + nodeId: json['node_id'] as String?, + owner: json['owner'] == null + ? null + : User.fromJson(json['owner'] as Map), + pem: json['pem'] as String?, + permissions: json['permissions'] == null + ? null + : Permissions.fromJson(json['permissions'] as Map), + slug: json['slug'] as String?, + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), + webhookSecret: json['webhook_secret'] as String?, + ); + +Map _$GitHubAppToJson(GitHubApp instance) => { + 'client_id': instance.clientId, + 'client_secret': instance.clientSecret, + 'created_at': instance.createdAt?.toIso8601String(), + 'description': instance.description, + 'events': instance.events, + 'external_url': instance.externalUrl, + 'html_url': instance.htmlUrl, + 'id': instance.id, + 'installations_count': instance.installationsCount, + 'name': instance.name, + 'node_id': instance.nodeId, + 'owner': instance.owner, + 'pem': instance.pem, + 'permissions': instance.permissions, + 'slug': instance.slug, + 'updated_at': instance.updatedAt?.toIso8601String(), + 'webhook_secret': instance.webhookSecret, + }; + +Rename _$RenameFromJson(Map json) => Rename( + from: json['from'] as String?, + to: json['to'] as String?, + ); + +Map _$RenameToJson(Rename instance) => { + 'from': instance.from, + 'to': instance.to, + }; + +DismissedReview _$DismissedReviewFromJson(Map json) => + DismissedReview( + dismissalCommitId: json['dismissal_commit_id'] as String?, + dismissalMessage: json['dismissal_message'] as String?, + reviewId: json['review_id'] as int?, + state: json['state'] as String?, + ); + +Map _$DismissedReviewToJson(DismissedReview instance) => + { + 'dismissal_commit_id': instance.dismissalCommitId, + 'dismissal_message': instance.dismissalMessage, + 'review_id': instance.reviewId, + 'state': instance.state, + }; + +ProjectCard _$ProjectCardFromJson(Map json) => ProjectCard( + columnName: json['column_name'] as String?, + id: json['id'] as int?, + previousColumnName: json['previous_column_name'] as String?, + projectId: json['project_id'] as int?, + projectUrl: json['project_url'] as String?, + url: json['url'] as String?, + ); + +Map _$ProjectCardToJson(ProjectCard instance) => + { + 'column_name': instance.columnName, + 'id': instance.id, + 'previous_column_name': instance.previousColumnName, + 'project_id': instance.projectId, + 'project_url': instance.projectUrl, + 'url': instance.url, + }; + +Source _$SourceFromJson(Map json) => Source( + issue: json['issue'] == null + ? null + : Issue.fromJson(json['issue'] as Map), + type: json['type'] as String?, + ); + +Map _$SourceToJson(Source instance) => { + 'issue': instance.issue, + 'type': instance.type, + }; + +License _$LicenseFromJson(Map json) => License( + htmlUrl: json['html_url'] as String?, + key: json['key'] as String?, + name: json['name'] as String?, + nodeId: json['node_id'] as String?, + spdxId: json['spdx_id'] as String?, + url: json['url'] as String?, + ); + +Map _$LicenseToJson(License instance) => { + 'html_url': instance.htmlUrl, + 'key': instance.key, + 'name': instance.name, + 'node_id': instance.nodeId, + 'spdx_id': instance.spdxId, + 'url': instance.url, + }; + +TemplateRepository _$TemplateRepositoryFromJson(Map json) => + TemplateRepository( + allowAutoMerge: json['allow_auto_merge'] as bool?, + allowMergeCommit: json['allow_merge_commit'] as bool?, + allowRebaseMerge: json['allow_rebase_merge'] as bool?, + allowSquashMerge: json['allow_squash_merge'] as bool?, + allowUpdateBranch: json['allow_update_branch'] as bool?, + archiveUrl: json['archive_url'] as String?, + archived: json['archived'] as bool?, + assigneesUrl: json['assignees_url'] as String?, + blobsUrl: json['blobs_url'] as String?, + branchesUrl: json['branches_url'] as String?, + cloneUrl: json['clone_url'] as String?, + collaboratorsUrl: json['collaborators_url'] as String?, + commentsUrl: json['comments_url'] as String?, + commitsUrl: json['commits_url'] as String?, + compareUrl: json['compare_url'] as String?, + contentsUrl: json['contents_url'] as String?, + contributorsUrl: json['contributors_url'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + defaultBranch: json['default_branch'] as String?, + deleteBranchOnMerge: json['delete_branch_on_merge'] as bool?, + deploymentsUrl: json['deployments_url'] as String?, + description: json['description'] as String?, + disabled: json['disabled'] as bool?, + downloadsUrl: json['downloads_url'] as String?, + eventsUrl: json['events_url'] as String?, + fork: json['fork'] as bool?, + forksCount: json['forks_count'] as int?, + forksUrl: json['forks_url'] as String?, + fullName: json['full_name'] as String?, + gitCommitsUrl: json['git_commits_url'] as String?, + gitRefsUrl: json['git_refs_url'] as String?, + gitTagsUrl: json['git_tags_url'] as String?, + gitUrl: json['git_url'] as String?, + hasDownloads: json['has_downloads'] as bool?, + hasIssues: json['has_issues'] as bool?, + hasPages: json['has_pages'] as bool?, + hasProjects: json['has_projects'] as bool?, + hasWiki: json['has_wiki'] as bool?, + homepage: json['homepage'] as String?, + hooksUrl: json['hooks_url'] as String?, + htmlUrl: json['html_url'] as String?, + id: json['id'] as int?, + isTemplate: json['is_template'] as bool?, + issueCommentUrl: json['issue_comment_url'] as String?, + issueEventsUrl: json['issue_events_url'] as String?, + issuesUrl: json['issues_url'] as String?, + keysUrl: json['keys_url'] as String?, + labelsUrl: json['labels_url'] as String?, + language: json['language'] as String?, + languagesUrl: json['languages_url'] as String?, + mergeCommitMessage: json['merge_commit_message'] as String?, + mergeCommitTitle: json['merge_commit_title'] as String?, + mergesUrl: json['merges_url'] as String?, + milestonesUrl: json['milestones_url'] as String?, + mirrorUrl: json['mirror_url'] as String?, + name: json['name'] as String?, + networkCount: json['network_count'] as int?, + nodeId: json['node_id'] as String?, + notificationsUrl: json['notifications_url'] as String?, + openIssuesCount: json['open_issues_count'] as int?, + owner: json['owner'] == null + ? null + : Owner.fromJson(json['owner'] as Map), + permissions: json['permissions'] == null + ? null + : Permissions.fromJson(json['permissions'] as Map), + private: json['private'] as bool?, + pullsUrl: json['pulls_url'] as String?, + pushedAt: json['pushed_at'] == null + ? null + : DateTime.parse(json['pushed_at'] as String), + releasesUrl: json['releases_url'] as String?, + size: json['size'] as int?, + squashMergeCommitMessage: json['squash_merge_commit_message'] as String?, + squashMergeCommitTitle: json['squash_merge_commit_title'] as String?, + sshUrl: json['ssh_url'] as String?, + stargazersCount: json['stargazers_count'] as int?, + stargazersUrl: json['stargazers_url'] as String?, + statusesUrl: json['statuses_url'] as String?, + subscribersCount: json['subscribers_count'] as int?, + subscribersUrl: json['subscribers_url'] as String?, + subscriptionUrl: json['subscription_url'] as String?, + svnUrl: json['svn_url'] as String?, + tagsUrl: json['tags_url'] as String?, + teamsUrl: json['teams_url'] as String?, + tempCloneToken: json['temp_clone_token'] as String?, + topics: + (json['topics'] as List?)?.map((e) => e as String).toList(), + treesUrl: json['trees_url'] as String?, + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), + url: json['url'] as String?, + visibility: json['visibility'] as String?, + watchersCount: json['watchers_count'] as int?, + ); + +Map _$TemplateRepositoryToJson(TemplateRepository instance) => + { + 'allow_auto_merge': instance.allowAutoMerge, + 'allow_merge_commit': instance.allowMergeCommit, + 'allow_rebase_merge': instance.allowRebaseMerge, + 'allow_squash_merge': instance.allowSquashMerge, + 'allow_update_branch': instance.allowUpdateBranch, + 'archive_url': instance.archiveUrl, + 'archived': instance.archived, + 'assignees_url': instance.assigneesUrl, + 'blobs_url': instance.blobsUrl, + 'branches_url': instance.branchesUrl, + 'clone_url': instance.cloneUrl, + 'collaborators_url': instance.collaboratorsUrl, + 'comments_url': instance.commentsUrl, + 'commits_url': instance.commitsUrl, + 'compare_url': instance.compareUrl, + 'contents_url': instance.contentsUrl, + 'contributors_url': instance.contributorsUrl, + 'created_at': instance.createdAt?.toIso8601String(), + 'default_branch': instance.defaultBranch, + 'delete_branch_on_merge': instance.deleteBranchOnMerge, + 'deployments_url': instance.deploymentsUrl, + 'description': instance.description, + 'disabled': instance.disabled, + 'downloads_url': instance.downloadsUrl, + 'events_url': instance.eventsUrl, + 'fork': instance.fork, + 'forks_count': instance.forksCount, + 'forks_url': instance.forksUrl, + 'full_name': instance.fullName, + 'git_commits_url': instance.gitCommitsUrl, + 'git_refs_url': instance.gitRefsUrl, + 'git_tags_url': instance.gitTagsUrl, + 'git_url': instance.gitUrl, + 'has_downloads': instance.hasDownloads, + 'has_issues': instance.hasIssues, + 'has_pages': instance.hasPages, + 'has_projects': instance.hasProjects, + 'has_wiki': instance.hasWiki, + 'homepage': instance.homepage, + 'hooks_url': instance.hooksUrl, + 'html_url': instance.htmlUrl, + 'id': instance.id, + 'is_template': instance.isTemplate, + 'issue_comment_url': instance.issueCommentUrl, + 'issue_events_url': instance.issueEventsUrl, + 'issues_url': instance.issuesUrl, + 'keys_url': instance.keysUrl, + 'labels_url': instance.labelsUrl, + 'language': instance.language, + 'languages_url': instance.languagesUrl, + 'merge_commit_message': instance.mergeCommitMessage, + 'merge_commit_title': instance.mergeCommitTitle, + 'merges_url': instance.mergesUrl, + 'milestones_url': instance.milestonesUrl, + 'mirror_url': instance.mirrorUrl, + 'name': instance.name, + 'network_count': instance.networkCount, + 'node_id': instance.nodeId, + 'notifications_url': instance.notificationsUrl, + 'open_issues_count': instance.openIssuesCount, + 'owner': instance.owner, + 'permissions': instance.permissions, + 'private': instance.private, + 'pulls_url': instance.pullsUrl, + 'pushed_at': instance.pushedAt?.toIso8601String(), + 'releases_url': instance.releasesUrl, + 'size': instance.size, + 'squash_merge_commit_message': instance.squashMergeCommitMessage, + 'squash_merge_commit_title': instance.squashMergeCommitTitle, + 'ssh_url': instance.sshUrl, + 'stargazers_count': instance.stargazersCount, + 'stargazers_url': instance.stargazersUrl, + 'statuses_url': instance.statusesUrl, + 'subscribers_count': instance.subscribersCount, + 'subscribers_url': instance.subscribersUrl, + 'subscription_url': instance.subscriptionUrl, + 'svn_url': instance.svnUrl, + 'tags_url': instance.tagsUrl, + 'teams_url': instance.teamsUrl, + 'temp_clone_token': instance.tempCloneToken, + 'topics': instance.topics, + 'trees_url': instance.treesUrl, + 'updated_at': instance.updatedAt?.toIso8601String(), + 'url': instance.url, + 'visibility': instance.visibility, + 'watchers_count': instance.watchersCount, + }; + +Owner _$OwnerFromJson(Map json) => Owner( + avatarUrl: json['avatar_url'] as String?, + eventsUrl: json['events_url'] as String?, + followersUrl: json['followers_url'] as String?, + followingUrl: json['following_url'] as String?, + gistsUrl: json['gists_url'] as String?, + gravatarId: json['gravatar_id'] as String?, + htmlUrl: json['html_url'] as String?, + id: json['id'] as int?, + login: json['login'] as String?, + nodeId: json['node_id'] as String?, + organizationsUrl: json['organizations_url'] as String?, + receivedEventsUrl: json['received_events_url'] as String?, + reposUrl: json['repos_url'] as String?, + siteAdmin: json['site_admin'] as bool?, + starredUrl: json['starred_url'] as String?, + subscriptionsUrl: json['subscriptions_url'] as String?, + type: json['type'] as String?, + url: json['url'] as String?, + ); + +Map _$OwnerToJson(Owner instance) => { + 'avatar_url': instance.avatarUrl, + 'events_url': instance.eventsUrl, + 'followers_url': instance.followersUrl, + 'following_url': instance.followingUrl, + 'gists_url': instance.gistsUrl, + 'gravatar_id': instance.gravatarId, + 'html_url': instance.htmlUrl, + 'id': instance.id, + 'login': instance.login, + 'node_id': instance.nodeId, + 'organizations_url': instance.organizationsUrl, + 'received_events_url': instance.receivedEventsUrl, + 'repos_url': instance.reposUrl, + 'site_admin': instance.siteAdmin, + 'starred_url': instance.starredUrl, + 'subscriptions_url': instance.subscriptionsUrl, + 'type': instance.type, + 'url': instance.url, + }; + +Tree _$TreeFromJson(Map json) => Tree( + sha: json['sha'] as String?, + url: json['url'] as String?, + htmlUrl: json['html_url'] as String?, + ); + +Map _$TreeToJson(Tree instance) => { + 'sha': instance.sha, + 'url': instance.url, + 'html_url': instance.htmlUrl, + }; + +Verification _$VerificationFromJson(Map json) => Verification( + payload: json['payload'] as String?, + reason: json['reason'] as String?, + signature: json['signature'] as String?, + verified: json['verified'] as bool?, + ); + +Map _$VerificationToJson(Verification instance) => + { + 'payload': instance.payload, + 'reason': instance.reason, + 'signature': instance.signature, + 'verified': instance.verified, + }; + +HtmlLink _$HtmlLinkFromJson(Map json) => HtmlLink( + href: json['href'] as String?, + ); + +Map _$HtmlLinkToJson(HtmlLink instance) => { + 'href': instance.href, + }; + +PullRequestLink _$PullRequestLinkFromJson(Map json) => + PullRequestLink( + href: json['href'] as String?, + ); + +Map _$PullRequestLinkToJson(PullRequestLink instance) => + { + 'href': instance.href, + }; diff --git a/lib/src/common/model/users.dart b/lib/src/common/model/users.dart index 8044983a..f66fd395 100644 --- a/lib/src/common/model/users.dart +++ b/lib/src/common/model/users.dart @@ -24,6 +24,22 @@ class User { this.followingCount, this.createdAt, this.updatedAt, + + // Properties from the Timeline API + this.eventsUrl, + this.followersUrl, + this.followingUrl, + this.gistsUrl, + this.gravatarId, + this.nodeId, + this.organizationsUrl, + this.receivedEventsUrl, + this.reposUrl, + this.starredAt, + this.starredUrl, + this.subscriptionsUrl, + this.type, + this.url, }); @JsonKey(includeToJson: false, includeFromJson: false) @@ -90,6 +106,49 @@ class User { /// The username of the twitter account (without leading @) String? twitterUsername; + // The following properties were added to support the Timeline API. + + /// Example: `https://api.github.com/users/octocat/events{/privacy}` + String? eventsUrl; + + /// Example: `https://api.github.com/users/octocat/followers` + String? followersUrl; + + /// Example: `https://api.github.com/users/octocat/following{/other_user}` + String? followingUrl; + + /// Example: `https://api.github.com/users/octocat/gists{/gist_id}` + String? gistsUrl; + + /// Example: `41d064eb2195891e12d0413f63227ea7` + String? gravatarId; + + /// Example: `MDQ6VXNlcjE=` + String? nodeId; + + /// Example: `https://api.github.com/users/octocat/orgs` + String? organizationsUrl; + + /// Example: `https://api.github.com/users/octocat/received_events` + String? receivedEventsUrl; + + /// Example: `https://api.github.com/users/octocat/repos` + String? reposUrl; + + DateTime? starredAt; + + /// Example: `https://api.github.com/users/octocat/starred{/owner}{/repo}` + String? starredUrl; + + /// Example: `https://api.github.com/users/octocat/subscriptions` + String? subscriptionsUrl; + + /// Example: `User` + String? type; + + /// Example: `https://api.github.com/users/octocat` + String? url; + factory User.fromJson(Map input) => _$UserFromJson(input); Map toJson() => _$UserToJson(this); } @@ -98,13 +157,6 @@ class User { // https://developer.github.com/v3/repos/collaborators/#response @JsonSerializable() class Collaborator { - final String? login; - final int? id; - final String? htmlUrl; - final String? type; - final bool? siteAdmin; - final Map? permissions; - Collaborator( this.login, this.id, @@ -114,6 +166,13 @@ class Collaborator { this.permissions, ); + String? login; + int? id; + String? htmlUrl; + String? type; + bool? siteAdmin; + Map? permissions; + factory Collaborator.fromJson(Map json) => _$CollaboratorFromJson(json); Map toJson() => _$CollaboratorToJson(this); diff --git a/lib/src/common/model/users.g.dart b/lib/src/common/model/users.g.dart index 2713125a..40e4a306 100644 --- a/lib/src/common/model/users.g.dart +++ b/lib/src/common/model/users.g.dart @@ -29,6 +29,22 @@ User _$UserFromJson(Map json) => User( updatedAt: json['updated_at'] == null ? null : DateTime.parse(json['updated_at'] as String), + eventsUrl: json['events_url'] as String?, + followersUrl: json['followers_url'] as String?, + followingUrl: json['following_url'] as String?, + gistsUrl: json['gists_url'] as String?, + gravatarId: json['gravatar_id'] as String?, + nodeId: json['node_id'] as String?, + organizationsUrl: json['organizations_url'] as String?, + receivedEventsUrl: json['received_events_url'] as String?, + reposUrl: json['repos_url'] as String?, + starredAt: json['starred_at'] == null + ? null + : DateTime.parse(json['starred_at'] as String), + starredUrl: json['starred_url'] as String?, + subscriptionsUrl: json['subscriptions_url'] as String?, + type: json['type'] as String?, + url: json['url'] as String?, )..twitterUsername = json['twitter_username'] as String?; Map _$UserToJson(User instance) => { @@ -51,6 +67,20 @@ Map _$UserToJson(User instance) => { 'created_at': instance.createdAt?.toIso8601String(), 'updated_at': instance.updatedAt?.toIso8601String(), 'twitter_username': instance.twitterUsername, + 'events_url': instance.eventsUrl, + 'followers_url': instance.followersUrl, + 'following_url': instance.followingUrl, + 'gists_url': instance.gistsUrl, + 'gravatar_id': instance.gravatarId, + 'node_id': instance.nodeId, + 'organizations_url': instance.organizationsUrl, + 'received_events_url': instance.receivedEventsUrl, + 'repos_url': instance.reposUrl, + 'starred_at': instance.starredAt?.toIso8601String(), + 'starred_url': instance.starredUrl, + 'subscriptions_url': instance.subscriptionsUrl, + 'type': instance.type, + 'url': instance.url, }; Collaborator _$CollaboratorFromJson(Map json) => Collaborator( @@ -119,6 +149,22 @@ CurrentUser _$CurrentUserFromJson(Map json) => CurrentUser() ? null : DateTime.parse(json['updated_at'] as String) ..twitterUsername = json['twitter_username'] as String? + ..eventsUrl = json['events_url'] as String? + ..followersUrl = json['followers_url'] as String? + ..followingUrl = json['following_url'] as String? + ..gistsUrl = json['gists_url'] as String? + ..gravatarId = json['gravatar_id'] as String? + ..nodeId = json['node_id'] as String? + ..organizationsUrl = json['organizations_url'] as String? + ..receivedEventsUrl = json['received_events_url'] as String? + ..reposUrl = json['repos_url'] as String? + ..starredAt = json['starred_at'] == null + ? null + : DateTime.parse(json['starred_at'] as String) + ..starredUrl = json['starred_url'] as String? + ..subscriptionsUrl = json['subscriptions_url'] as String? + ..type = json['type'] as String? + ..url = json['url'] as String? ..privateReposCount = json['total_private_repos'] as int? ..ownedPrivateReposCount = json['owned_private_repos'] as int? ..diskUsage = json['disk_usage'] as int? @@ -147,6 +193,20 @@ Map _$CurrentUserToJson(CurrentUser instance) => 'created_at': instance.createdAt?.toIso8601String(), 'updated_at': instance.updatedAt?.toIso8601String(), 'twitter_username': instance.twitterUsername, + 'events_url': instance.eventsUrl, + 'followers_url': instance.followersUrl, + 'following_url': instance.followingUrl, + 'gists_url': instance.gistsUrl, + 'gravatar_id': instance.gravatarId, + 'node_id': instance.nodeId, + 'organizations_url': instance.organizationsUrl, + 'received_events_url': instance.receivedEventsUrl, + 'repos_url': instance.reposUrl, + 'starred_at': instance.starredAt?.toIso8601String(), + 'starred_url': instance.starredUrl, + 'subscriptions_url': instance.subscriptionsUrl, + 'type': instance.type, + 'url': instance.url, 'total_private_repos': instance.privateReposCount, 'owned_private_repos': instance.ownedPrivateReposCount, 'disk_usage': instance.diskUsage, diff --git a/tool/process_github_schema.dart b/tool/process_github_schema.dart new file mode 100644 index 00000000..e3850df5 --- /dev/null +++ b/tool/process_github_schema.dart @@ -0,0 +1,621 @@ +import 'dart:convert'; +import 'dart:io'; + +const int width = 72; + +List wordWrap(String body) { + var result = []; + var start = 0; + for (var index = 0; index < body.length; index += 1) { + if ((index == body.length - 1) || + (body[index] == '\n') || + ((body[index] == ' ') && (index - start > width))) { + result.add(body.substring(start, index + 1).trimRight()); + start = index + 1; + } + } + assert(start == body.length); + return result; +} + +typedef GenTypeVisitor = void Function(GenType type); + +abstract class GenType extends Comparable { + GenType(); + + String get name; + String get comment => ''; + + String get signature; + + void cleanup() {} + + String generateDeclaration(); + + void visit(GenTypeVisitor visitor) { + visitor(this); + } + + GenType mergeWith(GenType other, GenAbstractClass? superclass) { + assert(signature == other.signature, + 'cannot merge types with different signatures'); + throw StateError( + 'not sure how to merge $runtimeType with ${other.runtimeType}'); + } + + @override + int compareTo(GenType other) { + return signature.compareTo(other.signature); + } + + @override + String toString() => '$runtimeType($name)'; +} + +class GenPrimitive extends GenType { + GenPrimitive(this.type, this.comment); + + @override + String get name => type.toString(); + + @override + String get signature => name; + + @override + String generateDeclaration() => ''; + + @override + final String comment; + + final Type type; + + @override + GenType mergeWith(GenType other, GenAbstractClass? superclass) { + assert(superclass == null); + if (other is GenPrimitive) { + assert(type == other.type); + if (comment != other.comment) { + return GenPrimitive( + type, + '$comment\n\n${other.comment}', + ); + } + return this; + } + return super.mergeWith(other, superclass); + } +} + +class GenUnion extends GenType { + GenUnion(this.subtypes); + + @override + String get name => 'Object'; + + @override + String get comment { + var result = StringBuffer(); + result.writeln('One of the following:'); + for (final subtype in subtypes) { + if (subtype.comment.isNotEmpty) { + result.writeln( + ' * [${subtype.name}]: ${subtype.comment.split('\n').first}'); + } else { + result.writeln(' * [${subtype.name}]'); + } + } + return result.toString(); + } + + @override + String get signature { + var subsignatures = + subtypes.map((GenType type) => type.signature).toList() + ..sort() + ..join(','); + return 'Union<$subsignatures>'; + } + + final List subtypes; + + @override + String generateDeclaration() => ''; + + @override + void visit(GenTypeVisitor visitor) { + super.visit(visitor); + for (final subtype in subtypes) { + subtype.visit(visitor); + } + } + + @override + GenType mergeWith(GenType other, GenAbstractClass? superclass) { + assert(superclass == null); + if (other is GenUnion) { + assert(subtypes.length == other.subtypes.length); + var subtypesA = subtypes..sort(); + var subtypesB = other.subtypes..sort(); + var subtypesC = []; + for (var index = 0; index < subtypesA.length; index += 1) { + subtypesC.add(subtypesA[index].mergeWith(subtypesB[index], null)); + } + return GenUnion(subtypesC); + } + return super.mergeWith(other, superclass); + } +} + +class GenList extends GenType { + GenList(this.members, this.comment); + + @override + String get name => 'List<${members.name}>'; + + @override + final String comment; + + final GenType members; + + @override + String get signature { + return 'List<${members.signature}>'; + } + + @override + String generateDeclaration() => ''; + + @override + void visit(GenTypeVisitor visitor) { + super.visit(visitor); + members.visit(visitor); + } + + @override + GenType mergeWith(GenType other, GenAbstractClass? superclass) { + assert(superclass == null); + if (other is GenList) { + var newComment = + comment != other.comment ? '$comment\n\n${other.comment}' : comment; + var newMembers = members.mergeWith(other.members, null); + return GenList(newMembers, newComment); + } + return super.mergeWith(other, superclass); + } +} + +class GenAbstractClass extends GenType { + GenAbstractClass(this.name, this.comment, {Map? properties}) + : properties = properties ?? {}; + + @override + final String name; + + @override + final String comment; + + final List subclasses = []; + final Map properties; + + @override + String get signature { + var propertySignatures = properties.keys + .map((String propertyName) => + '$propertyName:${properties[propertyName]!.signature}') + .toList() + ..sort() + ..join(','); + return 'abstract class $name { $propertySignatures }'; + } + + @override + void cleanup() { + if (subclasses.length > 1) { + var names = subclasses.first.properties.keys.toSet(); + properties: + for (final name in names) { + var signature = subclasses.first.properties[name]!.signature; + for (final subclass in subclasses.skip(1)) { + if (!subclass.properties.containsKey(name) || + subclass.properties[name]!.signature != signature) { + continue properties; + } + } + var property = subclasses.first.properties[name]!; + for (final subclass in subclasses.skip(1)) { + property = property.mergeWith(subclass.properties[name]!, null); + } + properties[name] = property; + for (final subclass in subclasses) { + subclass.properties.remove(name); + } + } + } + } + + @override + String generateDeclaration() { + var output = StringBuffer(); + if (comment.isNotEmpty) { + for (final line in wordWrap(comment)) { + output.writeln('/// $line'); + } + } + output.writeln('@JsonSerializable()'); + output.writeln('abstract class $name {'); + output.write(' $name('); + if (properties.isNotEmpty) { + output.writeln('{'); + for (final propertyName in properties.keys.toList()..sort()) { + output.writeln(' this.$propertyName,'); + } + output.write(' }'); + } + output.writeln(');'); + output.writeln(''); + var lastLineWasBlank = true; + for (final propertyName in properties.keys.toList()..sort()) { + if (properties[propertyName]!.comment.isNotEmpty) { + if (!lastLineWasBlank) { + output.writeln(''); + lastLineWasBlank = true; + } + for (final line in wordWrap(properties[propertyName]!.comment)) { + output.writeln(' /// $line'); + } + } else { + lastLineWasBlank = false; + } + output.writeln(' ${properties[propertyName]!.name}? $propertyName;'); + if (lastLineWasBlank) { + output.writeln(''); + lastLineWasBlank = true; + } + } + output.writeln('}'); + return output.toString(); + } + + @override + void visit(GenTypeVisitor visitor) { + super.visit(visitor); + for (final subclass in subclasses) { + subclass.visit(visitor); + } + } + + @override + GenType mergeWith(GenType other, GenAbstractClass? superclass) { + assert(superclass == null); + if (other is GenAbstractClass) { + assert(name == other.name); + assert(properties.length == other.properties.length); + var newComment = + comment != other.comment ? '$comment\n\n${other.comment}' : comment; + var newProperties = {}; + for (final propertyName in properties.keys) { + newProperties[propertyName] = properties[propertyName]! + .mergeWith(other.properties[propertyName]!, null); + } + var result = + GenAbstractClass(name, newComment, properties: newProperties); + var subclassesA = subclasses..sort(); + var subclassesB = other.subclasses..sort(); + for (var index = 0; index < subclassesA.length; index += 1) { + subclassesA[index].mergeWith(subclassesB[index], result); + } + assert(result.subclasses.length == subclasses.length); + assert(result.subclasses.length == other.subclasses.length); + return result; + } + return super.mergeWith(other, superclass); + } +} + +class GenClass extends GenType { + GenClass(this.name, this.comment, this.superclass, this.properties) { + if (superclass != null) { + superclass!.subclasses.add(this); + } + } + + @override + final String name; + + @override + final String comment; + + final GenAbstractClass? superclass; + final Map properties; + + @override + String get signature { + var propertySignatures = properties.keys + .map((String propertyName) => + '$propertyName:${properties[propertyName]!.signature}') + .toList() + ..sort() + ..join(','); + return 'class $name extends { ${superclass?.signature} } with { $propertySignatures }'; + } + + @override + String generateDeclaration() { + var output = StringBuffer(); + if (comment.isNotEmpty) { + for (final line in wordWrap(comment)) { + output.writeln('/// $line'); + } + } + output.writeln('@JsonSerializable()'); + output.write('class $name '); + if (superclass != null) { + output.write('extends ${superclass!.name} '); + } + output.writeln('{'); + output.writeln(' $name({'); + if (superclass != null) { + for (final propertyName in superclass!.properties.keys.toList()..sort()) { + output.writeln(' super.$propertyName,'); + } + } + for (final propertyName in properties.keys.toList()..sort()) { + output.writeln(' this.$propertyName,'); + } + output.writeln(' });'); + output.writeln(''); + var lastLineWasBlank = true; + for (final propertyName in properties.keys.toList()..sort()) { + if (properties[propertyName]!.comment.isNotEmpty) { + if (!lastLineWasBlank) { + output.writeln(''); + lastLineWasBlank = true; + } + for (final line in wordWrap(properties[propertyName]!.comment)) { + output.writeln(' /// $line'); + } + } else { + lastLineWasBlank = false; + } + output.writeln(' ${properties[propertyName]!.name}? $propertyName;'); + if (lastLineWasBlank) { + output.writeln(''); + lastLineWasBlank = true; + } + } + if (!lastLineWasBlank) { + output.writeln(''); + } + output + .writeln(' Map toJson() => _\$${name}ToJson(this);'); + output.writeln(''); + output.writeln(' factory $name.fromJson(Map input) =>'); + output.writeln(' _\$${name}FromJson(input);'); + output.writeln('}'); + return output.toString(); + } + + @override + void visit(GenTypeVisitor visitor) { + super.visit(visitor); + for (final property in properties.values) { + property.visit(visitor); + } + } + + @override + GenType mergeWith(GenType other, GenAbstractClass? superclass) { + assert((superclass == null) == (this.superclass == null)); + if (other is GenClass) { + assert((other.superclass == null) == (this.superclass == null)); + assert(name == other.name); + assert(properties.length == other.properties.length); + var newComment = + comment != other.comment ? '$comment\n\n${other.comment}' : comment; + var newProperties = {}; + for (final propertyName in properties.keys) { + newProperties[propertyName] = properties[propertyName]! + .mergeWith(other.properties[propertyName]!, null); + } + return GenClass(name, newComment, superclass, newProperties); + } + return super.mergeWith(other, superclass); + } +} + +void assure(bool condition, String Function() callback) { + if (!condition) { + print(callback()); + exit(1); + } +} + +String? camelCase(String? text, {bool uppercase = false}) { + if (text == null) { + return null; + } + var bits = text.split(RegExp('[- _]')); + var result = StringBuffer(); + for (final bit in bits) { + if (bit.isNotEmpty) { + if (result.isNotEmpty || uppercase) { + result.write(String.fromCharCode(bit.runes.first).toUpperCase()); + result.write(String.fromCharCodes(bit.runes.skip(1))); + } else { + result.write(bit); + } + } + } + return result.toString(); +} + +String buildComment(Map schema) { + var description = StringBuffer(); + if (schema['title'] != null) { + description.writeln(schema['title']); + } + if (schema['description'] != null && + schema['description'] != schema['title']) { + if (description.isNotEmpty) { + description.writeln(''); + } + description.writeln(schema['description']); + } + if (schema['format'] != null) { + if (description.isNotEmpty) { + description.writeln(''); + } + description.write('Format: '); + description.writeln(schema['format']); + } + if (schema['examples'] != null) { + assure(schema['examples'] is List, + () => 'examples should be a list, not as in $schema'); + for (final example in schema['examples'] as List) { + if (description.isNotEmpty) { + description.writeln(''); + } + description.writeln('Example: `$example`'); + } + } + return description.toString().trimRight(); +} + +GenType process(Map schema, {String? defaultName}) { + final comment = buildComment(schema); + String type; + if (schema['type'] is List) { + var types = schema['type'] as List; + if (types.length == 2) { + if (types[0] == 'null' && types[1] is String) { + type = types[1] as String; + } else if (types[1] == 'null' && types[0] is String) { + type = types[0] as String; + } else { + print('Arbitrary union types not supported: $types'); + exit(1); + } + } else { + print('Arbitrary union types not supported: $types'); + exit(1); + } + } else if (schema['type'] is String) { + type = schema['type'] as String; + } else { + var anyOf = schema['anyOf'] ?? schema['oneOf']; + if (anyOf != null) { + assure(comment.isEmpty, () => 'lost comment to anyOf/oneOf: $comment'); + assure( + anyOf is List, () => 'anyOf/oneOf key is not a JSON list'); + var subtypes = []; + for (final subtype in anyOf as List) { + assure(subtype is Map, + () => 'type in anyOf/oneOf is not a JSON object'); + subtypes.add(process(subtype as Map)); + } + if (subtypes.length == 2) { + if (subtypes[0] is GenPrimitive && + (subtypes[0] as GenPrimitive).type == Null) { + return subtypes[1]; + } + if (subtypes[1] is GenPrimitive && + (subtypes[1] as GenPrimitive).type == Null) { + return subtypes[0]; + } + } + return GenUnion(subtypes); + } + if (schema['type'] == null) { + print('missing type: $schema'); + exit(1); + } + print('unknown type ${schema['type']}'); + exit(1); + } + if (type == 'array') { + assure(schema['items'] is Map, + () => 'array items are not a JSON object'); + return GenList(process(schema['items'] as Map), comment); + } + if (type == 'object') { + var anyOf = schema['anyOf']; + if (anyOf != null) { + assure(anyOf is List, () => 'anyOf key is not a JSON list'); + var result = GenAbstractClass( + camelCase(schema['title'] as String?) ?? '##unnamed##', + comment, + ); + for (final subschema in anyOf as List) { + assure(subschema is Map, + () => 'anyOf value is not a JSON object'); + var subclass = processObject(subschema as Map, + superclass: result); + assert(result.subclasses.last == subclass); + } + return result; + } + return processObject(schema, defaultName: defaultName); + } + if (type == 'null') { + return GenPrimitive(Null, comment); + } + if (type == 'boolean') { + return GenPrimitive(bool, comment); + } + if (type == 'integer') { + return GenPrimitive(int, comment); + } + if (type == 'string') { + return GenPrimitive(String, comment); + } + print('unknown type $type'); + exit(1); +} + +GenClass processObject(Map schema, + {GenAbstractClass? superclass, String? comment, String? defaultName}) { + assert(schema['anyOf'] == null); + comment ??= buildComment(schema); + var properties = {}; + var propertiesData = schema['properties']; + assure(propertiesData is Map, + () => 'properties key is not a JSON map'); + for (final propertyName in (propertiesData as Map).keys) { + var propertyData = propertiesData[propertyName]; + assure(propertyData is Map, + () => 'property $propertyName is not a JSON object'); + properties[camelCase(propertyName)!] = process( + propertyData as Map, + defaultName: camelCase(propertyName, uppercase: true)); + } + return GenClass( + camelCase(schema['title'] as String?) ?? defaultName ?? '##unnamed##', + comment, + superclass, + properties, + ); +} + +void main(List arguments) { + if (arguments.length != 1) { + print( + 'Command must be run with one argument, the file name of the schema to process.'); + exit(1); + } + Object schema = json.decode(File(arguments.single).readAsStringSync()); + assure(schema is Map, () => 'schema is not a JSON object'); + var rootType = process(schema as Map); + rootType.visit((GenType type) { + type.cleanup(); + }); + var declarations = {}; + rootType.visit((GenType type) { + var declaration = type.generateDeclaration().trimRight(); + declarations.add(declaration); + }); + for (final declaration in declarations) { + print(declaration); + print(''); + } + print('// root type is: ${rootType.name}'); +} From 3771b3c9ab1912d32a0d0baffaf489d561caf558 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 17 Apr 2023 08:55:14 -0600 Subject: [PATCH 098/139] prep 9.12.0 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 62d162e6..5449f961 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.11.0 +version: 9.12.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 20588d01bc0fd3b9a4ada482078b1190695bda72 Mon Sep 17 00:00:00 2001 From: Ricardo Amador <32242716+ricardoamador@users.noreply.github.com> Date: Tue, 9 May 2023 19:53:24 -0700 Subject: [PATCH 099/139] Add node_id to the pull request model (#367) --- lib/src/common/model/pulls.dart | 4 + lib/src/common/model/pulls.g.dart | 2 + test/unit/common/model/pulls_test.dart | 246 +++++++++++++++++++++++++ 3 files changed, 252 insertions(+) create mode 100644 test/unit/common/model/pulls_test.dart diff --git a/lib/src/common/model/pulls.dart b/lib/src/common/model/pulls.dart index b6f20e55..cdbf6ed8 100644 --- a/lib/src/common/model/pulls.dart +++ b/lib/src/common/model/pulls.dart @@ -9,6 +9,7 @@ part 'pulls.g.dart'; class PullRequest { PullRequest({ this.id, + this.nodeId, this.htmlUrl, this.diffUrl, this.patchUrl, @@ -46,6 +47,9 @@ class PullRequest { /// Pull Request ID int? id; + /// Unique node identification string. + String? nodeId; + /// Url to the Pull Request Page String? htmlUrl; diff --git a/lib/src/common/model/pulls.g.dart b/lib/src/common/model/pulls.g.dart index 3608260c..dfe3a3b3 100644 --- a/lib/src/common/model/pulls.g.dart +++ b/lib/src/common/model/pulls.g.dart @@ -8,6 +8,7 @@ part of 'pulls.dart'; PullRequest _$PullRequestFromJson(Map json) => PullRequest( id: json['id'] as int?, + nodeId: json['node_id'] as String?, htmlUrl: json['html_url'] as String?, diffUrl: json['diff_url'] as String?, patchUrl: json['patch_url'] as String?, @@ -69,6 +70,7 @@ PullRequest _$PullRequestFromJson(Map json) => PullRequest( Map _$PullRequestToJson(PullRequest instance) => { 'id': instance.id, + 'node_id': instance.nodeId, 'html_url': instance.htmlUrl, 'diff_url': instance.diffUrl, 'patch_url': instance.patchUrl, diff --git a/test/unit/common/model/pulls_test.dart b/test/unit/common/model/pulls_test.dart new file mode 100644 index 00000000..f4d5fe65 --- /dev/null +++ b/test/unit/common/model/pulls_test.dart @@ -0,0 +1,246 @@ +import 'dart:convert'; + +import 'package:github/src/common/model/pulls.dart'; +import 'package:test/test.dart'; + +const String samplePullRequest = ''' + { + "url": "https://api.github.com/repos/flutter/cocoon/pulls/2703", + "id": 1344460863, + "node_id": "PR_kwDOA8VHis5QItg_", + "html_url": "https://github.com/flutter/cocoon/pull/2703", + "diff_url": "https://github.com/flutter/cocoon/pull/2703.diff", + "patch_url": "https://github.com/flutter/cocoon/pull/2703.patch", + "issue_url": "https://api.github.com/repos/flutter/cocoon/issues/2703", + "number": 2703, + "state": "open", + "locked": false, + "title": "Bump url_launcher from 6.1.10 to 6.1.11 in /dashboard", + "user": { + "login": "dependabot[bot]", + "id": 49699333, + "node_id": "MDM6Qm90NDk2OTkzMzM=", + "avatar_url": "https://avatars.githubusercontent.com/in/29110?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/dependabot%5Bbot%5D", + "html_url": "https://github.com/apps/dependabot", + "type": "Bot", + "site_admin": false + }, + "body": "Bumps [url_launcher](https://github.com/flutter/packages/tree/main/packages/url_launcher) from 6.1.10 to 6.1.11.", + "created_at": "2023-05-09T22:23:34Z", + "updated_at": "2023-05-09T22:23:35Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "252a1a4370e30631b090eeeda182879985cc8f08", + "assignee": null, + "assignees": [ + + ], + "requested_reviewers": [ + + ], + "requested_teams": [ + + ], + "labels": [ + { + "id": 3960015931, + "node_id": "LA_kwDOA8VHis7sCQw7", + "url": "https://api.github.com/repos/flutter/cocoon/labels/autosubmit", + "name": "autosubmit", + "color": "0E8A16", + "default": false, + "description": "Merge PR when tree becomes green via auto submit App" + } + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/flutter/cocoon/pulls/2703/commits", + "review_comments_url": "https://api.github.com/repos/flutter/cocoon/pulls/2703/comments", + "review_comment_url": "https://api.github.com/repos/flutter/cocoon/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/flutter/cocoon/issues/2703/comments", + "statuses_url": "https://api.github.com/repos/flutter/cocoon/statuses/57ec5a040c8a631e39b3f3dee82a77fdf79b6e19", + "head": { + "label": "flutter:dependabot/pub/dashboard/url_launcher-6.1.11", + "ref": "dependabot/pub/dashboard/url_launcher-6.1.11", + "sha": "57ec5a040c8a631e39b3f3dee82a77fdf79b6e19", + "user": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 63260554, + "node_id": "MDEwOlJlcG9zaXRvcnk2MzI2MDU1NA==", + "name": "cocoon", + "full_name": "flutter/cocoon", + "private": false, + "owner": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/flutter/cocoon", + "description": "Flutter's build coordinator and aggregator", + "fork": false, + "url": "https://api.github.com/repos/flutter/cocoon", + "forks_url": "https://api.github.com/repos/flutter/cocoon/forks", + "created_at": "2016-07-13T16:04:04Z", + "updated_at": "2023-04-12T16:34:46Z", + "pushed_at": "2023-05-09T22:23:35Z", + "git_url": "git://github.com/flutter/cocoon.git", + "ssh_url": "git@github.com:flutter/cocoon.git", + "clone_url": "https://github.com/flutter/cocoon.git", + "svn_url": "https://github.com/flutter/cocoon", + "homepage": null, + "size": 13247, + "stargazers_count": 171, + "watchers_count": 171, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "public", + "forks": 91, + "open_issues": 2, + "watchers": 171, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": false, + "allow_rebase_merge": false, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": true, + "squash_merge_commit_message": "PR_BODY", + "squash_merge_commit_title": "PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "flutter:main", + "ref": "main", + "sha": "152dd99368b8417b2ede8ed49d5923e594a3b0f2", + "user": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 63260554, + "node_id": "MDEwOlJlcG9zaXRvcnk2MzI2MDU1NA==", + "name": "cocoon", + "full_name": "flutter/cocoon", + "private": false, + "owner": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/flutter/cocoon", + "description": "Flutter's build coordinator and aggregator", + "fork": false, + "url": "https://api.github.com/repos/flutter/cocoon", + "forks_url": "https://api.github.com/repos/flutter/cocoon/forks", + "created_at": "2016-07-13T16:04:04Z", + "updated_at": "2023-04-12T16:34:46Z", + "pushed_at": "2023-05-09T22:23:35Z", + "git_url": "git://github.com/flutter/cocoon.git", + "ssh_url": "git@github.com:flutter/cocoon.git", + "clone_url": "https://github.com/flutter/cocoon.git", + "svn_url": "https://github.com/flutter/cocoon", + "homepage": null, + "size": 13247, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "public", + "forks": 91, + "open_issues": 2, + "watchers": 171, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": false, + "allow_rebase_merge": false, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": true, + "squash_merge_commit_message": "PR_BODY", + "squash_merge_commit_title": "PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "author_association": "CONTRIBUTOR", + "auto_merge": null, + "active_lock_reason": null, + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "unstable", + "merged_by": null, + "comments": 0, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 1, + "additions": 119, + "deletions": 202, + "changed_files": 2 + } +'''; + +void main() { + group('Pull Request fromJson', () { + test('Node ID is collected', () { + final pullRequest = PullRequest.fromJson(jsonDecode(samplePullRequest)); + expect(pullRequest, isNotNull); + expect(pullRequest.nodeId, "PR_kwDOA8VHis5QItg_"); + }); + }); +} From 87babe4af82a7cff2564ada331ccdd2256f3a8d6 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 9 May 2023 21:17:50 -0600 Subject: [PATCH 100/139] prep 9.13.0 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df8472a1..efd7d81c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.13.0 + +* Add node_id to the pull request model by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/367 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.12.0...9.13.0 + ## 9.12.0 * Add support for issue and PR timeline events via `Issue.listTimeline`. diff --git a/pubspec.yaml b/pubspec.yaml index 5449f961..c3efddc9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.12.0 +version: 9.13.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 4986ac130fd006bfaabe57c0ba1887ccd16628ec Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Thu, 11 May 2023 09:21:12 -0700 Subject: [PATCH 101/139] Add optional filter params on Repositories.listCommits (#368) * Add optional filter params on Repositories.listCommits * dart format --------- Co-authored-by: Rob Becker --- lib/src/common/repos_service.dart | 29 ++++++++++- test/common/data/repos_json.dart | 81 +++++++++++++++++++++++++++++ test/common/repos_service_test.dart | 49 +++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 test/common/data/repos_json.dart create mode 100644 test/common/repos_service_test.dart diff --git a/lib/src/common/repos_service.dart b/lib/src/common/repos_service.dart index 535e1060..a274710e 100644 --- a/lib/src/common/repos_service.dart +++ b/lib/src/common/repos_service.dart @@ -448,14 +448,41 @@ class RepositoriesService extends Service { /// Lists the commits of the provided repository [slug]. /// + /// [sha] is the SHA or branch to start listing commits from. Default: the + /// repository’s default branch (usually main). + /// + /// [path] will only show commits that changed that file path. + /// + /// [author] and [committer] are the GitHub username to filter commits for. + /// + /// [since] shows commit after this time, and [until] shows commits before + /// this time. + /// /// API docs: https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository - Stream listCommits(RepositorySlug slug) { + Stream listCommits( + RepositorySlug slug, { + String? sha, + String? path, + String? author, + String? committer, + DateTime? since, + DateTime? until, + }) { ArgumentError.checkNotNull(slug); + final params = { + if (author != null) 'author': author, + if (committer != null) 'committer': committer, + if (sha != null) 'sha': sha, + if (path != null) 'path': path, + if (since != null) 'since': since.toIso8601String(), + if (until != null) 'until': until.toIso8601String(), + }; return PaginationHelper(github) .objects, RepositoryCommit>( 'GET', '/repos/${slug.fullName}/commits', RepositoryCommit.fromJson, + params: params, ); } diff --git a/test/common/data/repos_json.dart b/test/common/data/repos_json.dart new file mode 100644 index 00000000..f5087cf7 --- /dev/null +++ b/test/common/data/repos_json.dart @@ -0,0 +1,81 @@ +const String listCommits = ''' +[ + { + "sha": "3771b3c9ab1912d32a0d0baffaf489d561caf558", + "node_id": "C_kwDOAVT0d9oAKDM3NzFiM2M5YWIxOTEyZDMyYTBkMGJhZmZhZjQ4OWQ1NjFjYWY1NTg", + "commit": { + "author": { + "name": "Rob Becker", + "email": "rob.becker@workiva.com", + "date": "2023-04-17T14:55:14Z" + }, + "committer": { + "name": "Rob Becker", + "email": "rob.becker@workiva.com", + "date": "2023-04-17T14:55:14Z" + }, + "message": "prep 9.12.0", + "tree": { + "sha": "282532b41e8fead81ec6d68e7e603139e7dd7581", + "url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/trees/282532b41e8fead81ec6d68e7e603139e7dd7581" + }, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart/git/commits/3771b3c9ab1912d32a0d0baffaf489d561caf558", + "comment_count": 0, + "verification": { + "verified": true, + "reason": "valid" + } + }, + "url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits/3771b3c9ab1912d32a0d0baffaf489d561caf558", + "html_url": "https://github.com/SpinlockLabs/github.dart/commit/3771b3c9ab1912d32a0d0baffaf489d561caf558", + "comments_url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits/3771b3c9ab1912d32a0d0baffaf489d561caf558/comments", + "author": { + "login": "robbecker-wf", + "id": 6053699, + "node_id": "MDQ6VXNlcjYwNTM2OTk=", + "avatar_url": "https://avatars.githubusercontent.com/u/6053699?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/robbecker-wf", + "html_url": "https://github.com/robbecker-wf", + "followers_url": "https://api.github.com/users/robbecker-wf/followers", + "following_url": "https://api.github.com/users/robbecker-wf/following{/other_user}", + "gists_url": "https://api.github.com/users/robbecker-wf/gists{/gist_id}", + "starred_url": "https://api.github.com/users/robbecker-wf/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/robbecker-wf/subscriptions", + "organizations_url": "https://api.github.com/users/robbecker-wf/orgs", + "repos_url": "https://api.github.com/users/robbecker-wf/repos", + "events_url": "https://api.github.com/users/robbecker-wf/events{/privacy}", + "received_events_url": "https://api.github.com/users/robbecker-wf/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "robbecker-wf", + "id": 6053699, + "node_id": "MDQ6VXNlcjYwNTM2OTk=", + "avatar_url": "https://avatars.githubusercontent.com/u/6053699?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/robbecker-wf", + "html_url": "https://github.com/robbecker-wf", + "followers_url": "https://api.github.com/users/robbecker-wf/followers", + "following_url": "https://api.github.com/users/robbecker-wf/following{/other_user}", + "gists_url": "https://api.github.com/users/robbecker-wf/gists{/gist_id}", + "starred_url": "https://api.github.com/users/robbecker-wf/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/robbecker-wf/subscriptions", + "organizations_url": "https://api.github.com/users/robbecker-wf/orgs", + "repos_url": "https://api.github.com/users/robbecker-wf/repos", + "events_url": "https://api.github.com/users/robbecker-wf/events{/privacy}", + "received_events_url": "https://api.github.com/users/robbecker-wf/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + { + "sha": "a3081681da68383d9a5f18ef3502f47f7144e7d8", + "url": "https://api.github.com/repos/SpinlockLabs/github.dart/commits/a3081681da68383d9a5f18ef3502f47f7144e7d8", + "html_url": "https://github.com/SpinlockLabs/github.dart/commit/a3081681da68383d9a5f18ef3502f47f7144e7d8" + } + ] + } +] +'''; diff --git a/test/common/repos_service_test.dart b/test/common/repos_service_test.dart new file mode 100644 index 00000000..feebe05c --- /dev/null +++ b/test/common/repos_service_test.dart @@ -0,0 +1,49 @@ +import 'package:github/src/common.dart'; +import 'package:http/http.dart'; +import 'package:http/testing.dart'; +import 'package:test/test.dart'; + +import 'data/repos_json.dart'; + +void main() { + final slug = RepositorySlug('SpinlockLabs', 'github.dart'); + RepositoriesService create(Future Function(Request) f) { + final client = MockClient(f); + final github = GitHub(client: client); + return RepositoriesService(github); + } + + test('listCommits', () async { + final repositories = create((request) async { + expect(request.url.path, '/repos/${slug.fullName}/commits'); + expect(request.url.query, 'page=1'); + + return Response(listCommits, StatusCodes.OK); + }); + final commits = await repositories.listCommits(slug).toList(); + expect(commits, hasLength(1)); + }); + + test('listCommits with query params', () async { + final repositories = create((request) async { + expect(request.url.path, '/repos/${slug.fullName}/commits'); + expect( + request.url.query, + 'author=octocat&committer=octodog&sha=abc&path=%2Fpath&since=2022-02-22T00%3A00%3A00.000&until=2023-02-22T00%3A00%3A00.000&page=1', + ); + return Response(listCommits, StatusCodes.OK); + }); + final commits = await repositories + .listCommits( + slug, + sha: 'abc', + path: '/path', + author: 'octocat', + committer: 'octodog', + since: DateTime(2022, 2, 22), + until: DateTime(2023, 2, 22), + ) + .toList(); + expect(commits, hasLength(1)); + }); +} From 7e01a0de2716f7c3fdad0a8da55ee9989ad9924c Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 11 May 2023 10:22:34 -0600 Subject: [PATCH 102/139] prep 9.14.0 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efd7d81c..b6ec9d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.14.0 + +* Add optional filter params on Repositories.listCommits by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/368 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.13.0...9.14.0 + ## 9.13.0 * Add node_id to the pull request model by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/367 diff --git a/pubspec.yaml b/pubspec.yaml index c3efddc9..ef9f83a7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.13.0 +version: 9.14.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 4effb605ea687025e82b50aefb6e8f261d6e8379 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Tue, 20 Jun 2023 01:27:45 -0700 Subject: [PATCH 103/139] Implement IssuesService.lock/unlock (#376) --- lib/src/common/issues_service.dart | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index 3b5e013f..243c81dd 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -443,4 +443,30 @@ class IssuesService extends Service { TimelineEvent.fromJson, ); } + + /// Lock an issue. + /// + /// API docs: https://docs.github.com/en/rest/issues/issues?apiVersion=2022-11-28#lock-an-issue + /// + /// The `lockReason`, if specified, must be one of: `off-topic`, `too heated`, `resolved`, `spam`. + Future lock(RepositorySlug slug, int number, + {String? lockReason}) async { + String body; + if (lockReason != null) { + body = GitHubJson.encode({'lock_reason': lockReason}); + } else { + body = '{}'; + } + await github.postJSON('/repos/${slug.fullName}/issues/$number/lock', + body: body, statusCode: 204); + } + + /// Unlock an issue. + /// + /// API docs: https://docs.github.com/en/rest/issues/issues?apiVersion=2022-11-28#unlock-an-issue + Future unlock(RepositorySlug slug, int number) async { + await github.request( + 'DELETE', '/repos/${slug.fullName}/issues/$number/lock', + statusCode: 204); + } } From fccb90ea05b356bf9e7b98534601cd97f603afcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 10:28:11 +0200 Subject: [PATCH 104/139] Bump JamesIves/github-pages-deploy-action from 4.4.1 to 4.4.2 (#371) Bumps [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) from 4.4.1 to 4.4.2. - [Release notes](https://github.com/JamesIves/github-pages-deploy-action/releases) - [Commits](https://github.com/JamesIves/github-pages-deploy-action/compare/v4.4.1...v4.4.2) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish_demos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index dec1be49..965e7949 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -24,7 +24,7 @@ jobs: rm build/example/packages - name: Publish 🚀 - uses: JamesIves/github-pages-deploy-action@v4.4.1 + uses: JamesIves/github-pages-deploy-action@v4.4.2 with: branch: gh-pages # The branch the action should deploy to. folder: build/example # The folder the action should deploy. From c07c6347e448a4b933c84b12b0f2bbe1f5bf3288 Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Tue, 20 Jun 2023 13:11:58 +0200 Subject: [PATCH 105/139] Make GitHub.auth non-nullable (#377) * add const everywhere --- example/index.dart | 2 +- example/user_info.dart | 4 ++-- lib/src/browser/xplat_browser.dart | 2 +- lib/src/common/github.dart | 21 ++++++++------------- lib/src/common/util/auth.dart | 4 ++-- lib/src/common/xplat_common.dart | 2 +- lib/src/server/xplat_server.dart | 2 +- test/common/github_test.dart | 19 ++++++++++++++++++- test/experiment/crawler.dart | 2 +- test/git_test.dart | 4 ++-- test/scenarios_test.dart | 4 ++-- 11 files changed, 39 insertions(+), 27 deletions(-) diff --git a/example/index.dart b/example/index.dart index 3a0f10b2..42851c96 100644 --- a/example/index.dart +++ b/example/index.dart @@ -3,7 +3,7 @@ import 'common.dart'; void main() { final tokenInput = querySelector('#token') as InputElement; - tokenInput.value = github.auth!.token ?? ''; + tokenInput.value = github.auth.token ?? ''; window.sessionStorage['GITHUB_TOKEN'] = tokenInput.value!; tokenInput.onKeyUp.listen((_) { window.sessionStorage['GITHUB_TOKEN'] = tokenInput.value!; diff --git a/example/user_info.dart b/example/user_info.dart index a5113646..071c2820 100644 --- a/example/user_info.dart +++ b/example/user_info.dart @@ -59,8 +59,8 @@ void loadUser() { }); }); - if (github.auth!.token != null) { - localToken!.value = github.auth!.token; + if (github.auth.token != null) { + localToken!.value = github.auth.token; loadBtn.click(); } } diff --git a/lib/src/browser/xplat_browser.dart b/lib/src/browser/xplat_browser.dart index 79aeeb17..71bed55a 100644 --- a/lib/src/browser/xplat_browser.dart +++ b/lib/src/browser/xplat_browser.dart @@ -11,7 +11,7 @@ Authentication findAuthenticationFromEnvironment() { // search the query string parameters first var auth = findAuthenticationInMap(_parseQuery(window.location.href)); auth ??= findAuthenticationInMap(window.sessionStorage); - return auth ?? Authentication.anonymous(); + return auth ?? const Authentication.anonymous(); } /// Parse the query string to a parameter `Map` diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index 62358bd8..ffddef00 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -19,12 +19,11 @@ class GitHub { /// [endpoint] is the api endpoint to use /// [auth] is the authentication information GitHub({ - Authentication? auth, + this.auth = const Authentication.anonymous(), this.endpoint = 'https://api.github.com', this.version = '2022-11-28', http.Client? client, - }) : auth = auth ?? Authentication.anonymous(), - client = client ?? http.Client(); + }) : client = client ?? http.Client(); static const _ratelimitLimitHeader = 'x-ratelimit-limit'; static const _ratelimitResetHeader = 'x-ratelimit-reset'; @@ -34,7 +33,7 @@ class GitHub { static const versionHeader = 'X-GitHub-Api-Version'; /// Authentication Information - Authentication? auth; + final Authentication auth; /// API Endpoint final String endpoint; @@ -369,16 +368,16 @@ class GitHub { headers['Accept'] = preview; } - if (auth!.isToken) { - headers.putIfAbsent('Authorization', () => 'token ${auth!.token}'); - } else if (auth!.isBasic) { + if (auth.isToken) { + headers.putIfAbsent('Authorization', () => 'token ${auth.token}'); + } else if (auth.isBasic) { final userAndPass = - base64Encode(utf8.encode('${auth!.username}:${auth!.password}')); + base64Encode(utf8.encode('${auth.username}:${auth.password}')); headers.putIfAbsent('Authorization', () => 'basic $userAndPass'); } // See https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#user-agent-required - headers.putIfAbsent('User-Agent', () => auth?.username ?? 'github.dart'); + headers.putIfAbsent('User-Agent', () => auth.username ?? 'github.dart'); if (method == 'PUT' && body == null) { headers.putIfAbsent('Content-Length', () => '0'); @@ -493,10 +492,6 @@ class GitHub { /// Disposes of this GitHub Instance. /// No other methods on this instance should be called after this method is called. void dispose() { - // Destroy the Authentication Information - // This is needed for security reasons. - auth = null; - // Closes the HTTP Client client.close(); } diff --git a/lib/src/common/util/auth.dart b/lib/src/common/util/auth.dart index 925ffc93..b287f16c 100644 --- a/lib/src/common/util/auth.dart +++ b/lib/src/common/util/auth.dart @@ -10,12 +10,12 @@ class Authentication { final String? password; /// Creates an [Authentication] instance that uses the specified OAuth2 [token]. - Authentication.withToken(this.token) + const Authentication.withToken(this.token) : username = null, password = null; /// Creates an [Authentication] instance that has no authentication. - Authentication.anonymous() + const Authentication.anonymous() : token = null, username = null, password = null; diff --git a/lib/src/common/xplat_common.dart b/lib/src/common/xplat_common.dart index cc0bfcbb..1c60f906 100644 --- a/lib/src/common/xplat_common.dart +++ b/lib/src/common/xplat_common.dart @@ -10,7 +10,7 @@ import 'package:github/src/common.dart'; /// In both contexts it delegates to [findAuthenticationInMap] to find the /// github token or username and password. Authentication findAuthenticationFromEnvironment() => - Authentication.anonymous(); + const Authentication.anonymous(); /// Checks the passed in map for keys in [COMMON_GITHUB_TOKEN_ENV_KEYS]. /// The first one that exists is used as the github token to call [Authentication.withToken] with. diff --git a/lib/src/server/xplat_server.dart b/lib/src/server/xplat_server.dart index 3bd6e100..a6c85d02 100644 --- a/lib/src/server/xplat_server.dart +++ b/lib/src/server/xplat_server.dart @@ -27,5 +27,5 @@ Authentication findAuthenticationFromEnvironment() { } return findAuthenticationInMap(Platform.environment) ?? - Authentication.anonymous(); + const Authentication.anonymous(); } diff --git a/test/common/github_test.dart b/test/common/github_test.dart index 4f7d6727..97ce2930 100644 --- a/test/common/github_test.dart +++ b/test/common/github_test.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:github/src/common/github.dart'; +import 'package:github/src/common.dart'; import 'package:http/http.dart'; import 'package:http/testing.dart'; import 'package:test/test.dart'; @@ -38,5 +38,22 @@ void main() { final userAgent = request!.headers['User-Agent']; expect(userAgent, 'github.dart'); }); + + test('anonymous auth passes no authorization header', () async { + Request? request; + final client = MockClient((r) async { + request = r; + return Response('{}', HttpStatus.ok); + }); + + final github = GitHub( + client: client, + auth: const Authentication.anonymous(), + ); + await github.getJSON(''); // Make HTTP request + + expect(request, isNotNull); + expect(request!.headers.containsKey('Authorization'), isFalse); + }); }); } diff --git a/test/experiment/crawler.dart b/test/experiment/crawler.dart index cc4e23ee..7dd8e737 100644 --- a/test/experiment/crawler.dart +++ b/test/experiment/crawler.dart @@ -1,7 +1,7 @@ import 'package:github/github.dart'; void main() { - final github = GitHub(auth: Authentication.anonymous()); + final github = GitHub(auth: const Authentication.anonymous()); final crawler = RepositoryCrawler( github, diff --git a/test/git_test.dart b/test/git_test.dart index 34487b95..228b3a0b 100644 --- a/test/git_test.dart +++ b/test/git_test.dart @@ -10,8 +10,8 @@ const date = '2014-10-02T15:21:29Z'; GitHub createGithub() { return GitHub( endpoint: fakeApiUrl, - auth: - Authentication.withToken('0000000000000000000000000000000000000001')); + auth: const Authentication.withToken( + '0000000000000000000000000000000000000001')); } void main() { diff --git a/test/scenarios_test.dart b/test/scenarios_test.dart index c39ceb53..70f1a789 100644 --- a/test/scenarios_test.dart +++ b/test/scenarios_test.dart @@ -28,8 +28,8 @@ Future createGithubWithScenario(String scenario, var j = json.decode(resp.body); return GitHub( endpoint: j['url'], - auth: - Authentication.withToken('0000000000000000000000000000000000000001')); + auth: const Authentication.withToken( + '0000000000000000000000000000000000000001')); } /// Run scenario tests against ockokits fixtures-server From f53f02142294e10282f944d69c8714d984b6dede Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 20 Jun 2023 16:32:38 -0600 Subject: [PATCH 106/139] prep 9.15.0 --- CHANGELOG.md | 9 +++++++++ pubspec.yaml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6ec9d9d..0c4cf6ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 9.15.0 + +* Implement IssuesService.lock/unlock by @Hixie in https://github.com/SpinlockLabs/github.dart/pull/376 +* Bump JamesIves/github-pages-deploy-action from 4.4.1 to 4.4.2 by @dependabot in https://github.com/SpinlockLabs/github.dart/pull/371 +* Make GitHub.auth non-nullable by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/377 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.14.0...9.15.0 + ## 9.14.0 * Add optional filter params on Repositories.listCommits by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/368 diff --git a/pubspec.yaml b/pubspec.yaml index ef9f83a7..2f10dcb8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.14.0 +version: 9.15.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 5d880caa5a218fbf6fd763f5f64eacb39bca13fe Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 20 Jun 2023 16:39:54 -0600 Subject: [PATCH 107/139] add permissions to pub publish workflow --- .github/workflows/publish_release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index bdc52863..853f8c53 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -5,6 +5,10 @@ on: tags: - '[0-9]+.[0-9]+.[0-9]+*' +permissions: + contents: read + id-token: write + jobs: publish: uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 From 256ef341a4f445545006467f225540ff70a65f7e Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Mon, 26 Jun 2023 18:02:53 +0200 Subject: [PATCH 108/139] Revert immutable auth (#378) --- lib/src/common/github.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index ffddef00..c08140bf 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -33,7 +33,7 @@ class GitHub { static const versionHeader = 'X-GitHub-Api-Version'; /// Authentication Information - final Authentication auth; + Authentication auth; /// API Endpoint final String endpoint; From eafa5ac50a733f136c994162a98177b89e28d46d Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 26 Jun 2023 10:05:46 -0600 Subject: [PATCH 109/139] prep 9.15.1 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c4cf6ef..b2b1464e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.15.1 + +* Revert immutable auth by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/378 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.15.0...9.15.1 + ## 9.15.0 * Implement IssuesService.lock/unlock by @Hixie in https://github.com/SpinlockLabs/github.dart/pull/376 diff --git a/pubspec.yaml b/pubspec.yaml index 2f10dcb8..b511b9f6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.15.0 +version: 9.15.1 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 33f2a4c5f584970fa17d734130998b9d6b9e1cb1 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 11 Jul 2023 09:45:38 -0700 Subject: [PATCH 110/139] Fix links and spelling nits in markdown files (#379) --- CONTRIBUTING.md | 18 +++++++++--------- README.md | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47a2036f..c9a832b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ GitHub.dart is of course Open Source! We love it when people contribute! ## Getting Started - Make sure you have a [GitHub Account](https://github.com/signup/free). -- Make sure the [Dart SDK](https://www.dartlang.org/tools/sdk/) is installed on your system. +- Make sure the [Dart SDK](https://dart.dev/tools/sdk) is installed on your system. - Make sure you have [Git](http://git-scm.com/) installed on your system. - [Fork](https://help.github.com/articles/fork-a-repo) the [repository](https://github.com/SpinlockLabs/github.dart) on GitHub. @@ -20,7 +20,7 @@ GitHub.dart is of course Open Source! We love it when people contribute! ## Code Style -GitHub.dart follows the [Dart Style Guide](https://www.dartlang.org/articles/style-guide/). Please note that if your code is not formatted according to the guide as much as possible, we will reject your Pull Request until it is fixed. Some things such as long lines will generally be accepted, however try to make it smaller if possible. +GitHub.dart follows the [Dart Style Guide](https://dart.dev/effective-dart/style). Please note that if your code is not formatted according to the guide as much as possible, we will reject your Pull Request until it is fixed. Some things such as long lines will generally be accepted, however try to make it smaller if possible. ## Efficiency @@ -28,7 +28,7 @@ GitHub.dart is committed to efficiency as much as possible. If your code is not ## Rejections -Pull Request rejections are not a bad thing. It just means you need to fix something. Perhaps it is important to define 'rejection' as it is used in this case. A rejection is when a GitHub.dart committer comments on a Pull Request with a comment like 'rejected due to incorrect formatting'. +Pull Request rejections are not a bad thing. It just means you need to fix something. Perhaps it is important to define 'rejection' as it is used in this case. A rejection is when a `GitHub.dart` committer comments on a Pull Request with a comment like 'rejected due to incorrect formatting'. ## Generated code @@ -61,20 +61,20 @@ If you get on IRC and ask us, we can review your work and add you as a committer ## Releasing & Publishing -This repo is now configured to release after every PR merge. This means a couple things for PRs that are put up: +This repo is now configured to release after every PR merge. This means a couple of things for PRs that are put up: -1. A semver label is required. A github check will remind you that you need one. Reviewers should check that it is correct. See https://semver.org/ to understand more. +1. A semver label is required. A GitHub check will remind you that you need one. Reviewers should check that it is correct. See https://semver.org/ to understand more. 2. There is no need to modify the version in the pubspec.yaml in your PRs. The tooling will update the version according to the semver label applied to your PR. 3. Same thing for the CHANGELOG.md. Tooling will update it automatically after merge. -4. A github release will be created and published to pub.dev for you. +4. A GitHub release will be created and published to pub.dev for you. For example if your PR has `semver:minor` label applied and the latest version is 1.2.3, once merged, the tooling will: - update the pubspec.yaml to 1.3.0 -- Add the github auto-generated release notes with 1.3.0 to the top of the CHANGELOG.md -- Create a release in github for 1.3.0 (which creates a git tag of 1.3.0) +- Add the GitHub auto-generated release notes with 1.3.0 to the top of the CHANGELOG.md +- Create a release in GitHub for 1.3.0 (which creates a git tag of 1.3.0) - Remove the `unreleased` label from the PR and add the `released` label - Comment on the PR stating the version that it was released in and link to the release - When the release is created, it will automatically be published to pub.dev NOTE: If you want the ability to merge a PR **WITHOUT** automatically releasing and publishing, simply add the `no_release_on_merge` label before merging. Do note that the PR has been merged though and whatever the next PR is that triggers a release will release and publish everything that has been merged. So if you want to batch a few PRs into 1 release, label them all `no_release_on_merge`. Then whichever is the last to be merged, remove that label before merging to trigger the release. -You may also manually trigger the action to release unreleased PRs from the Actions tab in Github. +You may also manually trigger the action to release unreleased PRs from the Actions tab in GitHub. diff --git a/README.md b/README.md index 24be2836..08dc8e09 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ # GitHub for Dart [![Dart Checks](https://github.com/SpinlockLabs/github.dart/actions/workflows/dart.yml/badge.svg)](https://github.com/SpinlockLabs/github.dart/actions/workflows/dart.yml) -[![Pub](https://img.shields.io/pub/v/github.svg)](https://pub.dartlang.org/packages/github) +[![Pub](https://img.shields.io/pub/v/github.svg)](https://pub.dev/packages/github) This is a library for interacting with GitHub in Dart. It works on all platforms including web, server, and Flutter. Please submit issues and pull requests, help out, or just give encouragement. -**Notice**: This is not an official Github project. It is maintained by volunteers. +**Notice**: This is not an official GitHub project. It is maintained by volunteers. We are looking for contributors. If you're interested or have questions, head over to discussions https://github.com/SpinlockLabs/github.dart/discussions ## Features - Works on the Server, Browser, and Flutter - Really Fast -- Plugable API +- Pluggable API - Supports Authentication - Builtin OAuth2 Flow - Hook Server Helper @@ -21,7 +21,7 @@ We are looking for contributors. If you're interested or have questions, head ov ## Links - [Library Demos](https://spinlocklabs.github.io/github.dart/) (based on the [sample code](https://github.com/SpinlockLabs/github.dart/tree/master/example)) -- [Pub Package](https://pub.dartlang.org/packages/github) +- [Pub Package](https://pub.dev/packages/github) - [Wiki](https://github.com/SpinlockLabs/github.dart/wiki) - [Latest API reference](https://pub.dev/documentation/github/latest/) From 6480a79d9de3c9321916fcad9eff7d9fcc49270c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 11 Jul 2023 09:45:51 -0700 Subject: [PATCH 111/139] Support latest pkg:http (#380) --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index b511b9f6..dbe9fb9a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ environment: sdk: '>=2.18.0 <3.0.0' dependencies: - http: ^0.13.0 + http: '>=0.13.0 <2.0.0' http_parser: ^4.0.0 json_annotation: ^4.8.0 meta: ^1.3.0 From 42e405e412807ba6fc5337441b3a6ee4bf7293b3 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 13 Jul 2023 14:54:23 -0600 Subject: [PATCH 112/139] prep 9.16.0 --- CHANGELOG.md | 8 ++++++++ pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2b1464e..b1443106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 9.16.0 + +* Fix links and spelling nits in markdown files by @kevmoo in https://github.com/SpinlockLabs/github.dart/pull/379 +* Support latest pkg:http by @kevmoo in https://github.com/SpinlockLabs/github.dart/pull/380 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.15.1...9.16.0 + ## 9.15.1 * Revert immutable auth by @CaseyHillers in https://github.com/SpinlockLabs/github.dart/pull/378 diff --git a/pubspec.yaml b/pubspec.yaml index dbe9fb9a..e6a7ced3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.15.1 +version: 9.16.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 2bee1096a2b83ad76c7d0ccfc0427c5096ca678e Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 25 Jul 2023 14:11:14 -0700 Subject: [PATCH 113/139] Add bearerToken constructor to Authentication class (#381) Also added `authorizationHeaderValue()` function. Also added `const` qualifier to `basic` constructor. --- lib/src/common/github.dart | 9 +++---- lib/src/common/util/auth.dart | 49 ++++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index c08140bf..ef803ea0 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -368,12 +368,9 @@ class GitHub { headers['Accept'] = preview; } - if (auth.isToken) { - headers.putIfAbsent('Authorization', () => 'token ${auth.token}'); - } else if (auth.isBasic) { - final userAndPass = - base64Encode(utf8.encode('${auth.username}:${auth.password}')); - headers.putIfAbsent('Authorization', () => 'basic $userAndPass'); + final authHeaderValue = auth.authorizationHeaderValue(); + if (authHeaderValue != null) { + headers.putIfAbsent('Authorization', () => authHeaderValue); } // See https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#user-agent-required diff --git a/lib/src/common/util/auth.dart b/lib/src/common/util/auth.dart index b287f16c..1c4d6798 100644 --- a/lib/src/common/util/auth.dart +++ b/lib/src/common/util/auth.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + /// Authentication information. class Authentication { /// OAuth2 Token @@ -9,26 +11,65 @@ class Authentication { /// GitHub Password final String? password; + final String? bearerToken; + + // TODO: mark the pram as `String` to REQUIRE a non-null value. + // NEXT major version /// Creates an [Authentication] instance that uses the specified OAuth2 [token]. const Authentication.withToken(this.token) : username = null, - password = null; + password = null, + bearerToken = null; + + /// Creates an [Authentication] instance that uses the specified + /// [bearerToken]. + const Authentication.bearerToken(String this.bearerToken) + : username = null, + password = null, + token = null; /// Creates an [Authentication] instance that has no authentication. const Authentication.anonymous() : token = null, username = null, - password = null; + password = null, + bearerToken = null; + // TODO: mark the `username` and `password` params as `String` to REQUIRE + // non-null values. - NEXT major version /// Creates an [Authentication] instance that uses a username and password. - Authentication.basic(this.username, this.password) : token = null; + const Authentication.basic(this.username, this.password) + : token = null, + bearerToken = null; /// Anonymous Authentication Flag - bool get isAnonymous => !isBasic && !isToken; + bool get isAnonymous => !isBasic && !isToken && !isBearer; /// Basic Authentication Flag bool get isBasic => username != null; /// Token Authentication Flag bool get isToken => token != null; + + // This instance represents a authentication with a "Bearer" token. + bool get isBearer => bearerToken != null; + + /// Returns a value for the `Authorization` HTTP request header or `null` + /// if [isAnonymous] is `true`. + String? authorizationHeaderValue() { + if (isToken) { + return 'token $token'; + } + + if (isBasic) { + final userAndPass = base64Encode(utf8.encode('$username:$password')); + return 'basic $userAndPass'; + } + + if (isBearer) { + return 'Bearer $bearerToken'; + } + + return null; + } } From 5ef10ff19858e21c66e14c0569439af488f39260 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 25 Jul 2023 16:12:26 -0600 Subject: [PATCH 114/139] prep 9.17.0 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1443106..8027a432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.17.0 + +* Add bearerToken constructor to Authentication class by @kevmoo in https://github.com/SpinlockLabs/github.dart/pull/381 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.16.0...9.17.0 + ## 9.16.0 * Fix links and spelling nits in markdown files by @kevmoo in https://github.com/SpinlockLabs/github.dart/pull/379 diff --git a/pubspec.yaml b/pubspec.yaml index e6a7ced3..0a917ea4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.16.0 +version: 9.17.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From a3b000641113f235196d9d3cfb8fed5ccca18117 Mon Sep 17 00:00:00 2001 From: Drew Roen <102626803+drewroengoogle@users.noreply.github.com> Date: Sun, 10 Sep 2023 18:10:57 -0500 Subject: [PATCH 115/139] Add the 'PushEvent' webhook and associated PushCommit object (#386) * Add the 'PushEvent' webhook and associated PushCommit object * Add a test, handle integer times that come in from the Repository object in PushEvents only * Remove unnecessary decorator + update changelog * Add a comment about the time weirdness --- CHANGELOG.md | 23 +++-- lib/src/common/model/git.dart | 22 +++++ lib/src/common/model/git.g.dart | 18 ++++ lib/src/common/model/repos.dart | 14 +++ lib/src/common/model/repos.g.dart | 8 +- lib/src/server/hooks.dart | 37 ++++++++ lib/src/server/hooks.g.dart | 28 ++++++ test/data_object_test.dart | 139 ++++++++++++++++++++++++++++++ 8 files changed, 274 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8027a432..6193c995 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.18.0 + +* Adds the initial `PushEvent` object in https://github.com/SpinlockLabs/github.dart/pull/386 +* Update the `Repository` values `created_at` and `pushed_at` to handle integer times + ## 9.17.0 * Add bearerToken constructor to Authentication class by @kevmoo in https://github.com/SpinlockLabs/github.dart/pull/381 @@ -307,7 +312,7 @@ Map? files; - Clean up lints https://github.com/SpinlockLabs/github.dart/pull/202 ## 6.0.5 - - Fix null errors issue https://github.com/SpinlockLabs/github.dart/issues/199 + - Fix null errors issue https://github.com/SpinlockLabs/github.dart/issues/199 ## 6.0.4 - This fixes #196 (https://github.com/SpinlockLabs/github.dart/issues/196) @@ -357,10 +362,10 @@ Map? files; Deprecations: -- The `draft` and `prerelease` properties in the CreateRelease and Release +- The `draft` and `prerelease` properties in the CreateRelease and Release - classes have been renamed to `isDraft` and `isPrerelease` for clarity. -- Release.targetCommitsh has been renamed to Release.targetCommitish. -- The `release` parameter in RepositoriesService.createRelease +- Release.targetCommitsh has been renamed to Release.targetCommitish. +- The `release` parameter in RepositoriesService.createRelease has been renamed to `createRelease`. - `RepositoriesService.getRelease` has been renamed to `RepositoriesService.getReleaseById` @@ -369,7 +374,7 @@ has been renamed to `createRelease`. - Add access to labels on Pull Requests https://github.com/SpinlockLabs/github.dart/pull/163 - Adding draft property to PR model https://github.com/SpinlockLabs/github.dart/pull/162 - updateFile request must be a PUT https://github.com/SpinlockLabs/github.dart/pull/160 - + ## v5.1.0 - `Repository`: added `updatedAt` and `license` fields. @@ -386,7 +391,7 @@ has been renamed to `createRelease`. ## v5.0.0 -- **BREAKING** `RepositoriesService.listCollaborators` now returns +- **BREAKING** `RepositoriesService.listCollaborators` now returns `Stream` instead of `Stream`. - `Collaborator` is a new type that includes collaborator-specific information. @@ -403,7 +408,7 @@ has been renamed to `createRelease`. - 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 + - 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. - Added `Stream github.search.code(...)` search API @@ -433,7 +438,7 @@ has been renamed to `createRelease`. ## v2.3.2 -- Automatically attempt to find GitHub user information in the process environment when running on the standalone VM. +- Automatically attempt to find GitHub user information in the process environment when running on the standalone VM. - Add `ref` parameter to `getReadme` method for the repository service. ## v2.3.1 @@ -447,7 +452,7 @@ has been renamed to `createRelease`. - Moved `CHANGELOG` content back to repo. - Added `rateLimitLimit`, `rateLimitRemaining` and `rateLimitReset` to `GitHub`. - Added `id` to `Issue` -- Added `direction`, `sort` and `since` optional arguments to +- Added `direction`, `sort` and `since` optional arguments to `IssueService.listByRepo`. ## v2.1.0 diff --git a/lib/src/common/model/git.dart b/lib/src/common/model/git.dart index 136c01c4..0e655572 100644 --- a/lib/src/common/model/git.dart +++ b/lib/src/common/model/git.dart @@ -98,6 +98,28 @@ class CreateGitCommit { Map toJson() => _$CreateGitCommitToJson(this); } +/// Model class for a pushed commit. +@JsonSerializable() +class PushGitCommit { + PushGitCommit(this.id, this.message, this.timestamp, this.url); + + /// The commit hash. + String? id; + + /// The commit message. + String? message; + + /// The timestamp of the commit. + DateTime? timestamp; + + /// The direct url to the commit. + String? url; + + factory PushGitCommit.fromJson(Map input) => + _$PushGitCommitFromJson(input); + Map toJson() => _$PushGitCommitToJson(this); +} + /// Model class for an author or committer of a commit. The [GitCommitUser] may /// not correspond to a GitHub [User]. @JsonSerializable(includeIfNull: false) diff --git a/lib/src/common/model/git.g.dart b/lib/src/common/model/git.g.dart index 61d5fc44..7b2ba940 100644 --- a/lib/src/common/model/git.g.dart +++ b/lib/src/common/model/git.g.dart @@ -88,6 +88,24 @@ Map _$CreateGitCommitToJson(CreateGitCommit instance) => 'author': instance.author, }; +PushGitCommit _$PushGitCommitFromJson(Map json) => + PushGitCommit( + json['id'] as String?, + json['message'] as String?, + json['timestamp'] == null + ? null + : DateTime.parse(json['timestamp'] as String), + json['url'] as String?, + ); + +Map _$PushGitCommitToJson(PushGitCommit instance) => + { + 'id': instance.id, + 'message': instance.message, + 'timestamp': instance.timestamp?.toIso8601String(), + 'url': instance.url, + }; + GitCommitUser _$GitCommitUserFromJson(Map json) => GitCommitUser( json['name'] as String?, diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index d09c1a7e..4e46566d 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -225,9 +225,11 @@ class Repository { int networkCount; /// The time the repository was created at + @JsonKey(fromJson: Repository.dynamicToDateTime) DateTime? createdAt; /// The last time the repository was pushed at + @JsonKey(fromJson: Repository.dynamicToDateTime) DateTime? pushedAt; DateTime? updatedAt; @@ -459,6 +461,18 @@ class Repository { @override String toString() => 'Repository: $owner/$name'; + + /// In some cases, github webhooks send time values as an integer. This method + /// is added to handle those cases, but otherwise parse like normal. + static DateTime? dynamicToDateTime(dynamic time) { + if (time == null) { + return null; + } + if (time.runtimeType == int) { + return DateTime.fromMillisecondsSinceEpoch(time * 1000); + } + return DateTime.parse(time as String); + } } /// Model class for repository permissions. diff --git a/lib/src/common/model/repos.g.dart b/lib/src/common/model/repos.g.dart index 490b18b1..871a3284 100644 --- a/lib/src/common/model/repos.g.dart +++ b/lib/src/common/model/repos.g.dart @@ -46,9 +46,7 @@ Repository _$RepositoryFromJson(Map json) => Repository( sshUrl: json['ssh_url'] as String? ?? '', svnUrl: json['svn_url'] as String? ?? '', defaultBranch: json['default_branch'] as String? ?? '', - createdAt: json['created_at'] == null - ? null - : DateTime.parse(json['created_at'] as String), + createdAt: Repository.dynamicToDateTime(json['created_at']), isPrivate: json['private'] as bool? ?? false, isFork: json['fork'] as bool? ?? false, stargazersCount: json['stargazers_count'] as int? ?? 0, @@ -68,9 +66,7 @@ Repository _$RepositoryFromJson(Map json) => Repository( updatedAt: json['updated_at'] == null ? null : DateTime.parse(json['updated_at'] as String), - pushedAt: json['pushed_at'] == null - ? null - : DateTime.parse(json['pushed_at'] as String), + pushedAt: Repository.dynamicToDateTime(json['pushed_at']), license: json['license'] == null ? null : LicenseKind.fromJson(json['license'] as Map), diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index ea250c48..3f8987d2 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -235,3 +235,40 @@ class CreateEvent extends HookEvent { Map toJson() => _$CreateEventToJson(this); } + +@JsonSerializable(fieldRename: FieldRename.snake) +class PushEvent extends HookEvent { + PushEvent({ + this.ref, + this.before, + this.after, + this.repository, + this.headCommit, + this.commits, + this.sender, + }); + + factory PushEvent.fromJson(Map input) => + _$PushEventFromJson(input); + String? ref; + String? before; + String? after; + @JsonKey(toJson: handleIntegerTimes) + Repository? repository; + PushGitCommit? headCommit; + List? commits; + User? sender; + + Map toJson() => _$PushEventToJson(this); + + static Map? handleIntegerTimes(Repository? repository) { + var repositoryMap = repository?.toJson(); + for (final parameter in ['created_at', 'pushed_at']) { + if (repositoryMap?[parameter] != null) { + final createdAt = DateTime.parse(repositoryMap?[parameter]); + repositoryMap?[parameter] = createdAt.millisecondsSinceEpoch ~/ 1000; + } + } + return repositoryMap; + } +} diff --git a/lib/src/server/hooks.g.dart b/lib/src/server/hooks.g.dart index 3babd5cf..0e4ca02e 100644 --- a/lib/src/server/hooks.g.dart +++ b/lib/src/server/hooks.g.dart @@ -173,3 +173,31 @@ Map _$CreateEventToJson(CreateEvent instance) => 'repository': instance.repository, 'sender': instance.sender, }; + +PushEvent _$PushEventFromJson(Map json) => PushEvent( + ref: json['ref'] as String?, + before: json['before'] as String?, + after: json['after'] as String?, + repository: json['repository'] == null + ? null + : Repository.fromJson(json['repository'] as Map), + headCommit: json['head_commit'] == null + ? null + : PushGitCommit.fromJson(json['head_commit'] as Map), + commits: (json['commits'] as List?) + ?.map((e) => PushGitCommit.fromJson(e as Map)) + .toList(), + sender: json['sender'] == null + ? null + : User.fromJson(json['sender'] as Map), + ); + +Map _$PushEventToJson(PushEvent instance) => { + 'ref': instance.ref, + 'before': instance.before, + 'after': instance.after, + 'repository': PushEvent.handleIntegerTimes(instance.repository), + 'head_commit': instance.headCommit, + 'commits': instance.commits, + 'sender': instance.sender, + }; diff --git a/test/data_object_test.dart b/test/data_object_test.dart index f1d1d5db..1654b0a6 100644 --- a/test/data_object_test.dart +++ b/test/data_object_test.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:github/github.dart'; +import 'package:github/hooks.dart'; import 'package:test/test.dart'; const _licenseJson = r''' { @@ -29,6 +30,134 @@ const _licenseJson = r''' { } }'''; +const _pushEventJson = r'''{ + "ref": "refs/heads/main", + "before": "def456def456", + "after": "abc123abc123", + "base_ref": null, + "repository": { + "name": "fake-repository", + "id": 680238321, + "full_name": "fakeuser/fake-repository", + "owner": { + "login": "fakeuser", + "id": 102626803, + "avatar_url": "https://avatars.githubusercontent.com/u/102626803?v=4", + "html_url": "https://github.com/fakeuser" + }, + "private": false, + "fork": false, + "html_url": "https://github.com/fakeuser/fake-repository", + "description": "", + "clone_url": "https://github.com/fakeuser/fake-repository.git", + "ssh_url": "git@github.com:fakeuser/fake-repository.git", + "svn_url": "https://github.com/fakeuser/fake-repository", + "git_url": "git://github.com/fakeuser/fake-repository.git", + "homepage": "", + "size": 1, + "stargazers_count": 0, + "watchers_count": 0, + "language": "", + "has_issues": true, + "has_wiki": true, + "has_downloads": true, + "has_pages": false, + "forks_count": 0, + "open_issues_count": 0, + "default_branch": "main", + "subscribers_count": 0, + "network_count": 0, + "created_at": 1692379465, + "pushed_at": 1694031233, + "updated_at": "2023-08-18T17:24:25.000Z", + "archived": false, + "disabled": false, + "allow_forking": true, + "assignees_url": "https://api.github.com/repos/fakeuser/fake-repository/assignees{/user}", + "blobs_url": "https://api.github.com/repos/fakeuser/fake-repository/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/fakeuser/fake-repository/branches{/branch}", + "collaborators_url": "https://api.github.com/repos/fakeuser/fake-repository/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/fakeuser/fake-repository/comments{/number}", + "commits_url": "https://api.github.com/repos/fakeuser/fake-repository/commits{/sha}", + "compare_url": "https://api.github.com/repos/fakeuser/fake-repository/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/fakeuser/fake-repository/contents/{+path}", + "contributors_url": "https://api.github.com/repos/fakeuser/fake-repository/contributors", + "deployments_url": "https://api.github.com/repos/fakeuser/fake-repository/deployments", + "downloads_url": "https://api.github.com/repos/fakeuser/fake-repository/downloads", + "events_url": "https://api.github.com/repos/fakeuser/fake-repository/events", + "forks": 0, + "forks_url": "https://api.github.com/repos/fakeuser/fake-repository/forks", + "git_commits_url": "https://api.github.com/repos/fakeuser/fake-repository/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/fakeuser/fake-repository/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/fakeuser/fake-repository/git/tags{/sha}", + "has_discussions": false, + "has_projects": true, + "hooks_url": "https://api.github.com/repos/fakeuser/fake-repository/hooks", + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/fakeuser/fake-repository/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/fakeuser/fake-repository/issues/events{/number}", + "issues_url": "https://api.github.com/repos/fakeuser/fake-repository/issues{/number}", + "keys_url": "https://api.github.com/repos/fakeuser/fake-repository/keys{/key_id}", + "labels_url": "https://api.github.com/repos/fakeuser/fake-repository/labels{/name}", + "languages_url": "https://api.github.com/repos/fakeuser/fake-repository/languages", + "master_branch": "main", + "merges_url": "https://api.github.com/repos/fakeuser/fake-repository/merges", + "milestones_url": "https://api.github.com/repos/fakeuser/fake-repository/milestones{/number}", + "node_id": "R_kgDOKIuc8Q", + "notifications_url": "https://api.github.com/repos/fakeuser/fake-repository/notifications{?since,all,participating}", + "open_issues": 0, + "pulls_url": "https://api.github.com/repos/fakeuser/fake-repository/pulls{/number}", + "releases_url": "https://api.github.com/repos/fakeuser/fake-repository/releases{/id}", + "stargazers_url": "https://api.github.com/repos/fakeuser/fake-repository/stargazers", + "statuses_url": "https://api.github.com/repos/fakeuser/fake-repository/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/fakeuser/fake-repository/subscribers", + "subscription_url": "https://api.github.com/repos/fakeuser/fake-repository/subscription", + "tags_url": "https://api.github.com/repos/fakeuser/fake-repository/tags", + "teams_url": "https://api.github.com/repos/fakeuser/fake-repository/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/fakeuser/fake-repository/git/trees{/sha}", + "url": "https://github.com/fakeuser/fake-repository", + "visibility": "public", + "watchers": 0, + "web_commit_signoff_required": false + }, + "head_commit": { + "id": "f1eab4d20a72fe5495183136e36584dfab447faf", + "message": "A message", + "timestamp": "2023-09-06T15:14:10.000Z", + "url": "fake-github-url.com" + }, + "commits": [ + { + "id": "f1eab4d20a72fe5495183136e36584dfab447faf", + "message": "A message", + "timestamp": "2023-09-06T15:14:10.000Z", + "url": "fake-github-url.com" + } + ], + "sender": { + "login": "fakeuser", + "id": 102626803, + "avatar_url": "https://avatars.githubusercontent.com/u/102626803?v=4", + "html_url": "https://github.com/fakeuser", + "site_admin": false, + "events_url": "https://api.github.com/users/fakeuser/events{/privacy}", + "followers_url": "https://api.github.com/users/fakeuser/followers", + "following_url": "https://api.github.com/users/fakeuser/following{/other_user}", + "gists_url": "https://api.github.com/users/fakeuser/gists{/gist_id}", + "gravatar_id": "", + "node_id": "U_kgDOBh318w", + "organizations_url": "https://api.github.com/users/fakeuser/orgs", + "received_events_url": "https://api.github.com/users/fakeuser/received_events", + "repos_url": "https://api.github.com/users/fakeuser/repos", + "starred_url": "https://api.github.com/users/fakeuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/fakeuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/fakeuser" + } +} +'''; + void main() { test('License round-trip', () { final licenseJson = jsonDecode(_licenseJson) as Map; @@ -39,6 +168,16 @@ void main() { expect(_prettyEncode(toJson), _prettyEncode(licenseJson)); }); + + test('PushEvent round-trip', () { + final pushEventJson = jsonDecode(_pushEventJson) as Map; + + final instance = PushEvent.fromJson(pushEventJson); + + final toJson = instance.toJson(); + + expect(_prettyEncode(toJson), _prettyEncode(pushEventJson)); + }); } String _prettyEncode(obj) => GitHubJson.encode(obj, indent: ' '); From 8ffe0d0ad2e246a2dc1b1e1b54809644d8a7bd3f Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 10 Sep 2023 17:13:10 -0600 Subject: [PATCH 116/139] prep 9.18.0 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 0a917ea4..9de50e38 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.17.0 +version: 9.18.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 1249a52d43a2c5212345355479625b28e88032c8 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 14 Sep 2023 14:25:12 -0600 Subject: [PATCH 117/139] Revert "Add the 'PushEvent' webhook and associated PushCommit object" (#387) * Revert "Add the 'PushEvent' webhook and associated PushCommit object (#386)" This reverts commit a3b000641113f235196d9d3cfb8fed5ccca18117. * update changelog --------- Co-authored-by: Rob Becker --- CHANGELOG.md | 21 +++-- lib/src/common/model/git.dart | 22 ----- lib/src/common/model/git.g.dart | 18 ---- lib/src/common/model/repos.dart | 14 --- lib/src/common/model/repos.g.dart | 8 +- lib/src/server/hooks.dart | 37 -------- lib/src/server/hooks.g.dart | 28 ------ test/data_object_test.dart | 139 ------------------------------ 8 files changed, 16 insertions(+), 271 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6193c995..836d730e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,6 @@ ## 9.18.0 -* Adds the initial `PushEvent` object in https://github.com/SpinlockLabs/github.dart/pull/386 -* Update the `Repository` values `created_at` and `pushed_at` to handle integer times +- Bad Release. Was: Add the 'PushEvent' webhook and associated PushCommit ## 9.17.0 @@ -312,7 +311,7 @@ Map? files; - Clean up lints https://github.com/SpinlockLabs/github.dart/pull/202 ## 6.0.5 - - Fix null errors issue https://github.com/SpinlockLabs/github.dart/issues/199 + - Fix null errors issue https://github.com/SpinlockLabs/github.dart/issues/199 ## 6.0.4 - This fixes #196 (https://github.com/SpinlockLabs/github.dart/issues/196) @@ -362,10 +361,10 @@ Map? files; Deprecations: -- The `draft` and `prerelease` properties in the CreateRelease and Release +- The `draft` and `prerelease` properties in the CreateRelease and Release - classes have been renamed to `isDraft` and `isPrerelease` for clarity. -- Release.targetCommitsh has been renamed to Release.targetCommitish. -- The `release` parameter in RepositoriesService.createRelease +- Release.targetCommitsh has been renamed to Release.targetCommitish. +- The `release` parameter in RepositoriesService.createRelease has been renamed to `createRelease`. - `RepositoriesService.getRelease` has been renamed to `RepositoriesService.getReleaseById` @@ -374,7 +373,7 @@ has been renamed to `createRelease`. - Add access to labels on Pull Requests https://github.com/SpinlockLabs/github.dart/pull/163 - Adding draft property to PR model https://github.com/SpinlockLabs/github.dart/pull/162 - updateFile request must be a PUT https://github.com/SpinlockLabs/github.dart/pull/160 - + ## v5.1.0 - `Repository`: added `updatedAt` and `license` fields. @@ -391,7 +390,7 @@ has been renamed to `createRelease`. ## v5.0.0 -- **BREAKING** `RepositoriesService.listCollaborators` now returns +- **BREAKING** `RepositoriesService.listCollaborators` now returns `Stream` instead of `Stream`. - `Collaborator` is a new type that includes collaborator-specific information. @@ -408,7 +407,7 @@ has been renamed to `createRelease`. - 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 + - 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. - Added `Stream github.search.code(...)` search API @@ -438,7 +437,7 @@ has been renamed to `createRelease`. ## v2.3.2 -- Automatically attempt to find GitHub user information in the process environment when running on the standalone VM. +- Automatically attempt to find GitHub user information in the process environment when running on the standalone VM. - Add `ref` parameter to `getReadme` method for the repository service. ## v2.3.1 @@ -452,7 +451,7 @@ has been renamed to `createRelease`. - Moved `CHANGELOG` content back to repo. - Added `rateLimitLimit`, `rateLimitRemaining` and `rateLimitReset` to `GitHub`. - Added `id` to `Issue` -- Added `direction`, `sort` and `since` optional arguments to +- Added `direction`, `sort` and `since` optional arguments to `IssueService.listByRepo`. ## v2.1.0 diff --git a/lib/src/common/model/git.dart b/lib/src/common/model/git.dart index 0e655572..136c01c4 100644 --- a/lib/src/common/model/git.dart +++ b/lib/src/common/model/git.dart @@ -98,28 +98,6 @@ class CreateGitCommit { Map toJson() => _$CreateGitCommitToJson(this); } -/// Model class for a pushed commit. -@JsonSerializable() -class PushGitCommit { - PushGitCommit(this.id, this.message, this.timestamp, this.url); - - /// The commit hash. - String? id; - - /// The commit message. - String? message; - - /// The timestamp of the commit. - DateTime? timestamp; - - /// The direct url to the commit. - String? url; - - factory PushGitCommit.fromJson(Map input) => - _$PushGitCommitFromJson(input); - Map toJson() => _$PushGitCommitToJson(this); -} - /// Model class for an author or committer of a commit. The [GitCommitUser] may /// not correspond to a GitHub [User]. @JsonSerializable(includeIfNull: false) diff --git a/lib/src/common/model/git.g.dart b/lib/src/common/model/git.g.dart index 7b2ba940..61d5fc44 100644 --- a/lib/src/common/model/git.g.dart +++ b/lib/src/common/model/git.g.dart @@ -88,24 +88,6 @@ Map _$CreateGitCommitToJson(CreateGitCommit instance) => 'author': instance.author, }; -PushGitCommit _$PushGitCommitFromJson(Map json) => - PushGitCommit( - json['id'] as String?, - json['message'] as String?, - json['timestamp'] == null - ? null - : DateTime.parse(json['timestamp'] as String), - json['url'] as String?, - ); - -Map _$PushGitCommitToJson(PushGitCommit instance) => - { - 'id': instance.id, - 'message': instance.message, - 'timestamp': instance.timestamp?.toIso8601String(), - 'url': instance.url, - }; - GitCommitUser _$GitCommitUserFromJson(Map json) => GitCommitUser( json['name'] as String?, diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index 4e46566d..d09c1a7e 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -225,11 +225,9 @@ class Repository { int networkCount; /// The time the repository was created at - @JsonKey(fromJson: Repository.dynamicToDateTime) DateTime? createdAt; /// The last time the repository was pushed at - @JsonKey(fromJson: Repository.dynamicToDateTime) DateTime? pushedAt; DateTime? updatedAt; @@ -461,18 +459,6 @@ class Repository { @override String toString() => 'Repository: $owner/$name'; - - /// In some cases, github webhooks send time values as an integer. This method - /// is added to handle those cases, but otherwise parse like normal. - static DateTime? dynamicToDateTime(dynamic time) { - if (time == null) { - return null; - } - if (time.runtimeType == int) { - return DateTime.fromMillisecondsSinceEpoch(time * 1000); - } - return DateTime.parse(time as String); - } } /// Model class for repository permissions. diff --git a/lib/src/common/model/repos.g.dart b/lib/src/common/model/repos.g.dart index 871a3284..490b18b1 100644 --- a/lib/src/common/model/repos.g.dart +++ b/lib/src/common/model/repos.g.dart @@ -46,7 +46,9 @@ Repository _$RepositoryFromJson(Map json) => Repository( sshUrl: json['ssh_url'] as String? ?? '', svnUrl: json['svn_url'] as String? ?? '', defaultBranch: json['default_branch'] as String? ?? '', - createdAt: Repository.dynamicToDateTime(json['created_at']), + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), isPrivate: json['private'] as bool? ?? false, isFork: json['fork'] as bool? ?? false, stargazersCount: json['stargazers_count'] as int? ?? 0, @@ -66,7 +68,9 @@ Repository _$RepositoryFromJson(Map json) => Repository( updatedAt: json['updated_at'] == null ? null : DateTime.parse(json['updated_at'] as String), - pushedAt: Repository.dynamicToDateTime(json['pushed_at']), + pushedAt: json['pushed_at'] == null + ? null + : DateTime.parse(json['pushed_at'] as String), license: json['license'] == null ? null : LicenseKind.fromJson(json['license'] as Map), diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index 3f8987d2..ea250c48 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -235,40 +235,3 @@ class CreateEvent extends HookEvent { Map toJson() => _$CreateEventToJson(this); } - -@JsonSerializable(fieldRename: FieldRename.snake) -class PushEvent extends HookEvent { - PushEvent({ - this.ref, - this.before, - this.after, - this.repository, - this.headCommit, - this.commits, - this.sender, - }); - - factory PushEvent.fromJson(Map input) => - _$PushEventFromJson(input); - String? ref; - String? before; - String? after; - @JsonKey(toJson: handleIntegerTimes) - Repository? repository; - PushGitCommit? headCommit; - List? commits; - User? sender; - - Map toJson() => _$PushEventToJson(this); - - static Map? handleIntegerTimes(Repository? repository) { - var repositoryMap = repository?.toJson(); - for (final parameter in ['created_at', 'pushed_at']) { - if (repositoryMap?[parameter] != null) { - final createdAt = DateTime.parse(repositoryMap?[parameter]); - repositoryMap?[parameter] = createdAt.millisecondsSinceEpoch ~/ 1000; - } - } - return repositoryMap; - } -} diff --git a/lib/src/server/hooks.g.dart b/lib/src/server/hooks.g.dart index 0e4ca02e..3babd5cf 100644 --- a/lib/src/server/hooks.g.dart +++ b/lib/src/server/hooks.g.dart @@ -173,31 +173,3 @@ Map _$CreateEventToJson(CreateEvent instance) => 'repository': instance.repository, 'sender': instance.sender, }; - -PushEvent _$PushEventFromJson(Map json) => PushEvent( - ref: json['ref'] as String?, - before: json['before'] as String?, - after: json['after'] as String?, - repository: json['repository'] == null - ? null - : Repository.fromJson(json['repository'] as Map), - headCommit: json['head_commit'] == null - ? null - : PushGitCommit.fromJson(json['head_commit'] as Map), - commits: (json['commits'] as List?) - ?.map((e) => PushGitCommit.fromJson(e as Map)) - .toList(), - sender: json['sender'] == null - ? null - : User.fromJson(json['sender'] as Map), - ); - -Map _$PushEventToJson(PushEvent instance) => { - 'ref': instance.ref, - 'before': instance.before, - 'after': instance.after, - 'repository': PushEvent.handleIntegerTimes(instance.repository), - 'head_commit': instance.headCommit, - 'commits': instance.commits, - 'sender': instance.sender, - }; diff --git a/test/data_object_test.dart b/test/data_object_test.dart index 1654b0a6..f1d1d5db 100644 --- a/test/data_object_test.dart +++ b/test/data_object_test.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:github/github.dart'; -import 'package:github/hooks.dart'; import 'package:test/test.dart'; const _licenseJson = r''' { @@ -30,134 +29,6 @@ const _licenseJson = r''' { } }'''; -const _pushEventJson = r'''{ - "ref": "refs/heads/main", - "before": "def456def456", - "after": "abc123abc123", - "base_ref": null, - "repository": { - "name": "fake-repository", - "id": 680238321, - "full_name": "fakeuser/fake-repository", - "owner": { - "login": "fakeuser", - "id": 102626803, - "avatar_url": "https://avatars.githubusercontent.com/u/102626803?v=4", - "html_url": "https://github.com/fakeuser" - }, - "private": false, - "fork": false, - "html_url": "https://github.com/fakeuser/fake-repository", - "description": "", - "clone_url": "https://github.com/fakeuser/fake-repository.git", - "ssh_url": "git@github.com:fakeuser/fake-repository.git", - "svn_url": "https://github.com/fakeuser/fake-repository", - "git_url": "git://github.com/fakeuser/fake-repository.git", - "homepage": "", - "size": 1, - "stargazers_count": 0, - "watchers_count": 0, - "language": "", - "has_issues": true, - "has_wiki": true, - "has_downloads": true, - "has_pages": false, - "forks_count": 0, - "open_issues_count": 0, - "default_branch": "main", - "subscribers_count": 0, - "network_count": 0, - "created_at": 1692379465, - "pushed_at": 1694031233, - "updated_at": "2023-08-18T17:24:25.000Z", - "archived": false, - "disabled": false, - "allow_forking": true, - "assignees_url": "https://api.github.com/repos/fakeuser/fake-repository/assignees{/user}", - "blobs_url": "https://api.github.com/repos/fakeuser/fake-repository/git/blobs{/sha}", - "branches_url": "https://api.github.com/repos/fakeuser/fake-repository/branches{/branch}", - "collaborators_url": "https://api.github.com/repos/fakeuser/fake-repository/collaborators{/collaborator}", - "comments_url": "https://api.github.com/repos/fakeuser/fake-repository/comments{/number}", - "commits_url": "https://api.github.com/repos/fakeuser/fake-repository/commits{/sha}", - "compare_url": "https://api.github.com/repos/fakeuser/fake-repository/compare/{base}...{head}", - "contents_url": "https://api.github.com/repos/fakeuser/fake-repository/contents/{+path}", - "contributors_url": "https://api.github.com/repos/fakeuser/fake-repository/contributors", - "deployments_url": "https://api.github.com/repos/fakeuser/fake-repository/deployments", - "downloads_url": "https://api.github.com/repos/fakeuser/fake-repository/downloads", - "events_url": "https://api.github.com/repos/fakeuser/fake-repository/events", - "forks": 0, - "forks_url": "https://api.github.com/repos/fakeuser/fake-repository/forks", - "git_commits_url": "https://api.github.com/repos/fakeuser/fake-repository/git/commits{/sha}", - "git_refs_url": "https://api.github.com/repos/fakeuser/fake-repository/git/refs{/sha}", - "git_tags_url": "https://api.github.com/repos/fakeuser/fake-repository/git/tags{/sha}", - "has_discussions": false, - "has_projects": true, - "hooks_url": "https://api.github.com/repos/fakeuser/fake-repository/hooks", - "is_template": false, - "issue_comment_url": "https://api.github.com/repos/fakeuser/fake-repository/issues/comments{/number}", - "issue_events_url": "https://api.github.com/repos/fakeuser/fake-repository/issues/events{/number}", - "issues_url": "https://api.github.com/repos/fakeuser/fake-repository/issues{/number}", - "keys_url": "https://api.github.com/repos/fakeuser/fake-repository/keys{/key_id}", - "labels_url": "https://api.github.com/repos/fakeuser/fake-repository/labels{/name}", - "languages_url": "https://api.github.com/repos/fakeuser/fake-repository/languages", - "master_branch": "main", - "merges_url": "https://api.github.com/repos/fakeuser/fake-repository/merges", - "milestones_url": "https://api.github.com/repos/fakeuser/fake-repository/milestones{/number}", - "node_id": "R_kgDOKIuc8Q", - "notifications_url": "https://api.github.com/repos/fakeuser/fake-repository/notifications{?since,all,participating}", - "open_issues": 0, - "pulls_url": "https://api.github.com/repos/fakeuser/fake-repository/pulls{/number}", - "releases_url": "https://api.github.com/repos/fakeuser/fake-repository/releases{/id}", - "stargazers_url": "https://api.github.com/repos/fakeuser/fake-repository/stargazers", - "statuses_url": "https://api.github.com/repos/fakeuser/fake-repository/statuses/{sha}", - "subscribers_url": "https://api.github.com/repos/fakeuser/fake-repository/subscribers", - "subscription_url": "https://api.github.com/repos/fakeuser/fake-repository/subscription", - "tags_url": "https://api.github.com/repos/fakeuser/fake-repository/tags", - "teams_url": "https://api.github.com/repos/fakeuser/fake-repository/teams", - "topics": [], - "trees_url": "https://api.github.com/repos/fakeuser/fake-repository/git/trees{/sha}", - "url": "https://github.com/fakeuser/fake-repository", - "visibility": "public", - "watchers": 0, - "web_commit_signoff_required": false - }, - "head_commit": { - "id": "f1eab4d20a72fe5495183136e36584dfab447faf", - "message": "A message", - "timestamp": "2023-09-06T15:14:10.000Z", - "url": "fake-github-url.com" - }, - "commits": [ - { - "id": "f1eab4d20a72fe5495183136e36584dfab447faf", - "message": "A message", - "timestamp": "2023-09-06T15:14:10.000Z", - "url": "fake-github-url.com" - } - ], - "sender": { - "login": "fakeuser", - "id": 102626803, - "avatar_url": "https://avatars.githubusercontent.com/u/102626803?v=4", - "html_url": "https://github.com/fakeuser", - "site_admin": false, - "events_url": "https://api.github.com/users/fakeuser/events{/privacy}", - "followers_url": "https://api.github.com/users/fakeuser/followers", - "following_url": "https://api.github.com/users/fakeuser/following{/other_user}", - "gists_url": "https://api.github.com/users/fakeuser/gists{/gist_id}", - "gravatar_id": "", - "node_id": "U_kgDOBh318w", - "organizations_url": "https://api.github.com/users/fakeuser/orgs", - "received_events_url": "https://api.github.com/users/fakeuser/received_events", - "repos_url": "https://api.github.com/users/fakeuser/repos", - "starred_url": "https://api.github.com/users/fakeuser/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/fakeuser/subscriptions", - "type": "User", - "url": "https://api.github.com/users/fakeuser" - } -} -'''; - void main() { test('License round-trip', () { final licenseJson = jsonDecode(_licenseJson) as Map; @@ -168,16 +39,6 @@ void main() { expect(_prettyEncode(toJson), _prettyEncode(licenseJson)); }); - - test('PushEvent round-trip', () { - final pushEventJson = jsonDecode(_pushEventJson) as Map; - - final instance = PushEvent.fromJson(pushEventJson); - - final toJson = instance.toJson(); - - expect(_prettyEncode(toJson), _prettyEncode(pushEventJson)); - }); } String _prettyEncode(obj) => GitHubJson.encode(obj, indent: ' '); From c86afa71aea32e727c02514456432410392a17cb Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Thu, 14 Sep 2023 14:25:45 -0600 Subject: [PATCH 118/139] prep 9.19.0 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 836d730e..94e3728c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.19.0 + +* Revert "Add the 'PushEvent' webhook and associated PushCommit object" by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/387 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.18.0...9.19.0 + ## 9.18.0 - Bad Release. Was: Add the 'PushEvent' webhook and associated PushCommit diff --git a/pubspec.yaml b/pubspec.yaml index 9de50e38..8bdc72f6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.18.0 +version: 9.19.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 01a87bf8c75048857d84d60fe50b5ea07463f248 Mon Sep 17 00:00:00 2001 From: Ricardo Amador <32242716+ricardoamador@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:42:30 -0800 Subject: [PATCH 119/139] Add a Changes object to the PullRequestEvent object so we can see what changed in edited PR events (#390) * Add changes object so we can see what changed in edited PR. * Remove unused import * Formatting. * Make objects const --- lib/src/common/model/changes.dart | 68 ++ lib/src/common/model/changes.g.dart | 71 ++ lib/src/server/hooks.dart | 5 + lib/src/server/hooks.g.dart | 4 + test/server/hooks_test.dart | 25 + test/server/hooks_test_data.dart | 1143 +++++++++++++++++++++++++++ 6 files changed, 1316 insertions(+) create mode 100644 lib/src/common/model/changes.dart create mode 100644 lib/src/common/model/changes.g.dart diff --git a/lib/src/common/model/changes.dart b/lib/src/common/model/changes.dart new file mode 100644 index 00000000..edccdbc5 --- /dev/null +++ b/lib/src/common/model/changes.dart @@ -0,0 +1,68 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:meta/meta.dart'; + +part 'changes.g.dart'; + +@immutable +@JsonSerializable() +class Ref { + const Ref(this.from); + final String? from; + + factory Ref.fromJson(Map input) => _$RefFromJson(input); + Map toJson() => _$RefToJson(this); +} + +@immutable +@JsonSerializable() +class Sha { + const Sha(this.from); + final String? from; + + factory Sha.fromJson(Map input) => _$ShaFromJson(input); + Map toJson() => _$ShaToJson(this); +} + +@immutable +@JsonSerializable() +class Base { + const Base(this.ref, this.sha); + final Ref? ref; + final Sha? sha; + + factory Base.fromJson(Map input) => _$BaseFromJson(input); + Map toJson() => _$BaseToJson(this); +} + +@immutable +@JsonSerializable() +class Body { + const Body(this.from); + final String? from; + + factory Body.fromJson(Map input) => _$BodyFromJson(input); + Map toJson() => _$BodyToJson(this); +} + +@immutable +@JsonSerializable() +class Title { + const Title({this.from}); + final String? from; + + factory Title.fromJson(Map input) => _$TitleFromJson(input); + Map toJson() => _$TitleToJson(this); +} + +@immutable +@JsonSerializable() +class Changes { + const Changes(this.base, this.body, this.title); + final Base? base; + final Body? body; + final Title? title; + + factory Changes.fromJson(Map input) => + _$ChangesFromJson(input); + Map toJson() => _$ChangesToJson(this); +} diff --git a/lib/src/common/model/changes.g.dart b/lib/src/common/model/changes.g.dart new file mode 100644 index 00000000..13e97d0e --- /dev/null +++ b/lib/src/common/model/changes.g.dart @@ -0,0 +1,71 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'changes.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Ref _$RefFromJson(Map json) => Ref( + json['from'] as String?, + ); + +Map _$RefToJson(Ref instance) => { + 'from': instance.from, + }; + +Sha _$ShaFromJson(Map json) => Sha( + json['from'] as String?, + ); + +Map _$ShaToJson(Sha instance) => { + 'from': instance.from, + }; + +Base _$BaseFromJson(Map json) => Base( + json['ref'] == null + ? null + : Ref.fromJson(json['ref'] as Map), + json['sha'] == null + ? null + : Sha.fromJson(json['sha'] as Map), + ); + +Map _$BaseToJson(Base instance) => { + 'ref': instance.ref, + 'sha': instance.sha, + }; + +Body _$BodyFromJson(Map json) => Body( + json['from'] as String?, + ); + +Map _$BodyToJson(Body instance) => { + 'from': instance.from, + }; + +Title _$TitleFromJson(Map json) => Title( + from: json['from'] as String?, + ); + +Map _$TitleToJson(Title instance) => { + 'from': instance.from, + }; + +Changes _$ChangesFromJson(Map json) => Changes( + json['base'] == null + ? null + : Base.fromJson(json['base'] as Map), + json['body'] == null + ? null + : Body.fromJson(json['body'] as Map), + json['title'] == null + ? null + : Title.fromJson(json['title'] as Map), + ); + +Map _$ChangesToJson(Changes instance) => { + 'base': instance.base, + 'body': instance.body, + 'title': instance.title, + }; diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index ea250c48..ae3fa0bf 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -1,8 +1,11 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; + import 'package:json_annotation/json_annotation.dart'; + import '../common.dart'; +import '../common/model/changes.dart'; part 'hooks.g.dart'; @@ -203,12 +206,14 @@ class PullRequestEvent extends HookEvent { this.pullRequest, this.sender, this.repository, + this.changes, }); String? action; int? number; PullRequest? pullRequest; User? sender; Repository? repository; + Changes? changes; factory PullRequestEvent.fromJson(Map input) => _$PullRequestEventFromJson(input); diff --git a/lib/src/server/hooks.g.dart b/lib/src/server/hooks.g.dart index 3babd5cf..e78b6cc9 100644 --- a/lib/src/server/hooks.g.dart +++ b/lib/src/server/hooks.g.dart @@ -142,6 +142,9 @@ PullRequestEvent _$PullRequestEventFromJson(Map json) => repository: json['repository'] == null ? null : Repository.fromJson(json['repository'] as Map), + changes: json['changes'] == null + ? null + : Changes.fromJson(json['changes'] as Map), ); Map _$PullRequestEventToJson(PullRequestEvent instance) => @@ -151,6 +154,7 @@ Map _$PullRequestEventToJson(PullRequestEvent instance) => 'pull_request': instance.pullRequest, 'sender': instance.sender, 'repository': instance.repository, + 'changes': instance.changes, }; CreateEvent _$CreateEventFromJson(Map json) => CreateEvent( diff --git a/test/server/hooks_test.dart b/test/server/hooks_test.dart index 09deae27..d00cb3de 100644 --- a/test/server/hooks_test.dart +++ b/test/server/hooks_test.dart @@ -57,4 +57,29 @@ void main() { expect(sender.htmlUrl, "https://github.com/Codertocat"); }); }); + + group('EditedPullRequest', () { + test('deserialize with body edit', () { + final pullRequestEditedEvent = PullRequestEvent.fromJson( + jsonDecode(prBodyEditedEvent) as Map); + final changes = pullRequestEditedEvent.changes; + expect(changes, isNotNull); + expect(changes!.body!.from, isNotNull); + assert(changes.body!.from == + '**This should not land until https://github.com/flutter/buildroot/pull/790'); + }); + + test('deserialize with base edit', () { + final pullRequestEditedEvent = PullRequestEvent.fromJson( + jsonDecode(prBaseEditedEvent) as Map); + final changes = pullRequestEditedEvent.changes; + expect(changes, isNotNull); + expect(changes!.body, isNull); + expect(changes.base, isNotNull); + expect(changes.base!.ref, isNotNull); + assert(changes.base!.ref!.from == 'main'); + assert(changes.base!.sha!.from == + 'b3af5d64d3e6e2110b07d71909fc432537339659'); + }); + }); } diff --git a/test/server/hooks_test_data.dart b/test/server/hooks_test_data.dart index c6f12f84..4f5b734b 100644 --- a/test/server/hooks_test_data.dart +++ b/test/server/hooks_test_data.dart @@ -672,3 +672,1146 @@ const String createString = ''' } } '''; + +const String prBodyEditedEvent = ''' +{ + "action": "edited", + "number": 47609, + "pull_request": { + "url": "https://api.github.com/repos/flutter/engine/pulls/47609", + "id": 1584723957, + "node_id": "PR_kwDOAlZRSc5edPf1", + "html_url": "https://github.com/flutter/engine/pull/47609", + "diff_url": "https://github.com/flutter/engine/pull/47609.diff", + "patch_url": "https://github.com/flutter/engine/pull/47609.patch", + "issue_url": "https://api.github.com/repos/flutter/engine/issues/47609", + "number": 47609, + "state": "open", + "locked": false, + "title": "Upgrade Android SDK to 34 UpsideDownCake", + "user": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "body": "~**This should not land until https://github.com/flutter/buildroot/pull/790 (re)lands, and I swap the buildroot url back to the latest commit.**~ Reland of PR to update buildroot at https://github.com/flutter/buildroot/pull/792. Upgrades to android api 34 Also: 1. Upgrades to java 17 in DEPS/ci", + "created_at": "2023-11-02T17:09:59Z", + "updated_at": "2023-11-08T21:00:47Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "8e5e3a59a5cba4239c542ed9a914899a246640b7", + "assignee": null, + "assignees": [ + + ], + "requested_reviewers": [ + + ], + "requested_teams": [ + + ], + "labels": [ + { + "id": 246348935, + "node_id": "MDU6TGFiZWwyNDYzNDg5MzU=", + "url": "https://api.github.com/repos/flutter/engine/labels/platform-android", + "name": "platform-android", + "color": "A4C639", + "default": false, + "description": null + } + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/flutter/engine/pulls/47609/commits", + "review_comments_url": "https://api.github.com/repos/flutter/engine/pulls/47609/comments", + "review_comment_url": "https://api.github.com/repos/flutter/engine/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/flutter/engine/issues/47609/comments", + "statuses_url": "https://api.github.com/repos/flutter/engine/statuses/a6765b4c309aa082bbebade68e0c7ec308a1cc6c", + "head": { + "label": "gmackall:upgrade_to_android14", + "ref": "upgrade_to_android14", + "sha": "a6765b4c309aa082bbebade68e0c7ec308a1cc6c", + "user": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 547558963, + "node_id": "R_kgDOIKMWMw", + "name": "engine", + "full_name": "gmackall/engine", + "private": false, + "owner": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/gmackall/engine", + "description": "The Flutter engine", + "fork": true, + "url": "https://api.github.com/repos/gmackall/engine", + "forks_url": "https://api.github.com/repos/gmackall/engine/forks", + "keys_url": "https://api.github.com/repos/gmackall/engine/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/gmackall/engine/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/gmackall/engine/teams", + "hooks_url": "https://api.github.com/repos/gmackall/engine/hooks", + "issue_events_url": "https://api.github.com/repos/gmackall/engine/issues/events{/number}", + "events_url": "https://api.github.com/repos/gmackall/engine/events", + "assignees_url": "https://api.github.com/repos/gmackall/engine/assignees{/user}", + "branches_url": "https://api.github.com/repos/gmackall/engine/branches{/branch}", + "tags_url": "https://api.github.com/repos/gmackall/engine/tags", + "blobs_url": "https://api.github.com/repos/gmackall/engine/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/gmackall/engine/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/gmackall/engine/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/gmackall/engine/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/gmackall/engine/statuses/{sha}", + "languages_url": "https://api.github.com/repos/gmackall/engine/languages", + "stargazers_url": "https://api.github.com/repos/gmackall/engine/stargazers", + "contributors_url": "https://api.github.com/repos/gmackall/engine/contributors", + "subscribers_url": "https://api.github.com/repos/gmackall/engine/subscribers", + "subscription_url": "https://api.github.com/repos/gmackall/engine/subscription", + "commits_url": "https://api.github.com/repos/gmackall/engine/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/gmackall/engine/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/gmackall/engine/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/gmackall/engine/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/gmackall/engine/contents/{+path}", + "compare_url": "https://api.github.com/repos/gmackall/engine/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/gmackall/engine/merges", + "archive_url": "https://api.github.com/repos/gmackall/engine/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/gmackall/engine/downloads", + "issues_url": "https://api.github.com/repos/gmackall/engine/issues{/number}", + "pulls_url": "https://api.github.com/repos/gmackall/engine/pulls{/number}", + "milestones_url": "https://api.github.com/repos/gmackall/engine/milestones{/number}", + "notifications_url": "https://api.github.com/repos/gmackall/engine/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/gmackall/engine/labels{/name}", + "releases_url": "https://api.github.com/repos/gmackall/engine/releases{/id}", + "deployments_url": "https://api.github.com/repos/gmackall/engine/deployments", + "created_at": "2022-10-07T22:25:57Z", + "updated_at": "2023-02-02T18:38:07Z", + "pushed_at": "2023-11-08T20:57:02Z", + "git_url": "git://github.com/gmackall/engine.git", + "ssh_url": "git@github.com:gmackall/engine.git", + "clone_url": "https://github.com/gmackall/engine.git", + "svn_url": "https://github.com/gmackall/engine", + "homepage": "https://flutter.dev", + "size": 466778, + "stargazers_count": 0, + "watchers_count": 0, + "language": "C++", + "has_issues": false, + "has_projects": true, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "public", + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "flutter:main", + "ref": "main", + "sha": "941e246d4851f652cf13312180174ebc9395fac4", + "user": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "followers_url": "https://api.github.com/users/flutter/followers", + "following_url": "https://api.github.com/users/flutter/following{/other_user}", + "gists_url": "https://api.github.com/users/flutter/gists{/gist_id}", + "starred_url": "https://api.github.com/users/flutter/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/flutter/subscriptions", + "organizations_url": "https://api.github.com/users/flutter/orgs", + "repos_url": "https://api.github.com/users/flutter/repos", + "events_url": "https://api.github.com/users/flutter/events{/privacy}", + "received_events_url": "https://api.github.com/users/flutter/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 39211337, + "node_id": "MDEwOlJlcG9zaXRvcnkzOTIxMTMzNw==", + "name": "engine", + "full_name": "flutter/engine", + "private": false, + "owner": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "followers_url": "https://api.github.com/users/flutter/followers", + "following_url": "https://api.github.com/users/flutter/following{/other_user}", + "gists_url": "https://api.github.com/users/flutter/gists{/gist_id}", + "starred_url": "https://api.github.com/users/flutter/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/flutter/subscriptions", + "organizations_url": "https://api.github.com/users/flutter/orgs", + "repos_url": "https://api.github.com/users/flutter/repos", + "events_url": "https://api.github.com/users/flutter/events{/privacy}", + "received_events_url": "https://api.github.com/users/flutter/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/flutter/engine", + "description": "The Flutter engine", + "fork": false, + "url": "https://api.github.com/repos/flutter/engine", + "forks_url": "https://api.github.com/repos/flutter/engine/forks", + "keys_url": "https://api.github.com/repos/flutter/engine/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/flutter/engine/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/flutter/engine/teams", + "hooks_url": "https://api.github.com/repos/flutter/engine/hooks", + "issue_events_url": "https://api.github.com/repos/flutter/engine/issues/events{/number}", + "events_url": "https://api.github.com/repos/flutter/engine/events", + "assignees_url": "https://api.github.com/repos/flutter/engine/assignees{/user}", + "branches_url": "https://api.github.com/repos/flutter/engine/branches{/branch}", + "tags_url": "https://api.github.com/repos/flutter/engine/tags", + "blobs_url": "https://api.github.com/repos/flutter/engine/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/flutter/engine/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/flutter/engine/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/flutter/engine/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/flutter/engine/statuses/{sha}", + "languages_url": "https://api.github.com/repos/flutter/engine/languages", + "stargazers_url": "https://api.github.com/repos/flutter/engine/stargazers", + "contributors_url": "https://api.github.com/repos/flutter/engine/contributors", + "subscribers_url": "https://api.github.com/repos/flutter/engine/subscribers", + "subscription_url": "https://api.github.com/repos/flutter/engine/subscription", + "commits_url": "https://api.github.com/repos/flutter/engine/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/flutter/engine/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/flutter/engine/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/flutter/engine/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/flutter/engine/contents/{+path}", + "compare_url": "https://api.github.com/repos/flutter/engine/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/flutter/engine/merges", + "archive_url": "https://api.github.com/repos/flutter/engine/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/flutter/engine/downloads", + "issues_url": "https://api.github.com/repos/flutter/engine/issues{/number}", + "pulls_url": "https://api.github.com/repos/flutter/engine/pulls{/number}", + "milestones_url": "https://api.github.com/repos/flutter/engine/milestones{/number}", + "notifications_url": "https://api.github.com/repos/flutter/engine/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/flutter/engine/labels{/name}", + "releases_url": "https://api.github.com/repos/flutter/engine/releases{/id}", + "deployments_url": "https://api.github.com/repos/flutter/engine/deployments", + "created_at": "2015-07-16T17:39:56Z", + "updated_at": "2023-11-08T07:16:25Z", + "pushed_at": "2023-11-08T21:00:38Z", + "git_url": "git://github.com/flutter/engine.git", + "ssh_url": "git@github.com:flutter/engine.git", + "clone_url": "https://github.com/flutter/engine.git", + "svn_url": "https://github.com/flutter/engine", + "homepage": "https://flutter.dev", + "size": 704170, + "stargazers_count": 6848, + "watchers_count": 6848, + "language": "C++", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 5600, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 99, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "c-plus-plus" + ], + "visibility": "public", + "forks": 5600, + "open_issues": 99, + "watchers": 6848, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": false, + "allow_rebase_merge": false, + "allow_auto_merge": false, + "delete_branch_on_merge": true, + "allow_update_branch": true, + "use_squash_pr_title_as_default": true, + "squash_merge_commit_message": "PR_BODY", + "squash_merge_commit_title": "PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/flutter/engine/pulls/47609" + }, + "html": { + "href": "https://github.com/flutter/engine/pull/47609" + }, + "issue": { + "href": "https://api.github.com/repos/flutter/engine/issues/47609" + }, + "comments": { + "href": "https://api.github.com/repos/flutter/engine/issues/47609/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/flutter/engine/pulls/47609/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/flutter/engine/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/flutter/engine/pulls/47609/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/flutter/engine/statuses/a6765b4c309aa082bbebade68e0c7ec308a1cc6c" + } + }, + "author_association": "MEMBER", + "auto_merge": null, + "active_lock_reason": null, + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "clean", + "merged_by": null, + "comments": 4, + "review_comments": 4, + "maintainer_can_modify": true, + "commits": 32, + "additions": 83, + "deletions": 77, + "changed_files": 18 + }, + "changes": { + "body": { + "from": "**This should not land until https://github.com/flutter/buildroot/pull/790" + } + }, + "repository": { + "id": 39211337, + "node_id": "MDEwOlJlcG9zaXRvcnkzOTIxMTMzNw==", + "name": "engine", + "full_name": "flutter/engine", + "private": false, + "owner": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "followers_url": "https://api.github.com/users/flutter/followers", + "following_url": "https://api.github.com/users/flutter/following{/other_user}", + "gists_url": "https://api.github.com/users/flutter/gists{/gist_id}", + "starred_url": "https://api.github.com/users/flutter/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/flutter/subscriptions", + "organizations_url": "https://api.github.com/users/flutter/orgs", + "repos_url": "https://api.github.com/users/flutter/repos", + "events_url": "https://api.github.com/users/flutter/events{/privacy}", + "received_events_url": "https://api.github.com/users/flutter/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/flutter/engine", + "description": "The Flutter engine", + "fork": false, + "url": "https://api.github.com/repos/flutter/engine", + "forks_url": "https://api.github.com/repos/flutter/engine/forks", + "keys_url": "https://api.github.com/repos/flutter/engine/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/flutter/engine/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/flutter/engine/teams", + "hooks_url": "https://api.github.com/repos/flutter/engine/hooks", + "issue_events_url": "https://api.github.com/repos/flutter/engine/issues/events{/number}", + "events_url": "https://api.github.com/repos/flutter/engine/events", + "assignees_url": "https://api.github.com/repos/flutter/engine/assignees{/user}", + "branches_url": "https://api.github.com/repos/flutter/engine/branches{/branch}", + "tags_url": "https://api.github.com/repos/flutter/engine/tags", + "blobs_url": "https://api.github.com/repos/flutter/engine/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/flutter/engine/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/flutter/engine/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/flutter/engine/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/flutter/engine/statuses/{sha}", + "languages_url": "https://api.github.com/repos/flutter/engine/languages", + "stargazers_url": "https://api.github.com/repos/flutter/engine/stargazers", + "contributors_url": "https://api.github.com/repos/flutter/engine/contributors", + "subscribers_url": "https://api.github.com/repos/flutter/engine/subscribers", + "subscription_url": "https://api.github.com/repos/flutter/engine/subscription", + "commits_url": "https://api.github.com/repos/flutter/engine/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/flutter/engine/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/flutter/engine/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/flutter/engine/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/flutter/engine/contents/{+path}", + "compare_url": "https://api.github.com/repos/flutter/engine/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/flutter/engine/merges", + "archive_url": "https://api.github.com/repos/flutter/engine/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/flutter/engine/downloads", + "issues_url": "https://api.github.com/repos/flutter/engine/issues{/number}", + "pulls_url": "https://api.github.com/repos/flutter/engine/pulls{/number}", + "milestones_url": "https://api.github.com/repos/flutter/engine/milestones{/number}", + "notifications_url": "https://api.github.com/repos/flutter/engine/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/flutter/engine/labels{/name}", + "releases_url": "https://api.github.com/repos/flutter/engine/releases{/id}", + "deployments_url": "https://api.github.com/repos/flutter/engine/deployments", + "created_at": "2015-07-16T17:39:56Z", + "updated_at": "2023-11-08T07:16:25Z", + "pushed_at": "2023-11-08T21:00:38Z", + "git_url": "git://github.com/flutter/engine.git", + "ssh_url": "git@github.com:flutter/engine.git", + "clone_url": "https://github.com/flutter/engine.git", + "svn_url": "https://github.com/flutter/engine", + "homepage": "https://flutter.dev", + "size": 704170, + "stargazers_count": 6848, + "watchers_count": 6848, + "language": "C++", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 5600, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 99, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "c-plus-plus" + ], + "visibility": "public", + "forks": 5600, + "open_issues": 99, + "watchers": 6848, + "default_branch": "main", + "custom_properties": { + + } + }, + "organization": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "url": "https://api.github.com/orgs/flutter", + "repos_url": "https://api.github.com/orgs/flutter/repos", + "events_url": "https://api.github.com/orgs/flutter/events", + "hooks_url": "https://api.github.com/orgs/flutter/hooks", + "issues_url": "https://api.github.com/orgs/flutter/issues", + "members_url": "https://api.github.com/orgs/flutter/members{/member}", + "public_members_url": "https://api.github.com/orgs/flutter/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "description": "Flutter is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, desktop, and embedded devices from a single codebase." + }, + "enterprise": { + "id": 1732, + "slug": "alphabet", + "name": "Alphabet", + "node_id": "MDEwOkVudGVycHJpc2UxNzMy", + "avatar_url": "https://avatars.githubusercontent.com/b/1732?v=4", + "description": "", + "website_url": "https://abc.xyz/", + "html_url": "https://github.com/enterprises/alphabet", + "created_at": "2019-12-19T00:30:52Z", + "updated_at": "2023-01-20T00:41:48Z" + }, + "sender": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "installation": { + "id": 10381585, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTAzODE1ODU=" + } +} +'''; + +const String prBaseEditedEvent = ''' +{ + "action": "edited", + "number": 47609, + "pull_request": { + "url": "https://api.github.com/repos/flutter/engine/pulls/47609", + "id": 1584723957, + "node_id": "PR_kwDOAlZRSc5edPf1", + "html_url": "https://github.com/flutter/engine/pull/47609", + "diff_url": "https://github.com/flutter/engine/pull/47609.diff", + "patch_url": "https://github.com/flutter/engine/pull/47609.patch", + "issue_url": "https://api.github.com/repos/flutter/engine/issues/47609", + "number": 47609, + "state": "open", + "locked": false, + "title": "Upgrade Android SDK to 34 UpsideDownCake", + "user": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "body": "~**This should not land until https://github.com/flutter/buildroot/pull/790 (re)lands, and I swap the buildroot url back to the latest commit.**~ Reland of PR to update buildroot at https://github.com/flutter/buildroot/pull/792. Upgrades to android api 34 Also: 1. Upgrades to java 17 in DEPS/ci", + "created_at": "2023-11-02T17:09:59Z", + "updated_at": "2023-11-08T21:00:47Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "8e5e3a59a5cba4239c542ed9a914899a246640b7", + "assignee": null, + "assignees": [ + + ], + "requested_reviewers": [ + + ], + "requested_teams": [ + + ], + "labels": [ + { + "id": 246348935, + "node_id": "MDU6TGFiZWwyNDYzNDg5MzU=", + "url": "https://api.github.com/repos/flutter/engine/labels/platform-android", + "name": "platform-android", + "color": "A4C639", + "default": false, + "description": null + } + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/flutter/engine/pulls/47609/commits", + "review_comments_url": "https://api.github.com/repos/flutter/engine/pulls/47609/comments", + "review_comment_url": "https://api.github.com/repos/flutter/engine/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/flutter/engine/issues/47609/comments", + "statuses_url": "https://api.github.com/repos/flutter/engine/statuses/a6765b4c309aa082bbebade68e0c7ec308a1cc6c", + "head": { + "label": "gmackall:upgrade_to_android14", + "ref": "upgrade_to_android14", + "sha": "a6765b4c309aa082bbebade68e0c7ec308a1cc6c", + "user": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 547558963, + "node_id": "R_kgDOIKMWMw", + "name": "engine", + "full_name": "gmackall/engine", + "private": false, + "owner": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/gmackall/engine", + "description": "The Flutter engine", + "fork": true, + "url": "https://api.github.com/repos/gmackall/engine", + "forks_url": "https://api.github.com/repos/gmackall/engine/forks", + "keys_url": "https://api.github.com/repos/gmackall/engine/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/gmackall/engine/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/gmackall/engine/teams", + "hooks_url": "https://api.github.com/repos/gmackall/engine/hooks", + "issue_events_url": "https://api.github.com/repos/gmackall/engine/issues/events{/number}", + "events_url": "https://api.github.com/repos/gmackall/engine/events", + "assignees_url": "https://api.github.com/repos/gmackall/engine/assignees{/user}", + "branches_url": "https://api.github.com/repos/gmackall/engine/branches{/branch}", + "tags_url": "https://api.github.com/repos/gmackall/engine/tags", + "blobs_url": "https://api.github.com/repos/gmackall/engine/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/gmackall/engine/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/gmackall/engine/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/gmackall/engine/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/gmackall/engine/statuses/{sha}", + "languages_url": "https://api.github.com/repos/gmackall/engine/languages", + "stargazers_url": "https://api.github.com/repos/gmackall/engine/stargazers", + "contributors_url": "https://api.github.com/repos/gmackall/engine/contributors", + "subscribers_url": "https://api.github.com/repos/gmackall/engine/subscribers", + "subscription_url": "https://api.github.com/repos/gmackall/engine/subscription", + "commits_url": "https://api.github.com/repos/gmackall/engine/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/gmackall/engine/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/gmackall/engine/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/gmackall/engine/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/gmackall/engine/contents/{+path}", + "compare_url": "https://api.github.com/repos/gmackall/engine/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/gmackall/engine/merges", + "archive_url": "https://api.github.com/repos/gmackall/engine/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/gmackall/engine/downloads", + "issues_url": "https://api.github.com/repos/gmackall/engine/issues{/number}", + "pulls_url": "https://api.github.com/repos/gmackall/engine/pulls{/number}", + "milestones_url": "https://api.github.com/repos/gmackall/engine/milestones{/number}", + "notifications_url": "https://api.github.com/repos/gmackall/engine/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/gmackall/engine/labels{/name}", + "releases_url": "https://api.github.com/repos/gmackall/engine/releases{/id}", + "deployments_url": "https://api.github.com/repos/gmackall/engine/deployments", + "created_at": "2022-10-07T22:25:57Z", + "updated_at": "2023-02-02T18:38:07Z", + "pushed_at": "2023-11-08T20:57:02Z", + "git_url": "git://github.com/gmackall/engine.git", + "ssh_url": "git@github.com:gmackall/engine.git", + "clone_url": "https://github.com/gmackall/engine.git", + "svn_url": "https://github.com/gmackall/engine", + "homepage": "https://flutter.dev", + "size": 466778, + "stargazers_count": 0, + "watchers_count": 0, + "language": "C++", + "has_issues": false, + "has_projects": true, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "public", + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "flutter:main", + "ref": "main", + "sha": "941e246d4851f652cf13312180174ebc9395fac4", + "user": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "followers_url": "https://api.github.com/users/flutter/followers", + "following_url": "https://api.github.com/users/flutter/following{/other_user}", + "gists_url": "https://api.github.com/users/flutter/gists{/gist_id}", + "starred_url": "https://api.github.com/users/flutter/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/flutter/subscriptions", + "organizations_url": "https://api.github.com/users/flutter/orgs", + "repos_url": "https://api.github.com/users/flutter/repos", + "events_url": "https://api.github.com/users/flutter/events{/privacy}", + "received_events_url": "https://api.github.com/users/flutter/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 39211337, + "node_id": "MDEwOlJlcG9zaXRvcnkzOTIxMTMzNw==", + "name": "engine", + "full_name": "flutter/engine", + "private": false, + "owner": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "followers_url": "https://api.github.com/users/flutter/followers", + "following_url": "https://api.github.com/users/flutter/following{/other_user}", + "gists_url": "https://api.github.com/users/flutter/gists{/gist_id}", + "starred_url": "https://api.github.com/users/flutter/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/flutter/subscriptions", + "organizations_url": "https://api.github.com/users/flutter/orgs", + "repos_url": "https://api.github.com/users/flutter/repos", + "events_url": "https://api.github.com/users/flutter/events{/privacy}", + "received_events_url": "https://api.github.com/users/flutter/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/flutter/engine", + "description": "The Flutter engine", + "fork": false, + "url": "https://api.github.com/repos/flutter/engine", + "forks_url": "https://api.github.com/repos/flutter/engine/forks", + "keys_url": "https://api.github.com/repos/flutter/engine/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/flutter/engine/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/flutter/engine/teams", + "hooks_url": "https://api.github.com/repos/flutter/engine/hooks", + "issue_events_url": "https://api.github.com/repos/flutter/engine/issues/events{/number}", + "events_url": "https://api.github.com/repos/flutter/engine/events", + "assignees_url": "https://api.github.com/repos/flutter/engine/assignees{/user}", + "branches_url": "https://api.github.com/repos/flutter/engine/branches{/branch}", + "tags_url": "https://api.github.com/repos/flutter/engine/tags", + "blobs_url": "https://api.github.com/repos/flutter/engine/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/flutter/engine/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/flutter/engine/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/flutter/engine/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/flutter/engine/statuses/{sha}", + "languages_url": "https://api.github.com/repos/flutter/engine/languages", + "stargazers_url": "https://api.github.com/repos/flutter/engine/stargazers", + "contributors_url": "https://api.github.com/repos/flutter/engine/contributors", + "subscribers_url": "https://api.github.com/repos/flutter/engine/subscribers", + "subscription_url": "https://api.github.com/repos/flutter/engine/subscription", + "commits_url": "https://api.github.com/repos/flutter/engine/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/flutter/engine/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/flutter/engine/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/flutter/engine/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/flutter/engine/contents/{+path}", + "compare_url": "https://api.github.com/repos/flutter/engine/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/flutter/engine/merges", + "archive_url": "https://api.github.com/repos/flutter/engine/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/flutter/engine/downloads", + "issues_url": "https://api.github.com/repos/flutter/engine/issues{/number}", + "pulls_url": "https://api.github.com/repos/flutter/engine/pulls{/number}", + "milestones_url": "https://api.github.com/repos/flutter/engine/milestones{/number}", + "notifications_url": "https://api.github.com/repos/flutter/engine/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/flutter/engine/labels{/name}", + "releases_url": "https://api.github.com/repos/flutter/engine/releases{/id}", + "deployments_url": "https://api.github.com/repos/flutter/engine/deployments", + "created_at": "2015-07-16T17:39:56Z", + "updated_at": "2023-11-08T07:16:25Z", + "pushed_at": "2023-11-08T21:00:38Z", + "git_url": "git://github.com/flutter/engine.git", + "ssh_url": "git@github.com:flutter/engine.git", + "clone_url": "https://github.com/flutter/engine.git", + "svn_url": "https://github.com/flutter/engine", + "homepage": "https://flutter.dev", + "size": 704170, + "stargazers_count": 6848, + "watchers_count": 6848, + "language": "C++", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 5600, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 99, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "c-plus-plus" + ], + "visibility": "public", + "forks": 5600, + "open_issues": 99, + "watchers": 6848, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": false, + "allow_rebase_merge": false, + "allow_auto_merge": false, + "delete_branch_on_merge": true, + "allow_update_branch": true, + "use_squash_pr_title_as_default": true, + "squash_merge_commit_message": "PR_BODY", + "squash_merge_commit_title": "PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/flutter/engine/pulls/47609" + }, + "html": { + "href": "https://github.com/flutter/engine/pull/47609" + }, + "issue": { + "href": "https://api.github.com/repos/flutter/engine/issues/47609" + }, + "comments": { + "href": "https://api.github.com/repos/flutter/engine/issues/47609/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/flutter/engine/pulls/47609/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/flutter/engine/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/flutter/engine/pulls/47609/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/flutter/engine/statuses/a6765b4c309aa082bbebade68e0c7ec308a1cc6c" + } + }, + "author_association": "MEMBER", + "auto_merge": null, + "active_lock_reason": null, + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "clean", + "merged_by": null, + "comments": 4, + "review_comments": 4, + "maintainer_can_modify": true, + "commits": 32, + "additions": 83, + "deletions": 77, + "changed_files": 18 + }, + "changes": { + "base": { + "ref": { + "from": "main" + }, + "sha": { + "from": "b3af5d64d3e6e2110b07d71909fc432537339659" + } + } + }, + "repository": { + "id": 39211337, + "node_id": "MDEwOlJlcG9zaXRvcnkzOTIxMTMzNw==", + "name": "engine", + "full_name": "flutter/engine", + "private": false, + "owner": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/flutter", + "html_url": "https://github.com/flutter", + "followers_url": "https://api.github.com/users/flutter/followers", + "following_url": "https://api.github.com/users/flutter/following{/other_user}", + "gists_url": "https://api.github.com/users/flutter/gists{/gist_id}", + "starred_url": "https://api.github.com/users/flutter/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/flutter/subscriptions", + "organizations_url": "https://api.github.com/users/flutter/orgs", + "repos_url": "https://api.github.com/users/flutter/repos", + "events_url": "https://api.github.com/users/flutter/events{/privacy}", + "received_events_url": "https://api.github.com/users/flutter/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/flutter/engine", + "description": "The Flutter engine", + "fork": false, + "url": "https://api.github.com/repos/flutter/engine", + "forks_url": "https://api.github.com/repos/flutter/engine/forks", + "keys_url": "https://api.github.com/repos/flutter/engine/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/flutter/engine/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/flutter/engine/teams", + "hooks_url": "https://api.github.com/repos/flutter/engine/hooks", + "issue_events_url": "https://api.github.com/repos/flutter/engine/issues/events{/number}", + "events_url": "https://api.github.com/repos/flutter/engine/events", + "assignees_url": "https://api.github.com/repos/flutter/engine/assignees{/user}", + "branches_url": "https://api.github.com/repos/flutter/engine/branches{/branch}", + "tags_url": "https://api.github.com/repos/flutter/engine/tags", + "blobs_url": "https://api.github.com/repos/flutter/engine/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/flutter/engine/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/flutter/engine/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/flutter/engine/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/flutter/engine/statuses/{sha}", + "languages_url": "https://api.github.com/repos/flutter/engine/languages", + "stargazers_url": "https://api.github.com/repos/flutter/engine/stargazers", + "contributors_url": "https://api.github.com/repos/flutter/engine/contributors", + "subscribers_url": "https://api.github.com/repos/flutter/engine/subscribers", + "subscription_url": "https://api.github.com/repos/flutter/engine/subscription", + "commits_url": "https://api.github.com/repos/flutter/engine/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/flutter/engine/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/flutter/engine/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/flutter/engine/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/flutter/engine/contents/{+path}", + "compare_url": "https://api.github.com/repos/flutter/engine/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/flutter/engine/merges", + "archive_url": "https://api.github.com/repos/flutter/engine/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/flutter/engine/downloads", + "issues_url": "https://api.github.com/repos/flutter/engine/issues{/number}", + "pulls_url": "https://api.github.com/repos/flutter/engine/pulls{/number}", + "milestones_url": "https://api.github.com/repos/flutter/engine/milestones{/number}", + "notifications_url": "https://api.github.com/repos/flutter/engine/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/flutter/engine/labels{/name}", + "releases_url": "https://api.github.com/repos/flutter/engine/releases{/id}", + "deployments_url": "https://api.github.com/repos/flutter/engine/deployments", + "created_at": "2015-07-16T17:39:56Z", + "updated_at": "2023-11-08T07:16:25Z", + "pushed_at": "2023-11-08T21:00:38Z", + "git_url": "git://github.com/flutter/engine.git", + "ssh_url": "git@github.com:flutter/engine.git", + "clone_url": "https://github.com/flutter/engine.git", + "svn_url": "https://github.com/flutter/engine", + "homepage": "https://flutter.dev", + "size": 704170, + "stargazers_count": 6848, + "watchers_count": 6848, + "language": "C++", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 5600, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 99, + "license": { + "key": "bsd-3-clause", + "name": "BSD 3-Clause New or Revised License", + "spdx_id": "BSD-3-Clause", + "url": "https://api.github.com/licenses/bsd-3-clause", + "node_id": "MDc6TGljZW5zZTU=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "c-plus-plus" + ], + "visibility": "public", + "forks": 5600, + "open_issues": 99, + "watchers": 6848, + "default_branch": "main", + "custom_properties": { + + } + }, + "organization": { + "login": "flutter", + "id": 14101776, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2", + "url": "https://api.github.com/orgs/flutter", + "repos_url": "https://api.github.com/orgs/flutter/repos", + "events_url": "https://api.github.com/orgs/flutter/events", + "hooks_url": "https://api.github.com/orgs/flutter/hooks", + "issues_url": "https://api.github.com/orgs/flutter/issues", + "members_url": "https://api.github.com/orgs/flutter/members{/member}", + "public_members_url": "https://api.github.com/orgs/flutter/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/14101776?v=4", + "description": "Flutter is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, desktop, and embedded devices from a single codebase." + }, + "enterprise": { + "id": 1732, + "slug": "alphabet", + "name": "Alphabet", + "node_id": "MDEwOkVudGVycHJpc2UxNzMy", + "avatar_url": "https://avatars.githubusercontent.com/b/1732?v=4", + "description": "", + "website_url": "https://abc.xyz/", + "html_url": "https://github.com/enterprises/alphabet", + "created_at": "2019-12-19T00:30:52Z", + "updated_at": "2023-01-20T00:41:48Z" + }, + "sender": { + "login": "gmackall", + "id": 34871572, + "node_id": "MDQ6VXNlcjM0ODcxNTcy", + "avatar_url": "https://avatars.githubusercontent.com/u/34871572?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gmackall", + "html_url": "https://github.com/gmackall", + "followers_url": "https://api.github.com/users/gmackall/followers", + "following_url": "https://api.github.com/users/gmackall/following{/other_user}", + "gists_url": "https://api.github.com/users/gmackall/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gmackall/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gmackall/subscriptions", + "organizations_url": "https://api.github.com/users/gmackall/orgs", + "repos_url": "https://api.github.com/users/gmackall/repos", + "events_url": "https://api.github.com/users/gmackall/events{/privacy}", + "received_events_url": "https://api.github.com/users/gmackall/received_events", + "type": "User", + "site_admin": false + }, + "installation": { + "id": 10381585, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTAzODE1ODU=" + } +} +'''; From 94ffec8306dc9c76cb632ae9cf5d6f7265cc7aa8 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Tue, 14 Nov 2023 10:48:31 -0700 Subject: [PATCH 120/139] prep 9.20.0 --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94e3728c..9acbade0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 9.20.0 + +* Add a Changes object to the PullRequestEvent object so we can see what changed in edited PR events by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/390 + + +**Full Changelog**: https://github.com/SpinlockLabs/github.dart/compare/9.19.0...9.20.0 + ## 9.19.0 * Revert "Add the 'PushEvent' webhook and associated PushCommit object" by @robrbecker in https://github.com/SpinlockLabs/github.dart/pull/387 diff --git a/pubspec.yaml b/pubspec.yaml index 8bdc72f6..4fb206a9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.19.0 +version: 9.20.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 1d4023c62ada078fb624344c842b2344893084e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:53:55 -0700 Subject: [PATCH 121/139] Bump actions/checkout from 3 to 4 (#388) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dart.yml | 2 +- .github/workflows/publish_demos.yml | 2 +- .github/workflows/release_unreleased_prs.yml | 2 +- .github/workflows/triage.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 151d23f4..5fb5a1c7 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -15,7 +15,7 @@ jobs: # Test with at least the declared minimum Dart version sdk: [2.18.7, stable] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 965e7949..3c5fa2e0 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -10,7 +10,7 @@ jobs: image: dart steps: - name: Checkout 🛎️ - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install rsync 📚 run: | diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml index 97f16aa3..2307c913 100644 --- a/.github/workflows/release_unreleased_prs.yml +++ b/.github/workflows/release_unreleased_prs.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 2 ref: master diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 224ea1ca..84a45759 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -8,7 +8,7 @@ jobs: name: Assign Rob runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Apply untriaged label uses: actions/github-script@v6 with: From d2c7bb288b07cb4e6b46bfa7a485523e59681303 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:54:14 -0700 Subject: [PATCH 122/139] Bump JamesIves/github-pages-deploy-action from 4.4.2 to 4.4.3 (#382) Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.4.2 to 4.4.3. - [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases) - [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.4.2...v4.4.3) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish_demos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 3c5fa2e0..546140c0 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -24,7 +24,7 @@ jobs: rm build/example/packages - name: Publish 🚀 - uses: JamesIves/github-pages-deploy-action@v4.4.2 + uses: JamesIves/github-pages-deploy-action@v4.4.3 with: branch: gh-pages # The branch the action should deploy to. folder: build/example # The folder the action should deploy. From 52f71de142641849cff1121a0d8b33c01549ec57 Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Wed, 29 Nov 2023 07:36:19 -0800 Subject: [PATCH 123/139] Update release process to use actions (#392) * Update release process to use actions * Add publish pubdev and some minor cleanup --- .github/workflows/create_release.yml | 16 ++ .github/workflows/create_tag.yml | 25 +++ .github/workflows/publish_pubdev.yml | 14 ++ .github/workflows/publish_release.yml | 14 -- .github/workflows/release_unreleased_prs.yml | 36 ---- .github/workflows/require_semver_label.yml | 29 --- CONTRIBUTING.md | 35 ++-- tool/release_unreleased_prs.dart | 178 ------------------- 8 files changed, 65 insertions(+), 282 deletions(-) create mode 100644 .github/workflows/create_release.yml create mode 100644 .github/workflows/create_tag.yml create mode 100644 .github/workflows/publish_pubdev.yml delete mode 100644 .github/workflows/publish_release.yml delete mode 100644 .github/workflows/release_unreleased_prs.yml delete mode 100644 .github/workflows/require_semver_label.yml delete mode 100644 tool/release_unreleased_prs.dart diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml new file mode 100644 index 00000000..8255c0c0 --- /dev/null +++ b/.github/workflows/create_release.yml @@ -0,0 +1,16 @@ +name: Create Release +on: + push: + tags: + - '*' +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Create a Release + uses: elgohr/Github-Release-Action@v5 + env: + GITHUB_TOKEN: "${{ secrets.RELEASE_TOKEN }}" + with: + title: ${{ github.ref }} diff --git a/.github/workflows/create_tag.yml b/.github/workflows/create_tag.yml new file mode 100644 index 00000000..c5793f0c --- /dev/null +++ b/.github/workflows/create_tag.yml @@ -0,0 +1,25 @@ +name: Release + +# Runs when a PR merges. +# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges +on: + pull_request: + types: + - closed + +jobs: + release: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + container: dart + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: master + - uses: jacopocarlini/action-autotag@3.0.0 + with: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/publish_pubdev.yml b/.github/workflows/publish_pubdev.yml new file mode 100644 index 00000000..336e0cf5 --- /dev/null +++ b/.github/workflows/publish_pubdev.yml @@ -0,0 +1,14 @@ +# .github/workflows/publish.yml +name: Publish to pub.dev + +on: + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+*' + +# Publish using the reusable workflow from dart-lang. +jobs: + publish: + permissions: + id-token: write # Required for authentication using OIDC + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 \ No newline at end of file diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml deleted file mode 100644 index 853f8c53..00000000 --- a/.github/workflows/publish_release.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Publish to pub.dev - -on: - push: - tags: - - '[0-9]+.[0-9]+.[0-9]+*' - -permissions: - contents: read - id-token: write - -jobs: - publish: - uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 diff --git a/.github/workflows/release_unreleased_prs.yml b/.github/workflows/release_unreleased_prs.yml deleted file mode 100644 index 2307c913..00000000 --- a/.github/workflows/release_unreleased_prs.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Release unreleased PRs - -# Runs when a PR merges. -# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-pull-request-merges -on: - workflow_dispatch: - - # Comment out for now and just use manual kickoff of the action - # until we can figure our permissions - # pull_request: - # types: - # - closed - -jobs: - release: - if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest - container: dart - permissions: - contents: write - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 2 - ref: master - - name: Release - run: | - git config --global user.name ${{ secrets.USER_NAME }} - git config --global user.email ${{ secrets.USER_EMAIL }} - export PATH="$PATH":"$HOME/.pub-cache/bin" - export GITHUB_TOKEN=${{secrets.MACHINE_GITHUB_API_TOKEN}} - export MACHINE_GITHUB_API_TOKEN=${{secrets.MACHINE_GITHUB_API_TOKEN}} - dart pub get - dart tool/release_unreleased_prs.dart \ No newline at end of file diff --git a/.github/workflows/require_semver_label.yml b/.github/workflows/require_semver_label.yml deleted file mode 100644 index 0ac40231..00000000 --- a/.github/workflows/require_semver_label.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Require semver:* and unreleased Label -on: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - -jobs: - label: - runs-on: ubuntu-latest - steps: - - uses: buildsville/add-remove-label@v2.0.0 - if: github.event.action == 'opened' - with: - token: ${{secrets.GITHUB_TOKEN}} - labels: Unreleased - type: add - # - uses: mheap/github-action-required-labels@v3 - # with: - # mode: exactly - # count: 1 - # labels: "semver:patch, semver:minor, semver:major" - # token: ${{secrets.GITHUB_TOKEN}} - # add_comment: Add a semantic version label (semver:patch semver:minor semver:major) - # - uses: mheap/github-action-required-labels@v3 - # with: - # mode: exactly - # count: 1 - # labels: "unreleased" - # token: ${{secrets.GITHUB_TOKEN}} - # add_comment: The unrelease label is required to track which PRs have yet to be released. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c9a832b4..b574e5a8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ GitHub.dart is of course Open Source! We love it when people contribute! - [Commit your code](http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository) for each logical change (see [tips for creating better commit messages](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message)). - [Push your change](https://help.github.com/articles/pushing-to-a-remote) to your fork. - [Create a Pull Request](https://help.github.com/articles/creating-a-pull-request) on GitHub for your change. -- Wait for reviewers (usually kaendfinger) to give feedback. +- Wait for reviewers (usually robrbecker) to give feedback. - When the reviewers think that the Pull Request is ready, they will merge it. ## Code Style @@ -34,12 +34,14 @@ Pull Request rejections are not a bad thing. It just means you need to fix somet To regenerate the JSON logic for the models, run: -``` +```sh dart run build_runner build -d ``` ## Tests +`dart test` will only run the unit tests. + To run the complete test suite you will need to install `octokit/fixtures-server`. @@ -52,29 +54,12 @@ GitHub and execute tests against it using your localhost port 3000. ## Contacting Us -- IRC: `#directcode on irc.esper.net and irc.freenode.net` -- Email: `kaendfinger@gmail.com` - -## Becoming a Committer - -If you get on IRC and ask us, we can review your work and add you as a committer if we think you should have it. - -## Releasing & Publishing - -This repo is now configured to release after every PR merge. This means a couple of things for PRs that are put up: +File issues at https://github.com/SpinlockLabs/github.dart/issues -1. A semver label is required. A GitHub check will remind you that you need one. Reviewers should check that it is correct. See https://semver.org/ to understand more. -2. There is no need to modify the version in the pubspec.yaml in your PRs. The tooling will update the version according to the semver label applied to your PR. -3. Same thing for the CHANGELOG.md. Tooling will update it automatically after merge. -4. A GitHub release will be created and published to pub.dev for you. +## Releases -For example if your PR has `semver:minor` label applied and the latest version is 1.2.3, once merged, the tooling will: -- update the pubspec.yaml to 1.3.0 -- Add the GitHub auto-generated release notes with 1.3.0 to the top of the CHANGELOG.md -- Create a release in GitHub for 1.3.0 (which creates a git tag of 1.3.0) -- Remove the `unreleased` label from the PR and add the `released` label -- Comment on the PR stating the version that it was released in and link to the release -- When the release is created, it will automatically be published to pub.dev +Merged pull requests that edit the `pubspec.yaml` version will create new releases. +Once CI is green, it will create a tag for that commit based on the version, which +gets published by pub.dev. -NOTE: If you want the ability to merge a PR **WITHOUT** automatically releasing and publishing, simply add the `no_release_on_merge` label before merging. Do note that the PR has been merged though and whatever the next PR is that triggers a release will release and publish everything that has been merged. So if you want to batch a few PRs into 1 release, label them all `no_release_on_merge`. Then whichever is the last to be merged, remove that label before merging to trigger the release. -You may also manually trigger the action to release unreleased PRs from the Actions tab in GitHub. +If no new version was created, nothing will be published. diff --git a/tool/release_unreleased_prs.dart b/tool/release_unreleased_prs.dart deleted file mode 100644 index b8cf8b17..00000000 --- a/tool/release_unreleased_prs.dart +++ /dev/null @@ -1,178 +0,0 @@ -import 'dart:io'; -import 'package:github/github.dart'; -import 'package:pub_semver/pub_semver.dart'; -import 'package:yaml_edit/yaml_edit.dart'; - -/////////////////////////////////////////////////////////// -const mainBranchName = 'master'; -const semverMajor = 'semver:major'; -const semverMinor = 'semver:minor'; -const semverPatch = 'semver:patch'; -const semvers = [semverMajor, semverMinor, semverPatch]; -const fullrepo = 'SpinlockLabs/github.dart'; -/////////////////////////////////////////////////////////// - -var _gh = GitHub(auth: findAuthenticationFromEnvironment()); -var _slug = RepositorySlug.full(fullrepo); - -Future main(List args) async { - // get the latest released version - var latestVersion = await getLatestVersion(_slug); - - // get all PRs (issues) that are merged but unreleased - var unreleased = await getUnreleasedPRs(); - - if (unreleased.isEmpty) { - print('No unreleased PRs found'); - return; - } - - // Calculate the next version - var nextVersion = getNextVersion(latestVersion, unreleased); - - // Use the new version to generate release notes - var notes = await generateReleaseNotes(latestVersion.toString(), nextVersion); - - // update the changelog with the new release notes - updateChangeLog(notes, nextVersion); - - // update the version in the pubspec - updatePubspec(nextVersion); - - // commit those changes and push them - commitUpdates(nextVersion); - - // create a new release in github at main - await createRelease(nextVersion, mainBranchName); - - // remove the unreleased labels - for (final i in unreleased) { - await _gh.issues.removeLabelForIssue(_slug, i.number, 'unreleased'); - await _gh.issues.addLabelsToIssue(_slug, i.number, ['released']); - await _gh.issues.createComment(_slug, i.number, - 'Released in version $nextVersion https://github.com/$fullrepo/releases/tag/$nextVersion'); - } - - exit(0); -} - -String run(String cmd, {List? rest}) { - var args = []; - if (rest != null) { - args = rest; - } else { - args = cmd.split(' '); - if (args.isEmpty) { - return ''; - } - cmd = args.removeAt(0); - } - var result = Process.runSync(cmd, args); - if (result.exitCode != 0) { - print('Command failed'); - } - if (result.stdout != null) { - print(result.stdout); - } - if (result.stderr != null) { - print(result.stderr); - } - if (result.exitCode != 0) { - exit(6); - } - - return result.stdout; -} - -Future getLatestVersion(RepositorySlug slug) async { - var latestRelease = await _gh.repositories.getLatestRelease(slug); - var latestTag = latestRelease.tagName!; - print('Latest Tag: $latestTag'); - return Version.parse(latestTag); -} - -Future> getUnreleasedPRs() async { - print('Loading unreleased PRs...'); - var prs = await _gh.search - .issues( - 'repo:${_slug.fullName} is:pull-request label:unreleased -label:no_release_on_merge state:closed', - sort: 'desc') - .toList(); - print('${prs.length} loaded'); - return prs; -} - -String getNextVersion(Version currentVersion, List unreleased) { - var semvers = {}; - for (final pr in unreleased) { - var prlabels = pr.labels - .where((element) => element.name.startsWith('semver:')) - .toList(); - for (final l in prlabels) { - semvers.add(l.name); - } - } - print('Calculating next version based on $semvers'); - var newVersion = ''; - if (semvers.contains('semver:major')) { - newVersion = currentVersion.nextMajor.toString(); - } else if (semvers.contains('semver:minor')) { - newVersion = currentVersion.nextMinor.toString(); - } else if (semvers.contains('semver:patch')) { - newVersion = currentVersion.nextPatch.toString(); - } - print('Next Version: $newVersion'); - return newVersion; -} - -Future generateReleaseNotes( - String fromVersion, String newVersion) async { - var notes = await _gh.repositories.generateReleaseNotes(CreateReleaseNotes( - _slug.owner, _slug.name, newVersion, - previousTagName: fromVersion)); - - var releaseNotes = notes.body.replaceFirst('## What\'s Changed', ''); - - var r = '## $newVersion\n$releaseNotes'; - print(r); - return r; -} - -void updateChangeLog(String notes, String version) { - var log = File('CHANGELOG.md'); - var logdata = log.existsSync() ? log.readAsStringSync() : ''; - if (logdata.contains('## $version')) { - return; - } - log.writeAsStringSync('$notes\n\n$logdata'); -} - -void updatePubspec(String newVersion) { - var f = File('pubspec.yaml'); - var editor = YamlEditor(f.readAsStringSync()); - editor.update(['version'], newVersion); - f.writeAsStringSync(editor.toString()); -} - -Future createRelease(String version, String target) async { - print('Creating release ...'); - var release = await _gh.repositories.createRelease( - _slug, - CreateRelease.from( - tagName: version, - name: version, - generateReleaseNotes: true, - targetCommitish: target, - isDraft: false, - isPrerelease: false)); - - print('Release ${release.name} created ${release.createdAt}'); - print(release.body); - return release; -} - -void commitUpdates(String version) { - run('git add pubspec.yaml CHANGELOG.md'); - run('git', rest: ['commit', '-m', 'prep $version']); - run('git push'); -} From 948c0f9310472c66dc75a8d29b335ee586be0317 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:21:45 -0800 Subject: [PATCH 124/139] Bump JamesIves/github-pages-deploy-action from 4.4.3 to 4.5.0 (#396) Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.4.3 to 4.5.0. - [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases) - [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.4.3...v4.5.0) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish_demos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 546140c0..603b4a09 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -24,7 +24,7 @@ jobs: rm build/example/packages - name: Publish 🚀 - uses: JamesIves/github-pages-deploy-action@v4.4.3 + uses: JamesIves/github-pages-deploy-action@v4.5.0 with: branch: gh-pages # The branch the action should deploy to. folder: build/example # The folder the action should deploy. From df7118a9b632a8754db07deccf8f5bf3a75d3620 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:22:08 -0800 Subject: [PATCH 125/139] Bump actions/checkout from 3 to 4 (#395) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/create_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 8255c0c0..2c071305 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -7,7 +7,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Create a Release uses: elgohr/Github-Release-Action@v5 env: From 7bc06677699847218e196d86a1839045464fcdec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:22:27 -0800 Subject: [PATCH 126/139] Bump actions/github-script from 6 to 7 (#394) Bumps [actions/github-script](https://github.com/actions/github-script) from 6 to 7. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/triage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 84a45759..4d51d30c 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Apply untriaged label - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | @@ -21,7 +21,7 @@ jobs: labels: ['untriaged','unreleased'] }) - name: Comment On New Issues - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | From 741c26d0142413b80b89049772a5e693e064ebfb Mon Sep 17 00:00:00 2001 From: Casey Hillers Date: Thu, 28 Dec 2023 09:26:23 -0800 Subject: [PATCH 127/139] Update MiscService.getApiStatus to v2 (#393) * v1 has been deleted Co-authored-by: Rob Becker --- CHANGELOG.md | 5 +++ lib/src/common/misc_service.dart | 4 +- lib/src/common/model/misc.dart | 62 ++++++++++++++++++++++++------ lib/src/common/model/misc.g.dart | 44 ++++++++++++++++----- pubspec.yaml | 2 +- test/common/misc_service_test.dart | 37 ++++++++++++++++++ 6 files changed, 131 insertions(+), 23 deletions(-) create mode 100644 test/common/misc_service_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 9acbade0..953f9937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.21.0 + +* Update MiscService.getApiStatus() to use the v2 API + * `APIStatus` has been refactored to match, now exposing `page` and `status` + ## 9.20.0 * Add a Changes object to the PullRequestEvent object so we can see what changed in edited PR events by @ricardoamador in https://github.com/SpinlockLabs/github.dart/pull/390 diff --git a/lib/src/common/misc_service.dart b/lib/src/common/misc_service.dart index 4951848f..bb351f3d 100644 --- a/lib/src/common/misc_service.dart +++ b/lib/src/common/misc_service.dart @@ -68,8 +68,10 @@ class MiscService extends Service { } /// Gets the GitHub API Status. + /// + /// API docs: https://www.githubstatus.com/api Future getApiStatus() => - github.getJSON('https://status.github.com/api/status.json', + github.getJSON('https://status.github.com/api/v2/status.json', statusCode: StatusCodes.OK, convert: APIStatus.fromJson); /// Returns an ASCII Octocat with the specified [text]. diff --git a/lib/src/common/model/misc.dart b/lib/src/common/model/misc.dart index adf7b2be..18fc0a54 100644 --- a/lib/src/common/model/misc.dart +++ b/lib/src/common/model/misc.dart @@ -60,27 +60,65 @@ class RateLimit { Map toJson() => _$RateLimitToJson(this); } -/// Model class for the GitHub api status. +/// Model class for the GitHub API status. @JsonSerializable() class APIStatus { APIStatus({ + this.page, this.status, - this.lastUpdatedAt, - this.createdOn, - this.message, }); - final String? status; - @JsonKey(name: 'last_updated') - final DateTime? lastUpdatedAt; + /// Details about where to find more information. + final APIStatusPage? page; - @JsonKey(name: 'created_on') - final DateTime? createdOn; - - @JsonKey(name: 'body') - final String? message; + /// An overview of the current status. + final APIStatusMessage? status; factory APIStatus.fromJson(Map input) => _$APIStatusFromJson(input); Map toJson() => _$APIStatusToJson(this); } + +@JsonSerializable() +class APIStatusPage { + const APIStatusPage({ + this.id, + this.name, + this.url, + this.updatedAt, + }); + + /// Unique identifier for the current status. + final String? id; + + final String? name; + + /// Where to get more detailed information. + final String? url; + + @JsonKey(name: 'updated_at') + final DateTime? updatedAt; + + factory APIStatusPage.fromJson(Map input) => + _$APIStatusPageFromJson(input); + Map toJson() => _$APIStatusPageToJson(this); +} + +/// Overview class of the GitHub API status. +@JsonSerializable() +class APIStatusMessage { + const APIStatusMessage({ + this.description, + this.indicator, + }); + + /// A human description of the blended component status. + final String? description; + + /// An indicator - one of none, minor, major, or critical. + final String? indicator; + + factory APIStatusMessage.fromJson(Map input) => + _$APIStatusMessageFromJson(input); + Map toJson() => _$APIStatusMessageToJson(this); +} diff --git a/lib/src/common/model/misc.g.dart b/lib/src/common/model/misc.g.dart index 34362c50..d7b3896c 100644 --- a/lib/src/common/model/misc.g.dart +++ b/lib/src/common/model/misc.g.dart @@ -31,19 +31,45 @@ Map _$RateLimitToJson(RateLimit instance) => { }; APIStatus _$APIStatusFromJson(Map json) => APIStatus( - status: json['status'] as String?, - lastUpdatedAt: json['last_updated'] == null + page: json['page'] == null ? null - : DateTime.parse(json['last_updated'] as String), - createdOn: json['created_on'] == null + : APIStatusPage.fromJson(json['page'] as Map), + status: json['status'] == null ? null - : DateTime.parse(json['created_on'] as String), - message: json['body'] as String?, + : APIStatusMessage.fromJson(json['status'] as Map), ); Map _$APIStatusToJson(APIStatus instance) => { + 'page': instance.page, 'status': instance.status, - 'last_updated': instance.lastUpdatedAt?.toIso8601String(), - 'created_on': instance.createdOn?.toIso8601String(), - 'body': instance.message, + }; + +APIStatusPage _$APIStatusPageFromJson(Map json) => + APIStatusPage( + id: json['id'] as String?, + name: json['name'] as String?, + url: json['url'] as String?, + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), + ); + +Map _$APIStatusPageToJson(APIStatusPage instance) => + { + 'id': instance.id, + 'name': instance.name, + 'url': instance.url, + 'updated_at': instance.updatedAt?.toIso8601String(), + }; + +APIStatusMessage _$APIStatusMessageFromJson(Map json) => + APIStatusMessage( + description: json['description'] as String?, + indicator: json['indicator'] as String?, + ); + +Map _$APIStatusMessageToJson(APIStatusMessage instance) => + { + 'description': instance.description, + 'indicator': instance.indicator, }; diff --git a/pubspec.yaml b/pubspec.yaml index 4fb206a9..0251b7c7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.20.0 +version: 9.21.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart diff --git a/test/common/misc_service_test.dart b/test/common/misc_service_test.dart new file mode 100644 index 00000000..2066e271 --- /dev/null +++ b/test/common/misc_service_test.dart @@ -0,0 +1,37 @@ +import 'dart:io'; + +import 'package:github/src/common.dart'; +import 'package:http/http.dart'; +import 'package:http/testing.dart'; +import 'package:test/test.dart'; + +void main() { + MiscService create(Future Function(Request) f) { + final client = MockClient(f); + final github = GitHub(client: client); + return MiscService(github); + } + + test('api status', () async { + final miscService = create( + (_) async => Response(''' +{ + "page":{ + "id":"kctbh9vrtdwd", + "name":"GitHub", + "url":"https://www.githubstatus.com", + "updated_at": "2023-11-29T08:03:04Z" + }, + "status": { + "description": "Partial System Outage", + "indicator": "major" + } +}''', HttpStatus.ok), + ); + final status = await miscService.getApiStatus(); + expect(status.page, isNotNull); + expect(status.page?.id, 'kctbh9vrtdwd'); + expect(status.status, isNotNull); + expect(status.status?.indicator, 'major'); + }); +} From 6b9678e0d207bdf4d74a6d43b84b000e8211de4b Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 3 Jan 2024 18:37:11 +0100 Subject: [PATCH 128/139] Make `User` field nullable in `PullRequestReview` (#383) * Make `User` field nullable in `PullRequestReview` * Rev version --- CHANGELOG.md | 4 ++++ lib/src/common/model/pulls.dart | 4 ++-- lib/src/common/model/pulls.g.dart | 4 +++- pubspec.yaml | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 953f9937..9665e6e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 9.22.0 + +* Add support for the `Ghost` user when the Github user is deleted. + ## 9.21.0 * Update MiscService.getApiStatus() to use the v2 API diff --git a/lib/src/common/model/pulls.dart b/lib/src/common/model/pulls.dart index cdbf6ed8..2cb10a8e 100644 --- a/lib/src/common/model/pulls.dart +++ b/lib/src/common/model/pulls.dart @@ -311,14 +311,14 @@ class PullRequestFile { class PullRequestReview { PullRequestReview( {required this.id, - required this.user, + this.user, this.body, this.state, this.htmlUrl, this.pullRequestUrl}); int id; - User user; + User? user; String? body; String? state; String? htmlUrl; diff --git a/lib/src/common/model/pulls.g.dart b/lib/src/common/model/pulls.g.dart index dfe3a3b3..cf370e22 100644 --- a/lib/src/common/model/pulls.g.dart +++ b/lib/src/common/model/pulls.g.dart @@ -253,7 +253,9 @@ Map _$PullRequestFileToJson(PullRequestFile instance) => PullRequestReview _$PullRequestReviewFromJson(Map json) => PullRequestReview( id: json['id'] as int, - user: User.fromJson(json['user'] as Map), + user: json['user'] == null + ? null + : User.fromJson(json['user'] as Map), body: json['body'] as String?, state: json['state'] as String?, htmlUrl: json['html_url'] as String?, diff --git a/pubspec.yaml b/pubspec.yaml index 0251b7c7..af2ff765 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.21.0 +version: 9.22.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From e0bd51a6de77b2278d435cda881a56de0758b3be Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 23 Feb 2024 11:24:18 -0800 Subject: [PATCH 129/139] require dart 3.0; update to the latest package:lints (#399) * require dart 3.0; update to the latest package:lints * update pubspec and changelog --- .github/workflows/dart.yml | 2 +- CHANGELOG.md | 5 +++++ analysis_options.yaml | 2 -- lib/src/common.dart | 2 ++ lib/src/common/activity_service.dart | 2 +- lib/src/common/authorizations_service.dart | 2 +- lib/src/common/checks_service.dart | 9 ++++----- lib/src/common/gists_service.dart | 2 +- lib/src/common/git_service.dart | 2 +- lib/src/common/issues_service.dart | 2 +- lib/src/common/misc_service.dart | 2 +- lib/src/common/model/checks.dart | 10 +++++----- lib/src/common/orgs_service.dart | 2 +- lib/src/common/pulls_service.dart | 2 +- lib/src/common/repos_service.dart | 2 +- lib/src/common/search_service.dart | 2 +- lib/src/common/url_shortener_service.dart | 2 +- lib/src/common/users_service.dart | 2 +- lib/src/common/util/errors.dart | 16 +++++++--------- lib/src/common/util/utils.dart | 2 +- pubspec.yaml | 8 ++++---- test/helper/http.dart | 4 ++-- test/server/hooks_test_data.dart | 1 + tool/process_github_schema.dart | 2 +- 24 files changed, 45 insertions(+), 42 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 5fb5a1c7..2d725e23 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -13,7 +13,7 @@ jobs: matrix: os: [ubuntu-latest] # Test with at least the declared minimum Dart version - sdk: [2.18.7, stable] + sdk: ['3.0', stable] steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9665e6e4..ea5c0870 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.23.0 + +* Require Dart 3.0. +* Update to the latest `package:lints`. + ## 9.22.0 * Add support for the `Ghost` user when the Github user is deleted. diff --git a/analysis_options.yaml b/analysis_options.yaml index f7a9ff49..1af8628e 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -15,8 +15,6 @@ linter: - avoid_implementing_value_types - avoid_js_rounded_ints - avoid_private_typedef_functions - - avoid_returning_null - - avoid_returning_null_for_future - avoid_returning_this - avoid_setters_without_getters - avoid_slow_async_io diff --git a/lib/src/common.dart b/lib/src/common.dart index 8ec0f7ae..df783a26 100644 --- a/lib/src/common.dart +++ b/lib/src/common.dart @@ -1,5 +1,7 @@ /// The Core of GitHub for Dart. /// Contains the Models and other GitHub stuff. +library; + export 'package:github/src/common/activity_service.dart'; export 'package:github/src/common/authorizations_service.dart'; export 'package:github/src/common/checks_service.dart'; diff --git a/lib/src/common/activity_service.dart b/lib/src/common/activity_service.dart index 0001fcdc..f69e8c49 100644 --- a/lib/src/common/activity_service.dart +++ b/lib/src/common/activity_service.dart @@ -9,7 +9,7 @@ import 'package:http/http.dart' as http; /// /// API docs: https://developer.github.com/v3/activity/ class ActivityService extends Service { - ActivityService(GitHub github) : super(github); + ActivityService(super.github); /// Lists public events. /// diff --git a/lib/src/common/authorizations_service.dart b/lib/src/common/authorizations_service.dart index 3cbe6ef0..68b80c25 100644 --- a/lib/src/common/authorizations_service.dart +++ b/lib/src/common/authorizations_service.dart @@ -10,7 +10,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://developer.github.com/v3/oauth_authorizations/ class AuthorizationsService extends Service { - AuthorizationsService(GitHub github) : super(github); + AuthorizationsService(super.github); /// Lists all authorizations. /// diff --git a/lib/src/common/checks_service.dart b/lib/src/common/checks_service.dart index 0e87f4d2..f3085197 100644 --- a/lib/src/common/checks_service.dart +++ b/lib/src/common/checks_service.dart @@ -18,14 +18,13 @@ class ChecksService extends Service { /// API docs: https://developer.github.com/v3/checks/suites/ final CheckSuitesService checkSuites; - ChecksService(GitHub github) + ChecksService(super.github) : checkRuns = CheckRunsService._(github), - checkSuites = CheckSuitesService._(github), - super(github); + checkSuites = CheckSuitesService._(github); } class CheckRunsService extends Service { - CheckRunsService._(GitHub github) : super(github); + CheckRunsService._(super.github); /// Creates a new check run for a specific commit in a repository. /// Your GitHub App must have the `checks:write` permission to create check runs. @@ -235,7 +234,7 @@ class CheckRunsService extends Service { } class CheckSuitesService extends Service { - CheckSuitesService._(GitHub github) : super(github); + CheckSuitesService._(super.github); /// Gets a single check suite using its `id`. /// GitHub Apps must have the `checks:read` permission on a private repository or pull access to a public repository to get check suites. diff --git a/lib/src/common/gists_service.dart b/lib/src/common/gists_service.dart index 9078e03d..05ac62bd 100644 --- a/lib/src/common/gists_service.dart +++ b/lib/src/common/gists_service.dart @@ -8,7 +8,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://developer.github.com/v3/gists/ class GistsService extends Service { - GistsService(GitHub github) : super(github); + GistsService(super.github); /// lists gists for a user. /// diff --git a/lib/src/common/git_service.dart b/lib/src/common/git_service.dart index 7052e4f6..338dbeba 100644 --- a/lib/src/common/git_service.dart +++ b/lib/src/common/git_service.dart @@ -8,7 +8,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://developer.github.com/v3/git/blobs/ class GitService extends Service { - const GitService(GitHub github) : super(github); + const GitService(super.github); /// Fetches a blob from [slug] for a given [sha]. /// diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index 243c81dd..ed061846 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -8,7 +8,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://developer.github.com/v3/issues/ class IssuesService extends Service { - IssuesService(GitHub github) : super(github); + IssuesService(super.github); /// List all issues across all the authenticated user’s visible repositories /// including owned repositories, member repositories, and organization repositories diff --git a/lib/src/common/misc_service.dart b/lib/src/common/misc_service.dart index bb351f3d..30385a18 100644 --- a/lib/src/common/misc_service.dart +++ b/lib/src/common/misc_service.dart @@ -7,7 +7,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://developer.github.com/v3/misc/ class MiscService extends Service { - MiscService(GitHub github) : super(github); + MiscService(super.github); /// Fetches all emojis available on GitHub /// Returns a map of the name to a url of the image. diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index 9d7d6e21..5068febc 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -9,7 +9,7 @@ class CheckRunAnnotationLevel extends EnumWithValue { static const warning = CheckRunAnnotationLevel._('warning'); static const failure = CheckRunAnnotationLevel._('failure'); - const CheckRunAnnotationLevel._(String value) : super(value); + const CheckRunAnnotationLevel._(String super.value); factory CheckRunAnnotationLevel._fromValue(String? value) { switch (value) { @@ -51,7 +51,7 @@ class CheckRunConclusion extends EnumWithValue { static const actionRequired = CheckRunConclusion._('action_required'); static const empty = CheckRunConclusion._(null); - const CheckRunConclusion._(String? value) : super(value); + const CheckRunConclusion._(super.value); factory CheckRunConclusion._fromValue(String? value) { if (value == null) { @@ -79,13 +79,13 @@ class CheckRunStatus extends EnumWithValue { static const queued = CheckRunStatus._('queued'); static const inProgress = CheckRunStatus._('in_progress'); static const completed = CheckRunStatus._('completed'); - const CheckRunStatus._(String value) : super(value); + const CheckRunStatus._(String super.value); } class CheckRunFilter extends EnumWithValue { static const all = CheckRunFilter._('all'); static const latest = CheckRunFilter._('latest'); - const CheckRunFilter._(String value) : super(value); + const CheckRunFilter._(String super.value); } @immutable @@ -253,7 +253,7 @@ class CheckRunAnnotation { assert(title.length <= 255); @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { if (other is CheckRunAnnotation) { return other.annotationLevel == annotationLevel && other.path == path && diff --git a/lib/src/common/orgs_service.dart b/lib/src/common/orgs_service.dart index d793a8b9..b2ca7b26 100644 --- a/lib/src/common/orgs_service.dart +++ b/lib/src/common/orgs_service.dart @@ -9,7 +9,7 @@ import 'package:http/http.dart' as http; /// /// API docs: https://developer.github.com/v3/orgs/ class OrganizationsService extends Service { - OrganizationsService(GitHub github) : super(github); + OrganizationsService(super.github); /// Lists all of the memberships in organizations for the given [userName]. /// If [userName] is not specified we list the memberships in organizations diff --git a/lib/src/common/pulls_service.dart b/lib/src/common/pulls_service.dart index 5242f0e3..7fee2bf9 100644 --- a/lib/src/common/pulls_service.dart +++ b/lib/src/common/pulls_service.dart @@ -8,7 +8,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://developer.github.com/v3/pulls/ class PullRequestsService extends Service { - PullRequestsService(GitHub github) : super(github); + PullRequestsService(super.github); /// Fetches several pull requests. /// diff --git a/lib/src/common/repos_service.dart b/lib/src/common/repos_service.dart index a274710e..83fa5ef0 100644 --- a/lib/src/common/repos_service.dart +++ b/lib/src/common/repos_service.dart @@ -9,7 +9,7 @@ import 'package:http/http.dart' as http; /// /// API docs: https://developer.github.com/v3/repos/ class RepositoriesService extends Service { - RepositoriesService(GitHub github) : super(github); + RepositoriesService(super.github); /// Lists the repositories of the currently authenticated user. /// diff --git a/lib/src/common/search_service.dart b/lib/src/common/search_service.dart index bf2b41ec..27cf6eef 100644 --- a/lib/src/common/search_service.dart +++ b/lib/src/common/search_service.dart @@ -8,7 +8,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://developer.github.com/v3/search/ class SearchService extends Service { - SearchService(GitHub github) : super(github); + SearchService(super.github); /// Search for repositories using [query]. /// Since the Search Rate Limit is small, this is a best effort implementation. diff --git a/lib/src/common/url_shortener_service.dart b/lib/src/common/url_shortener_service.dart index 0b1e296f..60db2958 100644 --- a/lib/src/common/url_shortener_service.dart +++ b/lib/src/common/url_shortener_service.dart @@ -6,7 +6,7 @@ import 'package:github/src/common.dart'; /// /// API docs: https://github.com/blog/985-git-io-github-url-shortener class UrlShortenerService extends Service { - UrlShortenerService(GitHub github) : super(github); + UrlShortenerService(super.github); /// Shortens the provided [url]. An optional [code] can be provided to create /// your own vanity URL. diff --git a/lib/src/common/users_service.dart b/lib/src/common/users_service.dart index bb27ff6d..6485f4b0 100644 --- a/lib/src/common/users_service.dart +++ b/lib/src/common/users_service.dart @@ -8,7 +8,7 @@ import 'package:http/http.dart' as http; /// /// API docs: https://developer.github.com/v3/users/ class UsersService extends Service { - UsersService(GitHub github) : super(github); + UsersService(super.github); /// Fetches the user specified by [name]. /// diff --git a/lib/src/common/util/errors.dart b/lib/src/common/util/errors.dart index 81fa72b2..14625a6c 100644 --- a/lib/src/common/util/errors.dart +++ b/lib/src/common/util/errors.dart @@ -25,14 +25,13 @@ class NotReady extends GitHubError { /// GitHub Entity was not found class NotFound extends GitHubError { const NotFound( - GitHub github, - String msg, - ) : super(github, msg); + super.github, + String super.msg, + ); } class BadRequest extends GitHubError { - const BadRequest(GitHub github, [String? msg = 'Not Found']) - : super(github, msg); + const BadRequest(super.github, [super.msg = 'Not Found']); } /// GitHub Repository was not found @@ -94,11 +93,10 @@ class NotAuthenticated extends GitHubError { } class InvalidJSON extends BadRequest { - const InvalidJSON(GitHub github, [String? message = 'Invalid JSON']) - : super(github, message); + const InvalidJSON(super.github, [super.message = 'Invalid JSON']); } class ValidationFailed extends GitHubError { - const ValidationFailed(GitHub github, [String message = 'Validation Failed']) - : super(github, message); + const ValidationFailed(super.github, + [String super.message = 'Validation Failed']); } diff --git a/lib/src/common/util/utils.dart b/lib/src/common/util/utils.dart index 57bd6712..5c690774 100644 --- a/lib/src/common/util/utils.dart +++ b/lib/src/common/util/utils.dart @@ -21,7 +21,7 @@ abstract class EnumWithValue { /// True iff [other] is an [EnumWithValue] with the same value as this object. @override - bool operator ==(dynamic other) => + bool operator ==(Object other) => other is EnumWithValue && value == other.value; @override diff --git a/pubspec.yaml b/pubspec.yaml index af2ff765..308c3631 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,10 @@ name: github -version: 9.22.0 +version: 9.23.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart environment: - sdk: '>=2.18.0 <3.0.0' + sdk: ^3.0.0 dependencies: http: '>=0.13.0 <2.0.0' @@ -19,10 +19,10 @@ dev_dependencies: collection: ^1.15.0 dependency_validator: json_serializable: ^6.6.1 - lints: ^2.0.0 + lints: ^3.0.0 mockito: ^5.0.0 nock: ^1.0.0 pub_semver: ^2.0.0 test: ^1.16.0 yaml: ^3.0.0 - yaml_edit: + yaml_edit: ^2.2.0 diff --git a/test/helper/http.dart b/test/helper/http.dart index 2c5eaab4..ffed40d4 100644 --- a/test/helper/http.dart +++ b/test/helper/http.dart @@ -25,8 +25,8 @@ class MockHTTPClient extends http.BaseClient { } class MockResponse extends http.Response { - MockResponse(String body, Map headers, int statusCode) - : super(body, statusCode, headers: headers); + MockResponse(super.body, Map headers, super.statusCode) + : super(headers: headers); factory MockResponse.fromAsset(String name) { final responseData = diff --git a/test/server/hooks_test_data.dart b/test/server/hooks_test_data.dart index 4f5b734b..ad02cc10 100644 --- a/test/server/hooks_test_data.dart +++ b/test/server/hooks_test_data.dart @@ -1,4 +1,5 @@ /// Json messages as dart string used for checks model tests. +library; String checkSuiteString = checkSuiteTemplate('requested'); diff --git a/tool/process_github_schema.dart b/tool/process_github_schema.dart index e3850df5..14994289 100644 --- a/tool/process_github_schema.dart +++ b/tool/process_github_schema.dart @@ -20,7 +20,7 @@ List wordWrap(String body) { typedef GenTypeVisitor = void Function(GenType type); -abstract class GenType extends Comparable { +abstract class GenType implements Comparable { GenType(); String get name; From f5a565f5d8389eccbde05744266be288f980785e Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 26 Feb 2024 09:42:10 -0800 Subject: [PATCH 130/139] Fix Issue.isOpen and Issue.isClosed getters (#398) * Update issues.dart * require dart 3.0; update to the latest package:lints (#399) * require dart 3.0; update to the latest package:lints * update pubspec and changelog * update the pubspec version; add a changelog entry --- CHANGELOG.md | 4 ++++ lib/src/common/model/issues.dart | 4 ++-- pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea5c0870..3f1f7db8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 9.24.0 + +* Bug fixes to the `Issue.isOpen` and `Issue.isClosed` getters. + ## 9.23.0 * Require Dart 3.0. diff --git a/lib/src/common/model/issues.dart b/lib/src/common/model/issues.dart index 12b40172..028552dd 100644 --- a/lib/src/common/model/issues.dart +++ b/lib/src/common/model/issues.dart @@ -103,8 +103,8 @@ class Issue { /// The user who closed the issue User? closedBy; - bool get isOpen => state == 'open'; - bool get isClosed => state == 'closed'; + bool get isOpen => state == 'OPEN'; + bool get isClosed => state == 'CLOSED'; // The following properties were added to support the Timeline API. diff --git a/pubspec.yaml b/pubspec.yaml index 308c3631..ab43b9e9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.23.0 +version: 9.24.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart From 816939826734db6c2be208a82bb3d67f8b28cbaa Mon Sep 17 00:00:00 2001 From: Kate Lovett Date: Sat, 13 Apr 2024 09:37:21 -0500 Subject: [PATCH 131/139] Fix case sensitivity in Issue.[isOpen, isClosed] (#402) Fixes https://github.com/SpinlockLabs/github.dart/issues/401 --- lib/src/common/model/issues.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/common/model/issues.dart b/lib/src/common/model/issues.dart index 028552dd..3d531e63 100644 --- a/lib/src/common/model/issues.dart +++ b/lib/src/common/model/issues.dart @@ -103,8 +103,8 @@ class Issue { /// The user who closed the issue User? closedBy; - bool get isOpen => state == 'OPEN'; - bool get isClosed => state == 'CLOSED'; + bool get isOpen => state.toUpperCase() == 'OPEN'; + bool get isClosed => state.toUpperCase() == 'CLOSED'; // The following properties were added to support the Timeline API. From d8af9b205c58bc3f1206fd7973bf762921be0e6d Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 14 Apr 2025 17:02:20 -0500 Subject: [PATCH 132/139] Update some dependencies, bump min SDK (#415) --- .github/workflows/dart.yml | 2 +- CHANGELOG.md | 5 +++++ analysis_options.yaml | 1 - pubspec.yaml | 26 +++++++++++++------------- test/scenarios_test.dart | 1 + 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 2d725e23..1dcc0100 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -13,7 +13,7 @@ jobs: matrix: os: [ubuntu-latest] # Test with at least the declared minimum Dart version - sdk: ['3.0', stable] + sdk: ['3.1', stable] steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f1f7db8..7939058a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.25.0-wip + +* Require Dart 3.1 +* Require `package:http` `^1.0.0`. + ## 9.24.0 * Bug fixes to the `Issue.isOpen` and `Issue.isClosed` getters. diff --git a/analysis_options.yaml b/analysis_options.yaml index 1af8628e..f2974469 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -31,7 +31,6 @@ linter: - omit_local_variable_types - one_member_abstracts - only_throw_errors - - package_api_docs - prefer_asserts_in_initializer_lists - prefer_const_constructors - prefer_const_constructors_in_immutables diff --git a/pubspec.yaml b/pubspec.yaml index ab43b9e9..e86ed709 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,28 +1,28 @@ name: github -version: 9.24.0 +version: 9.25.0-wip description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart environment: - sdk: ^3.0.0 + sdk: ^3.1.0 dependencies: - http: '>=0.13.0 <2.0.0' + http: ^1.0.0 http_parser: ^4.0.0 json_annotation: ^4.8.0 - meta: ^1.3.0 + meta: ^1.7.0 dev_dependencies: - build_runner: any - build_test: any - build_web_compilers: any + build_runner: ^2.2.1 + build_test: ^2.1.2 + build_web_compilers: ^3.2.6 collection: ^1.15.0 - dependency_validator: + dependency_validator: ^3.0.0 json_serializable: ^6.6.1 - lints: ^3.0.0 - mockito: ^5.0.0 - nock: ^1.0.0 + lints: ^4.0.0 + mockito: ^5.3.2 + nock: ^1.1.3 pub_semver: ^2.0.0 - test: ^1.16.0 - yaml: ^3.0.0 + test: ^1.21.6 + yaml: ^3.1.0 yaml_edit: ^2.2.0 diff --git a/test/scenarios_test.dart b/test/scenarios_test.dart index 70f1a789..fb453845 100644 --- a/test/scenarios_test.dart +++ b/test/scenarios_test.dart @@ -2,6 +2,7 @@ @Tags(['scenarios']) @TestOn('vm') +library; import 'dart:convert'; From edc3f5ae9210e882e692a8cb1e3a0f989eb9aaad Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Mon, 14 Apr 2025 16:19:40 -0600 Subject: [PATCH 133/139] Update json_annotation min and build_web_compilers range --- pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index e86ed709..9b29ea72 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,13 +9,13 @@ environment: dependencies: http: ^1.0.0 http_parser: ^4.0.0 - json_annotation: ^4.8.0 + json_annotation: ^4.9.0 meta: ^1.7.0 dev_dependencies: build_runner: ^2.2.1 build_test: ^2.1.2 - build_web_compilers: ^3.2.6 + build_web_compilers: '>=3.2.6 < 5.0.0' collection: ^1.15.0 dependency_validator: ^3.0.0 json_serializable: ^6.6.1 From 4926022d04082ea72bb74582b31c3b80bd3165d9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 14 Apr 2025 17:21:03 -0500 Subject: [PATCH 134/139] Rebuild JSON bits (#416) Co-authored-by: Rob Becker --- lib/src/common/model/authorizations.g.dart | 2 +- lib/src/common/model/gists.g.dart | 14 +++--- lib/src/common/model/git.g.dart | 6 +-- lib/src/common/model/issues.g.dart | 18 +++---- lib/src/common/model/keys.g.dart | 2 +- lib/src/common/model/misc.g.dart | 4 +- lib/src/common/model/orgs.g.dart | 18 +++---- lib/src/common/model/pulls.g.dart | 52 ++++++++++---------- lib/src/common/model/reaction.g.dart | 20 ++++---- lib/src/common/model/repos.g.dart | 36 +++++++------- lib/src/common/model/repos_commits.g.dart | 18 +++---- lib/src/common/model/repos_contents.g.dart | 2 +- lib/src/common/model/repos_hooks.g.dart | 2 +- lib/src/common/model/repos_pages.g.dart | 4 +- lib/src/common/model/repos_releases.g.dart | 8 +-- lib/src/common/model/repos_stats.g.dart | 38 ++++++++------ lib/src/common/model/repos_statuses.g.dart | 2 +- lib/src/common/model/search.g.dart | 2 +- lib/src/common/model/timeline.g.dart | 32 ++++++------ lib/src/common/model/timeline_support.g.dart | 28 +++++------ lib/src/common/model/users.g.dart | 38 +++++++------- lib/src/server/hooks.g.dart | 2 +- 22 files changed, 177 insertions(+), 171 deletions(-) diff --git a/lib/src/common/model/authorizations.g.dart b/lib/src/common/model/authorizations.g.dart index 7c3a2e73..918a8a47 100644 --- a/lib/src/common/model/authorizations.g.dart +++ b/lib/src/common/model/authorizations.g.dart @@ -8,7 +8,7 @@ part of 'authorizations.dart'; Authorization _$AuthorizationFromJson(Map json) => Authorization( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), scopes: (json['scopes'] as List?)?.map((e) => e as String).toList(), token: json['token'] as String?, diff --git a/lib/src/common/model/gists.g.dart b/lib/src/common/model/gists.g.dart index e1d6db23..3438e5ea 100644 --- a/lib/src/common/model/gists.g.dart +++ b/lib/src/common/model/gists.g.dart @@ -20,7 +20,7 @@ Gist _$GistFromJson(Map json) => Gist( (k, e) => MapEntry(k, GistFile.fromJson(e as Map)), ), htmlUrl: json['html_url'] as String?, - commentsCount: json['comments'] as int?, + commentsCount: (json['comments'] as num?)?.toInt(), gitPullUrl: json['git_pull_url'] as String?, gitPushUrl: json['git_push_url'] as String?, createdAt: json['created_at'] == null @@ -48,7 +48,7 @@ Map _$GistToJson(Gist instance) => { GistFile _$GistFileFromJson(Map json) => GistFile( filename: json['filename'] as String?, - size: json['size'] as int?, + size: (json['size'] as num?)?.toInt(), rawUrl: json['raw_url'] as String?, type: json['type'] as String?, language: json['language'] as String?, @@ -70,7 +70,7 @@ GistFork _$GistForkFromJson(Map json) => GistFork( user: json['user'] == null ? null : User.fromJson(json['user'] as Map), - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), createdAt: json['created_at'] == null ? null : DateTime.parse(json['created_at'] as String), @@ -92,9 +92,9 @@ GistHistoryEntry _$GistHistoryEntryFromJson(Map json) => user: json['user'] == null ? null : User.fromJson(json['user'] as Map), - deletions: json['change_status/deletions'] as int?, - additions: json['change_status/additions'] as int?, - totalChanges: json['change_status/total'] as int?, + deletions: (json['change_status/deletions'] as num?)?.toInt(), + additions: (json['change_status/additions'] as num?)?.toInt(), + totalChanges: (json['change_status/total'] as num?)?.toInt(), committedAt: json['committed_at'] == null ? null : DateTime.parse(json['committed_at'] as String), @@ -111,7 +111,7 @@ Map _$GistHistoryEntryToJson(GistHistoryEntry instance) => }; GistComment _$GistCommentFromJson(Map json) => GistComment( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), user: json['user'] == null ? null : User.fromJson(json['user'] as Map), diff --git a/lib/src/common/model/git.g.dart b/lib/src/common/model/git.g.dart index 61d5fc44..e041aeb3 100644 --- a/lib/src/common/model/git.g.dart +++ b/lib/src/common/model/git.g.dart @@ -11,7 +11,7 @@ GitBlob _$GitBlobFromJson(Map json) => GitBlob( encoding: json['encoding'] as String?, url: json['url'] as String?, sha: json['sha'] as String?, - size: json['size'] as int?, + size: (json['size'] as num?)?.toInt(), ); Map _$GitBlobToJson(GitBlob instance) => { @@ -50,7 +50,7 @@ GitCommit _$GitCommitFromJson(Map json) => GitCommit( parents: (json['parents'] as List?) ?.map((e) => GitCommit.fromJson(e as Map)) .toList(), - commentCount: json['comment_count'] as int?, + commentCount: (json['comment_count'] as num?)?.toInt(), ); Map _$GitCommitToJson(GitCommit instance) => { @@ -130,7 +130,7 @@ GitTreeEntry _$GitTreeEntryFromJson(Map json) => GitTreeEntry( json['path'] as String?, json['mode'] as String?, json['type'] as String?, - json['size'] as int?, + (json['size'] as num?)?.toInt(), json['sha'] as String?, json['url'] as String?, ); diff --git a/lib/src/common/model/issues.g.dart b/lib/src/common/model/issues.g.dart index 40bbfa94..e4a80082 100644 --- a/lib/src/common/model/issues.g.dart +++ b/lib/src/common/model/issues.g.dart @@ -7,10 +7,10 @@ part of 'issues.dart'; // ************************************************************************** Issue _$IssueFromJson(Map json) => Issue( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, url: json['url'] as String? ?? '', htmlUrl: json['html_url'] as String? ?? '', - number: json['number'] as int? ?? 0, + number: (json['number'] as num?)?.toInt() ?? 0, state: json['state'] as String? ?? '', title: json['title'] as String? ?? '', user: json['user'] == null @@ -29,7 +29,7 @@ Issue _$IssueFromJson(Map json) => Issue( milestone: json['milestone'] == null ? null : Milestone.fromJson(json['milestone'] as Map), - commentsCount: json['comments'] as int? ?? 0, + commentsCount: (json['comments'] as num?)?.toInt() ?? 0, pullRequest: json['pull_request'] == null ? null : IssuePullRequest.fromJson( @@ -119,7 +119,7 @@ IssueRequest _$IssueRequestFromJson(Map json) => IssueRequest( ?.map((e) => e as String) .toList(), state: json['state'] as String?, - milestone: json['milestone'] as int?, + milestone: (json['milestone'] as num?)?.toInt(), ); Map _$IssueRequestToJson(IssueRequest instance) => @@ -148,7 +148,7 @@ Map _$IssuePullRequestToJson(IssuePullRequest instance) => }; IssueComment _$IssueCommentFromJson(Map json) => IssueComment( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), body: json['body'] as String?, user: json['user'] == null ? null @@ -192,16 +192,16 @@ Map _$IssueLabelToJson(IssueLabel instance) => }; Milestone _$MilestoneFromJson(Map json) => Milestone( - id: json['id'] as int?, - number: json['number'] as int?, + id: (json['id'] as num?)?.toInt(), + number: (json['number'] as num?)?.toInt(), state: json['state'] as String?, title: json['title'] as String?, description: json['description'] as String?, creator: json['creator'] == null ? null : User.fromJson(json['creator'] as Map), - openIssuesCount: json['open_issues'] as int?, - closedIssuesCount: json['closed_issues'] as int?, + openIssuesCount: (json['open_issues'] as num?)?.toInt(), + closedIssuesCount: (json['closed_issues'] as num?)?.toInt(), createdAt: json['created_at'] == null ? null : DateTime.parse(json['created_at'] as String), diff --git a/lib/src/common/model/keys.g.dart b/lib/src/common/model/keys.g.dart index 1db24c87..7cecbcf2 100644 --- a/lib/src/common/model/keys.g.dart +++ b/lib/src/common/model/keys.g.dart @@ -7,7 +7,7 @@ part of 'keys.dart'; // ************************************************************************** PublicKey _$PublicKeyFromJson(Map json) => PublicKey( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), key: json['key'] as String?, title: json['title'] as String?, ); diff --git a/lib/src/common/model/misc.g.dart b/lib/src/common/model/misc.g.dart index d7b3896c..4ad9a310 100644 --- a/lib/src/common/model/misc.g.dart +++ b/lib/src/common/model/misc.g.dart @@ -19,8 +19,8 @@ Map _$GitignoreTemplateToJson(GitignoreTemplate instance) => }; RateLimit _$RateLimitFromJson(Map json) => RateLimit( - json['limit'] as int?, - json['remaining'] as int?, + (json['limit'] as num?)?.toInt(), + (json['remaining'] as num?)?.toInt(), json['resets'] == null ? null : DateTime.parse(json['resets'] as String), ); diff --git a/lib/src/common/model/orgs.g.dart b/lib/src/common/model/orgs.g.dart index c32f6702..dc9dc349 100644 --- a/lib/src/common/model/orgs.g.dart +++ b/lib/src/common/model/orgs.g.dart @@ -8,7 +8,7 @@ part of 'orgs.dart'; Organization _$OrganizationFromJson(Map json) => Organization( login: json['login'] as String?, - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), htmlUrl: json['html_url'] as String?, avatarUrl: json['avatar_url'] as String?, name: json['name'] as String?, @@ -16,10 +16,10 @@ Organization _$OrganizationFromJson(Map json) => Organization( blog: json['blog'] as String?, location: json['location'] as String?, email: json['email'] as String?, - publicReposCount: json['public_repos'] as int?, - publicGistsCount: json['public_gists'] as int?, - followersCount: json['followers'] as int?, - followingCount: json['following'] as int?, + publicReposCount: (json['public_repos'] as num?)?.toInt(), + publicGistsCount: (json['public_gists'] as num?)?.toInt(), + followersCount: (json['followers'] as num?)?.toInt(), + followingCount: (json['following'] as num?)?.toInt(), createdAt: json['created_at'] == null ? null : DateTime.parse(json['created_at'] as String), @@ -66,9 +66,9 @@ Map _$OrganizationMembershipToJson( Team _$TeamFromJson(Map json) => Team( description: json['description'] as String?, htmlUrl: json['html_url'] as String?, - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), ldapDn: json['ldap_dn'] as String?, - membersCount: json['members_count'] as int?, + membersCount: (json['members_count'] as num?)?.toInt(), membersUrl: json['members_url'] as String?, name: json['name'] as String?, nodeId: json['node_id'] as String?, @@ -83,7 +83,7 @@ Team _$TeamFromJson(Map json) => Team( ? null : Permissions.fromJson(json['permissions'] as Map), privacy: json['privacy'] as String?, - reposCount: json['repos_count'] as int?, + reposCount: (json['repos_count'] as num?)?.toInt(), repositoriesUrl: json['repositories_url'] as String?, slug: json['slug'] as String?, url: json['url'] as String?, @@ -128,7 +128,7 @@ Map _$PermissionsToJson(Permissions instance) => TeamMember _$TeamMemberFromJson(Map json) => TeamMember( login: json['login'] as String?, - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), avatarUrl: json['avatar_url'] as String?, type: json['type'] as String?, siteAdmin: json['site_admin'] as bool?, diff --git a/lib/src/common/model/pulls.g.dart b/lib/src/common/model/pulls.g.dart index cf370e22..e7dea0cb 100644 --- a/lib/src/common/model/pulls.g.dart +++ b/lib/src/common/model/pulls.g.dart @@ -7,12 +7,12 @@ part of 'pulls.dart'; // ************************************************************************** PullRequest _$PullRequestFromJson(Map json) => PullRequest( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), nodeId: json['node_id'] as String?, htmlUrl: json['html_url'] as String?, diffUrl: json['diff_url'] as String?, patchUrl: json['patch_url'] as String?, - number: json['number'] as int?, + number: (json['number'] as num?)?.toInt(), state: json['state'] as String?, title: json['title'] as String?, body: json['body'] as String?, @@ -44,18 +44,18 @@ PullRequest _$PullRequestFromJson(Map json) => PullRequest( mergedBy: json['merged_by'] == null ? null : User.fromJson(json['merged_by'] as Map), - commentsCount: json['comments'] as int? ?? 0, - commitsCount: json['commits'] as int? ?? 0, - additionsCount: json['additions'] as int? ?? 0, - deletionsCount: json['deletions'] as int? ?? 0, - changedFilesCount: json['changed_files'] as int? ?? 0, + commentsCount: (json['comments'] as num?)?.toInt() ?? 0, + commitsCount: (json['commits'] as num?)?.toInt() ?? 0, + additionsCount: (json['additions'] as num?)?.toInt() ?? 0, + deletionsCount: (json['deletions'] as num?)?.toInt() ?? 0, + changedFilesCount: (json['changed_files'] as num?)?.toInt() ?? 0, labels: (json['labels'] as List?) ?.map((e) => IssueLabel.fromJson(e as Map)) .toList(), requestedReviewers: (json['requested_reviewers'] as List?) ?.map((e) => User.fromJson(e as Map)) .toList(), - reviewCommentCount: json['review_comments'] as int? ?? 0, + reviewCommentCount: (json['review_comments'] as num?)?.toInt() ?? 0, milestone: json['milestone'] == null ? null : Milestone.fromJson(json['milestone'] as Map), @@ -162,11 +162,11 @@ Map _$CreatePullRequestToJson(CreatePullRequest instance) => PullRequestComment _$PullRequestCommentFromJson(Map json) => PullRequestComment( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), diffHunk: json['diff_hunk'] as String?, path: json['path'] as String?, - position: json['position'] as int?, - originalPosition: json['original_position'] as int?, + position: (json['position'] as num?)?.toInt(), + originalPosition: (json['original_position'] as num?)?.toInt(), commitId: json['commit_id'] as String?, originalCommitId: json['original_commit_id'] as String?, user: json['user'] == null @@ -210,7 +210,7 @@ CreatePullRequestComment _$CreatePullRequestCommentFromJson( json['body'] as String?, json['commit_id'] as String?, json['path'] as String?, - json['position'] as int?, + (json['position'] as num?)?.toInt(), ); Map _$CreatePullRequestCommentToJson( @@ -227,9 +227,9 @@ PullRequestFile _$PullRequestFileFromJson(Map json) => sha: json['sha'] as String?, filename: json['filename'] as String?, status: json['status'] as String?, - additionsCount: json['additions'] as int?, - deletionsCount: json['deletions'] as int?, - changesCount: json['changes'] as int?, + additionsCount: (json['additions'] as num?)?.toInt(), + deletionsCount: (json['deletions'] as num?)?.toInt(), + changesCount: (json['changes'] as num?)?.toInt(), blobUrl: json['blob_url'] as String?, rawUrl: json['raw_url'] as String?, contentsUrl: json['contents_url'] as String?, @@ -252,7 +252,7 @@ Map _$PullRequestFileToJson(PullRequestFile instance) => PullRequestReview _$PullRequestReviewFromJson(Map json) => PullRequestReview( - id: json['id'] as int, + id: (json['id'] as num).toInt(), user: json['user'] == null ? null : User.fromJson(json['user'] as Map), @@ -285,7 +285,7 @@ CreatePullRequestReview _$CreatePullRequestReviewFromJson( CreatePullRequestReview( json['owner'] as String, json['repo'] as String, - json['pull_number'] as int, + (json['pull_number'] as num).toInt(), json['event'] as String, body: json['body'] as String?, comments: (json['comments'] as List?) @@ -318,26 +318,26 @@ PullRequestReviewComment _$PullRequestReviewCommentFromJson( : DateTime.parse(json['created_at'] as String), diffHunk: json['diff_hunk'] as String?, htmlUrl: json['html_url'] as String?, - id: json['id'] as int?, - inReplyToId: json['in_reply_to_id'] as int?, - line: json['line'] as int?, + id: (json['id'] as num?)?.toInt(), + inReplyToId: (json['in_reply_to_id'] as num?)?.toInt(), + line: (json['line'] as num?)?.toInt(), links: json['_links'] == null ? null : ReviewLinks.fromJson(json['_links'] as Map), nodeId: json['node_id'] as String?, originalCommitId: json['original_commit_id'] as String?, - originalLine: json['original_line'] as int?, - originalPosition: json['original_position'] as int?, - originalStartLine: json['original_start_line'] as int?, + originalLine: (json['original_line'] as num?)?.toInt(), + originalPosition: (json['original_position'] as num?)?.toInt(), + originalStartLine: (json['original_start_line'] as num?)?.toInt(), path: json['path'] as String?, - position: json['position'] as int?, - pullRequestReviewId: json['pull_request_review_id'] as int?, + position: (json['position'] as num?)?.toInt(), + pullRequestReviewId: (json['pull_request_review_id'] as num?)?.toInt(), pullRequestUrl: json['pull_request_url'] as String?, reactions: json['reactions'] == null ? null : ReactionRollup.fromJson(json['reactions'] as Map), side: json['side'] as String?, - startLine: json['start_line'] as int?, + startLine: (json['start_line'] as num?)?.toInt(), startSide: json['start_side'] as String?, subjectType: json['subject_type'] as String?, updatedAt: json['updated_at'] == null diff --git a/lib/src/common/model/reaction.g.dart b/lib/src/common/model/reaction.g.dart index d94eede4..4647e160 100644 --- a/lib/src/common/model/reaction.g.dart +++ b/lib/src/common/model/reaction.g.dart @@ -7,7 +7,7 @@ part of 'reaction.dart'; // ************************************************************************** Reaction _$ReactionFromJson(Map json) => Reaction( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), nodeId: json['node_id'] as String?, user: json['user'] == null ? null @@ -28,15 +28,15 @@ Map _$ReactionToJson(Reaction instance) => { ReactionRollup _$ReactionRollupFromJson(Map json) => ReactionRollup( - plusOne: json['+1'] as int?, - minusOne: json['-1'] as int?, - confused: json['confused'] as int?, - eyes: json['eyes'] as int?, - heart: json['heart'] as int?, - hooray: json['hooray'] as int?, - laugh: json['laugh'] as int?, - rocket: json['rocket'] as int?, - totalCount: json['total_count'] as int?, + plusOne: (json['+1'] as num?)?.toInt(), + minusOne: (json['-1'] as num?)?.toInt(), + confused: (json['confused'] as num?)?.toInt(), + eyes: (json['eyes'] as num?)?.toInt(), + heart: (json['heart'] as num?)?.toInt(), + hooray: (json['hooray'] as num?)?.toInt(), + laugh: (json['laugh'] as num?)?.toInt(), + rocket: (json['rocket'] as num?)?.toInt(), + totalCount: (json['total_count'] as num?)?.toInt(), url: json['url'] as String?, ); diff --git a/lib/src/common/model/repos.g.dart b/lib/src/common/model/repos.g.dart index 490b18b1..fe19ea97 100644 --- a/lib/src/common/model/repos.g.dart +++ b/lib/src/common/model/repos.g.dart @@ -10,9 +10,9 @@ GitHubComparison _$GitHubComparisonFromJson(Map json) => GitHubComparison( json['url'] as String?, json['status'] as String?, - json['ahead_by'] as int?, - json['behind_by'] as int?, - json['total_commits'] as int?, + (json['ahead_by'] as num?)?.toInt(), + (json['behind_by'] as num?)?.toInt(), + (json['total_commits'] as num?)?.toInt(), (json['files'] as List?) ?.map((e) => CommitFile.fromJson(e as Map)) .toList(), @@ -34,7 +34,7 @@ Map _$GitHubComparisonToJson(GitHubComparison instance) => Repository _$RepositoryFromJson(Map json) => Repository( name: json['name'] as String? ?? '', - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, fullName: json['full_name'] as String? ?? '', owner: json['owner'] == null ? null @@ -51,17 +51,17 @@ Repository _$RepositoryFromJson(Map json) => Repository( : DateTime.parse(json['created_at'] as String), isPrivate: json['private'] as bool? ?? false, isFork: json['fork'] as bool? ?? false, - stargazersCount: json['stargazers_count'] as int? ?? 0, - watchersCount: json['watchers_count'] as int? ?? 0, + stargazersCount: (json['stargazers_count'] as num?)?.toInt() ?? 0, + watchersCount: (json['watchers_count'] as num?)?.toInt() ?? 0, language: json['language'] as String? ?? '', hasWiki: json['has_wiki'] as bool? ?? false, hasDownloads: json['has_downloads'] as bool? ?? false, - forksCount: json['forks_count'] as int? ?? 0, - openIssuesCount: json['open_issues_count'] as int? ?? 0, - subscribersCount: json['subscribers_count'] as int? ?? 0, - networkCount: json['network_count'] as int? ?? 0, + forksCount: (json['forks_count'] as num?)?.toInt() ?? 0, + openIssuesCount: (json['open_issues_count'] as num?)?.toInt() ?? 0, + subscribersCount: (json['subscribers_count'] as num?)?.toInt() ?? 0, + networkCount: (json['network_count'] as num?)?.toInt() ?? 0, hasIssues: json['has_issues'] as bool? ?? false, - size: json['size'] as int? ?? 0, + size: (json['size'] as num?)?.toInt() ?? 0, archived: json['archived'] as bool? ?? false, disabled: json['disabled'] as bool? ?? false, homepage: json['homepage'] as String? ?? '', @@ -100,7 +100,7 @@ Repository _$RepositoryFromJson(Map json) => Repository( deploymentsUrl: json['deployments_url'] as String?, downloadsUrl: json['downloads_url'] as String?, eventsUrl: json['events_url'] as String?, - forks: json['forks'] as int?, + forks: (json['forks'] as num?)?.toInt(), forksUrl: json['forks_url'] as String?, gitCommitsUrl: json['git_commits_url'] as String?, gitRefsUrl: json['git_refs_url'] as String?, @@ -123,7 +123,7 @@ Repository _$RepositoryFromJson(Map json) => Repository( mirrorUrl: json['mirror_url'] as String?, nodeId: json['node_id'] as String?, notificationsUrl: json['notifications_url'] as String?, - openIssues: json['open_issues'] as int?, + openIssues: (json['open_issues'] as num?)?.toInt(), organization: json['organization'] == null ? null : User.fromJson(json['organization'] as Map), @@ -150,7 +150,7 @@ Repository _$RepositoryFromJson(Map json) => Repository( treesUrl: json['trees_url'] as String?, url: json['url'] as String?, visibility: json['visibility'] as String?, - watchers: json['watchers'] as int?, + watchers: (json['watchers'] as num?)?.toInt(), webCommitSignoffRequired: json['web_commit_signoff_required'] as bool?, ); @@ -320,7 +320,7 @@ Map _$CommitDataToJson(CommitData instance) => CommitDataUser _$CommitDataUserFromJson(Map json) => CommitDataUser( json['login'] as String?, - json['id'] as int?, + (json['id'] as num?)?.toInt(), json['type'] as String?, ); @@ -347,7 +347,7 @@ Map _$CommitInfoToJson(CommitInfo instance) => UserInformation _$UserInformationFromJson(Map json) => UserInformation( json['login'] as String, - json['id'] as int, + (json['id'] as num).toInt(), json['avatar_url'] as String, json['html_url'] as String, ); @@ -380,7 +380,7 @@ CreateRepository _$CreateRepositoryFromJson(Map json) => private: json['private'] as bool?, hasIssues: json['has_issues'] as bool?, hasDownloads: json['has_downloads'] as bool?, - teamId: json['team_id'] as int?, + teamId: (json['team_id'] as num?)?.toInt(), autoInit: json['auto_init'] as bool?, gitignoreTemplate: json['gitignore_template'] as String?, licenseTemplate: json['license_template'] as String?, @@ -419,7 +419,7 @@ LicenseDetails _$LicenseDetailsFromJson(Map json) => name: json['name'] as String?, path: json['path'] as String?, sha: json['sha'] as String?, - size: json['size'] as int?, + size: (json['size'] as num?)?.toInt(), url: json['url'] == null ? null : Uri.parse(json['url'] as String), htmlUrl: json['html_url'] == null ? null diff --git a/lib/src/common/model/repos_commits.g.dart b/lib/src/common/model/repos_commits.g.dart index 5e74c999..a4b3a5fe 100644 --- a/lib/src/common/model/repos_commits.g.dart +++ b/lib/src/common/model/repos_commits.g.dart @@ -47,9 +47,9 @@ Map _$RepositoryCommitToJson(RepositoryCommit instance) => }; CommitStats _$CommitStatsFromJson(Map json) => CommitStats( - additions: json['additions'] as int?, - deletions: json['deletions'] as int?, - total: json['total'] as int?, + additions: (json['additions'] as num?)?.toInt(), + deletions: (json['deletions'] as num?)?.toInt(), + total: (json['total'] as num?)?.toInt(), ); Map _$CommitStatsToJson(CommitStats instance) => @@ -61,9 +61,9 @@ Map _$CommitStatsToJson(CommitStats instance) => CommitFile _$CommitFileFromJson(Map json) => CommitFile( name: json['filename'] as String?, - additions: json['additions'] as int?, - deletions: json['deletions'] as int?, - changes: json['changes'] as int?, + additions: (json['additions'] as num?)?.toInt(), + deletions: (json['deletions'] as num?)?.toInt(), + changes: (json['changes'] as num?)?.toInt(), status: json['status'] as String?, rawUrl: json['raw_url'] as String?, blobUrl: json['blob_url'] as String?, @@ -84,9 +84,9 @@ Map _$CommitFileToJson(CommitFile instance) => CommitComment _$CommitCommentFromJson(Map json) => CommitComment( - id: json['id'] as int?, - line: json['line'] as int?, - position: json['position'] as int?, + id: (json['id'] as num?)?.toInt(), + line: (json['line'] as num?)?.toInt(), + position: (json['position'] as num?)?.toInt(), path: json['path'] as String?, apiUrl: json['url'] as String?, commitId: json['commit_id'] as String?, diff --git a/lib/src/common/model/repos_contents.g.dart b/lib/src/common/model/repos_contents.g.dart index 96f92749..84dc677b 100644 --- a/lib/src/common/model/repos_contents.g.dart +++ b/lib/src/common/model/repos_contents.g.dart @@ -9,7 +9,7 @@ part of 'repos_contents.dart'; GitHubFile _$GitHubFileFromJson(Map json) => GitHubFile( type: json['type'] as String?, encoding: json['encoding'] as String?, - size: json['size'] as int?, + size: (json['size'] as num?)?.toInt(), name: json['name'] as String?, path: json['path'] as String?, content: json['content'] as String?, diff --git a/lib/src/common/model/repos_hooks.g.dart b/lib/src/common/model/repos_hooks.g.dart index c199f2ea..fa57fa4f 100644 --- a/lib/src/common/model/repos_hooks.g.dart +++ b/lib/src/common/model/repos_hooks.g.dart @@ -7,7 +7,7 @@ part of 'repos_hooks.dart'; // ************************************************************************** Hook _$HookFromJson(Map json) => Hook( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), name: json['name'] as String?, ) ..events = diff --git a/lib/src/common/model/repos_pages.g.dart b/lib/src/common/model/repos_pages.g.dart index a550ad75..ead9a68f 100644 --- a/lib/src/common/model/repos_pages.g.dart +++ b/lib/src/common/model/repos_pages.g.dart @@ -30,7 +30,7 @@ PageBuild _$PageBuildFromJson(Map json) => PageBuild( ? null : PageBuildPusher.fromJson(json['pusher'] as Map), commit: json['commit'] as String?, - duration: json['duration'] as int?, + duration: (json['duration'] as num?)?.toInt(), createdAt: json['created_at'] == null ? null : DateTime.parse(json['created_at'] as String), @@ -53,7 +53,7 @@ Map _$PageBuildToJson(PageBuild instance) => { PageBuildPusher _$PageBuildPusherFromJson(Map json) => PageBuildPusher( login: json['login'] as String?, - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), apiUrl: json['url'] as String?, htmlUrl: json['html_url'] as String?, type: json['type'] as String?, diff --git a/lib/src/common/model/repos_releases.g.dart b/lib/src/common/model/repos_releases.g.dart index 2e0998e7..e0596897 100644 --- a/lib/src/common/model/repos_releases.g.dart +++ b/lib/src/common/model/repos_releases.g.dart @@ -7,7 +7,7 @@ part of 'repos_releases.dart'; // ************************************************************************** Release _$ReleaseFromJson(Map json) => Release( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), url: json['url'] as String?, htmlUrl: json['html_url'] as String?, tarballUrl: json['tarball_url'] as String?, @@ -61,13 +61,13 @@ Map _$ReleaseToJson(Release instance) => { }; ReleaseAsset _$ReleaseAssetFromJson(Map json) => ReleaseAsset( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), name: json['name'] as String?, label: json['label'] as String?, state: json['state'] as String?, contentType: json['content_type'] as String?, - size: json['size'] as int?, - downloadCount: json['download_count'] as int?, + size: (json['size'] as num?)?.toInt(), + downloadCount: (json['download_count'] as num?)?.toInt(), browserDownloadUrl: json['browser_download_url'] as String?, createdAt: json['created_at'] == null ? null diff --git a/lib/src/common/model/repos_stats.g.dart b/lib/src/common/model/repos_stats.g.dart index 12a609a5..83bd1650 100644 --- a/lib/src/common/model/repos_stats.g.dart +++ b/lib/src/common/model/repos_stats.g.dart @@ -12,7 +12,7 @@ ContributorStatistics _$ContributorStatisticsFromJson( json['author'] == null ? null : User.fromJson(json['author'] as Map), - json['total'] as int?, + (json['total'] as num?)?.toInt(), (json['weeks'] as List?) ?.map((e) => ContributorWeekStatistics.fromJson(e as Map)) @@ -30,10 +30,10 @@ Map _$ContributorStatisticsToJson( ContributorWeekStatistics _$ContributorWeekStatisticsFromJson( Map json) => ContributorWeekStatistics( - json['w'] as int?, - json['a'] as int?, - json['d'] as int?, - json['c'] as int?, + (json['w'] as num?)?.toInt(), + (json['a'] as num?)?.toInt(), + (json['d'] as num?)?.toInt(), + (json['c'] as num?)?.toInt(), ); Map _$ContributorWeekStatisticsToJson( @@ -48,8 +48,12 @@ Map _$ContributorWeekStatisticsToJson( ContributorParticipation _$ContributorParticipationFromJson( Map json) => ContributorParticipation( - all: (json['all'] as List?)?.map((e) => e as int).toList(), - owner: (json['owner'] as List?)?.map((e) => e as int).toList(), + all: (json['all'] as List?) + ?.map((e) => (e as num).toInt()) + .toList(), + owner: (json['owner'] as List?) + ?.map((e) => (e as num).toInt()) + .toList(), ); Map _$ContributorParticipationToJson( @@ -61,9 +65,11 @@ Map _$ContributorParticipationToJson( YearCommitCountWeek _$YearCommitCountWeekFromJson(Map json) => YearCommitCountWeek( - days: (json['days'] as List?)?.map((e) => e as int).toList(), - total: json['total'] as int?, - timestamp: json['timestamp'] as int?, + days: (json['days'] as List?) + ?.map((e) => (e as num).toInt()) + .toList(), + total: (json['total'] as num?)?.toInt(), + timestamp: (json['timestamp'] as num?)?.toInt(), ); Map _$YearCommitCountWeekToJson( @@ -76,9 +82,9 @@ Map _$YearCommitCountWeekToJson( WeeklyChangesCount _$WeeklyChangesCountFromJson(Map json) => WeeklyChangesCount( - timestamp: json['timestamp'] as int?, - additions: json['additions'] as int?, - deletions: json['deletions'] as int?, + timestamp: (json['timestamp'] as num?)?.toInt(), + additions: (json['additions'] as num?)?.toInt(), + deletions: (json['deletions'] as num?)?.toInt(), ); Map _$WeeklyChangesCountToJson(WeeklyChangesCount instance) => @@ -90,9 +96,9 @@ Map _$WeeklyChangesCountToJson(WeeklyChangesCount instance) => PunchcardEntry _$PunchcardEntryFromJson(Map json) => PunchcardEntry( - weekday: json['weekday'] as int?, - hour: json['hour'] as int?, - commits: json['commits'] as int?, + weekday: (json['weekday'] as num?)?.toInt(), + hour: (json['hour'] as num?)?.toInt(), + commits: (json['commits'] as num?)?.toInt(), ); Map _$PunchcardEntryToJson(PunchcardEntry instance) => diff --git a/lib/src/common/model/repos_statuses.g.dart b/lib/src/common/model/repos_statuses.g.dart index 6cb7c947..86b7b8e3 100644 --- a/lib/src/common/model/repos_statuses.g.dart +++ b/lib/src/common/model/repos_statuses.g.dart @@ -11,7 +11,7 @@ CombinedRepositoryStatus _$CombinedRepositoryStatusFromJson( CombinedRepositoryStatus( state: json['state'] as String?, sha: json['sha'] as String?, - totalCount: json['total_count'] as int?, + totalCount: (json['total_count'] as num?)?.toInt(), statuses: (json['statuses'] as List?) ?.map((e) => RepositoryStatus.fromJson(e as Map)) .toList(), diff --git a/lib/src/common/model/search.g.dart b/lib/src/common/model/search.g.dart index d24fa9cb..9d606865 100644 --- a/lib/src/common/model/search.g.dart +++ b/lib/src/common/model/search.g.dart @@ -8,7 +8,7 @@ part of 'search.dart'; CodeSearchResults _$CodeSearchResultsFromJson(Map json) => CodeSearchResults() - ..totalCount = json['total_count'] as int? + ..totalCount = (json['total_count'] as num?)?.toInt() ..incompleteResults = json['incomplete_results'] as bool? ..items = CodeSearchItem.fromJsonList(json['items'] as List); diff --git a/lib/src/common/model/timeline.g.dart b/lib/src/common/model/timeline.g.dart index 9d0bfc5a..be7d916d 100644 --- a/lib/src/common/model/timeline.g.dart +++ b/lib/src/common/model/timeline.g.dart @@ -8,7 +8,7 @@ part of 'timeline.dart'; TimelineEvent _$TimelineEventFromJson(Map json) => TimelineEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -40,7 +40,7 @@ Map _$TimelineEventToJson(TimelineEvent instance) => }; LabelEvent _$LabelEventFromJson(Map json) => LabelEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -77,7 +77,7 @@ Map _$LabelEventToJson(LabelEvent instance) => MilestoneEvent _$MilestoneEventFromJson(Map json) => MilestoneEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -113,7 +113,7 @@ Map _$MilestoneEventToJson(MilestoneEvent instance) => }; RenameEvent _$RenameEventFromJson(Map json) => RenameEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -150,7 +150,7 @@ Map _$RenameEventToJson(RenameEvent instance) => ReviewRequestEvent _$ReviewRequestEventFromJson(Map json) => ReviewRequestEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -195,7 +195,7 @@ Map _$ReviewRequestEventToJson(ReviewRequestEvent instance) => ReviewDismissedEvent _$ReviewDismissedEventFromJson( Map json) => ReviewDismissedEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -233,7 +233,7 @@ Map _$ReviewDismissedEventToJson( }; LockEvent _$LockEventFromJson(Map json) => LockEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -266,7 +266,7 @@ Map _$LockEventToJson(LockEvent instance) => { }; ProjectEvent _$ProjectEventFromJson(Map json) => ProjectEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -302,7 +302,7 @@ Map _$ProjectEventToJson(ProjectEvent instance) => }; CommentEvent _$CommentEventFromJson(Map json) => CommentEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -359,7 +359,7 @@ Map _$CommentEventToJson(CommentEvent instance) => CrossReferenceEvent _$CrossReferenceEventFromJson(Map json) => CrossReferenceEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -401,7 +401,7 @@ Map _$CrossReferenceEventToJson( TimelineCommitEvent _$TimelineCommitEventFromJson(Map json) => TimelineCommitEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -460,7 +460,7 @@ Map _$TimelineCommitEventToJson( }; ReviewEvent _$ReviewEventFromJson(Map json) => ReviewEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -520,7 +520,7 @@ Map _$ReviewEventToJson(ReviewEvent instance) => TimelineLineCommentedEvent _$TimelineLineCommentedEventFromJson( Map json) => TimelineLineCommentedEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -560,7 +560,7 @@ Map _$TimelineLineCommentedEventToJson( TimelineCommitCommentedEvent _$TimelineCommitCommentedEventFromJson( Map json) => TimelineCommitCommentedEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -598,7 +598,7 @@ Map _$TimelineCommitCommentedEventToJson( AssigneeEvent _$AssigneeEventFromJson(Map json) => AssigneeEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null @@ -636,7 +636,7 @@ Map _$AssigneeEventToJson(AssigneeEvent instance) => StateChangeIssueEvent _$StateChangeIssueEventFromJson( Map json) => StateChangeIssueEvent( - id: json['id'] as int? ?? 0, + id: (json['id'] as num?)?.toInt() ?? 0, nodeId: json['node_id'] as String?, url: json['url'] as String?, actor: json['actor'] == null diff --git a/lib/src/common/model/timeline_support.g.dart b/lib/src/common/model/timeline_support.g.dart index c1e441f2..83adf60a 100644 --- a/lib/src/common/model/timeline_support.g.dart +++ b/lib/src/common/model/timeline_support.g.dart @@ -17,8 +17,8 @@ GitHubApp _$GitHubAppFromJson(Map json) => GitHubApp( (json['events'] as List?)?.map((e) => e as String).toList(), externalUrl: json['external_url'] as String?, htmlUrl: json['html_url'] as String?, - id: json['id'] as int?, - installationsCount: json['installations_count'] as int?, + id: (json['id'] as num?)?.toInt(), + installationsCount: (json['installations_count'] as num?)?.toInt(), name: json['name'] as String?, nodeId: json['node_id'] as String?, owner: json['owner'] == null @@ -69,7 +69,7 @@ DismissedReview _$DismissedReviewFromJson(Map json) => DismissedReview( dismissalCommitId: json['dismissal_commit_id'] as String?, dismissalMessage: json['dismissal_message'] as String?, - reviewId: json['review_id'] as int?, + reviewId: (json['review_id'] as num?)?.toInt(), state: json['state'] as String?, ); @@ -83,9 +83,9 @@ Map _$DismissedReviewToJson(DismissedReview instance) => ProjectCard _$ProjectCardFromJson(Map json) => ProjectCard( columnName: json['column_name'] as String?, - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), previousColumnName: json['previous_column_name'] as String?, - projectId: json['project_id'] as int?, + projectId: (json['project_id'] as num?)?.toInt(), projectUrl: json['project_url'] as String?, url: json['url'] as String?, ); @@ -160,7 +160,7 @@ TemplateRepository _$TemplateRepositoryFromJson(Map json) => downloadsUrl: json['downloads_url'] as String?, eventsUrl: json['events_url'] as String?, fork: json['fork'] as bool?, - forksCount: json['forks_count'] as int?, + forksCount: (json['forks_count'] as num?)?.toInt(), forksUrl: json['forks_url'] as String?, fullName: json['full_name'] as String?, gitCommitsUrl: json['git_commits_url'] as String?, @@ -175,7 +175,7 @@ TemplateRepository _$TemplateRepositoryFromJson(Map json) => homepage: json['homepage'] as String?, hooksUrl: json['hooks_url'] as String?, htmlUrl: json['html_url'] as String?, - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), isTemplate: json['is_template'] as bool?, issueCommentUrl: json['issue_comment_url'] as String?, issueEventsUrl: json['issue_events_url'] as String?, @@ -190,10 +190,10 @@ TemplateRepository _$TemplateRepositoryFromJson(Map json) => milestonesUrl: json['milestones_url'] as String?, mirrorUrl: json['mirror_url'] as String?, name: json['name'] as String?, - networkCount: json['network_count'] as int?, + networkCount: (json['network_count'] as num?)?.toInt(), nodeId: json['node_id'] as String?, notificationsUrl: json['notifications_url'] as String?, - openIssuesCount: json['open_issues_count'] as int?, + openIssuesCount: (json['open_issues_count'] as num?)?.toInt(), owner: json['owner'] == null ? null : Owner.fromJson(json['owner'] as Map), @@ -206,14 +206,14 @@ TemplateRepository _$TemplateRepositoryFromJson(Map json) => ? null : DateTime.parse(json['pushed_at'] as String), releasesUrl: json['releases_url'] as String?, - size: json['size'] as int?, + size: (json['size'] as num?)?.toInt(), squashMergeCommitMessage: json['squash_merge_commit_message'] as String?, squashMergeCommitTitle: json['squash_merge_commit_title'] as String?, sshUrl: json['ssh_url'] as String?, - stargazersCount: json['stargazers_count'] as int?, + stargazersCount: (json['stargazers_count'] as num?)?.toInt(), stargazersUrl: json['stargazers_url'] as String?, statusesUrl: json['statuses_url'] as String?, - subscribersCount: json['subscribers_count'] as int?, + subscribersCount: (json['subscribers_count'] as num?)?.toInt(), subscribersUrl: json['subscribers_url'] as String?, subscriptionUrl: json['subscription_url'] as String?, svnUrl: json['svn_url'] as String?, @@ -228,7 +228,7 @@ TemplateRepository _$TemplateRepositoryFromJson(Map json) => : DateTime.parse(json['updated_at'] as String), url: json['url'] as String?, visibility: json['visibility'] as String?, - watchersCount: json['watchers_count'] as int?, + watchersCount: (json['watchers_count'] as num?)?.toInt(), ); Map _$TemplateRepositoryToJson(TemplateRepository instance) => @@ -329,7 +329,7 @@ Owner _$OwnerFromJson(Map json) => Owner( gistsUrl: json['gists_url'] as String?, gravatarId: json['gravatar_id'] as String?, htmlUrl: json['html_url'] as String?, - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), login: json['login'] as String?, nodeId: json['node_id'] as String?, organizationsUrl: json['organizations_url'] as String?, diff --git a/lib/src/common/model/users.g.dart b/lib/src/common/model/users.g.dart index 40e4a306..1e61153c 100644 --- a/lib/src/common/model/users.g.dart +++ b/lib/src/common/model/users.g.dart @@ -7,7 +7,7 @@ part of 'users.dart'; // ************************************************************************** User _$UserFromJson(Map json) => User( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), login: json['login'] as String?, avatarUrl: json['avatar_url'] as String?, htmlUrl: json['html_url'] as String?, @@ -19,10 +19,10 @@ User _$UserFromJson(Map json) => User( email: json['email'] as String?, hirable: json['hirable'] as bool?, bio: json['bio'] as String?, - publicReposCount: json['public_repos'] as int?, - publicGistsCount: json['public_gists'] as int?, - followersCount: json['followers'] as int?, - followingCount: json['following'] as int?, + publicReposCount: (json['public_repos'] as num?)?.toInt(), + publicGistsCount: (json['public_gists'] as num?)?.toInt(), + followersCount: (json['followers'] as num?)?.toInt(), + followingCount: (json['following'] as num?)?.toInt(), createdAt: json['created_at'] == null ? null : DateTime.parse(json['created_at'] as String), @@ -85,7 +85,7 @@ Map _$UserToJson(User instance) => { Collaborator _$CollaboratorFromJson(Map json) => Collaborator( json['login'] as String?, - json['id'] as int?, + (json['id'] as num?)?.toInt(), json['html_url'] as String?, json['type'] as String?, json['site_admin'] as bool?, @@ -105,13 +105,13 @@ Map _$CollaboratorToJson(Collaborator instance) => }; Contributor _$ContributorFromJson(Map json) => Contributor( - id: json['id'] as int?, + id: (json['id'] as num?)?.toInt(), login: json['login'] as String?, avatarUrl: json['avatar_url'] as String?, htmlUrl: json['html_url'] as String?, type: json['type'] as String?, siteAdmin: json['site_admin'] as bool?, - contributions: json['contributions'] as int?, + contributions: (json['contributions'] as num?)?.toInt(), ); Map _$ContributorToJson(Contributor instance) => @@ -127,7 +127,7 @@ Map _$ContributorToJson(Contributor instance) => CurrentUser _$CurrentUserFromJson(Map json) => CurrentUser() ..login = json['login'] as String? - ..id = json['id'] as int? + ..id = (json['id'] as num?)?.toInt() ..avatarUrl = json['avatar_url'] as String? ..htmlUrl = json['html_url'] as String? ..siteAdmin = json['site_admin'] as bool? @@ -138,10 +138,10 @@ CurrentUser _$CurrentUserFromJson(Map json) => CurrentUser() ..email = json['email'] as String? ..hirable = json['hirable'] as bool? ..bio = json['bio'] as String? - ..publicReposCount = json['public_repos'] as int? - ..publicGistsCount = json['public_gists'] as int? - ..followersCount = json['followers'] as int? - ..followingCount = json['following'] as int? + ..publicReposCount = (json['public_repos'] as num?)?.toInt() + ..publicGistsCount = (json['public_gists'] as num?)?.toInt() + ..followersCount = (json['followers'] as num?)?.toInt() + ..followingCount = (json['following'] as num?)?.toInt() ..createdAt = json['created_at'] == null ? null : DateTime.parse(json['created_at'] as String) @@ -165,9 +165,9 @@ CurrentUser _$CurrentUserFromJson(Map json) => CurrentUser() ..subscriptionsUrl = json['subscriptions_url'] as String? ..type = json['type'] as String? ..url = json['url'] as String? - ..privateReposCount = json['total_private_repos'] as int? - ..ownedPrivateReposCount = json['owned_private_repos'] as int? - ..diskUsage = json['disk_usage'] as int? + ..privateReposCount = (json['total_private_repos'] as num?)?.toInt() + ..ownedPrivateReposCount = (json['owned_private_repos'] as num?)?.toInt() + ..diskUsage = (json['disk_usage'] as num?)?.toInt() ..plan = json['plan'] == null ? null : UserPlan.fromJson(json['plan'] as Map); @@ -215,9 +215,9 @@ Map _$CurrentUserToJson(CurrentUser instance) => UserPlan _$UserPlanFromJson(Map json) => UserPlan() ..name = json['name'] as String? - ..space = json['space'] as int? - ..privateReposCount = json['private_repos'] as int? - ..collaboratorsCount = json['collaborators'] as int?; + ..space = (json['space'] as num?)?.toInt() + ..privateReposCount = (json['private_repos'] as num?)?.toInt() + ..collaboratorsCount = (json['collaborators'] as num?)?.toInt(); Map _$UserPlanToJson(UserPlan instance) => { 'name': instance.name, diff --git a/lib/src/server/hooks.g.dart b/lib/src/server/hooks.g.dart index e78b6cc9..81cbb790 100644 --- a/lib/src/server/hooks.g.dart +++ b/lib/src/server/hooks.g.dart @@ -132,7 +132,7 @@ Map _$IssueEventToJson(IssueEvent instance) => PullRequestEvent _$PullRequestEventFromJson(Map json) => PullRequestEvent( action: json['action'] as String?, - number: json['number'] as int?, + number: (json['number'] as num?)?.toInt(), pullRequest: json['pull_request'] == null ? null : PullRequest.fromJson(json['pull_request'] as Map), From 137871baa8cf1f6b83d5e343af9c0f350d17fbfc Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 15 Apr 2025 09:59:25 -0500 Subject: [PATCH 135/139] Bump to latest lints (#417) Bump to latest lints, require Dart 3.5 --- .github/workflows/dart.yml | 2 +- CHANGELOG.md | 2 +- example/common.dart | 2 +- example/emoji.dart | 1 + example/index.dart | 2 ++ example/languages.dart | 2 +- example/organization.dart | 1 + example/pr.dart | 1 + example/readme.dart | 1 + example/release_notes.dart | 1 + example/releases.dart | 1 + example/repos.dart | 1 + example/search.dart | 2 ++ example/stars.dart | 1 + example/user_info.dart | 1 + example/users.dart | 1 + example/zen.dart | 2 ++ lib/browser_helper.dart | 3 ++- lib/hooks.dart | 3 +-- lib/src/browser/xplat_browser.dart | 2 ++ lib/src/common/activity_service.dart | 2 +- lib/src/common/github.dart | 8 ++++---- lib/src/common/util/pagination.dart | 1 - pubspec.yaml | 4 ++-- test/unit/orgs_service_test.dart | 1 - 25 files changed, 32 insertions(+), 16 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 1dcc0100..63b8adab 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -13,7 +13,7 @@ jobs: matrix: os: [ubuntu-latest] # Test with at least the declared minimum Dart version - sdk: ['3.1', stable] + sdk: ['3.5', stable] steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7939058a..7e6bd14e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## 9.25.0-wip -* Require Dart 3.1 +* Require Dart 3.5 * Require `package:http` `^1.0.0`. ## 9.24.0 diff --git a/example/common.dart b/example/common.dart index 1564a6c3..e508d0ee 100644 --- a/example/common.dart +++ b/example/common.dart @@ -1,4 +1,5 @@ import 'dart:async'; +// ignore: deprecated_member_use import 'dart:html'; import 'package:github/github.dart'; @@ -13,7 +14,6 @@ export 'package:github/github.dart'; Future initViewSourceButton(String script) async { // query the DOM for the view source button, handle clicks document.querySelector('#view-source')?.onClick.listen((_) { - // ignore: unsafe_html final popup = window.open( 'https://github.com/SpinlockLabs/github.dart/blob/master/example/$script', 'View Source'); diff --git a/example/emoji.dart b/example/emoji.dart index 7604d461..663269dd 100644 --- a/example/emoji.dart +++ b/example/emoji.dart @@ -1,4 +1,5 @@ import 'dart:async'; +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/index.dart b/example/index.dart index 42851c96..535acd07 100644 --- a/example/index.dart +++ b/example/index.dart @@ -1,4 +1,6 @@ +// ignore: deprecated_member_use import 'dart:html'; + import 'common.dart'; void main() { diff --git a/example/languages.dart b/example/languages.dart index 02da85e0..aa8b7ec1 100644 --- a/example/languages.dart +++ b/example/languages.dart @@ -1,3 +1,4 @@ +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; @@ -34,7 +35,6 @@ void reloadTable({int accuracy = 4}) { isReloadingTable = true; final md = generateMarkdown(accuracy); github.misc.renderMarkdown(md).then((html) { - // ignore: unsafe_html tableDiv!.setInnerHtml(html, treeSanitizer: NodeTreeSanitizer.trusted); isReloadingTable = false; }); diff --git a/example/organization.dart b/example/organization.dart index ef7135f8..d11d0fdd 100644 --- a/example/organization.dart +++ b/example/organization.dart @@ -1,4 +1,5 @@ import 'dart:async'; +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/pr.dart b/example/pr.dart index 15e18180..660d4c45 100644 --- a/example/pr.dart +++ b/example/pr.dart @@ -1,4 +1,5 @@ import 'dart:async'; +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/readme.dart b/example/readme.dart index ad9ec300..1920cca4 100644 --- a/example/readme.dart +++ b/example/readme.dart @@ -1,3 +1,4 @@ +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/release_notes.dart b/example/release_notes.dart index be929744..27835cdd 100644 --- a/example/release_notes.dart +++ b/example/release_notes.dart @@ -1,3 +1,4 @@ +// ignore: deprecated_member_use import 'dart:html'; import 'package:pub_semver/pub_semver.dart'; diff --git a/example/releases.dart b/example/releases.dart index ddd19570..c244c962 100644 --- a/example/releases.dart +++ b/example/releases.dart @@ -1,3 +1,4 @@ +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/repos.dart b/example/repos.dart index e7b21da4..409417ab 100644 --- a/example/repos.dart +++ b/example/repos.dart @@ -1,4 +1,5 @@ import 'dart:async'; +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/search.dart b/example/search.dart index 9ca8b0ac..aeee9cbb 100644 --- a/example/search.dart +++ b/example/search.dart @@ -1,4 +1,6 @@ +// ignore: deprecated_member_use import 'dart:html'; + import 'common.dart'; Future main() async { diff --git a/example/stars.dart b/example/stars.dart index 52a95e54..2bc50b4c 100644 --- a/example/stars.dart +++ b/example/stars.dart @@ -1,3 +1,4 @@ +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/user_info.dart b/example/user_info.dart index 071c2820..656207b1 100644 --- a/example/user_info.dart +++ b/example/user_info.dart @@ -1,3 +1,4 @@ +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/users.dart b/example/users.dart index ab75a061..003d3f5d 100644 --- a/example/users.dart +++ b/example/users.dart @@ -1,4 +1,5 @@ import 'dart:async'; +// ignore: deprecated_member_use import 'dart:html'; import 'common.dart'; diff --git a/example/zen.dart b/example/zen.dart index 2e4d8b57..34c55c87 100644 --- a/example/zen.dart +++ b/example/zen.dart @@ -1,4 +1,6 @@ +// ignore: deprecated_member_use import 'dart:html'; + import 'common.dart'; Future main() async { diff --git a/lib/browser_helper.dart b/lib/browser_helper.dart index 0d9af0f1..39ebd393 100644 --- a/lib/browser_helper.dart +++ b/lib/browser_helper.dart @@ -1,4 +1,6 @@ +// ignore: deprecated_member_use import 'dart:html'; + import 'package:github/src/common.dart'; /// Renders Markdown in HTML using the GitHub API @@ -24,7 +26,6 @@ void renderMarkdown(GitHub github, String selector, {int indent = 4}) { e.hidden = false; e.setAttribute('rendered', ''); e.classes.add('markdown-body'); - // ignore: unsafe_html e.setInnerHtml(html, treeSanitizer: NodeTreeSanitizer.trusted); }); } diff --git a/lib/hooks.dart b/lib/hooks.dart index 1a336ed2..19fc3fae 100644 --- a/lib/hooks.dart +++ b/lib/hooks.dart @@ -7,7 +7,6 @@ /// Add this import if you are in a non-web environment and writing something /// that uses github hooks. For more information, see github hooks documentation /// https://developer.github.com/v3/repos/hooks/ - -library hooks; +library; export 'src/server/xplat_server.dart'; diff --git a/lib/src/browser/xplat_browser.dart b/lib/src/browser/xplat_browser.dart index 71bed55a..c54a2530 100644 --- a/lib/src/browser/xplat_browser.dart +++ b/lib/src/browser/xplat_browser.dart @@ -1,4 +1,6 @@ +// ignore: deprecated_member_use import 'dart:html'; + import 'package:github/src/common.dart'; import 'package:github/src/common/xplat_common.dart' show findAuthenticationInMap; diff --git a/lib/src/common/activity_service.dart b/lib/src/common/activity_service.dart index f69e8c49..f97aefcf 100644 --- a/lib/src/common/activity_service.dart +++ b/lib/src/common/activity_service.dart @@ -329,7 +329,7 @@ class EventPoller { final List handledEvents = []; Timer? _timer; - StreamController? _controller; // ignore: close_sinks + StreamController? _controller; String? _lastFetched; diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index ef803ea0..e6ba64cb 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -190,7 +190,7 @@ class GitHub { /// /// The future will pass the object returned from this function to the then method. /// The default [convert] function returns the input object. - /// [body] is the data to send to the server. Pass in a List if you want to post binary body data. Everything else will have .toString() called on it and set as text content + /// [body] is the data to send to the server. Pass in a `List` if you want to post binary body data. Everything else will have .toString() called on it and set as text content /// [S] represents the input type. /// [T] represents the type return from this function after conversion Future postJSON( @@ -232,7 +232,7 @@ class GitHub { /// /// The future will pass the object returned from this function to the then method. /// The default [convert] function returns the input object. - /// [body] is the data to send to the server. Pass in a List if you want to post binary body data. Everything else will have .toString() called on it and set as text content + /// [body] is the data to send to the server. Pass in a `List` if you want to post binary body data. Everything else will have .toString() called on it and set as text content /// [S] represents the input type. /// [T] represents the type return from this function after conversion Future putJSON( @@ -274,7 +274,7 @@ class GitHub { /// /// The future will pass the object returned from this function to the then method. /// The default [convert] function returns the input object. - /// [body] is the data to send to the server. Pass in a List if you want to post binary body data. Everything else will have .toString() called on it and set as text content + /// [body] is the data to send to the server. Pass in a `List` if you want to post binary body data. Everything else will have .toString() called on it and set as text content /// [S] represents the input type. /// [T] represents the type return from this function after conversion Future patchJSON( @@ -343,7 +343,7 @@ class GitHub { /// [path] can either be a path like '/repos' or a full url. /// [headers] are HTTP Headers. If it doesn't exist, the 'Accept' and 'Authorization' headers are added. /// [params] are query string parameters. - /// [body] is the body content of requests that take content. Pass in a List if you want to post binary body data. Everything else will have .toString() called on it and set as text content + /// [body] is the body content of requests that take content. Pass in a `List` if you want to post binary body data. Everything else will have .toString() called on it and set as text content /// Future request( String method, diff --git a/lib/src/common/util/pagination.dart b/lib/src/common/util/pagination.dart index 95d47107..40cf621a 100644 --- a/lib/src/common/util/pagination.dart +++ b/lib/src/common/util/pagination.dart @@ -31,7 +31,6 @@ class PaginationHelper { var page = params['page'] ?? 1; params['page'] = page; - // ignore: literal_only_boolean_expressions while (true) { http.Response response; try { diff --git a/pubspec.yaml b/pubspec.yaml index 9b29ea72..b2f9b7f0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart environment: - sdk: ^3.1.0 + sdk: ^3.5.0 dependencies: http: ^1.0.0 @@ -19,7 +19,7 @@ dev_dependencies: collection: ^1.15.0 dependency_validator: ^3.0.0 json_serializable: ^6.6.1 - lints: ^4.0.0 + lints: ^5.0.0 mockito: ^5.3.2 nock: ^1.1.3 pub_semver: ^2.0.0 diff --git a/test/unit/orgs_service_test.dart b/test/unit/orgs_service_test.dart index 04fff9e1..9ba4ff3f 100644 --- a/test/unit/orgs_service_test.dart +++ b/test/unit/orgs_service_test.dart @@ -93,7 +93,6 @@ void main() { final github = GitHub(client: client); final organizationsService = OrganizationsService(github); - // ignore: omit_local_variable_types expect( () async => organizationsService.getTeamByName( 'flutter', 'flutter-programmers'), From d13786fb89e02266ae6c099bf3f0d79b4dc6eafe Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 17 Apr 2025 20:10:34 -0500 Subject: [PATCH 136/139] Fix pagination logic to use `next` link (#418) * Fix pagination logic to use `next` link Fixes https://github.com/SpinlockLabs/github.dart/issues/414 * Fix tests --- CHANGELOG.md | 3 ++- lib/src/common/util/pagination.dart | 6 ++---- pubspec.yaml | 2 +- test/common/repos_service_test.dart | 4 ++-- test/git_test.dart | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e6bd14e..8c92ab04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -## 9.25.0-wip +## 9.25.0 * Require Dart 3.5 * Require `package:http` `^1.0.0`. +* Fix pagination logic to use `next` link. ## 9.24.0 diff --git a/lib/src/common/util/pagination.dart b/lib/src/common/util/pagination.dart index 40cf621a..93f3a0d7 100644 --- a/lib/src/common/util/pagination.dart +++ b/lib/src/common/util/pagination.dart @@ -28,9 +28,6 @@ class PaginationHelper { params = Map.from(params); } - var page = params['page'] ?? 1; - params['page'] = page; - while (true) { http.Response response; try { @@ -70,7 +67,8 @@ class PaginationHelper { break; } - params['page'] = ++page; + path = next; + params = null; } } diff --git a/pubspec.yaml b/pubspec.yaml index b2f9b7f0..8168d555 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: github -version: 9.25.0-wip +version: 9.25.0 description: A high-level GitHub API Client Library that uses Github's v3 API homepage: https://github.com/SpinlockLabs/github.dart diff --git a/test/common/repos_service_test.dart b/test/common/repos_service_test.dart index feebe05c..2f3f9120 100644 --- a/test/common/repos_service_test.dart +++ b/test/common/repos_service_test.dart @@ -16,7 +16,7 @@ void main() { test('listCommits', () async { final repositories = create((request) async { expect(request.url.path, '/repos/${slug.fullName}/commits'); - expect(request.url.query, 'page=1'); + expect(request.url.query, isEmpty); return Response(listCommits, StatusCodes.OK); }); @@ -29,7 +29,7 @@ void main() { expect(request.url.path, '/repos/${slug.fullName}/commits'); expect( request.url.query, - 'author=octocat&committer=octodog&sha=abc&path=%2Fpath&since=2022-02-22T00%3A00%3A00.000&until=2023-02-22T00%3A00%3A00.000&page=1', + 'author=octocat&committer=octodog&sha=abc&path=%2Fpath&since=2022-02-22T00%3A00%3A00.000&until=2023-02-22T00%3A00%3A00.000', ); return Response(listCommits, StatusCodes.OK); }); diff --git a/test/git_test.dart b/test/git_test.dart index 228b3a0b..e95ef5d6 100644 --- a/test/git_test.dart +++ b/test/git_test.dart @@ -172,7 +172,7 @@ void main() { test('code search', () async { nock(fakeApiUrl) .get( - '/search/code?q=search%20repo%3ASpinlockLabs%2Fgithub.dart%20in%3Afile&per_page=20&page=1') + '/search/code?q=search%20repo%3ASpinlockLabs%2Fgithub.dart%20in%3Afile&per_page=20') .reply(200, nocked.searchResults); final results = (await github.search From 4256ac1e8baeeca975b1d75abe60b0fbda73e001 Mon Sep 17 00:00:00 2001 From: "John \"codefu\" McDole" Date: Thu, 17 Apr 2025 18:11:11 -0700 Subject: [PATCH 137/139] Handle 'null' conclusion (#413) Creating a new concolusion with the GitHub API and then encoding that CheckRun to json adds: `"conclusion":"null"` to the json string; attempting to decode that throws an exception. Fixes #412 Co-authored-by: Rob Becker --- lib/src/common/model/checks.dart | 2 +- test/unit/checks_test.dart | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index 5068febc..b7666579 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -54,7 +54,7 @@ class CheckRunConclusion extends EnumWithValue { const CheckRunConclusion._(super.value); factory CheckRunConclusion._fromValue(String? value) { - if (value == null) { + if (value == null || value == 'null') { return empty; } for (final level in const [ diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart index 8af59043..2eb7e6c4 100644 --- a/test/unit/checks_test.dart +++ b/test/unit/checks_test.dart @@ -100,6 +100,9 @@ const checkRunJson = '''{ const String expectedToString = '{"name":"mighty_readme","id":4,"external_id":"","status":"completed","head_sha":"","check_suite":{"id":5},"details_url":"https://example.com","started_at":"2018-05-04T01:14:52.000Z","conclusion":"neutral"}'; +const String newCheckRun = + '{"name":"New CheckRun","id":12345,"external_id":"","status":"queued","head_sha":"","check_suite":{"id":123456},"details_url":"https://example.com","started_at":"2024-12-05T01:05:24.000Z","conclusion":"null"}'; + void main() { group('Check run', () { test('CheckRun fromJson', () { @@ -110,6 +113,14 @@ void main() { expect(checkRun.conclusion, CheckRunConclusion.neutral); }); + test('CheckRun from freshly created and encoded', () { + final checkRun = CheckRun.fromJson(jsonDecode(newCheckRun)); + + expect(checkRun.id, 12345); + expect(checkRun.name, 'New CheckRun'); + expect(checkRun.conclusion, CheckRunConclusion.empty); + }); + test('CheckRun fromJson for skipped conclusion', () { /// The checkRun Json is the official Github values /// From 98f2e48df1736ec63ef48e086fefd4efbb522751 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 19:16:11 -0600 Subject: [PATCH 138/139] Bump JamesIves/github-pages-deploy-action from 4.5.0 to 4.6.1 (#408) Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.5.0 to 4.6.1. - [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases) - [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.5.0...v4.6.1) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Becker --- .github/workflows/publish_demos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 603b4a09..b6b6169e 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -24,7 +24,7 @@ jobs: rm build/example/packages - name: Publish 🚀 - uses: JamesIves/github-pages-deploy-action@v4.5.0 + uses: JamesIves/github-pages-deploy-action@v4.6.1 with: branch: gh-pages # The branch the action should deploy to. folder: build/example # The folder the action should deploy. From c3a02992b14d370ac8bd3ef2a09a588db2e2dbcb Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 17 Apr 2025 22:11:02 -0500 Subject: [PATCH 139/139] Drop mockito and rebuild (#419) --- lib/src/common/model/git.g.dart | 20 ++++++-------------- pubspec.yaml | 1 - 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/lib/src/common/model/git.g.dart b/lib/src/common/model/git.g.dart index e041aeb3..ccbb082b 100644 --- a/lib/src/common/model/git.g.dart +++ b/lib/src/common/model/git.g.dart @@ -95,20 +95,12 @@ GitCommitUser _$GitCommitUserFromJson(Map json) => json['date'] == null ? null : DateTime.parse(json['date'] as String), ); -Map _$GitCommitUserToJson(GitCommitUser instance) { - final val = {}; - - void writeNotNull(String key, dynamic value) { - if (value != null) { - val[key] = value; - } - } - - writeNotNull('name', instance.name); - writeNotNull('email', instance.email); - writeNotNull('date', dateToGitHubIso8601(instance.date)); - return val; -} +Map _$GitCommitUserToJson(GitCommitUser instance) => + { + if (instance.name case final value?) 'name': value, + if (instance.email case final value?) 'email': value, + if (dateToGitHubIso8601(instance.date) case final value?) 'date': value, + }; GitTree _$GitTreeFromJson(Map json) => GitTree( json['sha'] as String?, diff --git a/pubspec.yaml b/pubspec.yaml index 8168d555..eed1fec4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,7 +20,6 @@ dev_dependencies: dependency_validator: ^3.0.0 json_serializable: ^6.6.1 lints: ^5.0.0 - mockito: ^5.3.2 nock: ^1.1.3 pub_semver: ^2.0.0 test: ^1.21.6 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy