outdated --mode=null-safety, resolvable constrained to null-safe vers… (#2739)
From offline discussions we saw that this gives:
```
> env FLUTTER_ROOT=$HOME/projects/flutter dart ~/projects/pub/bin/pub.dart outdated --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:
adaptive_breakpoints ✗0.0.3 ✗0.0.3 ✗0.0.3 ✗0.0.3
animations ✗1.1.2 ✗1.1.2 ✗1.1.2 ✗1.1.2
flare_dart ✗2.3.4 ✗2.3.4 ✗2.3.4 ✗2.3.4
flare_flutter ✗2.0.6 ✗2.0.6 ✗2.0.6 ✗2.0.6
flutter_gallery_assets ✗0.2.6 ✗0.2.6 ✗0.2.6 ✗0.2.6
flutter_localized_locales ✗1.1.2 ✓2.0.0-nullsafety ✓2.0.0-nullsafety ✓2.0.0-nullsafety
flutter_staggered_grid_view ✗0.3.2 ✗0.3.2 ✗0.3.2 ✗0.3.2
google_fonts ✗1.1.1 ✗1.1.1 ✗1.1.1 ✗1.1.1
intl ✗0.16.1 ✓0.17.0-nullsafety.2 ✓0.17.0-nullsafety.2 ✓0.17.0-nullsafety.2
package_info ✗0.4.3+2 ✗0.4.3+2 ✗0.4.3+2 ✗0.4.3+2
provider ✗4.3.2+2 ✗4.3.2+2 ✗4.3.2+2 ✗4.3.2+2
rally_assets ✗2.0.0 ✗2.0.0 ✗2.0.0 ✗2.0.0
scoped_model ✗1.1.0 ✗1.1.0 ✗1.1.0 ✗1.1.0
shared_preferences ✗0.5.12+4 ✗0.5.12+4 ✗0.5.12+4 ✗0.5.12+4
shrine_images ✗1.1.2 ✗1.1.2 ✗1.1.2 ✗1.1.2
url_launcher ✗5.7.10 ✗5.7.10 ✓6.0.0-nullsafety.1 ✓6.0.0-nullsafety.1
dev_dependencies:
args ✗1.6.0 ✗1.6.0 ✗1.6.0 ✗1.6.0
grinder ✗0.8.6 ✗0.8.6 ✗0.8.6 ✗0.8.6
web_benchmarks ✗0.0.2 ✗0.0.2 ✗0.0.2 ✗0.0.2
2 upgradable dependencies are locked (in pubspec.lock) to older versions.
To update these dependencies, use `pub upgrade`.
1 dependency is constrained to a version that is older than a resolvable version.
To update it, edit pubspec.yaml.
```
which is ok,
Landing.
Travis failure seems to be an unrelated flake
diff --git a/lib/src/command/outdated.dart b/lib/src/command/outdated.dart
index be0a6a5..f033036 100644
--- a/lib/src/command/outdated.dart
+++ b/lib/src/command/outdated.dart
@@ -105,6 +105,12 @@
@override
Future<void> runProtected() async {
+ final mode = <String, Mode>{
+ 'outdated': _OutdatedMode(),
+ 'null-safety': _NullSafetyMode(cache, entrypoint,
+ shouldShowSpinner: _shouldShowSpinner),
+ }[argResults['mode']];
+
final includeDevDependencies = argResults['dev-dependencies'];
final includeDependencyOverrides = argResults['dependency-overrides'];
if (argResults['json'] && argResults.wasParsed('transitive')) {
@@ -120,7 +126,7 @@
? rootPubspec
: stripDevDependencies(rootPubspec);
- final resolvablePubspec = stripVersionUpperBounds(upgradablePubspec);
+ final resolvablePubspec = await mode.resolvablePubspec(upgradablePubspec);
List<PackageId> upgradablePackages;
List<PackageId> resolvablePackages;
@@ -221,11 +227,7 @@
}
rows.sort();
- final mode = <String, Mode>{
- 'outdated': _OutdatedMode(),
- 'null-safety': _NullSafetyMode(cache, entrypoint,
- shouldShowSpinner: _shouldShowSpinner),
- }[argResults['mode']];
+
final showAll = argResults['show-all'] || argResults['up-to-date'];
if (argResults['json']) {
await _outputJson(
@@ -587,6 +589,8 @@
String get explanation;
String get foundNoBadText;
String get allGood;
+
+ Future<Pubspec> resolvablePubspec(Pubspec pubspec);
}
class _OutdatedMode implements Mode {
@@ -642,6 +646,11 @@
}
return rows;
}
+
+ @override
+ Future<Pubspec> resolvablePubspec(Pubspec pubspec) async {
+ return stripVersionUpperBounds(pubspec);
+ }
}
class _NullSafetyMode implements Mode {
@@ -732,6 +741,11 @@
).toList()
];
}
+
+ @override
+ Future<Pubspec> resolvablePubspec(Pubspec pubspec) async {
+ return constrainedToAtLeastNullSafetyPubspec(pubspec, cache);
+ }
}
/// Details about a single version of a package.
diff --git a/lib/src/pubspec_utils.dart b/lib/src/pubspec_utils.dart
index 032ce63..2341887 100644
--- a/lib/src/pubspec_utils.dart
+++ b/lib/src/pubspec_utils.dart
@@ -8,6 +8,7 @@
import 'package_name.dart';
import 'pubspec.dart';
import 'source/hosted.dart';
+import 'system_cache.dart';
/// Returns a new [Pubspec] without [original]'s dev_dependencies.
Pubspec stripDevDependencies(Pubspec original) {
@@ -37,6 +38,65 @@
);
}
+Future<Pubspec> constrainedToAtLeastNullSafetyPubspec(
+ Pubspec original, SystemCache cache) async {
+ /// Get the first version of [package] opting in to null-safety.
+ Future<VersionRange> constrainToFirstWithNullSafety(
+ PackageRange packageRange) async {
+ final ref = packageRange.toRef();
+ final available = await cache.source(ref.source).getVersions(ref);
+ if (available.isEmpty) {
+ return stripUpperBound(packageRange.constraint);
+ }
+
+ available.sort((x, y) => x.version.compareTo(y.version));
+
+ for (final p in available) {
+ final pubspec = await cache.source(ref.source).describe(p);
+ if (pubspec.languageVersion.supportsNullSafety) {
+ return VersionRange(min: p.version, includeMin: true);
+ }
+ }
+ return stripUpperBound(packageRange.constraint);
+ }
+
+ Future<List<PackageRange>> allConstrainedToAtLeastNullSafety(
+ Map<String, PackageRange> constrained,
+ ) async {
+ final result = await Future.wait(constrained.keys.map((name) async {
+ final packageRange = constrained[name];
+ var unconstrainedRange = packageRange;
+
+ /// We only need to remove the upper bound if it is a hosted package.
+ if (packageRange.source is HostedSource) {
+ unconstrainedRange = PackageRange(
+ packageRange.name,
+ packageRange.source,
+ await constrainToFirstWithNullSafety(packageRange),
+ packageRange.description,
+ features: packageRange.features);
+ }
+ return unconstrainedRange;
+ }));
+
+ return result;
+ }
+
+ final constrainedLists = await Future.wait([
+ allConstrainedToAtLeastNullSafety(original.dependencies),
+ allConstrainedToAtLeastNullSafety(original.devDependencies),
+ ]);
+
+ return Pubspec(
+ original.name,
+ version: original.version,
+ sdkConstraints: original.sdkConstraints,
+ dependencies: constrainedLists[0],
+ devDependencies: constrainedLists[1],
+ dependencyOverrides: original.dependencyOverrides.values,
+ );
+}
+
/// Returns new pubspec with the same dependencies as [original] but with the
/// upper bounds of the constraints removed.
///
diff --git a/test/outdated/goldens/null_safety.txt b/test/outdated/goldens/null_safety.txt
index 212cc22..909c0cb 100644
--- a/test/outdated/goldens/null_safety.txt
+++ b/test/outdated/goldens/null_safety.txt
@@ -10,7 +10,7 @@
"version": "1.0.0"
},
"resolvable": {
- "version": "1.0.0"
+ "version": "2.0.0"
},
"latest": {
"version": "2.0.0"
@@ -85,7 +85,7 @@
"version": "1.0.0"
},
"resolvable": {
- "version": "2.0.0"
+ "version": "2.0.0-nullsafety.0"
},
"latest": {
"version": "2.0.0"
@@ -98,102 +98,102 @@
Showing outdated packages.
[*] indicates versions that are not the latest available.
-Package Name Current Upgradable Resolvable Latest
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar *1.0.0 *1.0.0 *1.0.0 2.0.0
-fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
-fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
-file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-foo *1.0.0 *1.0.0 2.0.0 2.0.0
+bar *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
+file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+foo *1.0.0 *1.0.0 *2.0.0-nullsafety.0 2.0.0
-5 dependencies are constrained to versions that are older than a resolvable version.
+6 dependencies are constrained to versions that are older than a resolvable version.
To update these dependencies, 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
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar *1.0.0 *1.0.0 *1.0.0 2.0.0
-fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
-fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
-file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-foo *1.0.0 *1.0.0 2.0.0 2.0.0
+bar *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
+file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+foo *1.0.0 *1.0.0 *2.0.0-nullsafety.0 2.0.0
-5 dependencies are constrained to versions that are older than a resolvable version.
+6 dependencies are constrained to versions that are older than a resolvable version.
To update these dependencies, 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
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar *1.0.0 *1.0.0 *1.0.0 2.0.0
-fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
-fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
-file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-foo *1.0.0 *1.0.0 2.0.0 2.0.0
+bar *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
+file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+foo *1.0.0 *1.0.0 *2.0.0-nullsafety.0 2.0.0
-5 dependencies are constrained to versions that are older than a resolvable version.
+6 dependencies are constrained to versions that are older than a resolvable version.
To update these dependencies, 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
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar *1.0.0 *1.0.0 *1.0.0 2.0.0
-fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
-fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
-file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-foo *1.0.0 *1.0.0 2.0.0 2.0.0
+bar *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
+file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+foo *1.0.0 *1.0.0 *2.0.0-nullsafety.0 2.0.0
-5 dependencies are constrained to versions that are older than a resolvable version.
+6 dependencies are constrained to versions that are older than a resolvable version.
To update these dependencies, 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
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar *1.0.0 *1.0.0 *1.0.0 2.0.0
-fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
-fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
-file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-foo *1.0.0 *1.0.0 2.0.0 2.0.0
+bar *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
+file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+foo *1.0.0 *1.0.0 *2.0.0-nullsafety.0 2.0.0
-5 dependencies are constrained to versions that are older than a resolvable version.
+6 dependencies are constrained to versions that are older than a resolvable version.
To update these dependencies, 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
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar *1.0.0 *1.0.0 *1.0.0 2.0.0
-fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
-fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
-file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
-foo *1.0.0 *1.0.0 2.0.0 2.0.0
+bar *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis *1.0.0 *1.0.0 2.0.0 2.0.0
+fails_analysis_in_dependency *1.0.0 *1.0.0 2.0.0 2.0.0
+file_in_dependency_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+file_opts_out *1.0.0 *1.0.0 2.0.0 2.0.0
+foo *1.0.0 *1.0.0 *2.0.0-nullsafety.0 2.0.0
-5 dependencies are constrained to versions that are older than a resolvable version.
+6 dependencies are constrained to versions that are older than a resolvable version.
To update these dependencies, edit pubspec.yaml.
$ pub outdated --no-color --mode=null-safety
@@ -201,42 +201,42 @@
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.
-Package Name Current Upgradable Resolvable Latest
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar ✗1.0.0 ✗1.0.0 ✗1.0.0 ✓2.0.0
-foo ✗1.0.0 ✗1.0.0 ✓2.0.0 ✓2.0.0
+bar ✗1.0.0 ✗1.0.0 ✓2.0.0 ✓2.0.0
+foo ✗1.0.0 ✗1.0.0 ✓2.0.0-nullsafety.0 ✓2.0.0
-1 dependency is constrained to a version that is older than a resolvable version.
-To update it, edit pubspec.yaml.
+2 dependencies are constrained to versions that are older than a resolvable version.
+To update these dependencies, 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
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar ✗1.0.0 ✗1.0.0 ✗1.0.0 ✓2.0.0
-foo ✗1.0.0 ✗1.0.0 ✓2.0.0 ✓2.0.0
+bar ✗1.0.0 ✗1.0.0 ✓2.0.0 ✓2.0.0
+foo ✗1.0.0 ✗1.0.0 ✓2.0.0-nullsafety.0 ✓2.0.0
-1 dependency is constrained to a version that is older than a resolvable version.
-To update it, edit pubspec.yaml.
+2 dependencies are constrained to versions that are older than a resolvable version.
+To update these dependencies, 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
+Package Name Current Upgradable Resolvable Latest
direct dependencies:
-bar ✗1.0.0 ✗1.0.0 ✗1.0.0 ✓2.0.0
-foo ✗1.0.0 ✗1.0.0 ✓2.0.0 ✓2.0.0
+bar ✗1.0.0 ✗1.0.0 ✓2.0.0 ✓2.0.0
+foo ✗1.0.0 ✗1.0.0 ✓2.0.0-nullsafety.0 ✓2.0.0
-1 dependency is constrained to a version that is older than a resolvable version.
-To update it, edit pubspec.yaml.
+2 dependencies are constrained to versions that are older than a resolvable version.
+To update these dependencies, edit pubspec.yaml.
$ pub outdated --json --mode=null-safety
{
@@ -252,8 +252,8 @@
"nullSafety": false
},
"resolvable": {
- "version": "1.0.0",
- "nullSafety": false
+ "version": "2.0.0",
+ "nullSafety": true
},
"latest": {
"version": "2.0.0",
@@ -271,7 +271,7 @@
"nullSafety": false
},
"resolvable": {
- "version": "2.0.0",
+ "version": "2.0.0-nullsafety.0",
"nullSafety": true
},
"latest": {
@@ -294,7 +294,7 @@
"version": "1.0.0"
},
"resolvable": {
- "version": "1.0.0"
+ "version": "2.0.0"
},
"latest": {
"version": "2.0.0"
@@ -369,7 +369,7 @@
"version": "1.0.0"
},
"resolvable": {
- "version": "2.0.0"
+ "version": "2.0.0-nullsafety.0"
},
"latest": {
"version": "2.0.0"
diff --git a/test/outdated/outdated_test.dart b/test/outdated/outdated_test.dart
index f10562b..d110142 100644
--- a/test/outdated/outdated_test.dart
+++ b/test/outdated/outdated_test.dart
@@ -206,6 +206,11 @@
..serve('bar', '1.0.0', pubspec: {
'environment': {'sdk': '>=2.9.0 < 3.0.0'}
})
+ ..serve('foo', '2.0.0-nullsafety.0', deps: {
+ 'bar': '^2.0.0'
+ }, pubspec: {
+ 'environment': {'sdk': '>=2.12.0 < 3.0.0'}
+ })
..serve('foo', '2.0.0', deps: {
'bar': '^1.0.0'
}, pubspec: {