Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sentry.properties #191

Merged
merged 14 commits into from
Jan 30, 2024
Merged
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Features

- Support reading config from sentry.properties file ([#191](https://github.com/getsentry/sentry-dart-plugin/pull/191))

### Dependencies

- Bump CLI from v2.21.2 to v2.22.3 ([#180](https://github.com/getsentry/sentry-dart-plugin/pull/180))
Expand Down
80 changes: 29 additions & 51 deletions lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import 'dart:io';
import 'package:file/file.dart';
import 'package:process/process.dart';
import 'package:system_info2/system_info2.dart';
import 'package:yaml/yaml.dart';

import 'cli/host_platform.dart';
import 'cli/setup.dart';
import 'utils/config-reader/config_reader.dart';
import 'utils/extensions.dart';
import 'utils/injector.dart';
import 'utils/log.dart';
Expand Down Expand Up @@ -80,57 +80,51 @@ class Configuration {
/// https://docs.sentry.io/product/cli/releases/#dealing-with-missing-commits
late bool ignoreMissing;

dynamic _getPubspec() {
final file = injector.get<FileSystem>().file("pubspec.yaml");
if (!file.existsSync()) {
Log.error("Pubspec not found: ${file.absolute.path}");
return {};
}
final pubspecString = file.readAsStringSync();
final pubspec = loadYaml(pubspecString);
return pubspec;
}

/// Loads the configuration values
Future<void> getConfigValues(List<String> arguments) async {
final environments = Platform.environment;
const taskName = 'reading config values';
Log.startingTask(taskName);

await _findAndSetCliPath();
final pubspec = _getPubspec();
final config = pubspec['sentry'] as YamlMap?;

release = config?['release']?.toString() ?? environments['SENTRY_RELEASE'];
dist = config?['dist']?.toString() ?? environments['SENTRY_DIST'];
final reader = ConfigReader();
loadConfig(reader);

Log.taskCompleted(taskName);
}

void loadConfig(ConfigReader reader) {
final environments = Platform.environment;
final pubspec = ConfigReader.getPubspec();

release = reader.getString('release') ?? environments['SENTRY_RELEASE'];
dist = reader.getString('dist') ?? environments['SENTRY_DIST'];
version = pubspec['version'].toString();
name = pubspec['name'].toString();

uploadDebugSymbols =
config?.get('upload_debug_symbols', 'upload_native_symbols') ?? true;
uploadSourceMaps = config?['upload_source_maps'] ?? false;
uploadSources =
config?.get('upload_sources', 'include_native_sources') ?? false;
commits = (config?['commits'] ?? 'auto').toString();
ignoreMissing = config?['ignore_missing'] ?? false;
uploadDebugSymbols = reader.getBool('upload_debug_symbols',
deprecatedKey: 'upload_native_symbols') ??
true;
uploadSourceMaps = reader.getBool('upload_source_maps') ?? false;
uploadSources = reader.getBool('upload_sources',
deprecatedKey: 'include_native_sources') ??
false;
commits = (reader.getString('commits') ?? 'auto').toString();
ignoreMissing = reader.getBool('ignore_missing') ?? false;

// uploading JS and Map files need to have the correct folder structure
// otherwise symbolication fails, the default path for the web build folder is build/web
// but can be customized so making it flexible.
final webBuildPath =
config?['web_build_path']?.toString() ?? _fs.path.join('build', 'web');
reader.getString('web_build_path') ?? _fs.path.join('build', 'web');
webBuildFilesFolder = _fs.path.join(buildFilesFolder, webBuildPath);

project = config?['project']?.toString(); // or env. var. SENTRY_PROJECT
org = config?['org']?.toString(); // or env. var. SENTRY_ORG
waitForProcessing = config?['wait_for_processing'] ?? false;
project = reader.getString('project'); // or env. var. SENTRY_PROJECT
org = reader.getString('org'); // or env. var. SENTRY_ORG
waitForProcessing = reader.getBool('wait_for_processing') ?? false;
authToken =
config?['auth_token']?.toString(); // or env. var. SENTRY_AUTH_TOKEN
url = config?['url']?.toString(); // or env. var. SENTRY_URL
logLevel =
config?['log_level']?.toString(); // or env. var. SENTRY_LOG_LEVEL

Log.taskCompleted(taskName);
reader.getString('auth_token'); // or env. var. SENTRY_AUTH_TOKEN
url = reader.getString('url'); // or env. var. SENTRY_URL
logLevel = reader.getString('log_level'); // or env. var. SENTRY_LOG_LEVEL
}

/// Validates the configuration values and log an error if required fields
Expand Down Expand Up @@ -227,19 +221,3 @@ class Configuration {
'Trying to fallback to preinstalled Sentry CLI, if available on PATH: $cliPath');
}
}

extension _Config on YamlMap {
T? get<T>(String name, String? deprecatedName) {
if (deprecatedName != null && containsKey(deprecatedName)) {
Log.warn(
'Your pubspec.yaml contains `$deprecatedName` which is deprecated. Consider switching to `$name`.');
}
if (containsKey(name)) {
return this[name];
} else if (deprecatedName != null && containsKey(deprecatedName)) {
return this[deprecatedName];
} else {
return null;
}
}
}
70 changes: 70 additions & 0 deletions lib/src/utils/config-reader/config_reader.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:properties/properties.dart';
import 'package:yaml/yaml.dart';
import 'package:file/file.dart';

import '../injector.dart';
import '../log.dart';
import 'no_op_config_reader.dart';
import 'properties_config_reader.dart';
import 'yaml_config_reader.dart';

abstract class ConfigReader {
String? getString(String key, {String? deprecatedKey});
bool? getBool(String key, {String? deprecatedKey});
bool contains(String key);

/// By default this ConfigReader factory will try to load pubspec.yaml first.
/// If the sentry config doesn't exist on pubspec.yaml it will use sentry.properties as fallback.
factory ConfigReader() {
// Attempt to retrieve the config from pubspec.yaml first
final pubspec = getPubspec();
final sentryConfig = pubspec['sentry'] as YamlMap?;
if (sentryConfig != null) {
Log.info('retrieving config from pubspec.yaml');
return YamlConfigReader(sentryConfig);
} else {
Log.info('sentry config not found in pubspec.yaml');
}

// If sentry config is not found in pubspec.yaml, try loading from sentry.properties
final propertiesFile = injector.get<FileSystem>().file("sentry.properties");
if (propertiesFile.existsSync()) {
Log.info('retrieving config from sentry.properties');
// Loads properties class via string as there are issues loading the file
// from path if run in the test suite
final properties =
Properties.fromString(propertiesFile.readAsStringSync());
return PropertiesConfigReader(properties);
}
Log.error('no config found, please use sentry.properties or pubspec.yaml.');
return NoOpConfigReader();
}

static dynamic getPubspec() {
final file = injector.get<FileSystem>().file("pubspec.yaml");
if (!file.existsSync()) {
Log.error("Pubspec not found: ${file.absolute.path}");
return {};
}
final pubspecString = file.readAsStringSync();
final pubspec = loadYaml(pubspecString);
return pubspec;
}
}

extension Config on ConfigReader {
T? get<T>(
String name, String? deprecatedName, T? Function(String key) resolve) {
if (deprecatedName != null && contains(deprecatedName)) {
Log.warn(
'Your config contains `$deprecatedName` which is deprecated. Consider switching to `$name`.');
}
if (contains(name)) {
return resolve(name);
} else if (deprecatedName != null && contains(deprecatedName)) {
return resolve(deprecatedName);
} else {
return null;
}
}
}
20 changes: 20 additions & 0 deletions lib/src/utils/config-reader/no_op_config_reader.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'config_reader.dart';

class NoOpConfigReader implements ConfigReader {
NoOpConfigReader();

@override
bool? getBool(String key, {String? deprecatedKey}) {
return null;
}

@override
String? getString(String key, {String? deprecatedKey}) {
return null;
}

@override
bool contains(String key) {
return false;
}
}
24 changes: 24 additions & 0 deletions lib/src/utils/config-reader/properties_config_reader.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:properties/properties.dart';

import 'config_reader.dart';

class PropertiesConfigReader implements ConfigReader {
final Properties _properties;

PropertiesConfigReader(Properties properties) : _properties = properties;

@override
bool? getBool(String key, {String? deprecatedKey}) {
return get(key, deprecatedKey, (key) => _properties.getBool((key)));
}

@override
String? getString(String key, {String? deprecatedKey}) {
return get(key, deprecatedKey, (key) => _properties.get((key)));
}

@override
bool contains(String key) {
return _properties.contains(key);
}
}
24 changes: 24 additions & 0 deletions lib/src/utils/config-reader/yaml_config_reader.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:yaml/yaml.dart';

import 'config_reader.dart';

class YamlConfigReader implements ConfigReader {
final YamlMap? _yamlMap;

YamlConfigReader(YamlMap? yamlMap) : _yamlMap = yamlMap;

@override
bool? getBool(String key, {String? deprecatedKey}) {
return get(key, deprecatedKey, (key) => _yamlMap?[key] as bool?);
}

@override
String? getString(String key, {String? deprecatedKey}) {
return get(key, deprecatedKey, (key) => (_yamlMap?[key]).toString());
}

@override
bool contains(String key) {
return _yamlMap?.containsKey(key) ?? false;
}
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies:
crypto: ^3.0.2
convert: ^3.0.2
process: ^4.2.4
properties: ^2.1.0

dev_dependencies:
lints: ^3.0.0
Expand Down
Loading
Loading