diff --git a/.ci/targets/repo_checks.yaml b/.ci/targets/repo_checks.yaml index 4480a0b569c..eccc1431d5f 100644 --- a/.ci/targets/repo_checks.yaml +++ b/.ci/targets/repo_checks.yaml @@ -27,10 +27,14 @@ tasks: # to be converted. Once https://github.com/flutter/flutter/issues/102679 # has been fixed, this can be removed --require-excerpts added to the # run above. - - name: README snippet validation + - name: README snippet configuration validation script: script/tool_runner.sh args: ["readme-check", "--require-excerpts", "--exclude=script/configs/temp_exclude_excerpt.yaml"] always: true + - name: README snippet validation + script: script/tool_runner.sh + args: ["update-excerpts", "--fail-on-change"] + always: true - name: Gradle validation script: script/tool_runner.sh args: ["gradle-check"] diff --git a/.cirrus.yml b/.cirrus.yml index 63e06aa906f..eae90c68ef4 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -69,10 +69,6 @@ task: - else - ./script/tool_runner.sh federation-safety-check - fi - - name: readme_excerpts - env: - CIRRUS_CLONE_SUBMODULES: true - script: ./script/tool_runner.sh update-excerpts --fail-on-change ### Linux desktop tasks ### - name: linux-platform_tests # Don't run full platform tests on both channels in pre-submit. diff --git a/script/tool/lib/src/update_excerpts_command.dart b/script/tool/lib/src/update_excerpts_command.dart index a3a56fcaf18..6904dfdf02f 100644 --- a/script/tool/lib/src/update_excerpts_command.dart +++ b/script/tool/lib/src/update_excerpts_command.dart @@ -9,8 +9,9 @@ import 'common/package_looping_command.dart'; import 'common/repository_package.dart'; class _UpdateResult { - const _UpdateResult(this.changed, this.errors); + const _UpdateResult(this.changed, this.snippetCount, this.errors); final bool changed; + final int snippetCount; final List errors; } @@ -41,6 +42,9 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { final String description = 'Updates code excerpts in .md files, based ' 'on code from code files, via pragmas.'; + @override + bool get hasLongOutput => false; + @override Future runForPackage(RepositoryPackage package) async { final List changedFiles = []; @@ -56,6 +60,12 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { .toList(); for (final File file in markdownFiles) { final _UpdateResult result = _updateExcerptsIn(file); + if (result.snippetCount > 0) { + final String displayPath = + getRelativePosixPath(file, from: package.directory); + print('${indentation}Checked ${result.snippetCount} snippet(s) in ' + '$displayPath.'); + } if (result.changed) { changedFiles.add(file); } @@ -65,22 +75,23 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { } if (errors.isNotEmpty) { - printError('Injecting excerpts failed:'); - printError(errors.join('\n')); + printError('${indentation}Injecting excerpts failed:'); + printError(errors.join('\n$indentation')); return PackageResult.fail(); } if (getBoolArg(_failOnChangeFlag) && changedFiles.isNotEmpty) { printError( - 'The following files have out of date excerpts:\n' - ' ${changedFiles.map((File file) => file.path).join("\n ")}\n' + '${indentation}The following files have out of date excerpts:\n' + '$indentation ${changedFiles.map((File file) => file.path).join("\n$indentation ")}\n' '\n' - 'If you edited code in a .md file directly, you should instead edit the ' - 'files that contain the sources of the excerpts.\n' - 'If you did edit those source files, run the repository tooling\'s "$name" ' - 'command on this package, and update your PR with the resulting changes.\n' + '${indentation}If you edited code in a .md file directly, you should ' + 'instead edit the files that contain the sources of the excerpts.\n' + '${indentation}If you did edit those source files, run the repository ' + 'tooling\'s "$name" command on this package, and update your PR with ' + 'the resulting changes.\n' '\n' - 'For more information, see ' + '${indentation}For more information, see ' 'https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#readme-code', ); return PackageResult.fail(); @@ -98,6 +109,7 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { _UpdateResult _updateExcerptsIn(File file) { bool detectedChange = false; + int snippetCount = 0; final List errors = []; Directory pathBase = file.parent; final StringBuffer output = StringBuffer(); @@ -118,6 +130,7 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { } else { match = _injectPattern.firstMatch(line); if (match != null) { + snippetCount++; final String excerptPath = path.normalize(match.namedGroup('path')!); final File excerptSourceFile = pathBase.childFile(excerptPath); @@ -165,7 +178,9 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { errors.add( '${file.path}:$lineNumber: code block was followed by a space character instead of the language (expected "$language")'); mode = _ExcerptParseMode.injecting; - } else if (line != '```$language' && line != '```rfwtxt' && line != '```json') { + } else if (line != '```$language' && + line != '```rfwtxt' && + line != '```json') { // We special-case rfwtxt and json because the rfw package extracts such sections from Dart files. // If we get more special cases we should think about a more general solution. errors.add( @@ -204,7 +219,7 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { } } } - return _UpdateResult(detectedChange, errors); + return _UpdateResult(detectedChange, snippetCount, errors); } String _extractExcerpt(File excerptSourceFile, String section, diff --git a/script/tool/test/update_excerpts_command_test.dart b/script/tool/test/update_excerpts_command_test.dart index 1e9022afaa6..71cf836616b 100644 --- a/script/tool/test/update_excerpts_command_test.dart +++ b/script/tool/test/update_excerpts_command_test.dart @@ -417,6 +417,36 @@ Y ``` '''); }); + + test('logs snippets checked', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + package.readmeFile.writeAsStringSync(''' +Example: + + +```dart +A B C +``` +'''); + package.directory.childFile('main.dart').writeAsStringSync(''' +FAIL +// #docregion SomeSection +A B C +// #enddocregion SomeSection +FAIL +'''); + + final List output = + await runCapturingPrint(runner, ['update-excerpts']); + + expect( + output, + containsAllInOrder([ + contains('Checked 1 snippet(s) in README.md.'), + ]), + ); + }); } void main() {