Warn on `pub publish` if `dart analyze` has messages (#3568)
diff --git a/lib/src/log.dart b/lib/src/log.dart
index f845aa6..61c6768 100644
--- a/lib/src/log.dart
+++ b/lib/src/log.dart
@@ -8,7 +8,6 @@
import 'dart:io';
import 'package:args/command_runner.dart';
-import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart';
import 'package:stack_trace/stack_trace.dart';
@@ -341,7 +340,6 @@
/// replacing it with '[...]' if it is too long.
///
/// [limit] must be more than 5.
-@visibleForTesting
String limitLength(String input, int limit) {
const snip = '[...]';
assert(limit > snip.length);
diff --git a/lib/src/validator.dart b/lib/src/validator.dart
index ef04bc4..82de012 100644
--- a/lib/src/validator.dart
+++ b/lib/src/validator.dart
@@ -11,6 +11,7 @@
import 'entrypoint.dart';
import 'log.dart' as log;
import 'sdk.dart';
+import 'validator/analyze.dart';
import 'validator/changelog.dart';
import 'validator/compiled_dartdoc.dart';
import 'validator/dependency.dart';
@@ -130,6 +131,7 @@
required List<String> warnings,
required List<String> errors}) async {
var validators = [
+ AnalyzeValidator(),
GitignoreValidator(),
PubspecValidator(),
LicenseValidator(),
diff --git a/lib/src/validator/analyze.dart b/lib/src/validator/analyze.dart
new file mode 100644
index 0000000..b9af306
--- /dev/null
+++ b/lib/src/validator/analyze.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2022, 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 'dart:async';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+
+import '../io.dart';
+
+import '../log.dart';
+import '../validator.dart';
+
+/// Runs `dart analyze` and gives a warning if it returns non-zero.
+class AnalyzeValidator extends Validator {
+ @override
+ Future<void> validate() async {
+ final result = await runProcess(Platform.resolvedExecutable, [
+ 'analyze',
+ '--fatal-infos',
+ if (!p.equals(entrypoint.root.dir, p.current)) entrypoint.root.dir,
+ ]);
+ if (result.exitCode != 0) {
+ final limitedOutput = limitLength(result.stdout.join('\n'), 1000);
+ warnings
+ .add('`dart analyze` found the following issue(s):\n$limitedOutput');
+ }
+ }
+}
diff --git a/test/validator/analyze_test.dart b/test/validator/analyze_test.dart
new file mode 100644
index 0000000..0717b3c
--- /dev/null
+++ b/test/validator/analyze_test.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2022, 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:pub/src/exit_codes.dart';
+import 'package:test/test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+
+Future<void> expectValidation(
+ error,
+ int exitCode, {
+ List<String> extraArgs = const [],
+ Map<String, String> environment = const {},
+ String? workingDirectory,
+}) async {
+ await runPub(
+ error: error,
+ args: ['publish', '--dry-run', ...extraArgs],
+ environment: {'_PUB_TEST_SDK_VERSION': '1.12.0', ...environment},
+ workingDirectory: workingDirectory ?? d.path(appPath),
+ exitCode: exitCode,
+ );
+}
+
+void main() {
+ test('should consider a package valid if it contains no warnings or errors',
+ () async {
+ await d.dir(appPath, [
+ d.libPubspec('test_pkg', '1.0.0', sdk: '>=1.8.0 <=2.0.0'),
+ d.file('LICENSE', 'Eh, do what you want.'),
+ d.file('README.md', "This package isn't real."),
+ d.file('CHANGELOG.md', '# 1.0.0\nFirst version\n'),
+ d.dir('lib', [d.file('test_pkg.dart', 'int i = 1;')])
+ ]).create();
+
+ await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '1.12.0'});
+
+ await expectValidation(contains('Package has 0 warnings.'), 0);
+ });
+
+ test('should warn if package contains errors, and works with --directory',
+ () async {
+ await d.dir(appPath, [
+ d.libPubspec('test_pkg', '1.0.0', sdk: '>=1.8.0 <=2.0.0'),
+ d.file('LICENSE', 'Eh, do what you want.'),
+ d.file('README.md', "This package isn't real."),
+ d.file('CHANGELOG.md', '# 1.0.0\nFirst version\n'),
+ d.dir('lib', [
+ d.file('test_pkg.dart', '''
+void main() {
+// Missing }
+''')
+ ])
+ ]).create();
+
+ await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '1.12.0'});
+
+ await expectValidation(
+ allOf([
+ contains('`dart analyze` found the following issue(s):'),
+ contains('Analyzing myapp...'),
+ contains('error -'),
+ contains("Expected to find '}'."),
+ contains('Package has 1 warning.')
+ ]),
+ DATA,
+ extraArgs: ['--directory', appPath],
+ workingDirectory: d.sandbox,
+ );
+ });
+
+ test('should warn if package contains infos', () async {
+ await d.dir(appPath, [
+ d.libPubspec('test_pkg', '1.0.0', sdk: '>=1.8.0 <=2.0.0'),
+ d.file('LICENSE', 'Eh, do what you want.'),
+ d.file('README.md', "This package isn't real."),
+ d.file('CHANGELOG.md', '# 1.0.0\nFirst version\n'),
+ d.dir('lib', [
+ d.file('test_pkg.dart', '''
+void main() {
+ final a = 10; // Unused.
+}
+''')
+ ]),
+ ]).create();
+
+ await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '1.12.0'});
+
+ await expectValidation(
+ allOf([
+ contains('`dart analyze` found the following issue(s):'),
+ contains('Analyzing myapp...'),
+ contains('info -'),
+ contains("The value of the local variable 'a' isn't used"),
+ contains('Package has 1 warning.')
+ ]),
+ DATA,
+ );
+ });
+}
diff --git a/test/validator/dependency_test.dart b/test/validator/dependency_test.dart
index 69fc4a8..b3adc34 100644
--- a/test/validator/dependency_test.dart
+++ b/test/validator/dependency_test.dart
@@ -39,10 +39,10 @@
}
Future<void> expectValidationWarning(error,
- {Map<String, String> environment = const {}}) async {
+ {int count = 1, Map<String, String> environment = const {}}) async {
if (error is String) error = contains(error);
await expectValidation(
- error: allOf([error, contains('Package has 1 warning.')]),
+ error: allOf([error, contains('Package has $count warning')]),
exitCode: DATA,
environment: environment,
);
@@ -106,7 +106,9 @@
await expectValidationWarning(
allOf([
contains(' foo: any'),
+ contains("Publishable packages can't have 'git' dependencies"),
]),
+ count: 2,
environment: {'_PUB_TEST_SDK_VERSION': '2.0.0'});
});