diff --git a/lib/sentry_dart_plugin.dart b/lib/sentry_dart_plugin.dart index a69463d7..aa3fac63 100644 --- a/lib/sentry_dart_plugin.dart +++ b/lib/sentry_dart_plugin.dart @@ -60,6 +60,8 @@ class SentryDartPlugin { await _executeFinalizeRelease(release); } on ExitError catch (e) { return e.code; + } finally { + Log.tasksSummary(); } return 0; } @@ -187,13 +189,27 @@ class SentryDartPlugin { } Future _executeNewRelease(String release) async { - await _executeAndLog('Failed to create a new release', + final taskName = 'create new release: $release'; + Log.startingTask(taskName); + final isSuccess = await _executeAndLog('Failed to create a new release', [..._releasesCliParams(), 'new', release]); + if (isSuccess) { + Log.taskCompleted(taskName); + } else { + Log.taskSkipped(taskName); + } } Future _executeFinalizeRelease(String release) async { - await _executeAndLog('Failed to finalize the new release', + final taskName = 'finalize new release: $release'; + Log.startingTask(taskName); + final isSuccess = await _executeAndLog('Failed to finalize the new release', [..._releasesCliParams(), 'finalize', release]); + if (isSuccess) { + Log.taskCompleted(taskName); + } else { + Log.taskSkipped(taskName); + } } Future _executeSetCommits(String release) async { @@ -214,7 +230,14 @@ class SentryDartPlugin { params.add('--ignore-missing'); } - await _executeAndLog('Failed to set commits', params); + final taskName = 'set commits'; + Log.startingTask(taskName); + final isSuccess = await _executeAndLog('Failed to set commits', params); + if (isSuccess) { + Log.taskCompleted(taskName); + } else { + Log.taskSkipped(taskName); + } } Future> _findAllJsFilePaths() async { @@ -280,7 +303,7 @@ class SentryDartPlugin { return await _executeAndLog('Failed to inject debug ids', params); } - Future _uploadSourceMaps( + Future _uploadSourceMaps( {required String release, required String? dist}) async { List params = []; @@ -325,7 +348,7 @@ class SentryDartPlugin { params.addAll(_baseCliParams()); - await _executeAndLog('Failed to sources files', params); + return await _executeAndLog('Failed to sources files', params); } /// Extracts and returns a list of path prefixes to strip from source maps. @@ -417,7 +440,7 @@ class SentryDartPlugin { } } - const taskName = 'uploading source maps'; + const taskName = 'uploading source maps (legacy)'; Log.startingTask(taskName); final params = []; @@ -440,7 +463,13 @@ class SentryDartPlugin { _addWait(releaseJsFilesParams); _addUrlPrefix(releaseJsFilesParams); - await _executeAndLog('Failed to upload source maps', releaseJsFilesParams); + final isSourcemapsUploadSuccessful = await _executeAndLog( + 'Failed to upload source maps', releaseJsFilesParams); + if (!isSourcemapsUploadSuccessful) { + Log.taskSkipped(taskName); + // no need to continue if it was a failure + return; + } if (_configuration.uploadSources) { // upload source files (dart) @@ -457,8 +486,13 @@ class SentryDartPlugin { _addWait(releaseDartFilesParams); - await _executeAndLog( + final isSourcesUploadSuccessful = await _executeAndLog( 'Failed to upload source files', releaseDartFilesParams); + if (!isSourcesUploadSuccessful) { + Log.taskSkipped(taskName); + // no need to continue if it was a failure + return; + } } Log.taskCompleted(taskName); @@ -471,12 +505,16 @@ class SentryDartPlugin { final debugIdInjectionSucceeded = await _injectDebugIds(); if (debugIdInjectionSucceeded) { - await _uploadSourceMaps(release: release, dist: dist); + final isSuccess = await _uploadSourceMaps(release: release, dist: dist); + if (isSuccess) { + Log.taskCompleted(taskName); + } else { + Log.taskSkipped(taskName); + } } else { Log.warn('Skipping source maps upload. Could not inject debug ids.'); + Log.taskSkipped(taskName); } - - Log.taskCompleted(taskName); } void _addUrlPrefix(List releaseDartFilesParams) { diff --git a/lib/src/utils/log.dart b/lib/src/utils/log.dart index cc4530b5..e9faa510 100644 --- a/lib/src/utils/log.dart +++ b/lib/src/utils/log.dart @@ -35,6 +35,7 @@ class Log { static final _gray09 = AnsiPen()..gray(level: 0.9); static int _numberOfTasksCompleted = 0; static int _lastMessageLength = 0; + static Map tasks = {}; /// Log with colors. Log(); @@ -81,6 +82,7 @@ class Log { /// Info log on a new task static void startingTask(String name) { + tasks[name] = 'start'; final emptyStr = _getlastMessageemptyStringLength(); _lastMessageLength = name.length; _renderProgressBar(); @@ -89,9 +91,10 @@ class Log { /// Info log on a completed task static void taskCompleted(String name) { + tasks[name] = 'completed'; _numberOfTasksCompleted++; stdout.writeCharCode(13); - stdout.write(_green('☑ ')); + stdout.write(_green('✓ ')); stdout.writeln( '$name '); if (_numberOfTasksCompleted >= _numberOfAllTasks) { @@ -101,6 +104,46 @@ class Log { } } + /// Info log on a skipped task. + /// + /// e.g when some operations implicitly trigger related tasks for example, + /// uploading debug symbols for a Windows build may also queue a sourcemap upload + /// if the sourcemaps upload config is set up + static void taskSkipped(String name) { + tasks[name] = 'skipped'; + stdout.writeCharCode(13); + stdout.write(_green('⏭ ')); + stdout.writeln( + '$name '); + } + + /// Logs a summary of executed tasks + static void tasksSummary() { + stdout.writeln(); + stdout.writeln(_gray09('Tasks Summary:')); + var completedCount = tasks.values.where((s) => s == 'completed').length; + var skippedCount = tasks.values.where((s) => s == 'skipped').length; + var startedCount = tasks.values.where((s) => s == 'started').length; + + stdout.writeln(_green('✔ Completed: $completedCount')); + stdout.writeln(_yellow('⏭ Skipped: $skippedCount')); + stdout.writeln(); + + tasks.forEach((name, status) { + if (status == 'completed' || status == 'skipped') { + String icon = status == 'completed' ? '✔' : '⏭'; + AnsiPen pen = status == 'completed' ? _green : _yellow; + stdout.writeln(pen('$icon $name')); + } else if (status == 'started') { + // This case is very unlikely to happen but let's still log it if it does + AnsiPen pen = _yellow; + stdout + .writeln(pen('$startedCount tasks were started but not finished.')); + } + }); + stdout.writeln(); + } + static String _getlastMessageemptyStringLength() { var emptyStr = ''; for (var i = 0; i < _lastMessageLength + 8; i++) {