Skip to content

Commit 21408da

Browse files
authored
Trim packages when running in a workspace. (#4278)
* Trim packages when running in a workspace. * Address review comments.
1 parent 0030712 commit 21408da

File tree

5 files changed

+117
-11
lines changed

5 files changed

+117
-11
lines changed

build_runner/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
- Bug fix: fix crash when you run `dart run build_runner build` in a
44
subdirectory of a package.
5+
- Bug fix: in a workspace, generate for transitive dependencies of the current
6+
package instead of for all packages in the workspace.
57

68
## 2.10.2
79

build_runner/lib/src/build_plan/package_graph.dart

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,31 @@ class PackageGraph implements AssetPathProvider {
155155
),
156156
);
157157
}
158-
return PackageGraph._(rootNode, nodes);
158+
159+
// A workspace can have packages that are not depended on by [rootPackage].
160+
// Compute transitive dependencies and filter to that.
161+
Set<PackageNode>? usedNodes;
162+
if (workspacePath != null) {
163+
usedNodes = {rootNode};
164+
final queue = [rootNode];
165+
while (queue.isNotEmpty) {
166+
final node = queue.removeLast();
167+
for (final dep in node.dependencies) {
168+
if (usedNodes.add(dep)) {
169+
queue.add(dep);
170+
}
171+
}
172+
}
173+
}
174+
175+
return PackageGraph._(
176+
rootNode,
177+
usedNodes == null
178+
? nodes
179+
: Map.fromEntries(
180+
nodes.entries.where((e) => usedNodes!.contains(e.value)),
181+
),
182+
);
159183
}
160184

161185
/// Creates a [PackageGraph] for the package in which you are currently

