Update revert regex to be more flexible with surrounding text and other quality changes (#2226)
diff --git a/auto_submit/lib/service/github_service.dart b/auto_submit/lib/service/github_service.dart
index 2affddc..87f0692 100644
--- a/auto_submit/lib/service/github_service.dart
+++ b/auto_submit/lib/service/github_service.dart
@@ -145,29 +145,50 @@
/// Compare the filesets of the current pull request and the original pull
/// request that is being reverted.
Future<bool> comparePullRequests(RepositorySlug repositorySlug, PullRequest revert, PullRequest current) async {
- List<PullRequestFile> originalPullRequestFiles = await getPullRequestFiles(repositorySlug, revert);
- List<PullRequestFile> currentPullRequestFiles = await getPullRequestFiles(repositorySlug, current);
+ final List<PullRequestFile> originalPullRequestFiles = await getPullRequestFiles(repositorySlug, revert);
+ final List<PullRequestFile> currentPullRequestFiles = await getPullRequestFiles(repositorySlug, current);
- return _validateFileSetsAreEqual(originalPullRequestFiles, currentPullRequestFiles);
+ return validateFileSetsAreEqual(originalPullRequestFiles, currentPullRequestFiles);
}
/// Validate that each pull request has the same number of files and that the
/// file names match. This must be the case in order to process the revert.
- bool _validateFileSetsAreEqual(
- List<PullRequestFile> revertPullRequestFiles,
- List<PullRequestFile> currentPullRequestFiles,
+ bool validateFileSetsAreEqual(
+ List<PullRequestFile> revertRequestFileList,
+ List<PullRequestFile> originalRequestFileList,
) {
- List<String?> revertFileNames = [];
- List<String?> currentFileNames = [];
+ if (revertRequestFileList.length != originalRequestFileList.length) {
+ return false;
+ }
- for (PullRequestFile element in revertPullRequestFiles) {
+ final List<String?> revertFileNames = [];
+ final List<String?> originalFileNames = [];
+
+ for (PullRequestFile element in revertRequestFileList) {
revertFileNames.add(element.filename);
}
- for (PullRequestFile element in currentPullRequestFiles) {
- currentFileNames.add(element.filename);
+ for (PullRequestFile element in originalRequestFileList) {
+ originalFileNames.add(element.filename);
}
- return revertFileNames.toSet().containsAll(currentFileNames) &&
- currentFileNames.toSet().containsAll(revertFileNames);
+ // At this point we know the file lists have the same amount of files but not the same files.
+ if (!revertFileNames.toSet().containsAll(originalFileNames) ||
+ !originalFileNames.toSet().containsAll(revertFileNames)) {
+ return false;
+ }
+
+ // At this point all the files are the same so we can iterate over one list to
+ // compare changes.
+ for (PullRequestFile revertRequestFile in revertRequestFileList) {
+ final PullRequestFile originalRequestFile =
+ originalRequestFileList.firstWhere((element) => element.filename == revertRequestFile.filename);
+ if (revertRequestFile.changesCount != originalRequestFile.changesCount ||
+ revertRequestFile.additionsCount != originalRequestFile.deletionsCount ||
+ revertRequestFile.deletionsCount != originalRequestFile.additionsCount) {
+ return false;
+ }
+ }
+
+ return true;
}
}
diff --git a/auto_submit/lib/validations/revert.dart b/auto_submit/lib/validations/revert.dart
index 0c2fee2..2cccccd 100644
--- a/auto_submit/lib/validations/revert.dart
+++ b/auto_submit/lib/validations/revert.dart
@@ -102,10 +102,13 @@
if (bodyText == null) {
return null;
}
- final RegExp regExp = RegExp(r'^[Rr]everts[\s]+([-\.a-zA-Z_]+/[-\.a-zA-Z_]+#[0-9]+)$', multiLine: true);
+ final RegExp regExp = RegExp(r'[Rr]everts[\s]+([-\.a-zA-Z_]+/[-\.a-zA-Z_]+#[0-9]+)', multiLine: true);
Iterable<RegExpMatch> matches = regExp.allMatches(bodyText);
- if (matches.isNotEmpty) {
+
+ if (matches.isNotEmpty && matches.length == 1) {
return matches.elementAt(0).group(1);
+ } else if (matches.isNotEmpty && matches.length != 1) {
+ log.warning('Detected more than 1 revert link. Cannot process more than one link.');
}
return null;
}
diff --git a/auto_submit/test/src/service/fake_github_service.dart b/auto_submit/test/src/service/fake_github_service.dart
index 3148b27..e39a1d0 100644
--- a/auto_submit/test/src/service/fake_github_service.dart
+++ b/auto_submit/test/src/service/fake_github_service.dart
@@ -229,25 +229,47 @@
List<PullRequestFile> revertPullRequestFiles = await getPullRequestFiles(repositorySlug, revert);
List<PullRequestFile> currentPullRequestFiles = await getPullRequestFiles(repositorySlug, current);
- return _validateFileSetsAreEqual(revertPullRequestFiles, currentPullRequestFiles);
+ return validateFileSetsAreEqual(revertPullRequestFiles, currentPullRequestFiles);
}
- bool _validateFileSetsAreEqual(
- List<PullRequestFile> revertPullRequestFiles,
- List<PullRequestFile> currentPullRequestFiles,
+ @override
+ bool validateFileSetsAreEqual(
+ List<PullRequestFile> changeList1,
+ List<PullRequestFile> changeList2,
) {
- List<String?> revertFileNames = [];
- List<String?> currentFileNames = [];
+ if (changeList1.length != changeList2.length) {
+ return false;
+ }
- for (var element in revertPullRequestFiles) {
+ final List<String?> revertFileNames = [];
+ final List<String?> currentFileNames = [];
+
+ for (PullRequestFile element in changeList1) {
revertFileNames.add(element.filename);
}
- for (var element in currentPullRequestFiles) {
+ for (PullRequestFile element in changeList2) {
currentFileNames.add(element.filename);
}
- return revertFileNames.toSet().containsAll(currentFileNames) &&
- currentFileNames.toSet().containsAll(revertFileNames);
+ // At this point we know the file lists have the same amount of files but not the same files.
+ if (!revertFileNames.toSet().containsAll(currentFileNames) ||
+ !currentFileNames.toSet().containsAll(revertFileNames)) {
+ return false;
+ }
+
+ // At this point all the files are the same so we can iterate over one list to
+ // compare changes.
+ for (PullRequestFile pullRequestFile in changeList1) {
+ PullRequestFile pullRequestFileChangeList2 =
+ changeList2.firstWhere((element) => element.filename == pullRequestFile.filename);
+ if (pullRequestFile.changesCount != pullRequestFileChangeList2.changesCount ||
+ pullRequestFile.additionsCount != pullRequestFileChangeList2.deletionsCount ||
+ pullRequestFile.deletionsCount != pullRequestFileChangeList2.additionsCount) {
+ return false;
+ }
+ }
+
+ return true;
}
@override
diff --git a/auto_submit/test/validations/revert_test.dart b/auto_submit/test/validations/revert_test.dart
index c81766e..9e72a3b 100644
--- a/auto_submit/test/validations/revert_test.dart
+++ b/auto_submit/test/validations/revert_test.dart
@@ -79,6 +79,12 @@
Some other notes in the description a developer might add.
And another note."""] = 'flutter/cocoon#123456';
+ tests['Pull request Reverts flutter/flutter#12334 is happening continuously.'] = 'flutter/flutter#12334';
+ tests['Reverts reverts flutter/flutter#9876'] = 'flutter/flutter#9876';
+ tests["""Some junk reverts flutter/cocoon#4563 is happening continuously.
+ Some other tests in the description that someone might add.
+ """] = 'flutter/cocoon#4563';
+ tests['This some text to add flavor before reverts flutter/flutter#8888.'] = 'flutter/flutter#8888';
tests.forEach((key, value) {
String? linkFound = revert.extractLinkFromText(key);
@@ -93,6 +99,15 @@
tests['revert flutter/cocoon#123456'] = '';
tests['Reverts flutter/cocoon#'] = '';
tests['Reverts flutter123'] = '';
+ // We should not allow processing of more than one link as this can be cause
+ // suspicion of other non revert changes in the pull request.
+ tests["""Reverts flutter/flutter#12345
+ Reverts flutter/flutter#34543"""] = '';
+ tests["""This some text to add flavor before reverts flutter/flutter#8888.
+ Also please reverts flutter/flutter#7678.
+ And reverts flutter/flutter#8763.
+ """] = '';
+ tests['This is some text flutter/flutter#456...44'] = '';
tests.forEach((key, value) {
String? linkFound = revert.extractLinkFromText(key);
diff --git a/auto_submit/test/validations/revert_test_data.dart b/auto_submit/test/validations/revert_test_data.dart
index a5e2bb3..b19d325 100644
--- a/auto_submit/test/validations/revert_test_data.dart
+++ b/auto_submit/test/validations/revert_test_data.dart
@@ -168,79 +168,154 @@
const String revertPullRequestFilesJson = """
[
{
- "filename": "dashboard/analysis_options.yaml"
+ "filename": "dashboard/analysis_options.yaml",
+ "additions": 0,
+ "deletions": 1,
+ "changes": 1
},
{
- "filename": "dashboard/lib/build_dashboard_page.dart"
+ "filename": "dashboard/lib/build_dashboard_page.dart",
+ "additions": 35,
+ "deletions": 45,
+ "changes": 80
},
{
- "filename": "dashboard/lib/index_page.dart"
+ "filename": "dashboard/lib/index_page.dart",
+ "additions": 10,
+ "deletions": 12,
+ "changes": 22
},
{
- "filename": "dashboard/lib/logic/brooks.dart"
+ "filename": "dashboard/lib/logic/brooks.dart",
+ "additions": 18,
+ "deletions": 20,
+ "changes": 38
},
{
- "filename": "dashboard/lib/logic/links.dart"
+ "filename": "dashboard/lib/logic/links.dart",
+ "additions": 15,
+ "deletions": 18,
+ "changes": 33
},
{
- "filename": "dashboard/lib/logic/task_grid_filter.dart"
+ "filename": "dashboard/lib/logic/task_grid_filter.dart",
+ "additions": 4,
+ "deletions": 12,
+ "changes": 16
},
{
- "filename": "dashboard/lib/main.dart"
+ "filename": "dashboard/lib/main.dart",
+ "additions": 6,
+ "deletions": 7,
+ "changes": 13
},
{
- "filename": "dashboard/lib/service/appengine_cocoon.dart"
+ "filename": "dashboard/lib/service/appengine_cocoon.dart",
+ "additions": 16,
+ "deletions": 23,
+ "changes": 39
},
{
- "filename": "dashboard/lib/service/dev_cocoon.dart"
+ "filename": "dashboard/lib/service/dev_cocoon.dart",
+ "additions": 8,
+ "deletions": 15,
+ "changes": 23
},
{
- "filename": "dashboard/lib/widgets/lattice.dart"
+ "filename": "dashboard/lib/widgets/lattice.dart",
+ "additions": 18,
+ "deletions": 22,
+ "changes": 40
},
{
- "filename": "dashboard/lib/widgets/luci_task_attempt_summary.dart"
+ "filename": "dashboard/lib/widgets/luci_task_attempt_summary.dart",
+ "additions": 4,
+ "deletions": 5,
+ "changes": 9
},
{
- "filename": "dashboard/lib/widgets/sign_in_button.dart"
+ "filename": "dashboard/lib/widgets/sign_in_button.dart",
+ "additions": 10,
+ "deletions": 12,
+ "changes": 22
},
{
- "filename": "dashboard/lib/widgets/task_grid.dart"
+ "filename": "dashboard/lib/widgets/task_grid.dart",
+ "additions": 13,
+ "deletions": 17,
+ "changes": 30
},
{
- "filename": "dashboard/lib/widgets/task_overlay.dart"
+ "filename": "dashboard/lib/widgets/task_overlay.dart",
+ "additions": 2,
+ "deletions": 3,
+ "changes": 5
},
{
- "filename": "dashboard/pubspec.lock"
+ "filename": "dashboard/pubspec.lock",
+ "additions": 1,
+ "deletions": 1,
+ "changes": 2
},
{
- "filename": "dashboard/test/build_dashboard_page_test.dart"
+ "filename": "dashboard/test/build_dashboard_page_test.dart",
+ "additions": 21,
+ "deletions": 33,
+ "changes": 54
},
{
- "filename": "dashboard/test/index_page_test.dart"
+ "filename": "dashboard/test/index_page_test.dart",
+ "additions": 4,
+ "deletions": 7,
+ "changes": 11
},
{
- "filename": "dashboard/test/logic/qualified_task_test.dart"
+ "filename": "dashboard/test/logic/qualified_task_test.dart",
+ "additions": 9,
+ "deletions": 16,
+ "changes": 25
},
{
- "filename": "dashboard/test/logic/task_grid_filter_test.dart"
+ "filename": "dashboard/test/logic/task_grid_filter_test.dart",
+ "additions": 11,
+ "deletions": 18,
+ "changes": 29
},
{
- "filename": "dashboard/test/service/appengine_cocoon_test.dart"
+ "filename": "dashboard/test/service/appengine_cocoon_test.dart",
+ "additions": 74,
+ "deletions": 112,
+ "changes": 186
},
{
- "filename": "dashboard/test/service/google_authentication_test.dart"
+ "filename": "dashboard/test/service/google_authentication_test.dart",
+ "additions": 2,
+ "deletions": 4,
+ "changes": 6
},
{
- "filename": "dashboard/test/state/build_test.dart"
+ "filename": "dashboard/test/state/build_test.dart",
+ "additions": 20,
+ "deletions": 31,
+ "changes": 51
},
{
- "filename": "dashboard/test/utils/fake_build.dart"
+ "filename": "dashboard/test/utils/fake_build.dart",
+ "additions": 6,
+ "deletions": 10,
+ "changes": 16
},
{
- "filename": "dashboard/test/utils/golden.dart"
+ "filename": "dashboard/test/utils/golden.dart",
+ "additions": 4,
+ "deletions": 6,
+ "changes": 10
},
{
- "filename": "dashboard/test/widgets/accessibility_test.dart"
+ "filename": "dashboard/test/widgets/accessibility_test.dart",
+ "additions": 14,
+ "deletions": 22,
+ "changes": 36
}
]
""";
@@ -360,79 +435,154 @@
const String originalPullRequestFilesJson = """
[
{
- "filename": "dashboard/analysis_options.yaml"
+ "filename": "dashboard/analysis_options.yaml",
+ "additions": 1,
+ "deletions": 0,
+ "changes": 1
},
{
- "filename": "dashboard/lib/build_dashboard_page.dart"
+ "filename": "dashboard/lib/build_dashboard_page.dart",
+ "additions": 45,
+ "deletions": 35,
+ "changes": 80
},
{
- "filename": "dashboard/lib/index_page.dart"
+ "filename": "dashboard/lib/index_page.dart",
+ "additions": 12,
+ "deletions": 10,
+ "changes": 22
},
{
- "filename": "dashboard/lib/logic/brooks.dart"
+ "filename": "dashboard/lib/logic/brooks.dart",
+ "additions": 20,
+ "deletions": 18,
+ "changes": 38
},
{
- "filename": "dashboard/lib/logic/links.dart"
+ "filename": "dashboard/lib/logic/links.dart",
+ "additions": 18,
+ "deletions": 15,
+ "changes": 33
},
{
- "filename": "dashboard/lib/logic/task_grid_filter.dart"
+ "filename": "dashboard/lib/logic/task_grid_filter.dart",
+ "additions": 12,
+ "deletions": 4,
+ "changes": 16
},
{
- "filename": "dashboard/lib/main.dart"
+ "filename": "dashboard/lib/main.dart",
+ "additions": 7,
+ "deletions": 6,
+ "changes": 13
},
{
- "filename": "dashboard/lib/service/appengine_cocoon.dart"
+ "filename": "dashboard/lib/service/appengine_cocoon.dart",
+ "additions": 23,
+ "deletions": 16,
+ "changes": 39
},
{
- "filename": "dashboard/lib/service/dev_cocoon.dart"
+ "filename": "dashboard/lib/service/dev_cocoon.dart",
+ "additions": 15,
+ "deletions": 8,
+ "changes": 23
},
{
- "filename": "dashboard/lib/widgets/lattice.dart"
+ "filename": "dashboard/lib/widgets/lattice.dart",
+ "additions": 22,
+ "deletions": 18,
+ "changes": 40
},
{
- "filename": "dashboard/lib/widgets/luci_task_attempt_summary.dart"
+ "filename": "dashboard/lib/widgets/luci_task_attempt_summary.dart",
+ "additions": 5,
+ "deletions": 4,
+ "changes": 9
},
{
- "filename": "dashboard/lib/widgets/sign_in_button.dart"
+ "filename": "dashboard/lib/widgets/sign_in_button.dart",
+ "additions": 12,
+ "deletions": 10,
+ "changes": 22
},
{
- "filename": "dashboard/lib/widgets/task_grid.dart"
+ "filename": "dashboard/lib/widgets/task_grid.dart",
+ "additions": 17,
+ "deletions": 13,
+ "changes": 30
},
{
- "filename": "dashboard/lib/widgets/task_overlay.dart"
+ "filename": "dashboard/lib/widgets/task_overlay.dart",
+ "additions": 3,
+ "deletions": 2,
+ "changes": 5
},
{
- "filename": "dashboard/pubspec.lock"
+ "filename": "dashboard/pubspec.lock",
+ "additions": 1,
+ "deletions": 1,
+ "changes": 2
},
{
- "filename": "dashboard/test/build_dashboard_page_test.dart"
+ "filename": "dashboard/test/build_dashboard_page_test.dart",
+ "additions": 33,
+ "deletions": 21,
+ "changes": 54
},
{
- "filename": "dashboard/test/index_page_test.dart"
+ "filename": "dashboard/test/index_page_test.dart",
+ "additions": 7,
+ "deletions": 4,
+ "changes": 11
},
{
- "filename": "dashboard/test/logic/qualified_task_test.dart"
+ "filename": "dashboard/test/logic/qualified_task_test.dart",
+ "additions": 16,
+ "deletions": 9,
+ "changes": 25
},
{
- "filename": "dashboard/test/logic/task_grid_filter_test.dart"
+ "filename": "dashboard/test/logic/task_grid_filter_test.dart",
+ "additions": 18,
+ "deletions": 11,
+ "changes": 29
},
{
- "filename": "dashboard/test/service/appengine_cocoon_test.dart"
+ "filename": "dashboard/test/service/appengine_cocoon_test.dart",
+ "additions": 112,
+ "deletions": 74,
+ "changes": 186
},
{
- "filename": "dashboard/test/service/google_authentication_test.dart"
+ "filename": "dashboard/test/service/google_authentication_test.dart",
+ "additions": 4,
+ "deletions": 2,
+ "changes": 6
},
{
- "filename": "dashboard/test/state/build_test.dart"
+ "filename": "dashboard/test/state/build_test.dart",
+ "additions": 31,
+ "deletions": 20,
+ "changes": 51
},
{
- "filename": "dashboard/test/utils/fake_build.dart"
+ "filename": "dashboard/test/utils/fake_build.dart",
+ "additions": 10,
+ "deletions": 6,
+ "changes": 16
},
{
- "filename": "dashboard/test/utils/golden.dart"
+ "filename": "dashboard/test/utils/golden.dart",
+ "additions": 6,
+ "deletions": 4,
+ "changes": 10
},
{
- "filename": "dashboard/test/widgets/accessibility_test.dart"
+ "filename": "dashboard/test/widgets/accessibility_test.dart",
+ "additions": 22,
+ "deletions": 14,
+ "changes": 36
}
]
""";
@@ -440,73 +590,142 @@
const String originalPullRequestFilesSubsetJson = """
[
{
- "filename": "dashboard/analysis_options.yaml"
+ "filename": "dashboard/analysis_options.yaml",
+ "additions": 1,
+ "deletions": 0,
+ "changes": 1
},
{
- "filename": "dashboard/lib/build_dashboard_page.dart"
+ "filename": "dashboard/lib/build_dashboard_page.dart",
+ "additions": 45,
+ "deletions": 35,
+ "changes": 80
},
{
- "filename": "dashboard/lib/index_page.dart"
+ "filename": "dashboard/lib/index_page.dart",
+ "additions": 12,
+ "deletions": 10,
+ "changes": 22
},
{
- "filename": "dashboard/lib/logic/brooks.dart"
+ "filename": "dashboard/lib/logic/brooks.dart",
+ "additions": 20,
+ "deletions": 18,
+ "changes": 38
},
{
- "filename": "dashboard/lib/logic/links.dart"
+ "filename": "dashboard/lib/logic/links.dart",
+ "additions": 18,
+ "deletions": 15,
+ "changes": 33
},
{
- "filename": "dashboard/lib/logic/task_grid_filter.dart"
+ "filename": "dashboard/lib/logic/task_grid_filter.dart",
+ "additions": 12,
+ "deletions": 4,
+ "changes": 16
},
{
- "filename": "dashboard/lib/service/appengine_cocoon.dart"
+ "filename": "dashboard/lib/service/appengine_cocoon.dart",
+ "additions": 23,
+ "deletions": 16,
+ "changes": 39
},
{
- "filename": "dashboard/lib/service/dev_cocoon.dart"
+ "filename": "dashboard/lib/service/dev_cocoon.dart",
+ "additions": 15,
+ "deletions": 8,
+ "changes": 23
},
{
- "filename": "dashboard/lib/widgets/lattice.dart"
+ "filename": "dashboard/lib/widgets/lattice.dart",
+ "additions": 22,
+ "deletions": 18,
+ "changes": 40
},
{
- "filename": "dashboard/lib/widgets/sign_in_button.dart"
+ "filename": "dashboard/lib/widgets/sign_in_button.dart",
+ "additions": 12,
+ "deletions": 10,
+ "changes": 22
},
{
- "filename": "dashboard/lib/widgets/task_grid.dart"
+ "filename": "dashboard/lib/widgets/task_grid.dart",
+ "additions": 17,
+ "deletions": 13,
+ "changes": 30
},
{
- "filename": "dashboard/lib/widgets/task_overlay.dart"
+ "filename": "dashboard/lib/widgets/task_overlay.dart",
+ "additions": 3,
+ "deletions": 2,
+ "changes": 5
},
{
- "filename": "dashboard/pubspec.lock"
+ "filename": "dashboard/pubspec.lock",
+ "additions": 1,
+ "deletions": 1,
+ "changes": 2
},
{
- "filename": "dashboard/test/build_dashboard_page_test.dart"
+ "filename": "dashboard/test/build_dashboard_page_test.dart",
+ "additions": 33,
+ "deletions": 21,
+ "changes": 54
},
{
- "filename": "dashboard/test/index_page_test.dart"
+ "filename": "dashboard/test/index_page_test.dart",
+ "additions": 7,
+ "deletions": 4,
+ "changes": 11
},
{
- "filename": "dashboard/test/logic/qualified_task_test.dart"
+ "filename": "dashboard/test/logic/qualified_task_test.dart",
+ "additions": 16,
+ "deletions": 9,
+ "changes": 25
},
{
- "filename": "dashboard/test/logic/task_grid_filter_test.dart"
+ "filename": "dashboard/test/logic/task_grid_filter_test.dart",
+ "additions": 18,
+ "deletions": 11,
+ "changes": 29
},
{
- "filename": "dashboard/test/service/appengine_cocoon_test.dart"
+ "filename": "dashboard/test/service/appengine_cocoon_test.dart",
+ "additions": 112,
+ "deletions": 74,
+ "changes": 186
},
{
- "filename": "dashboard/test/service/google_authentication_test.dart"
+ "filename": "dashboard/test/service/google_authentication_test.dart",
+ "additions": 4,
+ "deletions": 2,
+ "changes": 6
},
{
- "filename": "dashboard/test/state/build_test.dart"
+ "filename": "dashboard/test/state/build_test.dart",
+ "additions": 31,
+ "deletions": 20,
+ "changes": 51
},
{
- "filename": "dashboard/test/utils/fake_build.dart"
+ "filename": "dashboard/test/utils/fake_build.dart",
+ "additions": 10,
+ "deletions": 6,
+ "changes": 16
},
{
- "filename": "dashboard/test/utils/golden.dart"
+ "filename": "dashboard/test/utils/golden.dart",
+ "additions": 6,
+ "deletions": 4,
+ "changes": 10
},
{
- "filename": "dashboard/test/widgets/accessibility_test.dart"
+ "filename": "dashboard/test/widgets/accessibility_test.dart",
+ "additions": 22,
+ "deletions": 14,
+ "changes": 36
}
]
""";
diff --git a/dashboard/pubspec.lock b/dashboard/pubspec.lock
index ce096f8..da03b86 100644
--- a/dashboard/pubspec.lock
+++ b/dashboard/pubspec.lock
@@ -323,7 +323,7 @@
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
- version: "0.1.5"
+ version: "0.2.0"
meta:
dependency: transitive
description:
@@ -447,7 +447,7 @@
name: source_span
url: "https://pub.dartlang.org"
source: hosted
- version: "1.9.0"
+ version: "1.9.1"
stack_trace:
dependency: transitive
description:
@@ -461,7 +461,7 @@
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
stream_transform:
dependency: transitive
description:
@@ -489,7 +489,7 @@
name: test_api
url: "https://pub.dartlang.org"
source: hosted
- version: "0.4.12"
+ version: "0.4.14"
timing:
dependency: transitive
description:
@@ -573,7 +573,7 @@
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.2"
+ version: "2.1.4"
watcher:
dependency: transitive
description:
@@ -596,5 +596,5 @@
source: hosted
version: "3.1.1"
sdks:
- dart: ">=2.17.0 <3.0.0"
+ dart: ">=2.18.0 <3.0.0"
flutter: ">=2.10.0"