feat: adding public key to the patch command (#2149)
Co-authored-by: Bryan Oltman <bryan@shorebird.dev>
This commit is contained in:
@@ -11,7 +11,6 @@ import 'package:shorebird_cli/src/commands/patch/patcher.dart';
|
||||
import 'package:shorebird_cli/src/common_arguments.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/extensions/arg_results.dart';
|
||||
import 'package:shorebird_cli/src/extensions/file.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/patch_diff_checker.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
@@ -35,11 +34,6 @@ class AndroidPatcher extends Patcher {
|
||||
required super.target,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<void> assertArgsAreValid() async {
|
||||
argResults.file(CommonArguments.privateKeyArgName)?.assertExists();
|
||||
}
|
||||
|
||||
@override
|
||||
ReleaseType get releaseType => ReleaseType.android;
|
||||
|
||||
@@ -74,6 +68,7 @@ class AndroidPatcher extends Patcher {
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
args: argResults.forwardedArgs,
|
||||
base64PublicKey: argResults.encodedPublicKey,
|
||||
);
|
||||
buildProgress.complete();
|
||||
} on ArtifactBuildException catch (error) {
|
||||
@@ -158,7 +153,9 @@ Looked in:
|
||||
final patchArtifact = File(patchArtifactPath);
|
||||
final hash = sha256.convert(await patchArtifact.readAsBytes()).toString();
|
||||
|
||||
final privateKeyFile = argResults.file(CommonArguments.privateKeyArgName);
|
||||
final privateKeyFile = argResults.file(
|
||||
CommonArguments.privateKeyArg.name,
|
||||
);
|
||||
final hashSignature = privateKeyFile != null
|
||||
? codeSigner.sign(
|
||||
message: hash,
|
||||
|
||||
@@ -70,6 +70,7 @@ class IosFrameworkPatcher extends Patcher {
|
||||
|
||||
@override
|
||||
Future<void> assertArgsAreValid() async {
|
||||
await super.assertArgsAreValid();
|
||||
if (!argResults.wasParsed('release-version')) {
|
||||
logger.err('Missing required argument: --release-version');
|
||||
exit(ExitCode.usage.code);
|
||||
|
||||
@@ -100,6 +100,7 @@ class IosPatcher extends Patcher {
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
args: argResults.forwardedArgs,
|
||||
base64PublicKey: argResults.encodedPublicKey,
|
||||
);
|
||||
} on ProcessException catch (error) {
|
||||
buildProgress.fail('Failed to build: ${error.message}');
|
||||
@@ -213,7 +214,7 @@ class IosPatcher extends Patcher {
|
||||
}
|
||||
|
||||
final patchFileSize = patchFile.statSync().size;
|
||||
final privateKeyFile = argResults.file(CommonArguments.privateKeyArgName);
|
||||
final privateKeyFile = argResults.file(CommonArguments.privateKeyArg.name);
|
||||
final hash = sha256.convert(patchBuildFile.readAsBytesSync()).toString();
|
||||
final hashSignature = privateKeyFile != null
|
||||
? codeSigner.sign(
|
||||
|
||||
@@ -95,11 +95,14 @@ of the iOS app that is using this module.''',
|
||||
help: 'Validate but do not upload the patch.',
|
||||
)
|
||||
..addOption(
|
||||
CommonArguments.privateKeyArgName,
|
||||
CommonArguments.privateKeyArg.name,
|
||||
hide: true,
|
||||
help: '''
|
||||
The path for a private key file that will be used to sign the patch artifact.
|
||||
''',
|
||||
help: CommonArguments.privateKeyArg.description,
|
||||
)
|
||||
..addOption(
|
||||
CommonArguments.publicKeyArg.name,
|
||||
hide: true,
|
||||
help: CommonArguments.publicKeyArg.description,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@ import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/archive_analysis/archive_differ.dart';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/extensions/arg_results.dart';
|
||||
import 'package:shorebird_cli/src/patch_diff_checker.dart';
|
||||
import 'package:shorebird_cli/src/platform/platform.dart';
|
||||
import 'package:shorebird_cli/src/release_type.dart';
|
||||
@@ -66,8 +68,14 @@ https://docs.shorebird.dev/status#link-percentage-ios
|
||||
/// Asserts that the command can be run.
|
||||
Future<void> assertPreconditions();
|
||||
|
||||
@mustCallSuper
|
||||
|
||||
/// Asserts that the combination arguments passed to the command are valid.
|
||||
Future<void> assertArgsAreValid() async {}
|
||||
Future<void> assertArgsAreValid() async {
|
||||
// TODO(erickzanardo): Move this call to the patch_command so we don't need
|
||||
// to required sub classes to call super.
|
||||
argResults.assertAbsentOrValidKeyPair();
|
||||
}
|
||||
|
||||
/// Builds the release artifacts for the given platform. Returns the "primary"
|
||||
/// artifact for the platform (e.g. the AAB for Android, the IPA for iOS).
|
||||
|
||||
@@ -117,11 +117,9 @@ of the iOS app that is using this module.''',
|
||||
allowed: Arch.values.map((arch) => arch.targetPlatformCliArg),
|
||||
)
|
||||
..addOption(
|
||||
CommonArguments.publicKeyArgName,
|
||||
CommonArguments.publicKeyArg.name,
|
||||
hide: true,
|
||||
help: '''
|
||||
The path for a public key file that will be used to validate patch signatures.
|
||||
''',
|
||||
help: CommonArguments.publicKeyArg.description,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,33 @@
|
||||
/// {@template argument_describer}
|
||||
/// A class that describes an argument from a command/sub command.
|
||||
/// {@endtemplate}
|
||||
class ArgumentDescriber {
|
||||
const ArgumentDescriber({
|
||||
required this.name,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
/// Argument name as how the user writes it.
|
||||
final String name;
|
||||
|
||||
/// Argument description that will be shown in the help of the command.
|
||||
final String description;
|
||||
}
|
||||
|
||||
/// A class that houses the name of arguments that are shared between different
|
||||
/// commands and layers.
|
||||
class CommonArguments {
|
||||
static const String publicKeyArgName = 'public-key-path';
|
||||
static const String privateKeyArgName = 'private-key-path';
|
||||
static const publicKeyArg = ArgumentDescriber(
|
||||
name: 'public-key-path',
|
||||
description: '''
|
||||
The path for a public key file that will be used to validate patch signatures.
|
||||
''',
|
||||
);
|
||||
|
||||
static const privateKeyArg = ArgumentDescriber(
|
||||
name: 'private-key-path',
|
||||
description: '''
|
||||
The path for a private key file that will be used to sign the patch artifact.
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:shorebird_cli/src/code_signer.dart';
|
||||
import 'package:shorebird_cli/src/common_arguments.dart';
|
||||
import 'package:shorebird_cli/src/extensions/file.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
|
||||
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/src/base/io.dart';
|
||||
|
||||
extension OptionFinder on ArgResults {
|
||||
/// // Detects flags even when passed to underlying commands via a `--`
|
||||
@@ -49,12 +51,33 @@ extension CodeSign on ArgResults {
|
||||
/// Asserts that either there is no public key argument
|
||||
/// or that the path received exists.
|
||||
void assertAbsentOrValidPublicKey() {
|
||||
file(CommonArguments.publicKeyArgName)?.assertExists();
|
||||
file(CommonArguments.publicKeyArg.name)?.assertExists();
|
||||
}
|
||||
|
||||
/// Asserts that either there is no private key argument
|
||||
/// or that the path received exists.
|
||||
void assertAbsentOrValidPrivateKey() {
|
||||
file(CommonArguments.privateKeyArg.name)?.assertExists();
|
||||
}
|
||||
|
||||
/// Asserts that both public and private keys are either absent or
|
||||
/// when provided, that both of them are pointing to existing files.
|
||||
void assertAbsentOrValidKeyPair() {
|
||||
final publicKeyWasParsed = wasParsed(CommonArguments.publicKeyArg.name);
|
||||
final privateKeyWasParsed = wasParsed(CommonArguments.privateKeyArg.name);
|
||||
|
||||
if (publicKeyWasParsed == privateKeyWasParsed) {
|
||||
assertAbsentOrValidPublicKey();
|
||||
assertAbsentOrValidPrivateKey();
|
||||
} else {
|
||||
logger.err('Both public and private keys must be provided or absent.');
|
||||
exit(ExitCode.usage.code);
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the public key file and encode it to base64 if any.
|
||||
String? get encodedPublicKey {
|
||||
final publicKeyFile = file(CommonArguments.publicKeyArgName);
|
||||
final publicKeyFile = file(CommonArguments.publicKeyArg.name);
|
||||
|
||||
return publicKeyFile != null
|
||||
? codeSigner.base64PublicKey(publicKeyFile)
|
||||
|
||||
@@ -29,6 +29,7 @@ import 'package:shorebird_cli/src/version.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../helpers.dart';
|
||||
import '../../matchers.dart';
|
||||
import '../../mocks.dart';
|
||||
|
||||
@@ -158,12 +159,6 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('assertArgsAreValid', () {
|
||||
test('does nothing', () async {
|
||||
await expectLater(patcher.assertArgsAreValid(), completes);
|
||||
});
|
||||
});
|
||||
|
||||
group('assertPreconditions', () {
|
||||
setUp(() {
|
||||
when(() => doctor.androidCommandValidators)
|
||||
@@ -246,6 +241,7 @@ void main() {
|
||||
target: any(named: 'target'),
|
||||
targetPlatforms: any(named: 'targetPlatforms'),
|
||||
args: any(named: 'args'),
|
||||
base64PublicKey: any(named: 'base64PublicKey'),
|
||||
),
|
||||
).thenAnswer((_) async => aabFile);
|
||||
});
|
||||
@@ -319,6 +315,38 @@ Looked in:
|
||||
});
|
||||
});
|
||||
|
||||
group('when the key pair is provided', () {
|
||||
setUp(() {
|
||||
when(() => codeSigner.base64PublicKey(any()))
|
||||
.thenReturn('public_key_encoded');
|
||||
});
|
||||
|
||||
test('calls buildIpa with the provided key', () async {
|
||||
when(() => argResults.wasParsed(CommonArguments.publicKeyArg.name))
|
||||
.thenReturn(true);
|
||||
|
||||
final key = createTempFile('public.der')
|
||||
..writeAsStringSync('public_key');
|
||||
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(key.path);
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(key.path);
|
||||
await runWithOverrides(
|
||||
patcher.buildPatchArtifact,
|
||||
);
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildAppBundle(
|
||||
args: any(named: 'args'),
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
base64PublicKey: 'public_key_encoded',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
test('returns the aab file', () async {
|
||||
final result = await runWithOverrides(patcher.buildPatchArtifact);
|
||||
expect(result, equals(aabFile));
|
||||
@@ -467,7 +495,7 @@ Looked in:
|
||||
),
|
||||
)..createSync();
|
||||
|
||||
when(() => argResults[CommonArguments.privateKeyArgName])
|
||||
when(() => argResults[CommonArguments.privateKeyArg.name])
|
||||
.thenReturn(privateKey.path);
|
||||
|
||||
when(
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/artifact_manager.dart';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/patch/patch.dart';
|
||||
import 'package:shorebird_cli/src/common_arguments.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/engine_config.dart';
|
||||
import 'package:shorebird_cli/src/executables/aot_tools.dart';
|
||||
@@ -115,6 +116,10 @@ void main() {
|
||||
|
||||
when(() => argResults['build-number']).thenReturn('1.0');
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults.wasParsed(CommonArguments.privateKeyArg.name))
|
||||
.thenReturn(false);
|
||||
when(() => argResults.wasParsed(CommonArguments.publicKeyArg.name))
|
||||
.thenReturn(false);
|
||||
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../fakes.dart';
|
||||
import '../../helpers.dart';
|
||||
import '../../matchers.dart';
|
||||
import '../../mocks.dart';
|
||||
|
||||
@@ -143,12 +144,6 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
group('assertArgsAreValid', () {
|
||||
test('has no specific validations', () {
|
||||
expect(patcher.assertArgsAreValid, returnsNormally);
|
||||
});
|
||||
});
|
||||
|
||||
group('archiveDiffer', () {
|
||||
test('is an IosArchiveDiffer', () {
|
||||
expect(patcher.archiveDiffer, isA<IosArchiveDiffer>());
|
||||
@@ -389,6 +384,7 @@ void main() {
|
||||
args: any(named: 'args'),
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
base64PublicKey: any(named: 'base64PublicKey'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(() => artifactManager.getXcarchiveDirectory()).thenReturn(
|
||||
@@ -436,6 +432,41 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('when the key pair is provided', () {
|
||||
setUp(() {
|
||||
when(() => codeSigner.base64PublicKey(any()))
|
||||
.thenReturn('public_key_encoded');
|
||||
});
|
||||
|
||||
test('calls the buildIpa passing the key', () async {
|
||||
when(
|
||||
() => argResults.wasParsed(CommonArguments.publicKeyArg.name),
|
||||
).thenReturn(true);
|
||||
|
||||
final key = createTempFile('public.pem')
|
||||
..writeAsStringSync('public_key');
|
||||
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(key.path);
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(key.path);
|
||||
await runWithOverrides(
|
||||
patcher.buildPatchArtifact,
|
||||
);
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildIpa(
|
||||
exportOptionsPlist: any(named: 'exportOptionsPlist'),
|
||||
codesign: any(named: 'codesign'),
|
||||
args: any(named: 'args'),
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
base64PublicKey: 'public_key_encoded',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
test('returns xcarchive zip', () async {
|
||||
final artifact = await runWithOverrides(patcher.buildPatchArtifact);
|
||||
expect(p.basename(artifact.path), endsWith('.zip'));
|
||||
@@ -941,7 +972,7 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('when a private key is provided', () {
|
||||
group('when code signing the patch', () {
|
||||
setUp(() {
|
||||
final privateKey = File(
|
||||
p.join(
|
||||
@@ -950,7 +981,7 @@ void main() {
|
||||
),
|
||||
)..createSync();
|
||||
|
||||
when(() => argResults[CommonArguments.privateKeyArgName])
|
||||
when(() => argResults[CommonArguments.privateKeyArg.name])
|
||||
.thenReturn(privateKey.path);
|
||||
|
||||
when(
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:scoped_deps/scoped_deps.dart';
|
||||
import 'package:shorebird_cli/src/archive_analysis/archive_differ.dart';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/common_arguments.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/patch_diff_checker.dart';
|
||||
import 'package:shorebird_cli/src/platform/platform.dart';
|
||||
import 'package:shorebird_cli/src/release_type.dart';
|
||||
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
|
||||
import 'package:shorebird_code_push_protocol/src/models/create_patch_metadata.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../helpers.dart';
|
||||
import '../../matchers.dart';
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
@@ -25,6 +32,119 @@ void main() {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('assertArgsAreValid', () {
|
||||
late _TestPatcher patcher;
|
||||
late ArgResults argResults;
|
||||
late ShorebirdLogger logger;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
loggerRef.overrideWith(() => logger),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
setExitFunctionForTests();
|
||||
argResults = MockArgResults();
|
||||
logger = MockShorebirdLogger();
|
||||
patcher = _TestPatcher(
|
||||
argResults: argResults,
|
||||
flavor: null,
|
||||
target: null,
|
||||
);
|
||||
|
||||
when(() => argResults.wasParsed(CommonArguments.publicKeyArg.name))
|
||||
.thenReturn(false);
|
||||
|
||||
when(() => argResults.wasParsed(CommonArguments.privateKeyArg.name))
|
||||
.thenReturn(false);
|
||||
});
|
||||
|
||||
group('when no key pair is provided', () {
|
||||
test('is valid', () {
|
||||
expect(
|
||||
runWithOverrides(patcher.assertArgsAreValid),
|
||||
completes,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group(
|
||||
'when given existing private and public key files',
|
||||
() {
|
||||
test('is valid', () async {
|
||||
when(
|
||||
() => argResults.wasParsed(CommonArguments.privateKeyArg.name),
|
||||
).thenReturn(true);
|
||||
when(() => argResults.wasParsed(CommonArguments.publicKeyArg.name))
|
||||
.thenReturn(true);
|
||||
when(() => argResults[CommonArguments.privateKeyArg.name])
|
||||
.thenReturn(createTempFile('private.pem').path);
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(createTempFile('public.pem').path);
|
||||
|
||||
expect(
|
||||
runWithOverrides(patcher.assertArgsAreValid),
|
||||
completes,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
group(
|
||||
'when given an existing private key and nonexistent public key',
|
||||
() {
|
||||
test('logs error and exits with usage code', () async {
|
||||
when(
|
||||
() => argResults.wasParsed(CommonArguments.privateKeyArg.name),
|
||||
).thenReturn(true);
|
||||
when(() => argResults.wasParsed(CommonArguments.publicKeyArg.name))
|
||||
.thenReturn(false);
|
||||
when(() => argResults[CommonArguments.privateKeyArg.name])
|
||||
.thenReturn(createTempFile('private.pem').path);
|
||||
|
||||
await expectLater(
|
||||
() => runWithOverrides(patcher.assertArgsAreValid),
|
||||
exitsWithCode(ExitCode.usage),
|
||||
);
|
||||
verify(
|
||||
() => logger.err(
|
||||
'Both public and private keys must be provided or absent.',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
group(
|
||||
'when given an existing public key and nonexistent private key',
|
||||
() {
|
||||
test('fails and logs the err', () async {
|
||||
when(
|
||||
() => argResults.wasParsed(CommonArguments.privateKeyArg.name),
|
||||
).thenReturn(false);
|
||||
when(() => argResults.wasParsed(CommonArguments.publicKeyArg.name))
|
||||
.thenReturn(true);
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(createTempFile('public.pem').path);
|
||||
|
||||
await expectLater(
|
||||
() => runWithOverrides(patcher.assertArgsAreValid),
|
||||
exitsWithCode(ExitCode.usage),
|
||||
);
|
||||
verify(
|
||||
() => logger.err(
|
||||
'Both public and private keys must be provided or absent.',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ void main() {
|
||||
'public-key.pem',
|
||||
),
|
||||
)..writeAsStringSync('public key');
|
||||
when(() => argResults[CommonArguments.publicKeyArgName])
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(publicKeyFile.path);
|
||||
});
|
||||
|
||||
@@ -242,7 +242,7 @@ void main() {
|
||||
group('when a public key is provided but does not exist', () {
|
||||
setUp(() {
|
||||
when(() => argResults['artifact']).thenReturn('apk');
|
||||
when(() => argResults[CommonArguments.publicKeyArgName])
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn('non-existing-key.pem');
|
||||
});
|
||||
|
||||
@@ -434,7 +434,7 @@ void main() {
|
||||
'patch-signing-public-key.pem',
|
||||
),
|
||||
)..createSync(recursive: true);
|
||||
when(() => argResults[CommonArguments.publicKeyArgName])
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(patchSigningPublicKeyFile.path);
|
||||
|
||||
when(
|
||||
|
||||
@@ -258,7 +258,7 @@ void main() {
|
||||
'public-key.pem',
|
||||
),
|
||||
)..writeAsStringSync('public key');
|
||||
when(() => argResults[CommonArguments.publicKeyArgName])
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(publicKeyFile.path);
|
||||
});
|
||||
|
||||
@@ -272,7 +272,7 @@ void main() {
|
||||
|
||||
group('when the provided public key is a nonexistent file', () {
|
||||
setUp(() {
|
||||
when(() => argResults[CommonArguments.publicKeyArgName])
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn('non-existing-key.pem');
|
||||
});
|
||||
|
||||
@@ -339,7 +339,7 @@ void main() {
|
||||
'patch-signing-public-key.pem',
|
||||
),
|
||||
)..createSync(recursive: true);
|
||||
when(() => argResults[CommonArguments.publicKeyArgName])
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(patchSigningPublicKeyFile.path);
|
||||
|
||||
when(
|
||||
|
||||
@@ -501,7 +501,7 @@ $exception''',
|
||||
keyName,
|
||||
),
|
||||
)..writeAsStringSync('KEY');
|
||||
when(() => argResults[CommonArguments.publicKeyArgName])
|
||||
when(() => argResults[CommonArguments.publicKeyArg.name])
|
||||
.thenReturn(file.path);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'dart:io';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
File createTempFile(String name) {
|
||||
return File(
|
||||
p.join(
|
||||
Directory.systemTemp.createTempSync().path,
|
||||
name,
|
||||
),
|
||||
)..createSync();
|
||||
}
|
||||
Reference in New Issue
Block a user