build_runner/test/build_plan/package_graph_test.dart

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ void main() {
192192
group('workspace ', () {
193193
final workspaceFixturePath = p.absolute('test/fixtures/workspace');
194194

195-
test('Loads all packages in workspace. Has correct root', () async {
195+
test('loads only dependent packages, has correct root', () async {
196196
Matcher packageNodeEquals(PackageNode node) => isA<PackageNode>()
197197
.having((c) => c.path, 'path', node.path)
198198
.having(
@@ -223,17 +223,10 @@ void main() {
223223
null,
224224
);
225225
a.dependencies.add(b);
226-
final workspace = PackageNode(
227-
'workspace',
228-
workspaceFixturePath,
229-
DependencyType.path,
230-
null,
231-
);
232226

233227
expect(graph.allPackages, {
234228
'a': packageNodeEquals(a),
235229
'b': packageNodeEquals(b),
236-
'workspace': packageNodeEquals(workspace),
237230
r'$sdk': anything,
238231
});
239232

build_runner/test/common/build_runner_tester.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class BuildRunnerTester {
4343
required Map<String, String> files,
4444
List<String>? dependencies,
4545
List<String>? pathDependencies,
46+
List<String>? workspaceDependencies,
47+
bool inWorkspace = false,
4648
}) {
4749
_writeDirectory(
4850
name: name,
@@ -51,6 +53,8 @@ class BuildRunnerTester {
5153
name: name,
5254
dependencies: dependencies,
5355
pathDependencies: pathDependencies,
56+
workspaceDependencies: workspaceDependencies,
57+
inWorkspace: inWorkspace,
5458
),
5559
...files,
5660
},
@@ -410,22 +414,35 @@ class Pubspecs {
410414
/// The specified [pathDependencies] are included as path dependencies onto
411415
/// peer folders. This allows to add a dependency onto another package that
412416
/// will be written using `writePackage`.
417+
///
418+
/// The specified [workspaceDependencies] are included as "any" dependencies.
419+
/// They should be in the workspace so they can be resolved from there.
420+
///
421+
/// If [inWorkspace] then `resolution: workspace`.
413422
String pubspec({
414423
required String name,
415424
List<String>? dependencies,
416425
List<String>? pathDependencies,
426+
List<String>? workspaceDependencies,
427+
bool inWorkspace = false,
417428
}) {
418429
dependencies ??= [];
419430
pathDependencies ??= [];
431+
workspaceDependencies ??= [];
420432

421433
final result = StringBuffer('''
422434
name: $name
435+
${inWorkspace ? 'resolution: workspace' : ''}
423436
environment:
424437
sdk: '>=3.7.0 <4.0.0'
425438
dependencies:
426439
''');
427440

428-
for (final package in [...dependencies, ...pathDependencies]) {
441+
for (final package in [
442+
...dependencies,
443+
...pathDependencies,
444+
...workspaceDependencies,
445+
]) {
429446
result.writeln(' $package: any');
430447
}
431448

build_runner/test/integration_tests/build_command_packages_and_paths_test.dart

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,84 @@ void main() async {
2020
tester.writePackage(
2121
name: 'root_pkg',
2222
dependencies: ['build_runner'],
23-
pathDependencies: ['builder_pkg'],
23+
pathDependencies: ['builder_pkg', 'other_pkg'],
2424
files: {'lib/a.txt': 'a'},
2525
);
26+
tester.writePackage(name: 'other_pkg', files: {'lib/b.txt': 'b'});
2627

2728
// Runs in a subdirectory of the package.
2829
await tester.run('root_pkg/lib', 'dart run build_runner build');
2930
expect(tester.readFileTree('root_pkg/.dart_tool/build/generated'), {
3031
'root_pkg/lib/a.txt.copy': 'a',
32+
'other_pkg/lib/b.txt.copy': 'b',
33+
});
34+
35+
// Remove dep on `other_package`, no longer generated.
36+
tester.writePackage(
37+
name: 'root_pkg',
38+
dependencies: ['build_runner'],
39+
pathDependencies: ['builder_pkg'],
40+
files: {'lib/a.txt': 'a'},
41+
);
42+
_deletePubspecs(tester);
43+
await tester.run('root_pkg/lib', 'dart run build_runner build');
44+
expect(tester.readFileTree('root_pkg/.dart_tool/build/generated'), {
45+
'root_pkg/lib/a.txt.copy': 'a',
46+
});
47+
48+
// Change to a workspace, still no dep onto `other_pkg`.
49+
tester.writePackage(
50+
name: 'root_pkg',
51+
dependencies: ['build_runner'],
52+
pathDependencies: ['builder_pkg'],
53+
files: {'lib/a.txt': 'a'},
54+
inWorkspace: true,
55+
);
56+
tester.writePackage(
57+
name: 'other_pkg',
58+
files: {'lib/b.txt': 'b'},
59+
inWorkspace: true,
60+
);
61+
tester.write('pubspec.yaml', '''
62+
name: workspace
63+
environment:
64+
sdk: ^3.5.0
65+
workspace:
66+
- root_pkg
67+
- other_pkg
68+
''');
69+
70+
// Files still not generated for `other_pkg` as it's not a dep.
71+
_deletePubspecs(tester);
72+
await tester.run('root_pkg/lib', 'dart run build_runner build');
73+
expect(tester.readFileTree('root_pkg/.dart_tool/build/generated'), {
74+
'root_pkg/lib/a.txt.copy': 'a',
75+
});
76+
77+
// Add dep onto `other_pkg`.
78+
tester.writePackage(
79+
name: 'root_pkg',
80+
dependencies: ['build_runner'],
81+
pathDependencies: ['builder_pkg'],
82+
workspaceDependencies: ['other_pkg'],
83+
files: {'lib/a.txt': 'a'},
84+
inWorkspace: true,
85+
);
86+
87+
// Files generated for `other_pkg` now it's a dep.
88+
_deletePubspecs(tester);
89+
await tester.run('root_pkg/lib', 'dart run build_runner build');
90+
expect(tester.readFileTree('root_pkg/.dart_tool/build/generated'), {
91+
'root_pkg/lib/a.txt.copy': 'a',
92+
'other_pkg/lib/b.txt.copy': 'b',
3193
});
3294
});
3395
}
96+
97+
// Work around "dart run" issue https://github.com/dart-lang/sdk/issues/61950.
98+
void _deletePubspecs(BuildRunnerTester tester) {
99+
if (tester.read('pubspec.lock') != null) tester.delete('pubspec.lock');
100+
if (tester.read('root_pkg/pubspec.lock') != null) {
101+
tester.delete('root_pkg/pubspec.lock');
102+
}
103+
}

0 commit comments

Comments
 (0)