Skip to content

Commit b5e9dd3

Browse files
feat: add a default logger (#20)
1 parent 13854d9 commit b5e9dd3

File tree

6 files changed

+57
-52
lines changed

6 files changed

+57
-52
lines changed

README.md

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,17 @@ If you haven't already, create a `Cargo.toml` and `rust-toolchain.toml` in your
3232
keep reading for what these two files must contain
3333
(but don't worry if you forget, you'll get a helpful error message).
3434

35-
### Quick n' dirty ("it just works") setup
35+
### `hook/build.dart`
3636
```dart
37-
// hook/build.dart:
3837
import 'package:hooks/hooks.dart';
3938
import 'package:native_toolchain_rs/native_toolchain_rs.dart';
4039
4140
void main(List<String> args) async {
4241
await build(args, (input, output) async {
43-
await RustBuilder(
44-
assetName: 'src/my_ffi_bindings.g.dart',
45-
).run(input: input, output: output);
46-
});
47-
}
48-
```
49-
50-
### Recommended setup (so you get logs)
51-
```dart
52-
// hook/build.dart:
53-
import 'package:hooks/hooks.dart';
54-
import 'package:logging/logging.dart';
55-
import 'package:native_toolchain_rs/native_toolchain_rs.dart';
56-
57-
void main(List<String> args) async {
58-
Logger.root.level = Level.CONFIG; // or whatever level you prefer
59-
60-
await build(args, (input, output) async {
61-
final logger = Logger('my_package_build')..onRecord.listen(print);
62-
6342
await RustBuilder(
6443
assetName: 'src/my_ffi_bindings.g.dart',
6544
// ...maybe enable some Cargo features or something in here too
66-
).run(input: input, output: output, logger: logger);
45+
).run(input: input, output: output);
6746
});
6847
}
6948
```

native_toolchain_rs/lib/native_toolchain_rs.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:io';
2+
13
import 'package:code_assets/code_assets.dart';
24
import 'package:hooks/hooks.dart';
35
import 'package:logging/logging.dart';
@@ -89,6 +91,7 @@ final class RustBuilder implements Builder {
8991
List<AssetRouting> assetRouting = const [ToAppBundle()],
9092
Logger? logger,
9193
}) {
94+
logger ??= _createDefaultLogger();
9295
final processRunner = ProcessRunner(logger);
9396
const crateDirectoryResolver = CrateDirectoryResolver();
9497
final tomlDocumentWrapperFactory = TomlDocumentWrapperFactory(logger);
@@ -116,3 +119,22 @@ final class RustBuilder implements Builder {
116119
).run(input: input, output: output, assetRouting: assetRouting);
117120
}
118121
}
122+
123+
Logger _createDefaultLogger() {
124+
return Logger.detached('RustBuilder')
125+
..level = Level.CONFIG
126+
..onRecord.listen((LogRecord record) {
127+
final output = record.level >= Level.WARNING ? stderr : stdout;
128+
129+
// NOTE: this is an unreadable mess with cascade notation
130+
// ignore: cascade_invocations
131+
output.writeln(record);
132+
133+
if (record.error != null) {
134+
output.writeln(record.error);
135+
}
136+
if (record.stackTrace != null) {
137+
output.writeln(record.stackTrace);
138+
}
139+
});
140+
}

native_toolchain_rs/lib/src/build_runner.dart

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ interface class RustBuildRunner {
2424
});
2525

