feat: add min-link-percentage arg to patch command (#2852)

Co-authored-by: Felix Angelov <felix@shorebird.dev>
This commit is contained in:
Bryan Oltman
2025-02-05 13:49:35 -05:00
committed by GitHub
parent f449b64467
commit 6b19423055
5 changed files with 98 additions and 5 deletions
@@ -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;
@@ -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)}''',
];
@@ -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) {
@@ -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.
''',
);
}
@@ -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);
});
});
});
});
});