From 6b19423055f006d0f86ea8a56cf424fa8e82ce14 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Wed, 5 Feb 2025 13:49:35 -0500 Subject: [PATCH] feat: add min-link-percentage arg to patch command (#2852) Co-authored-by: Felix Angelov --- .../lib/src/commands/patch/ios_patcher.dart | 2 +- .../lib/src/commands/patch/patch_command.dart | 21 +++++- .../lib/src/commands/patch/patcher.dart | 4 +- .../lib/src/common_arguments.dart | 11 ++++ .../commands/patch/patch_command_test.dart | 65 +++++++++++++++++++ 5 files changed, 98 insertions(+), 5 deletions(-) diff --git a/packages/shorebird_cli/lib/src/commands/patch/ios_patcher.dart b/packages/shorebird_cli/lib/src/commands/patch/ios_patcher.dart index 164ab1de..dd54416e 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/ios_patcher.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/ios_patcher.dart @@ -341,7 +341,7 @@ For more information see: ${supportedFlutterVersionsUrl.toLink()}''', ); if (exitCode != ExitCode.success.code) throw ProcessExit(exitCode); if (linkPercentage != null && - linkPercentage < Patcher.minLinkPercentage) { + linkPercentage < Patcher.linkPercentageWarningThreshold) { logger.warn(Patcher.lowLinkPercentageWarning(linkPercentage)); } lastBuildLinkPercentage = linkPercentage; diff --git a/packages/shorebird_cli/lib/src/commands/patch/patch_command.dart b/packages/shorebird_cli/lib/src/commands/patch/patch_command.dart index ce1691a2..4b14e282 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/patch_command.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/patch_command.dart @@ -144,6 +144,12 @@ To target the latest release (e.g. the release that was most recently updated) u ..addOption( CommonArguments.splitDebugInfoArg.name, help: CommonArguments.splitDebugInfoArg.description, + ) + ..addOption( + CommonArguments.minLinkPercentage.name, + help: CommonArguments.minLinkPercentage.description, + defaultsTo: CommonArguments.minLinkPercentage.defaultValue, + allowed: [for (var i = 0; i <= 100; i++) '$i'], ); } @@ -551,14 +557,25 @@ Please re-run the release command for this version or create a new release.'''); }; })(); + final linkPercentage = patcher.linkPercentage; + final minLinkPercentage = int.parse( + results[CommonArguments.minLinkPercentage.name] as String, + ); + if (linkPercentage != null && linkPercentage < minLinkPercentage) { + logger.err( + '''The link percentage of this patch ($linkPercentage%) is below the minimum threshold ($minLinkPercentage%). Exiting.''', + ); + throw ProcessExit(ExitCode.software.code); + } + final summary = [ '''📱 App: ${lightCyan.wrap(app.displayName)} ${lightCyan.wrap('(${app.appId})')}''', if (flavor != null) '🍧 Flavor: ${lightCyan.wrap(flavor)}', 'đŸ“Ļ Release Version: ${lightCyan.wrap(releaseVersion)}', '''đŸ•šī¸ Platform: ${lightCyan.wrap(patcher.releaseType.releasePlatform.displayName)} ${lightCyan.wrap('[${archMetadata.join(', ')}]')}''', trackSummary, - if (patcher.linkPercentage != null && - patcher.linkPercentage! < Patcher.minLinkPercentage) + if (linkPercentage != null && + linkPercentage < Patcher.linkPercentageWarningThreshold) '''🔍 Debug Info: ${lightCyan.wrap(Patcher.debugInfoFile.path)}''', ]; diff --git a/packages/shorebird_cli/lib/src/commands/patch/patcher.dart b/packages/shorebird_cli/lib/src/commands/patch/patcher.dart index 07deeb38..bf9b3a9c 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/patcher.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/patcher.dart @@ -29,8 +29,8 @@ abstract class Patcher { required this.target, }); - /// Link percentage that is considered the minimum before a user might notice. - static const double minLinkPercentage = 75; + /// Link percentage below which a warning is issued. + static const double linkPercentageWarningThreshold = 75; /// The standard link percentage warning. static String lowLinkPercentageWarning(double linkPercentage) { diff --git a/packages/shorebird_cli/lib/src/common_arguments.dart b/packages/shorebird_cli/lib/src/common_arguments.dart index 84039538..5a237082 100644 --- a/packages/shorebird_cli/lib/src/common_arguments.dart +++ b/packages/shorebird_cli/lib/src/common_arguments.dart @@ -135,6 +135,17 @@ symbolize" command with the right program symbol file is required to obtain a hu name: 'no-confirm', description: ''' Bypass all confirmation messages. It's generally not advised to use this unless running from a script. +''', + ); + + /// An argument that allows the user to specify a minimum link percentage threshold. + static const minLinkPercentage = ArgumentDescriber( + name: 'min-link-percentage', + defaultValue: '0', + description: ''' +The minimum link percentage (0-100) required in order to generate a patch (Apple platforms only). + +Patches with a lower link percentage than what is provided here will fail. ''', ); } diff --git a/packages/shorebird_cli/test/src/commands/patch/patch_command_test.dart b/packages/shorebird_cli/test/src/commands/patch/patch_command_test.dart index fef19bed..8f952f9d 100644 --- a/packages/shorebird_cli/test/src/commands/patch/patch_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/patch/patch_command_test.dart @@ -180,6 +180,9 @@ void main() { when(() => argResults['dry-run']).thenReturn(false); when(() => argResults['platforms']).thenReturn(['android']); when(() => argResults['release-version']).thenReturn(releaseVersion); + when( + () => argResults[CommonArguments.minLinkPercentage.name], + ).thenReturn(CommonArguments.minLinkPercentage.defaultValue); when( () => argResults['track'], ).thenReturn(DeploymentTrack.stable.channel); @@ -747,6 +750,68 @@ void main() { ), ).called(1); }); + + group('when min-link-percentage is specified', () { + group('when link percentage is higher than min', () { + const minLinkPercentageArg = '40'; + + setUp(() { + when( + () => argResults[CommonArguments.minLinkPercentage.name], + ).thenReturn(minLinkPercentageArg); + }); + + test('completes, does not print error message', () async { + await expectLater( + runWithOverrides( + () => command.confirmCreatePatch( + app: appMetadata, + releaseVersion: releaseVersion, + patcher: patcher, + patchArtifactBundles: patchArtifactBundles, + ), + ), + completes, + ); + + verifyNever(() { + logger.err( + any(that: contains('is below the minimum threshold')), + ); + }); + }); + }); + + group('when link percentage is lower than min', () { + const minLinkPercentageArg = '50'; + + setUp(() { + when( + () => argResults[CommonArguments.minLinkPercentage.name], + ).thenReturn(minLinkPercentageArg); + }); + + test('prints error message and exits', () async { + await expectLater( + runWithOverrides( + () => command.confirmCreatePatch( + app: appMetadata, + releaseVersion: releaseVersion, + patcher: patcher, + patchArtifactBundles: patchArtifactBundles, + ), + ), + exitsWithCode(ExitCode.software), + ); + + verify( + () => logger.err( + '''The link percentage of this patch ($linkPercentage%) is below the minimum threshold (50%). Exiting.''', + ), + ).called(1); + }); + }); + }); }); });