Skip to content

Commit 9e29ed9

Browse files
fix: add all build dependencies to the output for rebuilds (#44)
Fixes #43
1 parent a8f3b3c commit 9e29ed9

File tree

5 files changed

+172
-41
lines changed

5 files changed

+172
-41
lines changed

native_toolchain_rust/lib/native_toolchain_rust.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:native_toolchain_rust/src/build_environment.dart';
88
import 'package:native_toolchain_rust/src/build_runner.dart';
99
import 'package:native_toolchain_rust/src/crate_info_validator.dart';
1010
import 'package:native_toolchain_rust/src/crate_resolver.dart';
11+
import 'package:native_toolchain_rust/src/dependency_discoverer.dart';
1112
import 'package:native_toolchain_rust/src/process_runner.dart';
1213
import 'package:native_toolchain_rust/src/toml_parsing.dart';
1314

@@ -108,6 +109,7 @@ final class RustBuilder implements Builder {
108109
toolchainTomlParser: toolchainTomlParser,
109110
cargoManifestParser: cargoManifestParser,
110111
);
112+
final dependencyDiscoverer = DependencyDiscoverer(logger);
111113

112114
return RustBuildRunner(
113115
config: this,
@@ -116,6 +118,7 @@ final class RustBuilder implements Builder {
116118
crateDirectoryResolver: crateDirectoryResolver,
117119
buildEnvironmentFactory: buildEnvironmentFactory,
118120
crateInfoValidator: crateInfoValidator,
121+
dependencyDiscoverer: dependencyDiscoverer,
119122
).run(input: input, output: output, assetRouting: assetRouting);
120123
}
121124
}

native_toolchain_rust/lib/src/build_runner.dart

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:native_toolchain_rust/src/build_environment.dart';
99
import 'package:native_toolchain_rust/src/config_mapping.dart';
1010
import 'package:native_toolchain_rust/src/crate_info_validator.dart';
1111
import 'package:native_toolchain_rust/src/crate_resolver.dart';
12+
import 'package:native_toolchain_rust/src/dependency_discoverer.dart';
1213
import 'package:native_toolchain_rust/src/process_runner.dart';
1314
import 'package:path/path.dart' as path;
1415

@@ -21,6 +22,7 @@ interface class RustBuildRunner {
2122
required this.processRunner,
2223
required this.buildEnvironmentFactory,
2324
required this.crateInfoValidator,
25+
required this.dependencyDiscoverer,
2426
});
2527

