Skip to content
Draft
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
56 changes: 45 additions & 11 deletions packages/patrol_cli/lib/src/android/android_test_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class AndroidTestBackend {

// :app:assembleDebug

final assembleOutputBuffer = <String>[];
process =
await _processManager.start(
options.toGradleAssembleInvocation(
Expand All @@ -71,21 +72,38 @@ class AndroidTestBackend {
},
)
..disposedBy(scope);
process.listenStdOut((l) => _logger.detail('\t: $l')).disposedBy(scope);
process.listenStdErr((l) => _logger.err('\t$l')).disposedBy(scope);
process
.listenStdOut((l) {
assembleOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);
process
.listenStdErr((l) {
assembleOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);
exitCode = await process.exitCode;
if (exitCode == exitCodeInterrupted) {
const cause = 'Gradle build interrupted';
task.fail('Failed to build $subject ($cause)');
throw Exception(cause);
throwToolExit(cause);
} else if (exitCode != 0) {
// Show buffered output on failure (only if not already shown in verbose mode)
if (_logger.level != Level.verbose) {
for (final line in assembleOutputBuffer) {
_logger.err('\t$line');
}
}
final cause = 'Gradle build failed with code $exitCode';
task.fail('Failed to build $subject ($cause)');
throw Exception(cause);
throwToolExit(cause);
}

// :app:assembleDebugAndroidTest

final assembleTestOutputBuffer = <String>[];
process =
await _processManager.start(
options.toGradleAssembleTestInvocation(
Expand All @@ -99,20 +117,36 @@ class AndroidTestBackend {
},
)
..disposedBy(scope);
process.listenStdOut((l) => _logger.detail('\t: $l')).disposedBy(scope);
process.listenStdErr((l) => _logger.err('\t$l')).disposedBy(scope);
process
.listenStdOut((l) {
assembleTestOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);
process
.listenStdErr((l) {
assembleTestOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);

exitCode = await process.exitCode;
if (exitCode == 0) {
task.complete('Completed building $subject');
} else if (exitCode == exitCodeInterrupted) {
const cause = 'Gradle build interrupted';
task.fail('Failed to build $subject ($cause)');
throw Exception(cause);
throwToolExit(cause);
} else {
// Show buffered output on failure (only if not already shown in verbose mode)
if (_logger.level != Level.verbose) {
for (final line in assembleTestOutputBuffer) {
_logger.err('\t$line');
}
}
final cause = 'Gradle build failed with code $exitCode';
task.fail('Failed to build $subject ($cause)');
throw Exception(cause);
throwToolExit(cause);
}
});
}
Expand Down Expand Up @@ -189,7 +223,7 @@ class AndroidTestBackend {

final exitCode = await process.exitCode;
if (exitCode != 0) {
throw Exception('Failed to build APK config with exit code $exitCode');
throwToolExit('Failed to build APK config with exit code $exitCode');
}
}

Expand Down Expand Up @@ -318,11 +352,11 @@ class AndroidTestBackend {
} else if (exitCode == exitCodeInterrupted) {
const cause = 'Gradle test execution interrupted';
task.fail('Failed to execute tests of $subject ($cause)');
throw Exception(cause);
throwToolInterrupted(cause);
} else {
final cause = 'Gradle test execution failed with code $exitCode';
task.fail('Failed to execute tests of $subject ($cause)');
throw Exception(cause);
throwToolExit(cause);
}
});
}
Expand Down
12 changes: 2 additions & 10 deletions packages/patrol_cli/lib/src/commands/build_android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,8 @@ class BuildAndroidCommand extends PatrolCommand {
uninstall: uninstall,
);

try {
await _androidTestBackend.build(androidOpts);
printApkPaths(flavor: flavor, buildMode: buildMode.androidName);
} catch (err, st) {
_logger
..err('$err')
..detail('$st')
..err(defaultFailureMessage);
rethrow;
}
await _androidTestBackend.build(androidOpts);
printApkPaths(flavor: flavor, buildMode: buildMode.androidName);

return 0;
}
Expand Down
26 changes: 9 additions & 17 deletions packages/patrol_cli/lib/src/commands/build_ios.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,23 +197,15 @@ class BuildIOSCommand extends PatrolCommand {
throwToolExit('Full isolation is only supported on iOS Simulator');
}

