filter out SDK dependencies (#2732)

* Added test case that flutter is not listed in outdated output

* Removed SDK source depenedencies from `pub outdated`
diff --git a/lib/src/command/outdated.dart b/lib/src/command/outdated.dart
index 55eed77..b2ec58c 100644
--- a/lib/src/command/outdated.dart
+++ b/lib/src/command/outdated.dart
@@ -19,6 +19,7 @@
 import '../pubspec.dart';
 import '../pubspec_utils.dart';
 import '../solver.dart';
+import '../source/sdk.dart' show SdkSource;
 import '../system_cache.dart';
 import '../utils.dart';
 
@@ -195,7 +196,7 @@
       ...upgradablePackages,
       ...resolvablePackages
     ]) {
-      if (!visited.add(id.name)) continue;
+      if (!visited.add(id.name) || id.source is SdkSource) continue;
       rows.add(await analyzeDependency(id.toRef()));
     }
 
@@ -231,8 +232,14 @@
         showAll: showAll,
         includeDevDependencies: includeDevDependencies,
         lockFileExists: fileExists(entrypoint.lockFilePath),
-        hasDirectDependencies: rootPubspec.dependencies.isNotEmpty,
-        hasDevDependencies: rootPubspec.devDependencies.isNotEmpty,
+        hasDirectDependencies: rootPubspec.dependencies.values.any(
+          // Test if it contains non-SDK dependencies
+          (c) => c.source is! SdkSource,
+        ),
+        hasDevDependencies: rootPubspec.devDependencies.values.any(
+          // Test if it contains non-SDK dependencies
+          (c) => c.source is! SdkSource,
+        ),
         showTransitiveDependencies: showTransitiveDependencies,
       );
     }
diff --git a/test/outdated/goldens/ignores_sdk_dependencies.txt b/test/outdated/goldens/ignores_sdk_dependencies.txt
new file mode 100644
index 0000000..5a9aa55
--- /dev/null
+++ b/test/outdated/goldens/ignores_sdk_dependencies.txt
@@ -0,0 +1,194 @@
+$ pub outdated --json
+{
+  "packages": [
+    {
+      "package": "foo",
+      "current": {
+        "version": "1.1.0"
+      },
+      "upgradable": {
+        "version": "1.1.0"
+      },
+      "resolvable": {
+        "version": "2.0.0"
+      },
+      "latest": {
+        "version": "2.0.0"
+      }
+    }
+  ]
+}
+
+$ pub outdated --no-color
+Showing outdated packages.
+[*] indicates versions that are not the latest available.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           *1.1.0   *1.1.0      2.0.0       2.0.0   
+
+dev_dependencies: all up-to-date.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --no-transitive
+Showing outdated packages.
+[*] indicates versions that are not the latest available.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           *1.1.0   *1.1.0      2.0.0       2.0.0   
+
+dev_dependencies: all up-to-date.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --up-to-date
+Showing outdated packages.
+[*] indicates versions that are not the latest available.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           *1.1.0   *1.1.0      2.0.0       2.0.0   
+
+dev_dependencies: all up-to-date.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --prereleases
+Showing outdated packages.
+[*] indicates versions that are not the latest available.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           *1.1.0   *1.1.0      2.0.0       2.0.0   
+
+dev_dependencies: all up-to-date.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --no-dev-dependencies
+Showing outdated packages.
+[*] indicates versions that are not the latest available.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           *1.1.0   *1.1.0      2.0.0       2.0.0   
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --no-dependency-overrides
+Showing outdated packages.
+[*] indicates versions that are not the latest available.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           *1.1.0   *1.1.0      2.0.0       2.0.0   
+
+dev_dependencies: all up-to-date.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --mode=null-safety
+Showing dependencies that are currently not opted in to null-safety.
+[✗] indicates versions without null safety support.
+[✓] indicates versions opting in to null safety.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           ✗1.1.0   ✗1.1.0      ✗2.0.0      ✗2.0.0  
+
+dev_dependencies: all support null safety.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --mode=null-safety --transitive
+Showing dependencies that are currently not opted in to null-safety.
+[✗] indicates versions without null safety support.
+[✓] indicates versions opting in to null safety.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           ✗1.1.0   ✗1.1.0      ✗2.0.0      ✗2.0.0  
+
+dev_dependencies: all support null safety.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --no-color --mode=null-safety --no-prereleases
+Showing dependencies that are currently not opted in to null-safety.
+[✗] indicates versions without null safety support.
+[✓] indicates versions opting in to null safety.
+
+Package Name  Current  Upgradable  Resolvable  Latest  
+
+direct dependencies:
+foo           ✗1.1.0   ✗1.1.0      ✗2.0.0      ✗2.0.0  
+
+dev_dependencies: all support null safety.
+
+1 dependency is constrained to a version that is older than a resolvable version.
+To update it, edit pubspec.yaml.
+
+$ pub outdated --json --mode=null-safety
+{
+  "packages": [
+    {
+      "package": "foo",
+      "current": {
+        "version": "1.1.0",
+        "nullSafety": false
+      },
+      "upgradable": {
+        "version": "1.1.0",
+        "nullSafety": false
+      },
+      "resolvable": {
+        "version": "2.0.0",
+        "nullSafety": false
+      },
+      "latest": {
+        "version": "2.0.0",
+        "nullSafety": false
+      }
+    }
+  ]
+}
+
+$ pub outdated --json --no-dev-dependencies
+{
+  "packages": [
+    {
+      "package": "foo",
+      "current": {
+        "version": "1.1.0"
+      },
+      "upgradable": {
+        "version": "1.1.0"
+      },
+      "resolvable": {
+        "version": "2.0.0"
+      },
+      "latest": {
+        "version": "2.0.0"
+      }
+    }
+  ]
+}
+
diff --git a/test/outdated/outdated_test.dart b/test/outdated/outdated_test.dart
index f9e6c93..f10562b 100644
--- a/test/outdated/outdated_test.dart
+++ b/test/outdated/outdated_test.dart
@@ -356,4 +356,50 @@
 
     await variations('prereleases');
   });
+
+  test('ignores SDK dependencies', () async {
+    await servePackages((builder) => builder
+      ..serve('foo', '1.0.0')
+      ..serve('foo', '1.1.0')
+      ..serve('foo', '2.0.0'));
+
+    await d.dir('flutter-root', [
+      d.file('version', '1.2.3'),
+      d.dir('packages', [
+        d.dir('flutter', [
+          d.libPubspec('flutter', '1.0.0'),
+        ]),
+        d.dir('flutter_test', [
+          d.libPubspec('flutter_test', '1.0.0'),
+        ]),
+      ]),
+    ]).create();
+
+    await d.dir(appPath, [
+      d.pubspec({
+        'name': 'app',
+        'version': '1.0.1',
+        'dependencies': {
+          'foo': '^1.0.0',
+          'flutter': {
+            'sdk': 'flutter',
+          },
+        },
+        'dev_dependencies': {
+          'foo': '^1.0.0',
+          'flutter_test': {
+            'sdk': 'flutter',
+          },
+        },
+      })
+    ]).create();
+
+    await pubGet(environment: {
+      'FLUTTER_ROOT': d.path('flutter-root'),
+    });
+
+    await variations('ignores_sdk_dependencies', environment: {
+      'FLUTTER_ROOT': d.path('flutter-root'),
+    });
+  });
 }