2626
final RustBuilder config;
27-
final Logger? logger;
27+
final Logger logger;
2828
final CrateDirectoryResolver crateDirectoryResolver;
2929
final ProcessRunner processRunner;
3030
final BuildEnvironmentFactory buildEnvironmentFactory;
@@ -35,19 +35,20 @@ interface class RustBuildRunner {
3535
required BuildOutputBuilder output,
3636
required List<AssetRouting> assetRouting,
3737
}) async {
38-
logger?.info('Starting build of Rust native assets');
39-
logger?.config(input);
40-
logger?.config(Platform.environment);
38+
logger
39+
..info('Starting build of Rust native assets')
40+
..config(input)
41+
..config(Platform.environment);
4142

4243
if (!input.config.buildCodeAssets) {
43-
logger?.info(
44+
logger.info(
4445
'buildCodeAssets is false; '
4546
'skipping build of Rust native assets',
4647
);
4748
return;
4849
}
4950

50-
logger?.info('Gathering all data required for the build');
51+
logger.info('Gathering all data required for the build');
5152
final codeConfig = input.config.code;
5253
final CodeConfig(:targetOS, :targetTriple, :linkMode) = codeConfig;
5354
final RustBuilder(
@@ -77,10 +78,10 @@ interface class RustBuildRunner {
7778
// NOTE: re-run build whenever anything in the Rust directory changes
7879
output.dependencies.add(crateDirectory.uri);
7980

80-
logger?.info('Ensuring $toolchainChannel is installed');
81+
logger.info('Ensuring $toolchainChannel is installed');
8182
await ensureToolchainDownloaded(crateDirectory.path);
8283

83-
logger?.info('Running cargo build');
84+
logger.info('Running cargo build');
8485
await processRunner.invokeRustup(
8586
[
8687
'run',
@@ -135,6 +136,6 @@ interface class RustBuildRunner {
135136
'show',
136137
'active-toolchain',
137138
], workingDirectory: crateDirectory);
138-
logger?.config(showToolchainOutput);
139+
logger.config(showToolchainOutput);
139140
}
140141
}

native_toolchain_rs/lib/src/process_runner.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import 'package:native_toolchain_rs/src/exception.dart';
77
@internal
88
interface class ProcessRunner {
99
const ProcessRunner(this.logger);
10-
final Logger? logger;
10+
final Logger logger;
1111

1212
Future<String> invoke(
1313
String executable,
@@ -16,7 +16,7 @@ interface class ProcessRunner {
1616
Map<String, String>? environment,
1717
}) async {
1818
try {
19-
logger?.info(
19+
logger.info(
2020
'Invoking "$executable $arguments" '
2121
'${workingDirectory != null ? 'in directory $workingDirectory ' : ''}'
2222
'with environment: ${environment ?? {}}',
@@ -35,7 +35,7 @@ interface class ProcessRunner {
3535
}
3636
return result.stdout as String;
3737
} on ProcessException catch (exception, stackTrace) {
38-
logger?.severe(
38+
logger.severe(
3939
'Failed to invoke "$executable $arguments"',
4040
exception,
4141
stackTrace,

native_toolchain_rs/lib/src/toml_parsing.dart

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:toml/toml.dart';
88
@internal
99
interface class TomlDocumentWrapperFactory {
1010
const TomlDocumentWrapperFactory(this.logger);
11-
final Logger? logger;
11+
final Logger logger;
1212

1313
TomlDocumentWrapper parseFile(String filePath) =>
1414
TomlDocumentWrapper(logger, filePath, TomlDocument.loadSync(filePath));
@@ -18,7 +18,7 @@ interface class TomlDocumentWrapperFactory {
1818
final class TomlDocumentWrapper {
1919
const TomlDocumentWrapper(this.logger, this.filePath, this.document);
2020

21-
final Logger? logger;
21+
final Logger logger;
2222
final String filePath;
2323
final TomlDocument document;
2424

@@ -32,7 +32,7 @@ final class TomlDocumentWrapper {
3232
}
3333
return currNode as T;
3434
} on Object catch (exception, stackTrace) {
35-
logger?.severe(
35+
logger.severe(
3636
'Failed to find $path in $filePath: $document',
3737
exception,
3838
stackTrace,
@@ -50,13 +50,13 @@ The following exception was thrown: $exception''',
5050
@internal
5151
interface class CargoManifestParser {
5252
const CargoManifestParser(this.logger, this.tomlDocumentFactory);
53-
final Logger? logger;
53+
final Logger logger;
5454
final TomlDocumentWrapperFactory tomlDocumentFactory;
5555

5656
({String crateName, List<String> libCrateTypes}) parseManifest(
5757
String manifestPath,
5858
) {
59-
logger?.info('Looking for Cargo.toml');
59+
logger.info('Looking for Cargo.toml');
6060
if (!File(manifestPath).existsSync()) {
6161
throw RustValidationException([
6262
'''
@@ -65,12 +65,12 @@ For more information, see https://github.com/GregoryConrad/native_toolchain_rs?t
6565
]);
6666
}
6767

68-
logger?.info('Parsing Cargo.toml');
68+
logger.info('Parsing Cargo.toml');
6969
final TomlDocumentWrapper manifest;
7070
try {
7171
manifest = tomlDocumentFactory.parseFile(manifestPath);
7272
} on Object catch (exception, stackTrace) {
73-
logger?.severe('Failed to parse Cargo.toml', exception, stackTrace);
73+
logger.severe('Failed to parse Cargo.toml', exception, stackTrace);
7474
throw RustValidationException([
7575
'''
7676
Failed to parse the Cargo.toml file at $manifestPath.
@@ -116,13 +116,13 @@ and https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-
116116
@internal
117117
interface class ToolchainTomlParser {
118118
const ToolchainTomlParser(this.logger, this.tomlDocumentFactory);
119-
final Logger? logger;
119+
final Logger logger;
120120
final TomlDocumentWrapperFactory tomlDocumentFactory;
121121

122122
({Set<String> targets, String channel}) parseToolchainToml(
123123
String toolchainTomlPath,
124124
) {
125-
logger?.info('Looking for rust-toolchain.toml');
125+
logger.info('Looking for rust-toolchain.toml');
126126
if (!File(toolchainTomlPath).existsSync()) {
127127
throw RustValidationException([
128128
'''
@@ -131,12 +131,12 @@ For more information, see https://github.com/GregoryConrad/native_toolchain_rs?t
131131
]);
132132
}
133133

134-
logger?.info('Parsing rust-toolchain.toml');
134+
logger.info('Parsing rust-toolchain.toml');
135135
final TomlDocumentWrapper toolchain;
136136
try {
137137
toolchain = tomlDocumentFactory.parseFile(toolchainTomlPath);
138138
} on Object catch (e, stackTrace) {
139-
logger?.severe('Failed to parse rust-toolchain.toml', e, stackTrace);
139+
logger.severe('Failed to parse rust-toolchain.toml', e, stackTrace);
140140
throw RustValidationException([
141141
'''
142142
Failed to parse the rust-toolchain.toml file at $toolchainTomlPath.

native_toolchain_rs/test/toml_parsing_test.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import 'dart:io';
22

3+
import 'package:logging/logging.dart';
34
import 'package:native_toolchain_rs/src/exception.dart';
45
import 'package:native_toolchain_rs/src/toml_parsing.dart';
56
import 'package:test/test.dart';
67

78
void main() {
9+
final logger = Logger.detached('TestLogger');
10+
811
group('TomlDocumentWrapper', () {
912
late Directory tempDir;
1013
late String tempFilePath;
@@ -20,14 +23,14 @@ void main() {
2023

2124
test('walk returns value when path is valid', () {
2225
File(tempFilePath).writeAsStringSync('key = "value"\n');
23-
const factory = TomlDocumentWrapperFactory(null);
26+
final factory = TomlDocumentWrapperFactory(logger);
2427
final wrapper = factory.parseFile(tempFilePath);
2528
expect(wrapper.walk<String>('key'), 'value');
2629
});
2730

2831
test('walk throws RustValidationException when path is invalid', () {
2932
File(tempFilePath).writeAsStringSync('key = "value"\n');
30-
const factory = TomlDocumentWrapperFactory(null);
33+
final factory = TomlDocumentWrapperFactory(logger);
3134
final wrapper = factory.parseFile(tempFilePath);
3235
expect(
3336
() => wrapper.walk<String>('invalid.path'),
@@ -37,8 +40,8 @@ void main() {
3740
});
3841

3942
group('CargoManifestParser', () {
40-
const tomlDocumentFactory = TomlDocumentWrapperFactory(null);
41-
const parser = CargoManifestParser(null, tomlDocumentFactory);
43+
final tomlDocumentFactory = TomlDocumentWrapperFactory(logger);
44+
final parser = CargoManifestParser(logger, tomlDocumentFactory);
4245
late Directory tempDir;
4346
late String tempManifestPath;
4447

@@ -84,8 +87,8 @@ crate-type = ["staticlib"]
8487
});
8588

8689
group('ToolchainTomlParser', () {
87-
const tomlDocumentFactory = TomlDocumentWrapperFactory(null);
88-
const parser = ToolchainTomlParser(null, tomlDocumentFactory);
90+
final tomlDocumentFactory = TomlDocumentWrapperFactory(logger);
91+
final parser = ToolchainTomlParser(logger, tomlDocumentFactory);
8992
late Directory tempDir;
9093
late String tempToolchainTomlPath;
9194

0 commit comments

Comments
 (0)