From f41ecc8d7f580c7fcf7c6d2cd622d2e7083067d1 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 12 Jul 2023 08:06:29 -0400 Subject: [PATCH 1/3] [ci] Move snippet checks to LUCI Moves the check that README snippets using code excerpting are up to date to LUCI. Now that the check has been rewritten to be extremely fast, it's folded into the existing repo checks instead of being a separate task. Part of https://github.com/flutter/flutter/issues/114373 --- .ci/targets/repo_checks.yaml | 6 +++++- .cirrus.yml | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) 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. From a679040dffd46f8aed719dd0b9732aaaf060e203 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 12 Jul 2023 08:18:52 -0400 Subject: [PATCH 2/3] Update tool output --- .../tool/lib/src/update_excerpts_command.dart | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/script/tool/lib/src/update_excerpts_command.dart b/script/tool/lib/src/update_excerpts_command.dart index a3a56fcaf18..573ed72b436 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} snippets 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, From 7c27d2c7e6097f377609ad8020c6d42bbd132b09 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 12 Jul 2023 08:22:34 -0400 Subject: [PATCH 3/3] Unit test --- .../tool/lib/src/update_excerpts_command.dart | 2 +- .../test/update_excerpts_command_test.dart | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/script/tool/lib/src/update_excerpts_command.dart b/script/tool/lib/src/update_excerpts_command.dart index 573ed72b436..6904dfdf02f 100644 --- a/script/tool/lib/src/update_excerpts_command.dart +++ b/script/tool/lib/src/update_excerpts_command.dart @@ -63,7 +63,7 @@ class UpdateExcerptsCommand extends PackageLoopingCommand { if (result.snippetCount > 0) { final String displayPath = getRelativePosixPath(file, from: package.directory); - print('${indentation}Checked ${result.snippetCount} snippets in ' + print('${indentation}Checked ${result.snippetCount} snippet(s) in ' '$displayPath.'); } if (result.changed) { 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() {