try {
await _iosTestBackend.build(iosOpts);
printBinaryPaths(
simulator: iosOpts.simulator,
buildMode: flutterOpts.buildMode.xcodeName,
);
await _printXcTestRunPath(
simulator: iosOpts.simulator,
scheme: iosOpts.scheme,
);
} catch (err, st) {
_logger
..err('$err')
..detail('$st')
..err(defaultFailureMessage);
rethrow;
}
await _iosTestBackend.build(iosOpts);
printBinaryPaths(
simulator: iosOpts.simulator,
buildMode: flutterOpts.buildMode.xcodeName,
);
await _printXcTestRunPath(
simulator: iosOpts.simulator,
scheme: iosOpts.scheme,
);

return 0;
}
Expand Down
18 changes: 5 additions & 13 deletions packages/patrol_cli/lib/src/commands/build_macos.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,11 @@ class BuildMacOSCommand extends PatrolCommand {
testServerPort: super.testServerPort,
);

try {
await _macosTestBackend.build(macosOpts);

printBinaryPaths(buildMode: flutterOpts.buildMode.xcodeName);

await printXcTestRunPath(scheme: macosOpts.scheme);
} catch (err, st) {
_logger
..err('$err')
..detail('$st')
..err(defaultFailureMessage);
rethrow;
}
await _macosTestBackend.build(macosOpts);

printBinaryPaths(buildMode: flutterOpts.buildMode.xcodeName);

await printXcTestRunPath(scheme: macosOpts.scheme);

return 0;
}
Expand Down
42 changes: 38 additions & 4 deletions packages/patrol_cli/lib/src/ios/ios_test_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class IOSTestBackend {
// flutter build ios --config-only

var flutterBuildKilled = false;
final flutterOutputBuffer = <String>[];
process = await _processManager.start(
options.toFlutterBuildInvocation(options.flutter.buildMode),
runInShell: true,
Expand All @@ -104,11 +105,27 @@ class IOSTestBackend {
process.kill();
flutterBuildKilled = true; // `flutter build` has exit code 0 on SIGINT
});
process.listenStdOut((l) => _logger.info('\t$l')).disposedBy(scope);
process.listenStdErr((l) => _logger.err('\t$l')).disposedBy(scope);
process
.listenStdOut((l) {
flutterOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);
process
.listenStdErr((l) {
flutterOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);
var exitCode = await process.exitCode;
final flutterCommand = options.flutter.command;
if (exitCode != 0) {
// Show buffered output on failure (only if not already shown in verbose mode)
if (_logger.level != Level.verbose) {
for (final line in flutterOutputBuffer) {
_logger.err('\t$line');
}
}
final cause = '`$flutterCommand build ios` exited with code $exitCode';
task.fail('Failed to build $subject ($cause)');
throwToolExit(cause);
Expand All @@ -120,15 +137,26 @@ class IOSTestBackend {

// xcodebuild build-for-testing

final xcodebuildOutputBuffer = <String>[];
process =
await _processManager.start(
options.buildForTestingInvocation(),
runInShell: true,
workingDirectory: _rootDirectory.childDirectory('ios').path,
)
..disposedBy(scope);
process.listenStdOut((l) => _logger.detail('\t$l')).disposedBy(scope);
process.listenStdErr((l) => _logger.err('\t$l')).disposedBy(scope);
process
.listenStdOut((l) {
xcodebuildOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);
process
.listenStdErr((l) {
xcodebuildOutputBuffer.add(l);
_logger.detail('\t$l');
})
.disposedBy(scope);
exitCode = await process.exitCode;
if (exitCode == 0) {
task.complete('Completed building $subject');
Expand All @@ -137,6 +165,12 @@ class IOSTestBackend {
task.fail('Failed to execute tests of $subject ($cause)');
throwToolInterrupted(cause);
} else {
// Show buffered output on failure (only if not already shown in verbose mode)
if (_logger.level != Level.verbose) {
for (final line in xcodebuildOutputBuffer) {
_logger.err('\t$line');
}
}
final cause = 'xcodebuild exited with code $exitCode';
task.fail('Failed to build $subject ($cause)');
throwToolExit(cause);
Expand Down
10 changes: 6 additions & 4 deletions packages/patrol_cli/lib/src/runner/patrol_command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,14 @@ To install a specific version of Patrol CLI, run:
}
exitCode = await runCommand(topLevelResults) ?? 0;
} on ToolExit catch (err, st) {
_logger.err('$err');
if (verbose) {
_logger
..err('$err')
..err('$st');
_logger.err('$st');
} else {
_logger.err('$err');
_logger.info(
'See the logs above to learn what happened. '
'Also consider running with --verbose.',
);
}
} on ToolInterrupted catch (err, st) {
if (verbose) {
Expand Down
Loading