Skip to content

Commit b6b4a21

Browse files
sigurdmjakemac53
andauthored
Support for resolving package config and pubspec.lock in workspaces (#3684)
Instead of expecting pubspec.lock and .dart_tool/package_config.json to reside in the same folder as pubspec.yaml, we visit each parent of the current directory until we find a .dart_tool/package_config.json, and expect pubspec.lock to exist next to that. Also invoke the generated scripts with an explicit packageConfig. This is to support running build_runner build in a workspace package, as implemented in dart-lang/pub#4127 --------- Co-authored-by: Jake Macdonald <[email protected]>
1 parent 264dee9 commit b6b4a21

File tree

11 files changed

+118
-5
lines changed

11 files changed

+118
-5
lines changed

build_runner/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## 2.4.11-wip
22

3+
- Explicitly pass the current isolates package config instead of assuming the
4+
location, to support the upcoming pub workspaces feature.
5+
36
## 2.4.10
47

58
- Support version `1.x` and `2.x` of `shelf_web_socket` and `2.x` and `3.x`

build_runner/lib/src/build_script_generate/bootstrap.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ Future<int> _createKernelIfNeeded(
164164
'lib/_internal/vm_platform_strong.dill',
165165
enabledExperiments: experiments,
166166
printIncrementalDependencies: false,
167+
packagesJson: (await Isolate.packageConfig)!.toFilePath(),
167168
);
168169

169170
var hadOutput = false;

build_runner_core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## 7.3.1-wip
22

3+
- Support the upcoming pub workspaces feature.
34
- Bump the min sdk to 3.4.0.
45
- Remove some unnecessary casts and non-null assertions now that we have private
56
field promotion.

build_runner_core/lib/src/package_graph/package_graph.dart

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,35 @@ class PackageGraph {
7878
'pubspec.yaml.');
7979
}
8080

81-
final packageConfig =
82-
await findPackageConfig(Directory(packagePath), recurse: false);
81+
// The path of the directory that contains .dart_tool/package_config.json.
82+
//
83+
// Should also contain `pubspec.lock`.
84+
var rootDir = packagePath;
85+
PackageConfig? packageConfig;
86+
// Manually recurse through parent directories, to obtain the [rootDir]
87+
// where a package config was found. It doesn't seem possible to obtain this
88+
// directly with package:package_config.
89+
while (true) {
90+
packageConfig =
91+
await findPackageConfig(Directory(rootDir), recurse: false);
92+
File(p.join(rootDir, '.dart_tool', 'package_config.json'));
93+
if (packageConfig != null) {
94+
break;
95+
}
96+
final next = p.dirname(rootDir);
97+
if (next == rootDir) {
98+
// We have reached the file system root.
99+
break;
100+
}
101+
rootDir = next;
102+
}
103+
83104
if (packageConfig == null) {
84105
throw StateError(
85106
'Unable to find package config for package at $packagePath.');
86107
}
87108

88-
final dependencyTypes = _parseDependencyTypes(packagePath);
109+
final dependencyTypes = _parseDependencyTypes(rootDir);
89110

90111
final nodes = <String, PackageNode>{};
91112
// A consistent package order _should_ mean a consistent order of build
@@ -94,11 +115,13 @@ class PackageGraph {
94115
final consistentlyOrderedPackages = packageConfig.packages.toList()
95116
..sort((a, b) => a.name.compareTo(b.name));
96117
for (final package in consistentlyOrderedPackages) {
97-
var isRoot = package.name == rootPackageName;
118+
final isRoot = package.name == rootPackageName;
98119
nodes[package.name] = PackageNode(
99120
package.name,
100121
package.root.toFilePath(),
101-
isRoot ? DependencyType.path : dependencyTypes[package.name],
122+
// If the package is missing from pubspec.lock, assume it is a path
123+
// dependency.
124+
dependencyTypes[package.name] ?? DependencyType.path,
102125
package.languageVersion,
103126
isRoot: isRoot);
104127
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"configVersion": 2,
3+
"packages": [
4+
{
5+
"name": "workspace",
6+
"rootUri": "../",
7+
"packageUri": "lib/",
8+
"languageVersion": "3.5"
9+
},
10+
{
11+
"name": "a",
12+
"rootUri": "../pkgs/a",
13+
"packageUri": "lib/",
14+
"languageVersion": "3.5"
15+
},
16+
{
17+
"name": "b",
18+
"rootUri": "../pkgs/b",
19+
"packageUri": "lib/",
20+
"languageVersion": "3.5"
21+
}
22+
]
23+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Take special care to include the .dart_tool/package_config.json
2+
#
3+
!.dart_tool
4+
.dart_tool/*
5+
!.dart_tool/package_config.json
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: a
2+
environment:
3+
sdk: ^3.5.0-0
4+
resolution: workspace
5+
dependencies:
6+
b:
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: b
2+
environment:
3+
sdk: ^3.5.0-0
4+
resolution: workspace
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Generated by pub
2+
# See https://dart.dev/tools/pub/glossary#lockfile
3+
packages: {}
4+
sdks:
5+
dart: ">=3.5.0-0 <4.0.0"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: workspace
2+
environment:
3+
sdk: ^3.5.0-0
4+
workspace:
5+
- pkgs/a
6+
- pkgs/b

build_runner_core/test/package_graph/package_graph_test.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,42 @@ void main() {
154154
throwsA(anything));
155155
});
156156
});
157+
158+
group('workspace ', () {
159+
var workspaceFixturePath = 'test/fixtures/workspace';
160+
161+
test('Loads all packages in workspace. Has correct root', () async {
162+
Matcher packageNodeEquals(PackageNode node) => isA<PackageNode>()
163+
.having((c) => c.path, 'path', node.path)
164+
.having((c) => c.dependencies, 'dependencies',
165+
node.dependencies.map(packageNodeEquals))
166+
.having(
167+
(c) => c.dependencyType, 'dependencyType', node.dependencyType);
168+
169+
final graph = await PackageGraph.forPath('$workspaceFixturePath/pkgs/a');
170+
var a = PackageNode(
171+
'a', '$workspaceFixturePath/pkgs/a', DependencyType.path, null,
172+
isRoot: true);
173+
var b = PackageNode(
174+
'b', '$workspaceFixturePath/pkgs/b', DependencyType.path, null);
175+
a.dependencies.add(b);
176+
var workspace = PackageNode(
177+
'workspace',
178+
workspaceFixturePath,
179+
DependencyType.path,
180+
null,
181+
);
182+
183+
expect(graph.allPackages, {
184+
'a': packageNodeEquals(a),
185+
'b': packageNodeEquals(b),
186+
'workspace': packageNodeEquals(workspace),
187+
r'$sdk': anything
188+
});
189+
190+
expect(graph.root, packageNodeEquals(a));
191+
});
192+
});
157193
}
158194

159195
void expectPkg(PackageNode node, String name, String location,

0 commit comments

Comments
 (0)