Skip to content
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
55 changes: 53 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,23 @@ Or use directly from sources:
dart bin/raygun_cli.dart <command> <arguments>
```

#### Built-in help

Using the `--help` argument will usually output a list of command-specifc arguments and their meanings.

Example:

```
raygun-cli deployments --help
```

#### Configuration parameters

All `raygun-cli` commands share the same configuration parameters.

- App ID: The Application ID in Raygun.com.
- Token: An access token from https://app.raygun.com/user/tokens.
- API key: The API key of your application in Raygun.com

You can pass these parameters via arguments, e.g. `--app-id=<id>`
or you can set them as environment variables.
Expand All @@ -59,6 +70,8 @@ Parameters passed as arguments have priority over environment variables.
|-----------|----------|----------------------|
| App ID | `app-id` | `RAYGUN_APP_ID` |
| Token | `token` | `RAYGUN_TOKEN` |
| API key | `api-key`| `RAYGUN_API_KEY` |


#### Sourcemap Uploader

Expand Down Expand Up @@ -94,6 +107,44 @@ raygun-cli sourcemap -p flutter --uri=https://example.com/main.dart.js --app-id=

_Not available yet!_

#### Android Proguard/R8 Uploader

Upload Proguard and R8 mapping files for Android to [raygun.com](https://raygun.com).

Documentation: https://raygun.com/documentation/language-guides/android/crash-reporting/proguard/
```
raygun-cli proguard <arguments>
```

Minimal required arguments are:

```
raygun-cli proguard --app-id=APP_ID --version=<app version> --path=<Path to mapping.txt file> --external-access-token=<EAT from your Raygun user account settings> --overwrite
```

Example outputs:

```
Success:

Uploading: <somewhere>/mapping.txt
Success uploading Proguard/R8 mapping file: 200
Result: true

Mapping file for version already exists:

Uploading: <somewhere>/mapping.txt
Error uploading Proguard/R8 mapping file: 400
Response: File 1.2.3.5 already exists. Please set overwrite=true if you really want to overwrite it.

Wrong External Access Token:

Uploading: <somewhere>/mapping.txt
Error uploading Proguard/R8 mapping file: 302
Response:

