| // Copyright 2013 The Flutter Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:async'; |
| |
| import 'package:file/file.dart'; |
| import 'package:meta/meta.dart'; |
| import 'package:path/path.dart' as p; |
| |
| import 'common/file_filters.dart'; |
| import 'common/package_looping_command.dart'; |
| import 'common/pub_utils.dart'; |
| import 'common/repository_package.dart'; |
| |
| /// A command to run dart fix tests for packages that have a test_fixes |
| /// directory. |
| class TestDartFixesCommand extends PackageLoopingCommand { |
| /// Creates an instance of the test dart fixes command. |
| TestDartFixesCommand(super.packagesDir, {super.processRunner, super.platform, super.gitDir}); |
| |
| /// A map of the test directory used for each package passed to runForPackage. |
| @visibleForTesting |
| final testDirectories = <String, Directory>{}; |
| |
| @override |
| final String name = 'test-dart-fixes'; |
| |
| @override |
| final String description = |
| 'Runs the Dart fix tests for all packages.\n\n' |
| 'This command requires "flutter" to be in your path.'; |
| |
| @override |
| bool shouldIgnoreFile(String path) { |
| return isRepoLevelNonCodeImpactingFile(path) || |
| isNativeCodeFile(path) || |
| isPackageSupportFile(path); |
| } |
| |
| @override |
| Future<PackageResult> runForPackage(RepositoryPackage package) async { |
| // Only run for packages that have a fix_tests directory. |
| if (!package.dartFixTestDirectory.existsSync()) { |
| final String localDartFixPath = p.relative( |
| package.dartFixTestDirectory.path, |
| from: package.directory.path, |
| ); |
| return PackageResult.skip('No $localDartFixPath directory.'); |
| } |
| |
| final Directory testDirectory; |
| try { |
| testDirectory = await _createTestDirectory(package); |
| } catch (error) { |
| return PackageResult.fail(['Failed to create temporary test directory: $error']); |
| } |
| |
| PackageResult result; |
| try { |
| final int exitCode = await _runDartFixTests(testDirectory); |
| result = exitCode == 0 |
| ? PackageResult.success() |
| : PackageResult.fail(['Dart fix tests failed.']); |
| } catch (error) { |
| result = PackageResult.fail(['Dart fix tests failed: $error']); |
| } |
| if (testDirectory.existsSync()) { |
| await testDirectory.delete(recursive: true); |
| } |
| testDirectories[package.displayName] = testDirectory; |
| return result; |
| } |
| |
| /// Create and prepare a temporary directory in which to run the dart fix |
| /// tests. |
| /// |
| /// It is the responsibility of the caller to delete this directory and its |
| /// contents when done. |
| static Future<Directory> _createTestDirectory(RepositoryPackage package) async { |
| final FileSystem fileSystem = package.directory.fileSystem; |
| final Directory testDirectory = await fileSystem.systemTempDirectory.createTemp(); |
| |
| // Copy from `test_fixes/` to the temp directory. |
| for (final FileSystemEntity entity in package.dartFixTestDirectory.listSync(recursive: true)) { |
| final String relativePath = fileSystem.path.relative( |
| entity.path, |
| from: package.dartFixTestDirectory.path, |
| ); |
| final String destPath = fileSystem.path.join(testDirectory.path, relativePath); |
| if (entity is Directory) { |
| fileSystem.directory(destPath).createSync(recursive: true); |
| } else if (entity is File) { |
| fileSystem.file(destPath).parent.createSync(recursive: true); |
| entity.copySync(destPath); |
| } |
| } |
| |
| // The pubspec.yaml file to create. |
| final File targetPubspecFile = fileSystem.file( |
| fileSystem.path.join(testDirectory.path, 'pubspec.yaml'), |
| ); |
| |
| final targetYaml = |
| ''' |
| name: test_fixes |
| publish_to: "none" |
| version: 1.0.0 |
| |
| environment: |
| sdk: ">=2.18.0 <4.0.0" |
| flutter: ">=3.3.0" |
| |
| dependencies: |
| flutter: |
| sdk: flutter |
| ${package.directory.basename}: |
| path: ${package.directory.path} |
| '''; |
| |
| await targetPubspecFile.writeAsString(targetYaml); |
| return testDirectory; |
| } |
| |
| /// Run the dart fix tests for the package in the given temporary directory. |
| /// |
| /// Resolves with the exit code of the command. |
| Future<int> _runDartFixTests(Directory testDirectory) async { |
| // Run flutter pub get in the temp directory to set it up. |
| final bool success = await runPubGet(RepositoryPackage(testDirectory), processRunner, platform); |
| |
| if (!success) { |
| throw Exception('Pub get failed.'); |
| } |
| |
| // Run dart fix --compare-to-golden in the temp directory. |
| return processRunner.runAndStream('dart', <String>[ |
| 'fix', |
| '--compare-to-golden', |
| ], workingDir: testDirectory); |
| } |
| } |