Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,45 +33,12 @@ Future<void> main(List<String> 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 '
Expand All @@ -85,13 +52,13 @@ Future<void> main(List<String> 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
Expand All @@ -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 = <String>[];
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<bool> _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;
}
Comment on lines +121 to +182

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _validatePackageSharedCode function is duplicated across run_tests.dart files in google_maps_flutter_ios, google_maps_flutter_ios_sdk10, and google_maps_flutter_ios_sdk9. To improve maintainability and avoid code duplication, consider moving this function to utils.dart.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, this could get old pretty fast on google_maps_flutter PRs.


Future<void> _printDiff(File expected, File actual) async {
final Process process = await Process.start('diff', [
'-u',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,45 +33,12 @@ Future<void> main(List<String> 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 '
Expand All @@ -85,13 +52,13 @@ Future<void> main(List<String> 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
Expand All @@ -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 = <String>[];
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<bool> _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<void> _printDiff(File expected, File actual) async {
final Process process = await Process.start('diff', [
'-u',
Expand Down
Loading
Loading