Show summary count of outdated packages after running `pub upgrade` (#2444)
diff --git a/lib/src/solver/report.dart b/lib/src/solver/report.dart
index 4f7318d..b175d17 100644
--- a/lib/src/solver/report.dart
+++ b/lib/src/solver/report.dart
@@ -130,6 +130,32 @@
}
}
+ /// Displays a two-line message, number of outdated packages and an
+ /// instruction to run `pub outdated` if outdated packages are detected.
+ void reportOutdated() {
+ final outdatedPackagesCount = _result.packages.where((id) {
+ final versions = _result.availableVersions[id.name];
+ // A version is counted:
+ // - if there is a newer version which is not a pre-release and current
+ // version is also not a pre-release or,
+ // - if the current version is pre-release then any upgraded version is
+ // considered.
+ return versions.any((v) =>
+ v > id.version && (id.version.isPreRelease || !v.isPreRelease));
+ }).length;
+
+ if (outdatedPackagesCount > 0) {
+ String packageCountString;
+ if (outdatedPackagesCount == 1) {
+ packageCountString = '1 package has';
+ } else {
+ packageCountString = '$outdatedPackagesCount packages have';
+ }
+ log.message('$packageCountString newer versions incompatible with '
+ 'dependency constraints.\nTry `pub outdated` for more information.');
+ }
+ }
+
/// Reports the results of the upgrade on the package named [name].
///
/// If [alwaysShow] is true, the package is reported even if it didn't change,
diff --git a/lib/src/solver/result.dart b/lib/src/solver/result.dart
index 94da92e..7c2b5a5 100644
--- a/lib/src/solver/result.dart
+++ b/lib/src/solver/result.dart
@@ -94,10 +94,16 @@
/// Displays a one-line message summarizing what changes were made (or would
/// be made) to the lockfile.
///
+ /// If [type] is `SolveType.UPGRADE` it also shows the number of packages
+ /// that are not at the latest available version.
+ ///
/// [type] is the type of version resolution that was run.
void summarizeChanges(SolveType type, {bool dryRun = false}) {
- SolveReport(type, _sources, _root, _previousLockFile, this)
- .summarize(dryRun: dryRun);
+ final report = SolveReport(type, _sources, _root, _previousLockFile, this);
+ report.summarize(dryRun: dryRun);
+ if (type == SolveType.UPGRADE) {
+ report.reportOutdated();
+ }
}
@override
diff --git a/test/test_pub.dart b/test/test_pub.dart
index deb68b9..fe45ce0 100644
--- a/test/test_pub.dart
+++ b/test/test_pub.dart
@@ -81,8 +81,10 @@
class RunCommand {
static final get = RunCommand(
'get', RegExp(r'Got dependencies!|Changed \d+ dependenc(y|ies)!'));
- static final upgrade = RunCommand('upgrade',
- RegExp(r'(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)$'));
+ static final upgrade = RunCommand('upgrade', RegExp(r'''
+(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)($|
+\d+ packages? (has|have) newer versions incompatible with dependency constraints.
+Try `pub outdated` for more information.$)'''));
static final downgrade = RunCommand('downgrade',
RegExp(r'(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)$'));
diff --git a/test/upgrade/report/shows_pub_outdated_test.dart b/test/upgrade/report/shows_pub_outdated_test.dart
new file mode 100644
index 0000000..1b2c2e5
--- /dev/null
+++ b/test/upgrade/report/shows_pub_outdated_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+
+void main() {
+ test('shows pub outdated', () async {
+ await servePackages((builder) {
+ builder.serve('multiple_newer', '1.0.0');
+ builder.serve('multiple_newer', '1.0.1-unstable.1');
+ builder.serve('multiple_newer', '1.0.1');
+ builder.serve('multiple_newer', '1.0.2-unstable.1');
+ builder.serve('multiple_newer', '1.0.2-unstable.2');
+ builder.serve('multiple_newer_stable', '1.0.0');
+ builder.serve('multiple_newer_stable', '1.0.1');
+ builder.serve('multiple_newer_stable', '1.0.2');
+ builder.serve('multiple_newer_unstable', '1.0.0');
+ builder.serve('multiple_newer_unstable', '1.0.1-unstable.1');
+ builder.serve('multiple_newer_unstable', '1.0.1-unstable.2');
+ builder.serve('no_newer', '1.0.0');
+ builder.serve('one_newer_unstable', '1.0.0');
+ builder.serve('one_newer_unstable', '1.0.1-unstable.1');
+ builder.serve('one_newer_stable', '1.0.0');
+ builder.serve('one_newer_stable', '1.0.1');
+ });
+
+ // Constraint everything to the first version.
+ await d.appDir({
+ 'multiple_newer': '1.0.0',
+ 'multiple_newer_stable': '1.0.0',
+ 'multiple_newer_unstable': '1.0.0',
+ 'no_newer': '1.0.0',
+ 'one_newer_unstable': '1.0.0',
+ 'one_newer_stable': '1.0.0'
+ }).create();
+
+ // Upgrade everything.
+ await pubUpgrade(output: RegExp(r'''
+3 packages have newer versions incompatible with dependency constraints.
+Try `pub outdated` for more information.$''', multiLine: true));
+
+ // Upgrade `multiple_newer` to `1.0.1`.
+ await d.appDir({
+ 'multiple_newer': '1.0.1',
+ 'multiple_newer_stable': '1.0.0',
+ 'multiple_newer_unstable': '1.0.0',
+ 'no_newer': '1.0.0',
+ 'one_newer_unstable': '1.0.0',
+ 'one_newer_stable': '1.0.0'
+ }).create();
+
+ // Upgrade everything.
+ await pubUpgrade(output: RegExp(r'''
+2 packages have newer versions incompatible with dependency constraints.
+Try `pub outdated` for more information.$''', multiLine: true));
+
+ // Upgrade `multiple_newer` to `1.0.2-unstable.1`.
+ await d.appDir({
+ 'multiple_newer': '1.0.2-unstable.1',
+ 'multiple_newer_stable': '1.0.0',
+ 'multiple_newer_unstable': '1.0.0',
+ 'no_newer': '1.0.0',
+ 'one_newer_unstable': '1.0.0',
+ 'one_newer_stable': '1.0.0'
+ }).create();
+
+ // Upgrade everything.
+ await pubUpgrade(output: RegExp(r'''
+3 packages have newer versions incompatible with dependency constraints.
+Try `pub outdated` for more information.$''', multiLine: true));
+
+ // Upgrade all except `one_newer_stable`.
+ await d.appDir({
+ 'multiple_newer': '1.0.2-unstable.2',
+ 'multiple_newer_stable': '1.0.2',
+ 'multiple_newer_unstable': '1.0.1-unstable.2',
+ 'no_newer': '1.0.0',
+ 'one_newer_unstable': '1.0.1-unstable.1',
+ 'one_newer_stable': '1.0.0'
+ }).create();
+
+ // Upgrade everything.
+ await pubUpgrade(output: RegExp(r'''
+1 package has newer versions incompatible with dependency constraints.
+Try `pub outdated` for more information.$''', multiLine: true));
+ });
+}