Do not show advisories text if no version is affected (#4157)
diff --git a/lib/src/command/outdated.dart b/lib/src/command/outdated.dart
index 40d84fd..d0a42f1 100644
--- a/lib/src/command/outdated.dart
+++ b/lib/src/command/outdated.dart
@@ -676,10 +676,31 @@
}
}
+ List<Advisory> advisoriesWithAffectedVersions(_PackageDetails package) {
+ return package.advisories
+ .where(
+ (advisory) => advisory.affectedVersions
+ .intersection(
+ [
+ package.current,
+ package.upgradable,
+ package.resolvable,
+ package.latest,
+ ].map((e) => e?._pubspec.version.canonicalizedVersion).toSet(),
+ )
+ .isNotEmpty,
+ )
+ .toList();
+ }
+
+ var advisoriesToDisplay = <String, List<Advisory>>{};
+ for (final package in rows) {
+ advisoriesToDisplay[package.name] = advisoriesWithAffectedVersions(package);
+ }
bool displayExtraInfo(_PackageDetails package) =>
package.isDiscontinued ||
package.isCurrentRetracted ||
- (package.advisories.isNotEmpty);
+ (advisoriesToDisplay[package.name]!.isNotEmpty);
if (rows.any(displayExtraInfo)) {
log.message('\n');
@@ -700,8 +721,9 @@
'See https://dart.dev/go/package-retraction',
);
}
- if (package.advisories.isNotEmpty) {
- final advisoriesText = package.advisories.length > 1
+ var displayedAdvisories = advisoriesToDisplay[package.name]!;
+ if (displayedAdvisories.isNotEmpty) {
+ final advisoriesText = displayedAdvisories.length > 1
? 'security advisories'
: 'a security advisory';
log.message(
@@ -709,21 +731,16 @@
'See https://dart.dev//go/pub-security-advisories',
);
log.message('\n');
- for (final advisory in package.advisories) {
- final displayedVersions = <String>{};
- for (final versionDetails in [
- package.current,
- package.upgradable,
- package.resolvable,
- package.latest,
- ]) {
- final version =
- versionDetails?._pubspec.version.canonicalizedVersion;
- if (version != null &&
- advisory.affectedVersions.contains(version)) {
- displayedVersions.add(version);
- }
- }
+
+ for (final advisory in displayedAdvisories) {
+ var displayedVersions = advisory.affectedVersions.intersection(
+ [
+ package.current,
+ package.upgradable,
+ package.resolvable,
+ package.latest,
+ ].map((e) => e?._pubspec.version.canonicalizedVersion).toSet(),
+ );
log.message(' - "${advisory.summary}"');
log.message(' Affects: ${displayedVersions.join(', ')}');
log.message(' ${advisoriesDisplayUrl(advisory.id)}');
diff --git a/lib/src/source/hosted.dart b/lib/src/source/hosted.dart
index c078cb5..aa8ed7b 100644
--- a/lib/src/source/hosted.dart
+++ b/lib/src/source/hosted.dart
@@ -680,7 +680,7 @@
'Advisory $id does not contain $packageName among its affected packages.',
);
}
- var affectedVersions = <String>[];
+ final affectedVersions = <String>{};
final versions = affectedPkg['versions'];
if (versions is! List) {
throw FormatException('package versions must be a list');
@@ -1810,7 +1810,7 @@
/// is retrieved from /api/packages/$package/advisories
class Advisory {
String id;
- List<String> affectedVersions;
+ Set<String> affectedVersions;
List<String> aliases;
String summary;
Advisory(this.id, this.affectedVersions, this.aliases, this.summary);
diff --git a/test/outdated/outdated_test.dart b/test/outdated/outdated_test.dart
index aa8affa..2034ca8 100644
--- a/test/outdated/outdated_test.dart
+++ b/test/outdated/outdated_test.dart
@@ -449,7 +449,32 @@
advisoryId: 'VXYZ-1234-5678-9101',
affectedVersions: ['1.0.0'],
);
+ builder.serve('foo', '1.2.0');
+ await ctx.runOutdatedTests();
+ });
+ testWithGolden('do not show advisories if no version is affected',
+ (ctx) async {
+ final builder = await servePackages();
+ builder
+ ..serve('foo', '1.0.0', deps: {'transitive': '^1.0.0'})
+ ..serve('transitive', '1.2.3');
+
+ await d.dir(appPath, [
+ d.pubspec({
+ 'name': 'app',
+ 'dependencies': {
+ 'foo': '^1.0.0',
+ },
+ }),
+ ]).create();
+ await pubGet();
+
+ builder.affectVersionsByAdvisory(
+ packageName: 'foo',
+ advisoryId: 'ABCD-1234-5678-9101',
+ affectedVersions: ['0.1.0'],
+ );
builder.serve('foo', '1.2.0');
await ctx.runOutdatedTests();
});
diff --git a/test/testdata/goldens/outdated/outdated_test/do not show advisories if no version is affected.txt b/test/testdata/goldens/outdated/outdated_test/do not show advisories if no version is affected.txt
new file mode 100644
index 0000000..e19e537
--- /dev/null
+++ b/test/testdata/goldens/outdated/outdated_test/do not show advisories if no version is affected.txt
@@ -0,0 +1,146 @@
+# GENERATED BY: test/outdated/outdated_test.dart
+
+## Section 0
+$ pub outdated --json
+{
+ "packages": [
+ {
+ "package": "foo",
+ "kind": "direct",
+ "isDiscontinued": false,
+ "isCurrentRetracted": false,
+ "isCurrentAffectedByAdvisory": false,
+ "current": {
+ "version": "1.0.0"
+ },
+ "upgradable": {
+ "version": "1.2.0"
+ },
+ "resolvable": {
+ "version": "1.2.0"
+ },
+ "latest": {
+ "version": "1.2.0"
+ }
+ }
+ ]
+}
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+## Section 1
+$ 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.0.0 1.2.0 1.2.0 1.2.0
+
+1 upgradable dependency is locked (in pubspec.lock) to an older version.
+To update it, use `dart pub upgrade`.
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+## Section 2
+$ 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.0.0 1.2.0 1.2.0 1.2.0
+
+1 upgradable dependency is locked (in pubspec.lock) to an older version.
+To update it, use `dart pub upgrade`.
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+## Section 3
+$ 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.0.0 1.2.0 1.2.0 1.2.0
+
+1 upgradable dependency is locked (in pubspec.lock) to an older version.
+To update it, use `dart pub upgrade`.
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+## Section 4
+$ 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.0.0 1.2.0 1.2.0 1.2.0
+
+1 upgradable dependency is locked (in pubspec.lock) to an older version.
+To update it, use `dart pub upgrade`.
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+## Section 5
+$ 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.0.0 1.2.0 1.2.0 1.2.0
+
+1 upgradable dependency is locked (in pubspec.lock) to an older version.
+To update it, use `dart pub upgrade`.
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+## Section 6
+$ 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.0.0 1.2.0 1.2.0 1.2.0
+
+1 upgradable dependency is locked (in pubspec.lock) to an older version.
+To update it, use `dart pub upgrade`.
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+## Section 7
+$ pub outdated --json --no-dev-dependencies
+{
+ "packages": [
+ {
+ "package": "foo",
+ "kind": "direct",
+ "isDiscontinued": false,
+ "isCurrentRetracted": false,
+ "isCurrentAffectedByAdvisory": false,
+ "current": {
+ "version": "1.0.0"
+ },
+ "upgradable": {
+ "version": "1.2.0"
+ },
+ "resolvable": {
+ "version": "1.2.0"
+ },
+ "latest": {
+ "version": "1.2.0"
+ }
+ }
+ ]
+}
+