diff --git a/script/tool/CHANGELOG.md b/script/tool/CHANGELOG.md index a8a8268c04..0e2a33e15e 100644 --- a/script/tool/CHANGELOG.md +++ b/script/tool/CHANGELOG.md @@ -2,6 +2,8 @@ - Fixes changelog validation when reverting to a `NEXT` state. - Fixes multiplication of `--force` flag when publishing multiple packages. +- Checks for template boilerplate in `readme-check`. +- `readme-check` now validates example READMEs when present. ## 0.8.5 diff --git a/script/tool/lib/src/common/package_looping_command.dart b/script/tool/lib/src/common/package_looping_command.dart index b48743be31..a295215f36 100644 --- a/script/tool/lib/src/common/package_looping_command.dart +++ b/script/tool/lib/src/common/package_looping_command.dart @@ -16,6 +16,20 @@ import 'plugin_command.dart'; import 'process_runner.dart'; import 'repository_package.dart'; +/// Enumeration options for package looping commands. +enum PackageLoopingType { + /// Only enumerates the top level packages, without including any of their + /// subpackages. + topLevelOnly, + + /// Enumerates the top level packages and any example packages they contain. + includeExamples, + + /// Enumerates all packages recursively, including both example and + /// non-example subpackages. + includeAllSubpackages, +} + /// Possible outcomes of a command run for a package. enum RunState { /// The command succeeded for the package. @@ -109,9 +123,26 @@ abstract class PackageLoopingCommand extends PluginCommand { /// Note: Consistent behavior across commands whenever possibel is a goal for /// this tool, so this should be overridden only in rare cases. Stream getPackagesToProcess() async* { - yield* includeSubpackages - ? getTargetPackagesAndSubpackages(filterExcluded: false) - : getTargetPackages(filterExcluded: false); + switch (packageLoopingType) { + case PackageLoopingType.topLevelOnly: + yield* getTargetPackages(filterExcluded: false); + break; + case PackageLoopingType.includeExamples: + await for (final PackageEnumerationEntry packageEntry + in getTargetPackages(filterExcluded: false)) { + yield packageEntry; + yield* Stream.fromIterable(packageEntry + .package + .getExamples() + .map((RepositoryPackage package) => PackageEnumerationEntry( + package, + excluded: packageEntry.excluded))); + } + break; + case PackageLoopingType.includeAllSubpackages: + yield* getTargetPackagesAndSubpackages(filterExcluded: false); + break; + } } /// Runs the command for [package], returning a list of errors. @@ -140,9 +171,9 @@ abstract class PackageLoopingCommand extends PluginCommand { /// to make the output structure easier to follow. bool get hasLongOutput => true; - /// Whether to loop over all packages (e.g., including example/), rather than - /// only top-level packages. - bool get includeSubpackages => false; + /// Whether to loop over top-level packages only, or some or all of their + /// sub-packages as well. + PackageLoopingType get packageLoopingType => PackageLoopingType.topLevelOnly; /// The text to output at the start when reporting one or more failures. /// This will be followed by a list of packages that reported errors, with diff --git a/script/tool/lib/src/pubspec_check_command.dart b/script/tool/lib/src/pubspec_check_command.dart index 23c9c00e33..3598a39da9 100644 --- a/script/tool/lib/src/pubspec_check_command.dart +++ b/script/tool/lib/src/pubspec_check_command.dart @@ -64,7 +64,8 @@ class PubspecCheckCommand extends PackageLoopingCommand { bool get hasLongOutput => false; @override - bool get includeSubpackages => true; + PackageLoopingType get packageLoopingType => + PackageLoopingType.includeAllSubpackages; @override Future runForPackage(RepositoryPackage package) async { diff --git a/script/tool/lib/src/readme_check_command.dart b/script/tool/lib/src/readme_check_command.dart index 0cb64920de..6e79b73678 100644 --- a/script/tool/lib/src/readme_check_command.dart +++ b/script/tool/lib/src/readme_check_command.dart @@ -54,34 +54,72 @@ class ReadmeCheckCommand extends PackageLoopingCommand { @override Future runForPackage(RepositoryPackage package) async { - final File readme = package.readmeFile; - - if (!readme.existsSync()) { - return PackageResult.fail(['Missing README.md']); + final List errors = _validateReadme(package.readmeFile, + mainPackage: package, isExample: false); + for (final RepositoryPackage packageToCheck in package.getExamples()) { + errors.addAll(_validateReadme(packageToCheck.readmeFile, + mainPackage: package, isExample: true)); } + // If there's an example/README.md for a multi-example package, validate + // that as well, as it will be shown on pub.dev. + final Directory exampleDir = package.directory.childDirectory('example'); + final File exampleDirReadme = exampleDir.childFile('README.md'); + if (exampleDir.existsSync() && !isPackage(exampleDir)) { + errors.addAll(_validateReadme(exampleDirReadme, + mainPackage: package, isExample: true)); + } + + return errors.isEmpty + ? PackageResult.success() + : PackageResult.fail(errors); + } + + List _validateReadme(File readme, + {required RepositoryPackage mainPackage, required bool isExample}) { + if (!readme.existsSync()) { + if (isExample) { + print('${indentation}No README for ' + '${getRelativePosixPath(readme.parent, from: mainPackage.directory)}'); + return []; + } else { + printError('${indentation}No README found at ' + '${getRelativePosixPath(readme, from: mainPackage.directory)}'); + return ['Missing README.md']; + } + } + + print('${indentation}Checking ' + '${getRelativePosixPath(readme, from: mainPackage.directory)}...'); + + final List readmeLines = readme.readAsLinesSync(); final List errors = []; - final Pubspec pubspec = package.parsePubspec(); - final bool isPlugin = pubspec.flutter?['plugin'] != null; - - final List readmeLines = package.readmeFile.readAsLinesSync(); - final String? blockValidationError = _validateCodeBlocks(readmeLines); if (blockValidationError != null) { errors.add(blockValidationError); } - if (isPlugin && (!package.isFederated || package.isAppFacing)) { - final String? error = _validateSupportedPlatforms(readmeLines, pubspec); - if (error != null) { - errors.add(error); + if (_containsTemplateBoilerplate(readmeLines)) { + printError('${indentation}The boilerplate section about getting started ' + 'with Flutter should not be left in.'); + errors.add('Contains template boilerplate'); + } + + // Check if this is the main readme for a plugin, and if so enforce extra + // checks. + if (!isExample) { + final Pubspec pubspec = mainPackage.parsePubspec(); + final bool isPlugin = pubspec.flutter?['plugin'] != null; + if (isPlugin && (!mainPackage.isFederated || mainPackage.isAppFacing)) { + final String? error = _validateSupportedPlatforms(readmeLines, pubspec); + if (error != null) { + errors.add(error); + } } } - return errors.isEmpty - ? PackageResult.success() - : PackageResult.fail(errors); + return errors; } /// Validates that code blocks (``` ... ```) follow repository standards. @@ -223,4 +261,11 @@ ${indentation * 2}Please use standard capitalizations: ${sortedListString(expect // https://github.com/flutter/flutter/issues/84200 return null; } + + /// Returns true if the README still has the boilerplate from the + /// `flutter create` templates. + bool _containsTemplateBoilerplate(List readmeLines) { + return readmeLines.any((String line) => + line.contains('For help getting started with Flutter')); + } } diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index 27a01c95e8..5101b8f19e 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -37,7 +37,8 @@ class TestCommand extends PackageLoopingCommand { 'This command requires "flutter" to be in your path.'; @override - bool get includeSubpackages => true; + PackageLoopingType get packageLoopingType => + PackageLoopingType.includeAllSubpackages; @override Future runForPackage(RepositoryPackage package) async { diff --git a/script/tool/test/common/package_looping_command_test.dart b/script/tool/test/common/package_looping_command_test.dart index 3dd6a47ae2..a7e7dfdf6e 100644 --- a/script/tool/test/common/package_looping_command_test.dart +++ b/script/tool/test/common/package_looping_command_test.dart @@ -98,7 +98,7 @@ void main() { TestPackageLoopingCommand createTestCommand({ String gitDiffResponse = '', bool hasLongOutput = true, - bool includeSubpackages = false, + PackageLoopingType packageLoopingType = PackageLoopingType.topLevelOnly, bool failsDuringInit = false, bool warnsDuringInit = false, bool warnsDuringCleanup = false, @@ -122,7 +122,7 @@ void main() { packagesDir, platform: mockPlatform, hasLongOutput: hasLongOutput, - includeSubpackages: includeSubpackages, + packageLoopingType: packageLoopingType, failsDuringInit: failsDuringInit, warnsDuringInit: warnsDuringInit, warnsDuringCleanup: warnsDuringCleanup, @@ -236,14 +236,41 @@ void main() { unorderedEquals([package1.path, package2.path])); }); - test('includes subpackages when requested', () async { + test('includes all subpackages when requested', () async { final RepositoryPackage plugin = createFakePlugin('a_plugin', packagesDir, examples: ['example1', 'example2']); final RepositoryPackage package = createFakePackage('a_package', packagesDir); + final RepositoryPackage subPackage = createFakePackage( + 'sub_package', package.directory, + examples: []); - final TestPackageLoopingCommand command = - createTestCommand(includeSubpackages: true); + final TestPackageLoopingCommand command = createTestCommand( + packageLoopingType: PackageLoopingType.includeAllSubpackages); + await runCommand(command); + + expect( + command.checkedPackages, + unorderedEquals([ + plugin.path, + getExampleDir(plugin).childDirectory('example1').path, + getExampleDir(plugin).childDirectory('example2').path, + package.path, + getExampleDir(package).path, + subPackage.path, + ])); + }); + + test('includes examples when requested', () async { + final RepositoryPackage plugin = createFakePlugin('a_plugin', packagesDir, + examples: ['example1', 'example2']); + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + final RepositoryPackage subPackage = + createFakePackage('sub_package', package.directory); + + final TestPackageLoopingCommand command = createTestCommand( + packageLoopingType: PackageLoopingType.includeExamples); await runCommand(command); expect( @@ -255,6 +282,7 @@ void main() { package.path, getExampleDir(package).path, ])); + expect(command.checkedPackages, isNot(contains(subPackage.path))); }); test('excludes subpackages when main package is excluded', () async { @@ -263,9 +291,38 @@ void main() { examples: ['example1', 'example2']); final RepositoryPackage included = createFakePackage('a_package', packagesDir); + final RepositoryPackage subpackage = + createFakePackage('sub_package', excluded.directory); - final TestPackageLoopingCommand command = - createTestCommand(includeSubpackages: true); + final TestPackageLoopingCommand command = createTestCommand( + packageLoopingType: PackageLoopingType.includeAllSubpackages); + await runCommand(command, arguments: ['--exclude=a_plugin']); + + final Iterable examples = excluded.getExamples(); + + expect( + command.checkedPackages, + unorderedEquals([ + included.path, + getExampleDir(included).path, + ])); + expect(command.checkedPackages, isNot(contains(excluded.path))); + expect(examples.length, 2); + for (final RepositoryPackage example in examples) { + expect(command.checkedPackages, isNot(contains(example.path))); + } + expect(command.checkedPackages, isNot(contains(subpackage.path))); + }); + + test('excludes examples when main package is excluded', () async { + final RepositoryPackage excluded = createFakePlugin( + 'a_plugin', packagesDir, + examples: ['example1', 'example2']); + final RepositoryPackage included = + createFakePackage('a_package', packagesDir); + + final TestPackageLoopingCommand command = createTestCommand( + packageLoopingType: PackageLoopingType.includeExamples); await runCommand(command, arguments: ['--exclude=a_plugin']); final Iterable examples = excluded.getExamples(); @@ -290,8 +347,9 @@ void main() { final RepositoryPackage included = createFakePackage('a_package', packagesDir); - final TestPackageLoopingCommand command = - createTestCommand(includeSubpackages: true, hasLongOutput: false); + final TestPackageLoopingCommand command = createTestCommand( + packageLoopingType: PackageLoopingType.includeAllSubpackages, + hasLongOutput: false); final List output = await runCommand(command, arguments: [ '--skip-if-not-supporting-flutter-version=2.5.0' ]); @@ -769,7 +827,7 @@ class TestPackageLoopingCommand extends PackageLoopingCommand { Directory packagesDir, { required Platform platform, this.hasLongOutput = true, - this.includeSubpackages = false, + this.packageLoopingType = PackageLoopingType.topLevelOnly, this.customFailureListHeader, this.customFailureListFooter, this.failsDuringInit = false, @@ -795,7 +853,7 @@ class TestPackageLoopingCommand extends PackageLoopingCommand { bool hasLongOutput; @override - bool includeSubpackages; + PackageLoopingType packageLoopingType; @override String get failureListHeader => diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index c2042c2663..f74431c5ce 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -101,15 +101,18 @@ void main() { '/packages/plugin1/pubspec.yaml', '/packages/plugin1/AUTHORS', '/packages/plugin1/CHANGELOG.md', + '/packages/plugin1/README.md', '/packages/plugin1/example/pubspec.yaml', '/packages/plugin2/pubspec.yaml', '/packages/plugin2/AUTHORS', '/packages/plugin2/CHANGELOG.md', + '/packages/plugin2/README.md', '/packages/plugin2/example/example1/pubspec.yaml', '/packages/plugin2/example/example2/pubspec.yaml', '/packages/plugin3/pubspec.yaml', '/packages/plugin3/AUTHORS', '/packages/plugin3/CHANGELOG.md', + '/packages/plugin3/README.md', ]), ); }); diff --git a/script/tool/test/readme_check_command_test.dart b/script/tool/test/readme_check_command_test.dart index f53fa06a81..fa4fc604dd 100644 --- a/script/tool/test/readme_check_command_test.dart +++ b/script/tool/test/readme_check_command_test.dart @@ -37,8 +37,33 @@ void main() { runner.addCommand(command); }); - test('fails when README is missing', () async { - createFakePackage('a_package', packagesDir); + test('prints paths of checked READMEs', () async { + final RepositoryPackage package = createFakePackage( + 'a_package', packagesDir, + examples: ['example1', 'example2']); + for (final RepositoryPackage example in package.getExamples()) { + example.readmeFile.writeAsStringSync('A readme'); + } + getExampleDir(package).childFile('README.md').writeAsStringSync('A readme'); + + final List output = + await runCapturingPrint(runner, ['readme-check']); + + expect( + output, + containsAll([ + contains(' Checking README.md...'), + contains(' Checking example/README.md...'), + contains(' Checking example/example1/README.md...'), + contains(' Checking example/example2/README.md...'), + ]), + ); + }); + + test('fails when package README is missing', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + package.readmeFile.deleteSync(); Error? commandError; final List output = await runCapturingPrint( @@ -55,6 +80,143 @@ void main() { ); }); + test('passes when example README is missing', () async { + createFakePackage('a_package', packagesDir); + + final List output = + await runCapturingPrint(runner, ['readme-check']); + + expect( + output, + containsAllInOrder([ + contains('No README for example'), + ]), + ); + }); + + test('does not inculde non-example subpackages', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + const String subpackageName = 'special_test'; + final RepositoryPackage miscSubpackage = + createFakePackage(subpackageName, package.directory); + miscSubpackage.readmeFile.delete(); + + final List output = + await runCapturingPrint(runner, ['readme-check']); + + expect(output, isNot(contains(subpackageName))); + }); + + test('fails when README still has plugin template boilerplate', () async { + final RepositoryPackage package = createFakePlugin('a_plugin', packagesDir); + package.readmeFile.writeAsStringSync(''' +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/developing-packages/), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter development, view the +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. +'''); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['readme-check'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('The boilerplate section about getting started with Flutter ' + 'should not be left in.'), + contains('Contains template boilerplate'), + ]), + ); + }); + + test('fails when example README still has application template boilerplate', + () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + package.getExamples().first.readmeFile.writeAsStringSync(''' +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. +'''); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['readme-check'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('The boilerplate section about getting started with Flutter ' + 'should not be left in.'), + contains('Contains template boilerplate'), + ]), + ); + }); + + test( + 'fails when multi-example top-level example directory README still has ' + 'application template boilerplate', () async { + final RepositoryPackage package = createFakePackage( + 'a_package', packagesDir, + examples: ['example1', 'example2']); + package.directory + .childDirectory('example') + .childFile('README.md') + .writeAsStringSync(''' +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. +'''); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['readme-check'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('The boilerplate section about getting started with Flutter ' + 'should not be left in.'), + contains('Contains template boilerplate'), + ]), + ); + }); + group('plugin OS support', () { test( 'does not check support table for anything other than app-facing plugin packages', @@ -62,20 +224,12 @@ void main() { const String federatedPluginName = 'a_federated_plugin'; final Directory federatedDir = packagesDir.childDirectory(federatedPluginName); - final List packages = [ - // A non-plugin package. - createFakePackage('a_package', packagesDir), - // Non-app-facing parts of a federated plugin. - createFakePlugin( - '${federatedPluginName}_platform_interface', federatedDir), - createFakePlugin('${federatedPluginName}_android', federatedDir), - ]; - - for (final RepositoryPackage package in packages) { - package.readmeFile.writeAsStringSync(''' -A very useful package. -'''); - } + // A non-plugin package. + createFakePackage('a_package', packagesDir); + // Non-app-facing parts of a federated plugin. + createFakePlugin( + '${federatedPluginName}_platform_interface', federatedDir); + createFakePlugin('${federatedPluginName}_android', federatedDir); final List output = await runCapturingPrint(runner, [ 'readme-check', @@ -94,12 +248,7 @@ A very useful package. test('fails when non-federated plugin is missing an OS support table', () async { - final RepositoryPackage plugin = - createFakePlugin('a_plugin', packagesDir); - - plugin.readmeFile.writeAsStringSync(''' -A very useful plugin. -'''); + createFakePlugin('a_plugin', packagesDir); Error? commandError; final List output = await runCapturingPrint( @@ -119,12 +268,7 @@ A very useful plugin. test( 'fails when app-facing part of a federated plugin is missing an OS support table', () async { - final RepositoryPackage plugin = - createFakePlugin('a_plugin', packagesDir.childDirectory('a_plugin')); - - plugin.readmeFile.writeAsStringSync(''' -A very useful plugin. -'''); + createFakePlugin('a_plugin', packagesDir.childDirectory('a_plugin')); Error? commandError; final List output = await runCapturingPrint( diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index effdd03891..7255bf9a92 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -125,7 +125,7 @@ RepositoryPackage createFakePlugin( /// separators, of extra files to create in the package. /// /// If [includeCommonFiles] is true, common but non-critical files like -/// CHANGELOG.md and AUTHORS will be included. +/// CHANGELOG.md, README.md, and AUTHORS will be included. /// /// If non-null, [directoryName] will be used for the directory instead of /// [name]. @@ -152,11 +152,12 @@ RepositoryPackage createFakePackage( version: version, flutterConstraint: flutterConstraint); if (includeCommonFiles) { - createFakeCHANGELOG(package, ''' + package.changelogFile.writeAsStringSync(''' ## $version * Some changes. '''); - createFakeAuthors(package); + package.readmeFile.writeAsStringSync('A very useful package'); + package.authorsFile.writeAsStringSync('Google Inc.'); } if (examples.length == 1) { @@ -188,11 +189,6 @@ RepositoryPackage createFakePackage( return package; } -void createFakeCHANGELOG(RepositoryPackage package, String texts) { - package.changelogFile.createSync(); - package.changelogFile.writeAsStringSync(texts); -} - /// Creates a `pubspec.yaml` file with a flutter dependency. /// /// [platformSupport] is a map of platform string to the support details for @@ -267,11 +263,6 @@ $pluginSection package.pubspecFile.writeAsStringSync(yaml); } -void createFakeAuthors(RepositoryPackage package) { - package.authorsFile.createSync(); - package.authorsFile.writeAsStringSync('Google Inc.'); -} - String _pluginPlatformSection( String platform, PlatformDetails support, String packageName) { String entry = ''; diff --git a/script/tool/test/version_check_command_test.dart b/script/tool/test/version_check_command_test.dart index 6af3c112f9..a310f0f09f 100644 --- a/script/tool/test/version_check_command_test.dart +++ b/script/tool/test/version_check_command_test.dart @@ -421,7 +421,7 @@ This is necessary because of X, Y, and Z ## $version * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); final List output = await runCapturingPrint( runner, ['version-check', '--base-sha=main']); expect( @@ -439,7 +439,7 @@ This is necessary because of X, Y, and Z ## 1.0.2 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); Error? commandError; final List output = await runCapturingPrint( runner, ['version-check', '--base-sha=main', '--against-pub'], @@ -465,7 +465,7 @@ This is necessary because of X, Y, and Z ## $version * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); final List output = await runCapturingPrint( runner, ['version-check', '--base-sha=main']); expect( @@ -488,7 +488,7 @@ This is necessary because of X, Y, and Z ## 1.0.0 * Some other changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); bool hasError = false; final List output = await runCapturingPrint( runner, ['version-check', '--base-sha=main', '--against-pub'], @@ -518,7 +518,7 @@ This is necessary because of X, Y, and Z ## $version * Some other changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -547,7 +547,7 @@ This is necessary because of X, Y, and Z ## 1.0.0 * Some other changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); bool hasError = false; final List output = await runCapturingPrint( runner, ['version-check', '--base-sha=main', '--against-pub'], @@ -580,7 +580,7 @@ This is necessary because of X, Y, and Z ## 1.0.0 * Some other changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); bool hasError = false; final List output = await runCapturingPrint( @@ -612,7 +612,7 @@ This is necessary because of X, Y, and Z ## 1.0.0 * Some other changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); bool hasError = false; final List output = await runCapturingPrint( @@ -642,8 +642,8 @@ This is necessary because of X, Y, and Z ## 1.0.0 * Some other changes. '''; - createFakeCHANGELOG(plugin, changelog); - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.1'), ]; @@ -671,7 +671,7 @@ This is necessary because of X, Y, and Z # 1.0.0 * Some other changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -704,7 +704,7 @@ This is necessary because of X, Y, and Z ## Alpha * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -749,7 +749,7 @@ This is necessary because of X, Y, and Z ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -778,7 +778,7 @@ This is necessary because of X, Y, and Z ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -813,7 +813,7 @@ packages/plugin/lib/plugin.dart ## 1.0.1 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -844,7 +844,7 @@ packages/plugin/pubspec.yaml ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -874,7 +874,7 @@ tool/plugin/lib/plugin.dart ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -907,7 +907,7 @@ packages/plugin/CHANGELOG.md ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -948,7 +948,7 @@ No version change: Code change is only to implementation comments. ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -983,7 +983,7 @@ packages/plugin/example/lib/foo.dart ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -1014,7 +1014,7 @@ packages/plugin/CHANGELOG.md ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ]; @@ -1048,7 +1048,7 @@ packages/another_plugin/CHANGELOG.md ## 1.0.0 * Some changes. '''; - createFakeCHANGELOG(plugin, changelog); + plugin.changelogFile.writeAsStringSync(changelog); processRunner.mockProcessesForExecutable['git-show'] = [ MockProcess(stdout: 'version: 1.0.0'), ];