diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/tool/run_tests.dart b/packages/google_maps_flutter/google_maps_flutter_ios/tool/run_tests.dart index f86778c0c2a1..f49c29eaf7fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/tool/run_tests.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/tool/run_tests.dart @@ -33,45 +33,12 @@ Future main(List args) async { p.join(packageRoot.parent.path, 'google_maps_flutter_ios_shared_code'), ); - var failed = false; - for (final FileSystemEntity entity in sharedSourceRoot.listSync( - recursive: true, - )) { - if (entity is! File) { - continue; - } - final String relativePath = p.relative( - entity.path, - from: sharedSourceRoot.path, - ); - // The shared source README.md is not part of the shared source of truth, - // just an explanation of this source-sharing system. - if (relativePath == 'README.md') { - continue; - } - - // Adjust the paths to account for the package name being part of the - // directory structure for Swift packages. - final String packagePath = p.join( - packageRoot.path, - packageRelativePathForSharedSourceRelativePath(packageName, relativePath), - ); - - print('Validating $relativePath'); - final packageFile = File(packagePath); - if (!packageFile.existsSync()) { - print(' File $relativePath does not exist in $packageName'); - failed = true; - continue; - } - final String expectedContents = normalizedFileContents(entity); - final String contents = normalizedFileContents(packageFile); - if (contents != expectedContents) { - print(' File $relativePath does not match expected contents:'); - await _printDiff(entity, packageFile); - failed = true; - } - } + bool passesValidation = await _validatePackageSharedCode( + packageRoot, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: true, + ); print( '\nChecking for unshared source files that are not in ' @@ -85,13 +52,13 @@ Future main(List args) async { if (unsharedFiles.isEmpty) { print(' No unexpected unshared files.'); } else { - failed = true; + passesValidation = false; for (final file in unsharedFiles) { print(' $file is not shared'); } } - if (failed) { + if (!passesValidation) { print(''' If the changes you made should be shared with other copies of the @@ -105,11 +72,115 @@ approach to sharing as much code as can still be shared. For more information on the code sharing structure used by this package, see the google_maps_flutter_ios_shared_code/README.md file. - '''); +'''); + exit(1); + } + + // If everything else passed, sanity-check the other implementation packages. + // Full diff evaluation is done by the copy of this script in each + // implementation package, but if someone edits the shared code without + // updating the other packages, this will catch it. This is useful both + // locally, where people are unlikely to run the tests in every package, and + // in CI, where if there are no changes to an implementation package the CI + // for that package will be skipped. + print('\nChecking other implementation packages...'); + final failingPackages = []; + for (final FileSystemEntity entity in packageRoot.parent.listSync()) { + final String packageName = p.basename(entity.path); + if (entity is! Directory || + !packageName.startsWith('google_maps_flutter_ios_') || + packageName == 'google_maps_flutter_ios_shared_code') { + continue; + } + if (!await _validatePackageSharedCode( + entity, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: false, + )) { + failingPackages.add(packageName); + } + } + + if (failingPackages.isEmpty) { + print(' No unexpected diffs found.'); + } else { + print(''' + The following packages do not match the shared source code: +${failingPackages.map((p) => ' $p').join('\n')} + +If you manually synchronized changes to the shared code, you will also need to +copy those changes to the other implementation packages. In the future, consider +using sync_shared_files.dart instead of copying changes to the shared source +manually. +'''); exit(1); } } +/// Validates that the shared code in [packageRoot] matches the shared source of +/// truth. +/// +/// Returns true if the package matches the shared source of truth. +Future _validatePackageSharedCode( + Directory packageRoot, + String packageName, { + required Directory sharedSourceRoot, + required bool log, +}) async { + var hasDiffs = false; + for (final FileSystemEntity entity in sharedSourceRoot.listSync( + recursive: true, + )) { + if (entity is! File) { + continue; + } + final String relativePath = p.relative( + entity.path, + from: sharedSourceRoot.path, + ); + // The shared source README.md is not part of the shared source of truth, + // just an explanation of this source-sharing system. + if (relativePath == 'README.md') { + continue; + } + // Ignore .DS_Store files, which may be created in the shared source + // directory by the OS. + if (relativePath.endsWith('.DS_Store')) { + continue; + } + + // Adjust the paths to account for the package name being part of the + // directory structure for Swift packages. + final String packagePath = p.join( + packageRoot.path, + packageRelativePathForSharedSourceRelativePath(packageName, relativePath), + ); + + if (log) { + print('Validating $relativePath'); + } + final packageFile = File(packagePath); + if (!packageFile.existsSync()) { + if (log) { + print(' File $relativePath does not exist in $packageName'); + } + hasDiffs = true; + continue; + } + final String expectedContents = normalizedFileContents(entity); + final String contents = normalizedFileContents(packageFile); + if (contents != expectedContents) { + if (log) { + print(' File $relativePath does not match expected contents:'); + await _printDiff(entity, packageFile); + } + hasDiffs = true; + } + } + return !hasDiffs; +} + Future _printDiff(File expected, File actual) async { final Process process = await Process.start('diff', [ '-u', diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/tool/run_tests.dart b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/tool/run_tests.dart index f86778c0c2a1..f49c29eaf7fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/tool/run_tests.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/tool/run_tests.dart @@ -33,45 +33,12 @@ Future main(List args) async { p.join(packageRoot.parent.path, 'google_maps_flutter_ios_shared_code'), ); - var failed = false; - for (final FileSystemEntity entity in sharedSourceRoot.listSync( - recursive: true, - )) { - if (entity is! File) { - continue; - } - final String relativePath = p.relative( - entity.path, - from: sharedSourceRoot.path, - ); - // The shared source README.md is not part of the shared source of truth, - // just an explanation of this source-sharing system. - if (relativePath == 'README.md') { - continue; - } - - // Adjust the paths to account for the package name being part of the - // directory structure for Swift packages. - final String packagePath = p.join( - packageRoot.path, - packageRelativePathForSharedSourceRelativePath(packageName, relativePath), - ); - - print('Validating $relativePath'); - final packageFile = File(packagePath); - if (!packageFile.existsSync()) { - print(' File $relativePath does not exist in $packageName'); - failed = true; - continue; - } - final String expectedContents = normalizedFileContents(entity); - final String contents = normalizedFileContents(packageFile); - if (contents != expectedContents) { - print(' File $relativePath does not match expected contents:'); - await _printDiff(entity, packageFile); - failed = true; - } - } + bool passesValidation = await _validatePackageSharedCode( + packageRoot, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: true, + ); print( '\nChecking for unshared source files that are not in ' @@ -85,13 +52,13 @@ Future main(List args) async { if (unsharedFiles.isEmpty) { print(' No unexpected unshared files.'); } else { - failed = true; + passesValidation = false; for (final file in unsharedFiles) { print(' $file is not shared'); } } - if (failed) { + if (!passesValidation) { print(''' If the changes you made should be shared with other copies of the @@ -105,11 +72,115 @@ approach to sharing as much code as can still be shared. For more information on the code sharing structure used by this package, see the google_maps_flutter_ios_shared_code/README.md file. - '''); +'''); + exit(1); + } + + // If everything else passed, sanity-check the other implementation packages. + // Full diff evaluation is done by the copy of this script in each + // implementation package, but if someone edits the shared code without + // updating the other packages, this will catch it. This is useful both + // locally, where people are unlikely to run the tests in every package, and + // in CI, where if there are no changes to an implementation package the CI + // for that package will be skipped. + print('\nChecking other implementation packages...'); + final failingPackages = []; + for (final FileSystemEntity entity in packageRoot.parent.listSync()) { + final String packageName = p.basename(entity.path); + if (entity is! Directory || + !packageName.startsWith('google_maps_flutter_ios_') || + packageName == 'google_maps_flutter_ios_shared_code') { + continue; + } + if (!await _validatePackageSharedCode( + entity, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: false, + )) { + failingPackages.add(packageName); + } + } + + if (failingPackages.isEmpty) { + print(' No unexpected diffs found.'); + } else { + print(''' + The following packages do not match the shared source code: +${failingPackages.map((p) => ' $p').join('\n')} + +If you manually synchronized changes to the shared code, you will also need to +copy those changes to the other implementation packages. In the future, consider +using sync_shared_files.dart instead of copying changes to the shared source +manually. +'''); exit(1); } } +/// Validates that the shared code in [packageRoot] matches the shared source of +/// truth. +/// +/// Returns true if the package matches the shared source of truth. +Future _validatePackageSharedCode( + Directory packageRoot, + String packageName, { + required Directory sharedSourceRoot, + required bool log, +}) async { + var hasDiffs = false; + for (final FileSystemEntity entity in sharedSourceRoot.listSync( + recursive: true, + )) { + if (entity is! File) { + continue; + } + final String relativePath = p.relative( + entity.path, + from: sharedSourceRoot.path, + ); + // The shared source README.md is not part of the shared source of truth, + // just an explanation of this source-sharing system. + if (relativePath == 'README.md') { + continue; + } + // Ignore .DS_Store files, which may be created in the shared source + // directory by the OS. + if (relativePath.endsWith('.DS_Store')) { + continue; + } + + // Adjust the paths to account for the package name being part of the + // directory structure for Swift packages. + final String packagePath = p.join( + packageRoot.path, + packageRelativePathForSharedSourceRelativePath(packageName, relativePath), + ); + + if (log) { + print('Validating $relativePath'); + } + final packageFile = File(packagePath); + if (!packageFile.existsSync()) { + if (log) { + print(' File $relativePath does not exist in $packageName'); + } + hasDiffs = true; + continue; + } + final String expectedContents = normalizedFileContents(entity); + final String contents = normalizedFileContents(packageFile); + if (contents != expectedContents) { + if (log) { + print(' File $relativePath does not match expected contents:'); + await _printDiff(entity, packageFile); + } + hasDiffs = true; + } + } + return !hasDiffs; +} + Future _printDiff(File expected, File actual) async { final Process process = await Process.start('diff', [ '-u', diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/tool/run_tests.dart b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/tool/run_tests.dart index f86778c0c2a1..f49c29eaf7fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/tool/run_tests.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/tool/run_tests.dart @@ -33,45 +33,12 @@ Future main(List args) async { p.join(packageRoot.parent.path, 'google_maps_flutter_ios_shared_code'), ); - var failed = false; - for (final FileSystemEntity entity in sharedSourceRoot.listSync( - recursive: true, - )) { - if (entity is! File) { - continue; - } - final String relativePath = p.relative( - entity.path, - from: sharedSourceRoot.path, - ); - // The shared source README.md is not part of the shared source of truth, - // just an explanation of this source-sharing system. - if (relativePath == 'README.md') { - continue; - } - - // Adjust the paths to account for the package name being part of the - // directory structure for Swift packages. - final String packagePath = p.join( - packageRoot.path, - packageRelativePathForSharedSourceRelativePath(packageName, relativePath), - ); - - print('Validating $relativePath'); - final packageFile = File(packagePath); - if (!packageFile.existsSync()) { - print(' File $relativePath does not exist in $packageName'); - failed = true; - continue; - } - final String expectedContents = normalizedFileContents(entity); - final String contents = normalizedFileContents(packageFile); - if (contents != expectedContents) { - print(' File $relativePath does not match expected contents:'); - await _printDiff(entity, packageFile); - failed = true; - } - } + bool passesValidation = await _validatePackageSharedCode( + packageRoot, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: true, + ); print( '\nChecking for unshared source files that are not in ' @@ -85,13 +52,13 @@ Future main(List args) async { if (unsharedFiles.isEmpty) { print(' No unexpected unshared files.'); } else { - failed = true; + passesValidation = false; for (final file in unsharedFiles) { print(' $file is not shared'); } } - if (failed) { + if (!passesValidation) { print(''' If the changes you made should be shared with other copies of the @@ -105,11 +72,115 @@ approach to sharing as much code as can still be shared. For more information on the code sharing structure used by this package, see the google_maps_flutter_ios_shared_code/README.md file. - '''); +'''); + exit(1); + } + + // If everything else passed, sanity-check the other implementation packages. + // Full diff evaluation is done by the copy of this script in each + // implementation package, but if someone edits the shared code without + // updating the other packages, this will catch it. This is useful both + // locally, where people are unlikely to run the tests in every package, and + // in CI, where if there are no changes to an implementation package the CI + // for that package will be skipped. + print('\nChecking other implementation packages...'); + final failingPackages = []; + for (final FileSystemEntity entity in packageRoot.parent.listSync()) { + final String packageName = p.basename(entity.path); + if (entity is! Directory || + !packageName.startsWith('google_maps_flutter_ios_') || + packageName == 'google_maps_flutter_ios_shared_code') { + continue; + } + if (!await _validatePackageSharedCode( + entity, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: false, + )) { + failingPackages.add(packageName); + } + } + + if (failingPackages.isEmpty) { + print(' No unexpected diffs found.'); + } else { + print(''' + The following packages do not match the shared source code: +${failingPackages.map((p) => ' $p').join('\n')} + +If you manually synchronized changes to the shared code, you will also need to +copy those changes to the other implementation packages. In the future, consider +using sync_shared_files.dart instead of copying changes to the shared source +manually. +'''); exit(1); } } +/// Validates that the shared code in [packageRoot] matches the shared source of +/// truth. +/// +/// Returns true if the package matches the shared source of truth. +Future _validatePackageSharedCode( + Directory packageRoot, + String packageName, { + required Directory sharedSourceRoot, + required bool log, +}) async { + var hasDiffs = false; + for (final FileSystemEntity entity in sharedSourceRoot.listSync( + recursive: true, + )) { + if (entity is! File) { + continue; + } + final String relativePath = p.relative( + entity.path, + from: sharedSourceRoot.path, + ); + // The shared source README.md is not part of the shared source of truth, + // just an explanation of this source-sharing system. + if (relativePath == 'README.md') { + continue; + } + // Ignore .DS_Store files, which may be created in the shared source + // directory by the OS. + if (relativePath.endsWith('.DS_Store')) { + continue; + } + + // Adjust the paths to account for the package name being part of the + // directory structure for Swift packages. + final String packagePath = p.join( + packageRoot.path, + packageRelativePathForSharedSourceRelativePath(packageName, relativePath), + ); + + if (log) { + print('Validating $relativePath'); + } + final packageFile = File(packagePath); + if (!packageFile.existsSync()) { + if (log) { + print(' File $relativePath does not exist in $packageName'); + } + hasDiffs = true; + continue; + } + final String expectedContents = normalizedFileContents(entity); + final String contents = normalizedFileContents(packageFile); + if (contents != expectedContents) { + if (log) { + print(' File $relativePath does not match expected contents:'); + await _printDiff(entity, packageFile); + } + hasDiffs = true; + } + } + return !hasDiffs; +} + Future _printDiff(File expected, File actual) async { final Process process = await Process.start('diff', [ '-u', diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/tool/run_tests.dart b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/tool/run_tests.dart index f86778c0c2a1..f49c29eaf7fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/tool/run_tests.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/tool/run_tests.dart @@ -33,45 +33,12 @@ Future main(List args) async { p.join(packageRoot.parent.path, 'google_maps_flutter_ios_shared_code'), ); - var failed = false; - for (final FileSystemEntity entity in sharedSourceRoot.listSync( - recursive: true, - )) { - if (entity is! File) { - continue; - } - final String relativePath = p.relative( - entity.path, - from: sharedSourceRoot.path, - ); - // The shared source README.md is not part of the shared source of truth, - // just an explanation of this source-sharing system. - if (relativePath == 'README.md') { - continue; - } - - // Adjust the paths to account for the package name being part of the - // directory structure for Swift packages. - final String packagePath = p.join( - packageRoot.path, - packageRelativePathForSharedSourceRelativePath(packageName, relativePath), - ); - - print('Validating $relativePath'); - final packageFile = File(packagePath); - if (!packageFile.existsSync()) { - print(' File $relativePath does not exist in $packageName'); - failed = true; - continue; - } - final String expectedContents = normalizedFileContents(entity); - final String contents = normalizedFileContents(packageFile); - if (contents != expectedContents) { - print(' File $relativePath does not match expected contents:'); - await _printDiff(entity, packageFile); - failed = true; - } - } + bool passesValidation = await _validatePackageSharedCode( + packageRoot, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: true, + ); print( '\nChecking for unshared source files that are not in ' @@ -85,13 +52,13 @@ Future main(List args) async { if (unsharedFiles.isEmpty) { print(' No unexpected unshared files.'); } else { - failed = true; + passesValidation = false; for (final file in unsharedFiles) { print(' $file is not shared'); } } - if (failed) { + if (!passesValidation) { print(''' If the changes you made should be shared with other copies of the @@ -105,11 +72,115 @@ approach to sharing as much code as can still be shared. For more information on the code sharing structure used by this package, see the google_maps_flutter_ios_shared_code/README.md file. - '''); +'''); + exit(1); + } + + // If everything else passed, sanity-check the other implementation packages. + // Full diff evaluation is done by the copy of this script in each + // implementation package, but if someone edits the shared code without + // updating the other packages, this will catch it. This is useful both + // locally, where people are unlikely to run the tests in every package, and + // in CI, where if there are no changes to an implementation package the CI + // for that package will be skipped. + print('\nChecking other implementation packages...'); + final failingPackages = []; + for (final FileSystemEntity entity in packageRoot.parent.listSync()) { + final String packageName = p.basename(entity.path); + if (entity is! Directory || + !packageName.startsWith('google_maps_flutter_ios_') || + packageName == 'google_maps_flutter_ios_shared_code') { + continue; + } + if (!await _validatePackageSharedCode( + entity, + packageName, + sharedSourceRoot: sharedSourceRoot, + log: false, + )) { + failingPackages.add(packageName); + } + } + + if (failingPackages.isEmpty) { + print(' No unexpected diffs found.'); + } else { + print(''' + The following packages do not match the shared source code: +${failingPackages.map((p) => ' $p').join('\n')} + +If you manually synchronized changes to the shared code, you will also need to +copy those changes to the other implementation packages. In the future, consider +using sync_shared_files.dart instead of copying changes to the shared source +manually. +'''); exit(1); } } +/// Validates that the shared code in [packageRoot] matches the shared source of +/// truth. +/// +/// Returns true if the package matches the shared source of truth. +Future _validatePackageSharedCode( + Directory packageRoot, + String packageName, { + required Directory sharedSourceRoot, + required bool log, +}) async { + var hasDiffs = false; + for (final FileSystemEntity entity in sharedSourceRoot.listSync( + recursive: true, + )) { + if (entity is! File) { + continue; + } + final String relativePath = p.relative( + entity.path, + from: sharedSourceRoot.path, + ); + // The shared source README.md is not part of the shared source of truth, + // just an explanation of this source-sharing system. + if (relativePath == 'README.md') { + continue; + } + // Ignore .DS_Store files, which may be created in the shared source + // directory by the OS. + if (relativePath.endsWith('.DS_Store')) { + continue; + } + + // Adjust the paths to account for the package name being part of the + // directory structure for Swift packages. + final String packagePath = p.join( + packageRoot.path, + packageRelativePathForSharedSourceRelativePath(packageName, relativePath), + ); + + if (log) { + print('Validating $relativePath'); + } + final packageFile = File(packagePath); + if (!packageFile.existsSync()) { + if (log) { + print(' File $relativePath does not exist in $packageName'); + } + hasDiffs = true; + continue; + } + final String expectedContents = normalizedFileContents(entity); + final String contents = normalizedFileContents(packageFile); + if (contents != expectedContents) { + if (log) { + print(' File $relativePath does not match expected contents:'); + await _printDiff(entity, packageFile); + } + hasDiffs = true; + } + } + return !hasDiffs; +} + Future _printDiff(File expected, File actual) async { final Process process = await Process.start('diff', [ '-u',