From 3d81a0071fcd6fe6e01b5ed5f1e8ab2d2620f3b1 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 31 Jan 2023 16:52:49 -0800 Subject: [PATCH] [tool] More main-branch detection improvement (#7067) Follow-up to https://github.com/flutter/plugins/pull/7038 to try to make it work on LUCI. Looking at the checkout steps of a LUCI run, it looks like we do a full `fetch` of `origin`, but likely only have a `master` branch locally. Rather than rely on a specific local branch name existing, this allows for checking `origin` (and just in case, since it's another common remote name, `upstream`). Hopefully fixes https://github.com/flutter/flutter/issues/119330 --- .../tool/lib/src/common/package_command.dart | 26 ++++++++++-- script/tool/pubspec.yaml | 2 +- .../test/common/package_command_test.dart | 40 +++++++++++++++++++ 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/script/tool/lib/src/common/package_command.dart b/script/tool/lib/src/common/package_command.dart index 0e084c4c2d5c..8a2bbfc40058 100644 --- a/script/tool/lib/src/common/package_command.dart +++ b/script/tool/lib/src/common/package_command.dart @@ -538,10 +538,28 @@ abstract class PackageCommand extends Command { // This is used because CI may check out a specific hash rather than a branch, // in which case branch-name detection won't work. Future _isCheckoutFromBranch(String branchName) async { - final io.ProcessResult result = await (await gitDir).runCommand( - ['merge-base', '--is-ancestor', 'HEAD', branchName], - throwOnError: false); - return result.exitCode == 0; + // The target branch may not exist locally; try some common remote names for + // the branch as well. + final List candidateBranchNames = [ + branchName, + 'origin/$branchName', + 'upstream/$branchName', + ]; + for (final String branch in candidateBranchNames) { + final io.ProcessResult result = await (await gitDir).runCommand( + ['merge-base', '--is-ancestor', 'HEAD', branch], + throwOnError: false); + if (result.exitCode == 0) { + return true; + } else if (result.exitCode == 1) { + // 1 indicates that the branch was successfully checked, but it's not + // an ancestor. + return false; + } + // Any other return code is an error, such as `branch` not being a valid + // name in the repository, so try other name variants. + } + return false; } Future _getBranch() async { diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml index 73429638a402..52d23b8f72a3 100644 --- a/script/tool/pubspec.yaml +++ b/script/tool/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_plugin_tools description: Productivity utils for flutter/plugins and flutter/packages repository: https://github.com/flutter/plugins/tree/main/script/tool -version: 0.13.4+1 +version: 0.13.4+2 dependencies: args: ^2.1.0 diff --git a/script/tool/test/common/package_command_test.dart b/script/tool/test/common/package_command_test.dart index ed76408bb300..3620f8fd63a9 100644 --- a/script/tool/test/common/package_command_test.dart +++ b/script/tool/test/common/package_command_test.dart @@ -875,6 +875,46 @@ packages/b_package/lib/src/foo.dart )); }); + test( + 'only tests changed packages relative to the previous commit if ' + 'running on a specific hash from origin/main', () async { + processRunner.mockProcessesForExecutable['git-diff'] = [ + MockProcess(stdout: 'packages/plugin1/plugin1.dart'), + ]; + processRunner.mockProcessesForExecutable['git-rev-parse'] = [ + MockProcess(stdout: 'HEAD'), + ]; + processRunner.mockProcessesForExecutable['git-merge-base'] = [ + MockProcess(exitCode: 128), // Fail with a non-1 exit code for 'main' + MockProcess(), // Succeed for the variant. + ]; + final RepositoryPackage plugin1 = + createFakePlugin('plugin1', packagesDir); + createFakePlugin('plugin2', packagesDir); + + final List output = await runCapturingPrint( + runner, ['sample', '--packages-for-branch']); + + expect(command.plugins, unorderedEquals([plugin1.path])); + expect( + output, + containsAllInOrder([ + contains( + '--packages-for-branch: running on a commit from default branch.'), + contains( + '--packages-for-branch: using parent commit as the diff base'), + contains( + 'Running for all packages that have diffs relative to "HEAD~"'), + ])); + // Ensure that it's diffing against the prior commit. + expect( + processRunner.recordedCalls, + contains( + const ProcessCall( + 'git-diff', ['--name-only', 'HEAD~', 'HEAD'], null), + )); + }); + test( 'only tests changed packages relative to the previous commit on master', () async {