```

#### Flutter obfuscation symbols

Manages obfuscation symbols to [raygun.com](https://raygun.com).
Expand Down Expand Up @@ -160,10 +211,10 @@ Send deployment tracking notifications to [raygun.com](https://raygun.com).

Documentation: https://raygun.com/documentation/product-guides/deployment-tracking/overview/

Minimal arguments are:
Minimal required arguments are:

```
raygun-cli depoyments --app-id=APP_ID --token=TOKEN --version=<app version> --api-key=<Raygun app API key>
raygun-cli depoyments --token=TOKEN --version=<app version> --api-key=API_KEY
```

Example outputs:
Expand Down
10 changes: 10 additions & 0 deletions bin/raygun_cli.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:args/args.dart';
import 'package:raygun_cli/sourcemap/sourcemap_command.dart';
import 'package:raygun_cli/symbols/flutter_symbols.dart';
import 'package:raygun_cli/deployments/deployments_command.dart';
import 'package:raygun_cli/proguard/proguard_command.dart';

const String version = '0.0.2';

Expand Down Expand Up @@ -35,6 +36,10 @@ ArgParser buildParser() {
..addCommand(
kDeploymentsCommand,
buildParserDeployments(),
)
..addCommand(
kProguardCommand,
buildParserProguard(),
);
}

Expand Down Expand Up @@ -84,6 +89,11 @@ void main(List<String> arguments) {
return;
}

if (results.command?.name == kProguardCommand) {
parseProguardCommand(results.command!, verbose);
return;
}

if (verbose) {
print('[VERBOSE] All arguments: ${results.arguments}');
}
Expand Down
1 change: 1 addition & 0 deletions lib/deployments/deployments_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ArgParser buildParserDeployments() {
)
..addOption(
'token',
mandatory: true,
help: 'Raygun access token',
)
..addOption(
Expand Down
64 changes: 64 additions & 0 deletions lib/proguard/proguard.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import 'dart:io';

import 'package:raygun_cli/proguard/proguard_api.dart';
import 'package:args/args.dart';
import '../config_props.dart';

class Proguard {
final ArgResults command;
final bool verbose;

Proguard({
required this.command,
required this.verbose,
});

Future<void> upload() async {
if (!command.wasParsed('path')) {
print('Error: Missing "--path"');
print(' Please provide "--path" via argument');
exit(2);
}

if (!command.wasParsed('version')) {
print('Error: Missing "--version"');
print(' Please provide "--version" via argument');
exit(2);
}

if (!command.wasParsed('external-access-token')) {
print('Error: Missing "--external-access-token"');
print(' Please provide "--external-access-token" via argument');
exit(2);
}

final externalAccessToken =
command.option('external-access-token') as String;
final path = command.option('path') as String;
final version = command.option('version') as String;
final overwrite = command.wasParsed('overwrite');
final appId = ConfigProp.appId.load(command);

if (verbose) {
print('app-id: $appId');
print('external-access-token: $externalAccessToken');
print('path: $path');
print('version: $version');
print('overwrite: $overwrite');
}

final success = await uploadProguardMapping(
appId: appId,
externalAccessToken: externalAccessToken,
path: path,
version: version,
overwrite: overwrite,
);

if (success) {
exit(0);
} else {
exit(2);
}
}
}
57 changes: 57 additions & 0 deletions lib/proguard/proguard_api.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'dart:io';

import 'package:http/http.dart' as http;

Future<bool> uploadProguardMapping({
required String appId,
required String externalAccessToken,
required String path,
required String version,
required bool overwrite,
}) async {
final file = File(path);
if (!file.existsSync()) {
print('$path: file not found!');
return false;
}
print('Uploading: $path');

final url =
'https://app.raygun.com/upload/proguardsymbols/$appId?authToken=$externalAccessToken';

final request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(
http.MultipartFile(
'file',
file.readAsBytes().asStream(),
file.lengthSync(),
filename: path.split("/").last,
),
);
request.fields.addAll({
'version': version,
});
if (overwrite) {
request.fields.addAll({
'overwrite': 'true',
});
}
try {
final response = await request.send();
final responseBody = await response.stream.bytesToString();

if (response.statusCode == 200) {
print(
'Success uploading Proguard/R8 mapping file: ${response.statusCode}');
print('Result: $responseBody');
return true;
}

print('Error uploading Proguard/R8 mapping file: ${response.statusCode}');
print('Response: $responseBody');
return false;
} catch (e) {
print('Exception while uploading Proguard/R8 mapping file: $e');
return false;
}
}
54 changes: 54 additions & 0 deletions lib/proguard/proguard_command.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'dart:io';

import 'package:args/args.dart';
import 'package:raygun_cli/proguard/proguard.dart';

const kProguardCommand = 'proguard';

ArgParser buildParserProguard() {
return ArgParser()
..addFlag(
'help',
abbr: 'h',
negatable: false,
help: 'Print proguard usage information',
)
..addOption(
'app-id',
mandatory: true,
help: 'Raygun application ID',
)
..addOption(
'external-access-token',
mandatory: true,
help: 'Raygun external access token',
)
..addOption(
'path',
mandatory: true,
help: 'Path to the ProGuard/R8 mapping file',
)
..addOption(
'version',
mandatory: true,
help: 'Version of the app this mapping file is for',
)
..addFlag(
'overwrite',
defaultsTo: false,
help: 'Overwrite existing mapping file if one exists for this version',
);
}

void parseProguardCommand(ArgResults command, bool verbose) {
if (command.wasParsed('help')) {
print('Usage: raygun-cli proguard <arguments>');
print(buildParserProguard().usage);
exit(0);
}

Proguard(
command: command,
verbose: verbose,
).upload();
}
Loading