2628
final RustBuilder config;
@@ -29,6 +31,7 @@ interface class RustBuildRunner {
2931
final ProcessRunner processRunner;
3032
final BuildEnvironmentFactory buildEnvironmentFactory;
3133
final CrateInfoValidator crateInfoValidator;
34+
final DependencyDiscoverer dependencyDiscoverer;
3235

3336
Future<void> run({
3437
required BuildInput input,
@@ -75,9 +78,6 @@ interface class RustBuildRunner {
7578
toolchainTomlPath: path.join(crateDirectory.path, 'rust-toolchain.toml'),
7679
);
7780

78-
// NOTE: re-run build whenever anything in the Rust directory changes
79-
output.dependencies.add(crateDirectory.uri);
80-
8181
logger.info('Ensuring $toolchainChannel is installed');
8282
await ensureToolchainDownloaded(crateDirectory.path);
8383

@@ -107,22 +107,25 @@ interface class RustBuildRunner {
107107
},
108108
);
109109

110+
final binaryFilePath = path.join(
111+
outputDir,
112+
targetTriple,
113+
cargoBuildMode,
114+
targetOS.libraryFileName(crateName, linkMode).replaceAll('-', '_'),
115+
);
116+
117+
// NOTE: re-run build whenever any of the dependencies change
118+
output.dependencies.addAll(
119+
dependencyDiscoverer.discover(path.setExtension(binaryFilePath, '.d')),
120+
);
121+
110122
for (final routing in assetRouting) {
111123
output.assets.code.add(
112124
CodeAsset(
113125
package: input.packageName,
114126
name: assetName,
115127
linkMode: linkMode,
116-
file: path.toUri(
117-
path.join(
118-
outputDir,
119-
targetTriple,
120-
cargoBuildMode,
121-
targetOS
122-
.libraryFileName(crateName, linkMode)
123-
.replaceAll('-', '_'),
124-
),
125-
),
128+
file: path.toUri(binaryFilePath),
126129
),
127130
routing: routing,
128131
);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import 'dart:io';
2+
3+
import 'package:logging/logging.dart';
4+
import 'package:meta/meta.dart';
5+
import 'package:path/path.dart' as path;
6+
7+
@internal
8+
interface class DependencyDiscoverer {
9+
const DependencyDiscoverer(this.logger);
10+
11+
final Logger logger;
12+
13+
/// Finds all the dependencies from the specified dependency file,
14+
/// including the dependency file itself.
15+
Iterable<Uri> discover(String dependencyFilePath) {
16+
logger.fine('Discovering dependencies in $dependencyFilePath');
17+
return File(dependencyFilePath)
18+
.readAsLinesSync()
19+
.map((line) {
20+
final splitIndex = line.indexOf(':');
21+
if (splitIndex < 0) return null;
22+
return line.substring(splitIndex + 1).trim();
23+
})
24+
.nonNulls
25+
.expand((files) => files.split(' '))
26+
.followedBy([dependencyFilePath])
27+
.map(path.toUri);
28+
}
29+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import 'dart:io';
2+
3+
import 'package:logging/logging.dart';
4+
import 'package:native_toolchain_rust/src/dependency_discoverer.dart';
5+
import 'package:path/path.dart' as path;
6+
import 'package:test/test.dart';
7+
8+
void main() {
9+
group('DependencyDiscoverer', () {
10+
late DependencyDiscoverer dependencyDiscoverer;
11+
late Directory tempDir;
12+
13+
setUp(() {
14+
tempDir = Directory.systemTemp.createTempSync();
15+
dependencyDiscoverer = DependencyDiscoverer(Logger.detached(''));
16+
});
17+
18+
tearDown(() {
19+
tempDir.deleteSync(recursive: true);
20+
});
21+
22+
test('discover returns dependencies from a valid dependency file', () {
23+
final dependencyFilePath = path.join(tempDir.path, 'test.d');
24+
File(dependencyFilePath).writeAsStringSync(
25+
'target/debug/librust_lib.a: src/lib.rs /path/to/some/other/file.rs',
26+
);
27+
28+
final dependencies = dependencyDiscoverer.discover(dependencyFilePath);
29+
30+
expect(
31+
dependencies,
32+
containsAll([
33+
path.toUri('src/lib.rs'),
34+
path.toUri('/path/to/some/other/file.rs'),
35+
path.toUri(dependencyFilePath),
36+
]),
37+
);
38+
});
39+
40+
test('discover handles multiple lines in the dependency file', () {
41+
final dependencyFilePath = path.join(tempDir.path, 'test.d');
42+
File(dependencyFilePath).writeAsStringSync('''
43+
target/debug/librust_lib.a: src/lib.rs
44+
target/debug/librust_lib.a: /path/to/some/other/file.rs
45+
''');
46+
47+
final dependencies = dependencyDiscoverer.discover(dependencyFilePath);
48+
49+
expect(
50+
dependencies,
51+
containsAll([
52+
path.toUri('src/lib.rs'),
53+
path.toUri('/path/to/some/other/file.rs'),
54+
path.toUri(dependencyFilePath),
55+
]),
56+
);
57+
});
58+
59+
test('discover ignores lines without a colon', () {
60+
final dependencyFilePath = path.join(tempDir.path, 'test.d');
61+
File(dependencyFilePath).writeAsStringSync('''
62+
invalid line
63+
target/debug/librust_lib.a: src/lib.rs
64+
''');
65+
66+
final dependencies = dependencyDiscoverer.discover(dependencyFilePath);
67+
68+
expect(
69+
dependencies,
70+
containsAll([
71+
path.toUri('src/lib.rs'),
72+
path.toUri(dependencyFilePath),
73+
]),
74+
);
75+
expect(dependencies.length, 2);
76+
});
77+
78+
test('discover handles an empty dependency file', () {
79+
final dependencyFilePath = path.join(tempDir.path, 'test.d');
80+
File(dependencyFilePath).writeAsStringSync('');
81+
82+
final dependencies = dependencyDiscoverer.discover(dependencyFilePath);
83+
84+
expect(
85+
dependencies,
86+
containsAll([
87+
path.toUri(dependencyFilePath),
88+
]),
89+
);
90+
expect(dependencies.length, 1);
91+
});
92+
93+
test(
94+
'discover throws an exception if the dependency file is not found',
95+
() {
96+
final dependencyFilePath = path.join(tempDir.path, 'non_existent.d');
97+
expect(
98+
() => dependencyDiscoverer.discover(dependencyFilePath),
99+
throwsA(isA<PathNotFoundException>()),
100+
);
101+
},
102+
);
103+
});
104+
}

pubspec.lock

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ packages:
55
dependency: transitive
66
description:
77
name: _fe_analyzer_shared
8-
sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d
8+
sha256: "5b7468c326d2f8a4f630056404ca0d291ade42918f4a3c6233618e724f39da8e"
99
url: "https://pub.dev"
1010
source: hosted
11-
version: "91.0.0"
11+
version: "92.0.0"
1212
analyzer:
1313
dependency: transitive
1414
description:
1515
name: analyzer
16-
sha256: f51c8499b35f9b26820cfe914828a6a98a94efd5cc78b37bb7d03debae3a1d08
16+
sha256: "70e4b1ef8003c64793a9e268a551a82869a8a96f39deb73dea28084b0e8bf75e"
1717
url: "https://pub.dev"
1818
source: hosted
19-
version: "8.4.1"
19+
version: "9.0.0"
2020
ansi_styles:
2121
dependency: transitive
2222
description:
@@ -157,10 +157,10 @@ packages:
157157
dependency: transitive
158158
description:
159159
name: dart_style
160-
sha256: c87dfe3d56f183ffe9106a18aebc6db431fc7c98c31a54b952a77f3d54a85697
160+
sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b
161161
url: "https://pub.dev"
162162
source: hosted
163-
version: "3.1.2"
163+
version: "3.1.3"
164164
fake_async:
165165
dependency: transitive
166166
description:
@@ -181,10 +181,10 @@ packages:
181181
dependency: transitive
182182
description:
183183
name: ffigen
184-
sha256: "5c792e87491e762b64c225c295563534e37df68b4d4ccbf2f6b928d264285a73"
184+
sha256: b7803707faeec4ce3c1b0c2274906504b796e3b70ad573577e72333bd1c9b3ba
185185
url: "https://pub.dev"
186186
source: hosted
187-
version: "20.1.0"
187+
version: "20.1.1"
188188
file:
189189
dependency: transitive
190190
description:
@@ -282,14 +282,6 @@ packages:
282282
url: "https://pub.dev"
283283
source: hosted
284284
version: "1.0.5"
285-
js:
286-
dependency: transitive
287-
description:
288-
name: js
289-
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
290-
url: "https://pub.dev"
291-
source: hosted
292-
version: "0.7.2"
293285
json_annotation:
294286
dependency: transitive
295287
description:
@@ -334,18 +326,18 @@ packages:
334326
dependency: transitive
335327
description:
336328
name: matcher
337-
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
329+
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
338330
url: "https://pub.dev"
339331
source: hosted
340-
version: "0.12.17"
332+
version: "0.12.18"
341333
material_color_utilities:
342334
dependency: transitive
343335
description:
344336
name: material_color_utilities
345-
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
337+
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
346338
url: "https://pub.dev"
347339
source: hosted
348-
version: "0.11.1"
340+
version: "0.13.0"
349341
melos:
350342
dependency: "direct dev"
351343
description:
@@ -587,26 +579,26 @@ packages:
587579
dependency: transitive
588580
description:
589581
name: test
590-
sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
582+
sha256: "77cc98ea27006c84e71a7356cf3daf9ddbde2d91d84f77dbfe64cf0e4d9611ae"
591583
url: "https://pub.dev"
592584
source: hosted
593-
version: "1.26.3"
585+
version: "1.28.0"
594586
test_api:
595587
dependency: transitive
596588
description:
597589
name: test_api
598-
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
590+
sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8"
599591
url: "https://pub.dev"
600592
source: hosted
601-
version: "0.7.7"
593+
version: "0.7.8"
602594
test_core:
603595
dependency: transitive
604596
description:
605597
name: test_core
606-
sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
598+
sha256: f1072617a6657e5fc09662e721307f7fb009b4ed89b19f47175d11d5254a62d4
607599
url: "https://pub.dev"
608600
source: hosted
609-
version: "0.6.12"
601+
version: "0.6.14"
610602
toml:
611603
dependency: transitive
612604
description:
@@ -715,10 +707,10 @@ packages:
715707
dependency: transitive
716708
description:
717709
name: yaml_edit
718-
sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5
710+
sha256: ec709065bb2c911b336853b67f3732dd13e0336bd065cc2f1061d7610ddf45e3
719711
url: "https://pub.dev"
720712
source: hosted
721-
version: "2.2.2"
713+
version: "2.2.3"
722714
sdks:
723715
dart: ">=3.9.0 <4.0.0"
724716
flutter: ">=3.18.0-18.0.pre.54"

0 commit comments

Comments
 (0)