Skip to content

Commit a7fb7f2

Browse files
authored
Write .dart_tool/package_graph.json when writing package_config.json (#4524)
1 parent 531836e commit a7fb7f2

File tree

5 files changed

+212
-3
lines changed

5 files changed

+212
-3
lines changed

lib/src/entrypoint.dart

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,10 @@ See $workspacesDocUrl for more information.''',
302302
p.normalize(p.join(workspaceRoot.dir, '.dart_tool', 'package_config.json')),
303303
);
304304

305+
late final String packageGraphPath = p.relative(
306+
p.normalize(p.join(workspaceRoot.dir, '.dart_tool', 'package_graph.json')),
307+
);
308+
305309
/// The path to the entrypoint workspace's lockfile.
306310
String get lockFilePath =>
307311
p.normalize(p.join(workspaceRoot.dir, 'pubspec.lock'));
@@ -396,10 +400,12 @@ See $workspacesDocUrl for more information.''',
396400
/// Writes the .dart_tool/package_config.json file and workspace references to
397401
/// it.
398402
///
403+
/// Also writes the .dart_tool.package_graph.json file.
404+
///
399405
/// If the workspace is non-trivial: For each package in the workspace write:
400406
/// `.dart_tool/pub/workspace_ref.json` with a pointer to the workspace root
401407
/// package dir.
402-
Future<void> writePackageConfigFile() async {
408+
Future<void> writePackageConfigFiles() async {
403409
ensureDir(p.dirname(packageConfigPath));
404410
writeTextFile(
405411
packageConfigPath,
@@ -409,6 +415,7 @@ See $workspacesDocUrl for more information.''',
409415
.pubspec.sdkConstraints[sdk.identifier]?.effectiveConstraint,
410416
),
411417
);
418+
writeTextFile(packageGraphPath, await _packageGraphFile(cache));
412419
if (workspaceRoot.workspaceChildren.isNotEmpty) {
413420
for (final package in workspaceRoot.transitiveWorkspace) {
414421
final workspaceRefDir = p.join(package.dir, '.dart_tool', 'pub');
@@ -426,6 +433,30 @@ See $workspacesDocUrl for more information.''',
426433
}
427434
}
428435

436+
Future<String> _packageGraphFile(SystemCache cache) async {
437+
return const JsonEncoder.withIndent(' ').convert({
438+
'roots': workspaceRoot.transitiveWorkspace.map((p) => p.name).toList()
439+
..sort(),
440+
'packages': [
441+
for (final p in workspaceRoot.transitiveWorkspace)
442+
{
443+
'name': p.name,
444+
'version': p.version.toString(),
445+
'dependencies': p.dependencies.keys.toList()..sort(),
446+
'devDependencies': p.devDependencies.keys.toList()..sort(),
447+
},
448+
for (final p in lockFile.packages.values)
449+
{
450+
'name': p.name,
451+
'version': p.version.toString(),
452+
'dependencies': (await cache.describe(p)).dependencies.keys.toList()
453+
..sort(),
454+
},
455+
],
456+
'configVersion': 1,
457+
});
458+
}
459+
429460
/// Returns the contents of the `.dart_tool/package_config` file generated
430461
/// from this entrypoint based on [lockFile].
431462
///
@@ -605,7 +636,7 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without
605636
/// have to reload and reparse all the pubspecs.
606637
_packageGraph = Future.value(PackageGraph.fromSolveResult(this, result));
607638

608-
await writePackageConfigFile();
639+
await writePackageConfigFiles();
609640

610641
try {
611642
if (precompile) {

lib/src/global_packages.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ To recompile executables, first run `$topLevelProgram pub global deactivate $nam
298298
solveResult: result,
299299
);
300300

301-
await entrypoint.writePackageConfigFile();
301+
await entrypoint.writePackageConfigFiles();
302302

303303
await entrypoint.precompileExecutables();
304304

test/package_graph_file_test.dart

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:convert';
6+
import 'dart:io';
7+
8+
import 'package:path/path.dart' as p;
9+
import 'package:test/test.dart';
10+
11+
import 'descriptor.dart' as d;
12+
import 'test_pub.dart';
13+
14+
void main() {
15+
test('package_config.json file is created', () async {
16+
await servePackages()
17+
..serve(
18+
'foo',
19+
'1.2.3',
20+
deps: {'baz': '2.2.2'},
21+
sdk: '^3.5.0',
22+
pubspec: {
23+
// dev_dependencies of non-workspace packages should not be listed
24+
// in the package_graph.
25+
'dev_dependencies': {'test': '^1.0.0'},
26+
},
27+
)
28+
..serve(
29+
'bar',
30+
'3.2.1',
31+
sdk: '^3.5.0',
32+
)
33+
..serve(
34+
'baz',
35+
'2.2.2',
36+
sdk: '^3.5.0',
37+
deps: {'bar': '3.2.1'},
38+
contents: [d.dir('lib', [])],
39+
)
40+
..serve(
41+
'test',
42+
'1.0.0',
43+
sdk: '^3.5.0',
44+
)
45+
..serve(
46+
'test',
47+
'2.0.0',
48+
sdk: '^3.5.0',
49+
);
50+
51+
await d.dir('boo', [
52+
d.libPubspec(
53+
'boo',
54+
'2.0.0',
55+
sdk: '^3.5.0',
56+
deps: {'bar': 'any'},
57+
devDeps: {'test': '^1.0.0'},
58+
),
59+
]).create();
60+
61+
await d.dir(appPath, [
62+
d.appPubspec(
63+
dependencies: {
64+
'foo': '1.2.3',
65+
'boo': {'path': '../boo'},
66+
},
67+
extras: {
68+
'environment': {
69+
'sdk': '^3.5.0',
70+
},
71+
'dev_dependencies': {'test': '^2.0.0'},
72+
'workspace': ['helper/'],
73+
},
74+
),
75+
d.dir('helper', [
76+
d.libPubspec(
77+
'helper',
78+
'2.0.0',
79+
resolutionWorkspace: true,
80+
),
81+
]),
82+
]).create();
83+
84+
await pubGet(
85+
environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
86+
);
87+
88+
final packageGraph = jsonDecode(
89+
File(p.join(d.sandbox, packageGraphFilePath)).readAsStringSync(),
90+
);
91+
expect(packageGraph, {
92+
'roots': ['helper', 'myapp'],
93+
'packages': [
94+
{
95+
'name': 'myapp',
96+
'version': '0.0.0',
97+
'dependencies': ['boo', 'foo'],
98+
'devDependencies': ['test'],
99+
},
100+
{
101+
'name': 'helper',
102+
'version': '2.0.0',
103+
'dependencies': <Object?>[],
104+
'devDependencies': <Object?>[],
105+
},
106+
{'name': 'test', 'version': '2.0.0', 'dependencies': <Object?>[]},
107+
{
108+
'name': 'boo',
109+
'version': '2.0.0',
110+
'dependencies': ['bar'],
111+
},
112+
{
113+
'name': 'foo',
114+
'version': '1.2.3',
115+
'dependencies': ['baz'],
116+
},
117+
{'name': 'bar', 'version': '3.2.1', 'dependencies': <Object?>[]},
118+
{
119+
'name': 'baz',
120+
'version': '2.2.2',
121+
'dependencies': ['bar'],
122+
}
123+
],
124+
'configVersion': 1,
125+
});
126+
});
127+
}

test/test_pub.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ const String appPath = 'myapp';
7575
String packageConfigFilePath =
7676
p.join(appPath, '.dart_tool', 'package_config.json');
7777

78+
/// The path of the ".dart_tool/package_graph.json" file in the mock app used
79+
/// for tests, relative to the sandbox directory.
80+
String packageGraphFilePath =
81+
p.join(appPath, '.dart_tool', 'package_graph.json');
82+
7883
/// The entry from the `.dart_tool/package_config.json` file for [packageName].
7984
Map<String, dynamic> packageSpec(String packageName) => dig(
8085
json.decode(File(d.path(packageConfigFilePath)).readAsStringSync()),

test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,29 @@ MSG : Logs written to $SANDBOX/cache/log/pub_log.txt.
127127
[E] | "generatorVersion": "3.1.2+3",
128128
[E] | "pubCache": "file://$SANDBOX/cache"
129129
[E] | }
130+
[E] IO : Writing $N characters to text file .dart_tool/package_graph.json.
131+
[E] FINE: Contents:
132+
[E] | {
133+
[E] | "roots": [
134+
[E] | "myapp"
135+
[E] | ],
136+
[E] | "packages": [
137+
[E] | {
138+
[E] | "name": "myapp",
139+
[E] | "version": "0.0.0",
140+
[E] | "dependencies": [
141+
[E] | "foo"
142+
[E] | ],
143+
[E] | "devDependencies": []
144+
[E] | },
145+
[E] | {
146+
[E] | "name": "foo",
147+
[E] | "version": "1.0.0",
148+
[E] | "dependencies": []
149+
[E] | }
150+
[E] | ],
151+
[E] | "configVersion": 1
152+
[E] | }
130153
[E] IO : Writing $N characters to text file $SANDBOX/cache/log/pub_log.txt.
131154

132155
-------------------------------- END OF OUTPUT ---------------------------------
@@ -291,6 +314,29 @@ FINE: Contents:
291314
| "generatorVersion": "3.1.2+3",
292315
| "pubCache": "file://$SANDBOX/cache"
293316
| }
317+
IO : Writing $N characters to text file .dart_tool/package_graph.json.
318+
FINE: Contents:
319+
| {
320+
| "roots": [
321+
| "myapp"
322+
| ],
323+
| "packages": [
324+
| {
325+
| "name": "myapp",
326+
| "version": "0.0.0",
327+
| "dependencies": [
328+
| "foo"
329+
| ],
330+
| "devDependencies": []
331+
| },
332+
| {
333+
| "name": "foo",
334+
| "version": "1.0.0",
335+
| "dependencies": []
336+
| }
337+
| ],
338+
| "configVersion": 1
339+
| }
294340
---- End log transcript ----
295341
-------------------------------- END OF OUTPUT ---------------------------------
296342

0 commit comments

Comments
 (0)