pub upgrade command shows count of discontinued packages (#2908)

diff --git a/lib/src/solver/report.dart b/lib/src/solver/report.dart
index 3fd18cf..fa6a4cc 100644
--- a/lib/src/solver/report.dart
+++ b/lib/src/solver/report.dart
@@ -143,6 +143,25 @@
     }
   }
 
+  /// Displays a single-line message, number of discontinued packages
+  /// if discontinued packages are detected.
+  Future<void> reportDiscontinued() async {
+    var numDiscontinued = 0;
+    for (var id in _result.packages) {
+      if (id.source == null) continue;
+      final status =
+          await _cache.source(id.source).status(id, Duration(days: 3));
+      if (status.isDiscontinued) numDiscontinued++;
+    }
+    if (numDiscontinued > 0) {
+      if (numDiscontinued == 1) {
+        log.message('1 package is discontinued.');
+      } else {
+        log.message('$numDiscontinued packages are discontinued.');
+      }
+    }
+  }
+
   /// Displays a two-line message, number of outdated packages and an
   /// instruction to run `pub outdated` if outdated packages are detected.
   void reportOutdated() {
diff --git a/lib/src/solver/result.dart b/lib/src/solver/result.dart
index 5b1022b..45939c8 100644
--- a/lib/src/solver/result.dart
+++ b/lib/src/solver/result.dart
@@ -109,6 +109,7 @@
         SolveReport(type, _sources, _root, _previousLockFile, this, cache);
     report.summarize(dryRun: dryRun);
     if (type == SolveType.UPGRADE) {
+      await report.reportDiscontinued();
       report.reportOutdated();
     }
   }
diff --git a/test/upgrade/report/describes_change_test.dart b/test/upgrade/report/describes_change_test.dart
index 3f05bc6..dc6f3cf 100644
--- a/test/upgrade/report/describes_change_test.dart
+++ b/test/upgrade/report/describes_change_test.dart
@@ -8,6 +8,30 @@
 import '../../test_pub.dart';
 
 void main() {
+  test('Shows count of discontinued packages', () async {
+    await servePackages((builder) {
+      builder.serve('foo', '2.0.0');
+    });
+
+    globalPackageServer.add((builder) => builder..discontinue('foo'));
+
+    // Create the first lockfile.
+    await d.appDir({'foo': '2.0.0'}).create();
+
+    await pubGet();
+
+    // Do the dry run.
+    await pubUpgrade(
+      args: ['--dry-run'],
+      output: contains('1 package is discontinued.'),
+    );
+
+    // Try without --dry-run
+    await pubUpgrade(
+      output: contains('1 package is discontinued.'),
+    );
+  });
+
   test('shows how package changed from previous lockfile', () async {
     await servePackages((builder) {
       builder.serve('unchanged', '1.0.0');