diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index 10023da7c2d..4dcaa7cf930 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -74,19 +74,26 @@ class PublishCheckCommand extends PackageLoopingCommand { @override Future runForPackage(RepositoryPackage package) async { - _PublishCheckResult? result = await _passesPublishCheck(package); - if (result == null) { + if (_isMarkedAsUnpublishable(package)) { return PackageResult.skip('Package is marked as unpublishable.'); } + + // The pre-publish hook must be run first if it exists, since passing the + // publish check may rely on its execution. + final bool prePublishHookPassesOrNoops = + await _validatePrePublishHook(package); + // Given that, don't run publish check if the pre-publish hook fails. + _PublishCheckResult result = prePublishHookPassesOrNoops + ? await _passesPublishCheck(package) + : _PublishCheckResult.error; + + // But do continue with other checks to find all problems at once. if (!_passesAuthorsCheck(package)) { _printImportantStatusMessage( 'No AUTHORS file found. Packages must include an AUTHORS file.', isError: true); result = _PublishCheckResult.error; } - if (!await _validatePrePublishHook(package)) { - result = _PublishCheckResult.error; - } if (result.index > _overallResult.index) { _overallResult = result; @@ -200,17 +207,22 @@ class PublishCheckCommand extends PackageLoopingCommand { 'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.'); } + /// Returns true if the package has been explicitly marked as not for + /// publishing. + bool _isMarkedAsUnpublishable(RepositoryPackage package) { + final Pubspec? pubspec = _tryParsePubspec(package); + return pubspec?.publishTo == 'none'; + } + /// Returns the result of the publish check, or null if the package is marked /// as unpublishable. - Future<_PublishCheckResult?> _passesPublishCheck( + Future<_PublishCheckResult> _passesPublishCheck( RepositoryPackage package) async { final String packageName = package.directory.basename; final Pubspec? pubspec = _tryParsePubspec(package); if (pubspec == null) { print('No valid pubspec found.'); return _PublishCheckResult.error; - } else if (pubspec.publishTo == 'none') { - return null; } final Version? version = pubspec.version; diff --git a/script/tool/test/publish_check_command_test.dart b/script/tool/test/publish_check_command_test.dart index a014c055e9f..0869888f058 100644 --- a/script/tool/test/publish_check_command_test.dart +++ b/script/tool/test/publish_check_command_test.dart @@ -319,6 +319,22 @@ void main() { )); }); + test('skips packages that are marked as not for publishing', () async { + createFakePackage('a_package', packagesDir, + version: '0.1.0', publishTo: 'none'); + + final List output = + await runCapturingPrint(runner, ['publish-check']); + + expect( + output, + containsAllInOrder([ + contains('SKIPPING: Package is marked as unpublishable.'), + ]), + ); + expect(processRunner.recordedCalls, isEmpty); + }); + test( 'runs validation even for packages that are already published and reports success', () async { @@ -405,6 +421,43 @@ void main() { ])); }); + test('runs before publish --dry-run', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir, examples: []); + package.prePublishScript.createSync(recursive: true); + + final List output = await runCapturingPrint(runner, [ + 'publish-check', + ]); + + expect( + output, + containsAllInOrder([ + contains('Running pre-publish hook tool/pre_publish.dart...'), + ]), + ); + expect( + processRunner.recordedCalls, + containsAllInOrder([ + ProcessCall( + 'dart', + const [ + 'run', + 'tool/pre_publish.dart', + ], + package.directory.path), + ProcessCall( + 'flutter', + const [ + 'pub', + 'publish', + '--', + '--dry-run', + ], + package.directory.path), + ])); + }); + test('causes command failure if it fails', () async { final RepositoryPackage package = createFakePackage( 'a_package', packagesDir,