Skip to content

Commit

Permalink
Provide path to local sentry-cli (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
denrase authored Apr 16, 2024
1 parent b5dce98 commit a9e00b2
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 95 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- This is a breaking change, please check if the `release` and `dist` values are as you expect them.
- Add option to provide alternative binary directory ([#214](https://github.com/getsentry/sentry-dart-plugin/pull/214))
- Support configuration arguments via `--sentry-define` ([#198](https://github.com/getsentry/sentry-dart-plugin/pull/198))
- Provide path to local `sentry-cli` ([#224](https://github.com/getsentry/sentry-dart-plugin/pull/224))

### Dependencies

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ ignore_missing=true
| commits | Release commits integration | default: auto | no | - |
| ignore_missing | Ignore missing commits previously used in the release | default: false | no | - |
| bin_dir | The folder where the plugin downloads the sentry-cli binary | .dart_tool/pub/bin/sentry_dart_plugin (string) | no | - |
| bin_path | Path to the sentry-cli binary to use instead of downloading. Make sure to use the correct version. | null (string) | no | - |

## Release

Expand Down
39 changes: 27 additions & 12 deletions lib/src/cli/_sources.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,33 @@ const _urlPrefix = 'https://downloads.sentry-cdn.com/sentry-cli/$_version';

final currentCLISources = {
HostPlatform.darwinUniversal: CLISource(
'$_urlPrefix/sentry-cli-Darwin-universal',
'5d12bee428d18ca49657f2573b130a0c5990a665e0cbe6fad583e72a2fd1e3cc'),
HostPlatform.linuxAarch64: CLISource('$_urlPrefix/sentry-cli-Linux-aarch64',
'2b92198d58ffd2f4551db6782b42b42ecc1ba3c7c7864f0c4ae84be940f927d3'),
HostPlatform.linuxArmv7: CLISource('$_urlPrefix/sentry-cli-Linux-armv7',
'2745bc24c84fa7bf1b2c8331acc5bce8741a329ed3866162c5279296d856b1f6'),
HostPlatform.linux64bit: CLISource('$_urlPrefix/sentry-cli-Linux-x86_64',
'baeb5b4ca0a5e500d667087f0b7fbb2865d3b8f01896cfba5144433dbe59bebd'),
'$_urlPrefix/sentry-cli-Darwin-universal',
_version,
'5d12bee428d18ca49657f2573b130a0c5990a665e0cbe6fad583e72a2fd1e3cc',
),
HostPlatform.linuxAarch64: CLISource(
'$_urlPrefix/sentry-cli-Linux-aarch64',
_version,
'2b92198d58ffd2f4551db6782b42b42ecc1ba3c7c7864f0c4ae84be940f927d3',
),
HostPlatform.linuxArmv7: CLISource(
'$_urlPrefix/sentry-cli-Linux-armv7',
_version,
'2745bc24c84fa7bf1b2c8331acc5bce8741a329ed3866162c5279296d856b1f6',
),
HostPlatform.linux64bit: CLISource(
'$_urlPrefix/sentry-cli-Linux-x86_64',
_version,
'baeb5b4ca0a5e500d667087f0b7fbb2865d3b8f01896cfba5144433dbe59bebd',
),
HostPlatform.windows32bit: CLISource(
'$_urlPrefix/sentry-cli-Windows-i686.exe',
'5620bd8d7ce13dfa489d45fab2c6c421ee0570c8217e7c3fbbddae38c910bba5'),
'$_urlPrefix/sentry-cli-Windows-i686.exe',
_version,
'5620bd8d7ce13dfa489d45fab2c6c421ee0570c8217e7c3fbbddae38c910bba5',
),
HostPlatform.windows64bit: CLISource(
'$_urlPrefix/sentry-cli-Windows-x86_64.exe',
'de063e8f5ab9e8e8642f7316dec5b5bb7f856dd4ac2cb1a1b58149e2e9d31758'),
'$_urlPrefix/sentry-cli-Windows-x86_64.exe',
_version,
'de063e8f5ab9e8e8642f7316dec5b5bb7f856dd4ac2cb1a1b58149e2e9d31758',
),
};
15 changes: 12 additions & 3 deletions lib/src/cli/setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@ class CLISetup {
return file.path;
}

Future<void> check(HostPlatform platform, String path) async {
final file = injector.get<FileSystem>().file(path);
final source = _sources[platform]!;
if (!await _check(source, file)) {
Log.warn(
"Download Sentry CLI ${source.version} from '${source.downloadUrl}' and update at path '${file.path}'.");
}
}

Future<void> _download(CLISource source, File file) async {
Log.info(
"Downloading sentry-cli from ${source.downloadUrl} to ${file.path}");
"Downloading Sentry CLI ${source.version} from ${source.downloadUrl} to ${file.path}");

final client = http.Client();
try {
Expand Down Expand Up @@ -59,12 +68,12 @@ class CLISetup {
final expected = source.hash;
if (calculated != expected) {
Log.warn(
"Sentry CLI checksum mismatch on ${file.path} - expected $expected but got $calculated");
"Sentry CLI checksum mismatch on ${file.path} - expected $expected but got $calculated.");
return false;
}

Log.info(
"Downloaded Sentry CLI binary checksum verification passed successfully (hash: $calculated).");
"Sentry CLI binary checksum verification passed successfully (hash: $calculated).");
return true;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/src/cli/sources.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class CLISource {
final Uri downloadUrl;
final String version;
final String hash;

CLISource(String downloadUrl, this.hash)
CLISource(String downloadUrl, this.version, this.hash)
: downloadUrl = Uri.parse(downloadUrl);
}

Expand Down
94 changes: 56 additions & 38 deletions lib/src/configuration.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:io';

import 'package:file/file.dart';
Expand Down Expand Up @@ -85,6 +86,10 @@ class Configuration {
/// `.dart_tool/pub/bin/sentry_dart_plugin`.
late String binDir;

/// An alternative path to sentry-cli. If provided, the SDK will not be
/// downloaded. Please make sure to use the matching version.
late String? binPath;

/// Loads the configuration values
Future<void> getConfigValues(List<String> cliArguments) async {
const taskName = 'reading config values';
Expand Down Expand Up @@ -140,6 +145,7 @@ class Configuration {
url = configValues.url; // or env. var. SENTRY_URL
logLevel = configValues.logLevel; // or env. var. SENTRY_LOG_LEVEL
binDir = configValues.binDir ?? '.dart_tool/pub/bin/sentry_dart_plugin';
binPath = configValues.binPath;
}

/// Validates the configuration values and log an error if required fields
Expand Down Expand Up @@ -182,57 +188,69 @@ class Configuration {
}

Future<void> _findAndSetCliPath() async {
HostPlatform? platform;
final platform = _getHostPlatform();
final binPath = this.binPath;
if (binPath != null && binPath.isNotEmpty) {
if (platform != null) {
await injector.get<CLISetup>().check(platform, binPath);
} else {
Log.warn('Host platform not supported. Cannot verify Sentry CLI.');
}
cliPath = binPath;
Log.info("Using Sentry CLI at path '$cliPath'");
} else {
try {
cliPath = await _downloadSentryCli(platform);
} catch (e) {
Log.error("Failed to download Sentry CLI: $e");

cliPath = _getPreInstalledCli();
Log.info('Trying to fallback to Sentry CLI at path: $cliPath');
}
}
}

String _getPreInstalledCli() {
return Platform.isWindows ? 'sentry-cli.exe' : 'sentry-cli';
}

Future<String> _downloadSentryCli(HostPlatform? platform) async {
if (platform == null) {
throw Exception(
'Host platform not supported: ${Platform.operatingSystem} ${SysInfo.kernelArchitecture}');
}
final cliPath = await injector.get<CLISetup>().download(platform, binDir);
if (!Platform.isWindows) {
final result =
await injector.get<ProcessManager>().run(['chmod', '+x', cliPath]);
if (result.exitCode != 0) {
throw Exception(
'Failed to make binary executable: ${result.stdout}\n${result.stderr}');
}
}
return cliPath;
}

HostPlatform? _getHostPlatform() {
if (Platform.isMacOS) {
platform = HostPlatform.darwinUniversal;
return HostPlatform.darwinUniversal;
} else if (Platform.isWindows) {
platform = SysInfo.kernelBitness == 32
return SysInfo.kernelBitness == 32
? HostPlatform.windows32bit
: HostPlatform.windows64bit;
} else if (Platform.isLinux) {
switch (SysInfo.kernelArchitecture.name.toLowerCase()) {
case 'arm':
case 'armv6':
case 'armv7':
platform = HostPlatform.linuxArmv7;
break;
return HostPlatform.linuxArmv7;
case 'aarch64':
platform = HostPlatform.linuxAarch64;
break;
return HostPlatform.linuxAarch64;
case 'amd64':
case 'x86_64':
platform = HostPlatform.linux64bit;
break;
}
}

if (platform == null) {
Log.error(
'Host platform not supported - cannot download Sentry CLI for ${Platform.operatingSystem} ${SysInfo.kernelArchitecture}');
return _setPreInstalledCli();
}

try {
cliPath = await injector.get<CLISetup>().download(platform, binDir);
} on Exception catch (e) {
Log.error("Failed to download Sentry CLI: $e");
return _setPreInstalledCli();
}

if (!Platform.isWindows) {
final result =
await injector.get<ProcessManager>().run(['chmod', '+x', cliPath!]);
if (result.exitCode != 0) {
Log.error(
"Failed to make downloaded Sentry CLI executable: ${result.stdout}\n${result.stderr}");
return _setPreInstalledCli();
return HostPlatform.linux64bit;
}
}
}

void _setPreInstalledCli() {
cliPath = Platform.isWindows ? 'sentry-cli.exe' : 'sentry-cli';
Log.info(
'Trying to fallback to preinstalled Sentry CLI, if available on PATH: $cliPath');
return null;
}
}
53 changes: 29 additions & 24 deletions lib/src/configuration_values.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class ConfigurationValues {
final String? commits;
final bool? ignoreMissing;
final String? binDir;
final String? binPath;

ConfigurationValues({
this.version,
Expand All @@ -39,6 +40,7 @@ class ConfigurationValues {
this.commits,
this.ignoreMissing,
this.binDir,
this.binPath,
});

factory ConfigurationValues.fromArguments(List<String> arguments) {
Expand All @@ -62,30 +64,31 @@ class ConfigurationValues {
}

return ConfigurationValues(
version: sentryArguments['version'],
name: sentryArguments['name'],
uploadDebugSymbols: boolFromString(
sentryArguments['upload_debug_symbols'] ??
sentryArguments['upload_native_symbols'],
),
uploadSourceMaps: boolFromString(sentryArguments['upload_source_maps']),
uploadSources: boolFromString(
sentryArguments['upload_sources'] ??
sentryArguments['include_native_sources'],
),
project: sentryArguments['project'],
org: sentryArguments['org'],
authToken: sentryArguments['auth_token'],
url: sentryArguments['url'],
waitForProcessing:
boolFromString(sentryArguments['wait_for_processing']),
logLevel: sentryArguments['log_level'],
release: sentryArguments['release'],
dist: sentryArguments['dist'],
webBuildPath: sentryArguments['web_build_path'],
commits: sentryArguments['commits'],
ignoreMissing: boolFromString(sentryArguments['ignore_missing']),
binDir: sentryArguments['bin_dir']);
version: sentryArguments['version'],
name: sentryArguments['name'],
uploadDebugSymbols: boolFromString(
sentryArguments['upload_debug_symbols'] ??
sentryArguments['upload_native_symbols'],
),
uploadSourceMaps: boolFromString(sentryArguments['upload_source_maps']),
uploadSources: boolFromString(
sentryArguments['upload_sources'] ??
sentryArguments['include_native_sources'],
),
project: sentryArguments['project'],
org: sentryArguments['org'],
authToken: sentryArguments['auth_token'],
url: sentryArguments['url'],
waitForProcessing: boolFromString(sentryArguments['wait_for_processing']),
logLevel: sentryArguments['log_level'],
release: sentryArguments['release'],
dist: sentryArguments['dist'],
webBuildPath: sentryArguments['web_build_path'],
commits: sentryArguments['commits'],
ignoreMissing: boolFromString(sentryArguments['ignore_missing']),
binDir: sentryArguments['bin_dir'],
binPath: sentryArguments['bin_path'],
);
}

factory ConfigurationValues.fromReader(ConfigReader configReader) {
Expand Down Expand Up @@ -113,6 +116,7 @@ class ConfigurationValues {
commits: configReader.getString('commits'),
ignoreMissing: configReader.getBool('ignore_missing'),
binDir: configReader.getString('bin_dir'),
binPath: configReader.getString('bin_path'),
);
}

Expand Down Expand Up @@ -156,6 +160,7 @@ class ConfigurationValues {
commits: args.commits ?? file.commits,
ignoreMissing: args.ignoreMissing ?? file.ignoreMissing,
binDir: args.binDir ?? file.binDir,
binPath: args.binPath ?? file.binPath,
);
}
}
38 changes: 26 additions & 12 deletions scripts/update-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,34 @@ const _urlPrefix = 'https://downloads.sentry-cdn.com/sentry-cli/\$_version';
final currentCLISources = {
HostPlatform.darwinUniversal: CLISource(
'\$_urlPrefix/sentry-cli-Darwin-universal',
'$(hashFor Darwin-universal)'),
HostPlatform.linuxAarch64: CLISource('\$_urlPrefix/sentry-cli-Linux-aarch64',
'$(hashFor Linux-aarch64)'),
HostPlatform.linuxArmv7: CLISource('\$_urlPrefix/sentry-cli-Linux-armv7',
'$(hashFor Linux-armv7)'),
HostPlatform.linux64bit: CLISource('\$_urlPrefix/sentry-cli-Linux-x86_64',
'$(hashFor Linux-x86_64)'),
'\$_urlPrefix/sentry-cli-Darwin-universal',
_version,
'$(hashFor Darwin-universal)',
),
HostPlatform.linuxAarch64: CLISource(
'\$_urlPrefix/sentry-cli-Linux-aarch64',
_version,
'$(hashFor Linux-aarch64)',
),
HostPlatform.linuxArmv7: CLISource(
'\$_urlPrefix/sentry-cli-Linux-armv7',
_version,
'$(hashFor Linux-armv7)'),
HostPlatform.linux64bit: CLISource(
'\$_urlPrefix/sentry-cli-Linux-x86_64',
_version,
'$(hashFor Linux-x86_64)',
),
HostPlatform.windows32bit: CLISource(
'\$_urlPrefix/sentry-cli-Windows-i686.exe',
'$(hashFor Windows-i686.exe)'),
'\$_urlPrefix/sentry-cli-Windows-i686.exe',
_version,
'$(hashFor Windows-i686.exe)',
),
HostPlatform.windows64bit: CLISource(
'\$_urlPrefix/sentry-cli-Windows-x86_64.exe',
'$(hashFor Windows-x86_64.exe)'),
'\$_urlPrefix/sentry-cli-Windows-x86_64.exe',
_version,
'$(hashFor Windows-x86_64.exe)',
),
};
EOF
;;
Expand Down
Loading

0 comments on commit a9e00b2

Please sign in to comment.